Update to latest version of squire. fixes #30
Already update later version of Fomantic. fixes #30
This commit is contained in:
parent
3d6e527e3a
commit
5975ab6d68
@ -24,22 +24,19 @@ var win = doc.defaultView;
|
|||||||
var ua = navigator.userAgent;
|
var ua = navigator.userAgent;
|
||||||
|
|
||||||
var isAndroid = /Android/.test( ua );
|
var isAndroid = /Android/.test( ua );
|
||||||
var isIOS = /iP(?:ad|hone|od)/.test( ua );
|
|
||||||
var isMac = /Mac OS X/.test( ua );
|
var isMac = /Mac OS X/.test( ua );
|
||||||
var isWin = /Windows NT/.test( ua );
|
var isWin = /Windows NT/.test( ua );
|
||||||
|
var isIOS = /iP(?:ad|hone|od)/.test( ua ) ||
|
||||||
|
( isMac && !!navigator.maxTouchPoints );
|
||||||
|
|
||||||
var isGecko = /Gecko\//.test( ua );
|
var isGecko = /Gecko\//.test( ua );
|
||||||
var isIElt11 = /Trident\/[456]\./.test( ua );
|
|
||||||
var isPresto = !!win.opera;
|
|
||||||
var isEdge = /Edge\//.test( ua );
|
var isEdge = /Edge\//.test( ua );
|
||||||
var isWebKit = !isEdge && /WebKit\//.test( ua );
|
var isWebKit = !isEdge && /WebKit\//.test( ua );
|
||||||
var isIE = /Trident\/[4567]\./.test( ua );
|
var isIE = /Trident\/[4567]\./.test( ua );
|
||||||
|
|
||||||
var ctrlKey = isMac ? 'meta-' : 'ctrl-';
|
var ctrlKey = isMac ? 'meta-' : 'ctrl-';
|
||||||
|
|
||||||
var useTextFixer = isIElt11 || isPresto;
|
var cantFocusEmptyTextNodes = isWebKit;
|
||||||
var cantFocusEmptyTextNodes = isIElt11 || isWebKit;
|
|
||||||
var losesSelectionOnBlur = isIElt11;
|
|
||||||
|
|
||||||
var canObserveMutations = typeof MutationObserver !== 'undefined';
|
var canObserveMutations = typeof MutationObserver !== 'undefined';
|
||||||
var canWeakMap = typeof WeakMap !== 'undefined';
|
var canWeakMap = typeof WeakMap !== 'undefined';
|
||||||
@ -49,15 +46,6 @@ var notWS = /[^ \t\r\n]/;
|
|||||||
|
|
||||||
var indexOf = Array.prototype.indexOf;
|
var indexOf = Array.prototype.indexOf;
|
||||||
|
|
||||||
// Polyfill for FF3.5
|
|
||||||
if ( !Object.create ) {
|
|
||||||
Object.create = function ( proto ) {
|
|
||||||
var F = function () {};
|
|
||||||
F.prototype = proto;
|
|
||||||
return new F();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Native TreeWalker is buggy in IE and Opera:
|
Native TreeWalker is buggy in IE and Opera:
|
||||||
* IE9/10 sometimes throw errors when calling TreeWalker#nextNode or
|
* IE9/10 sometimes throw errors when calling TreeWalker#nextNode or
|
||||||
@ -390,7 +378,7 @@ function createElement ( doc, tag, props, children ) {
|
|||||||
for ( attr in props ) {
|
for ( attr in props ) {
|
||||||
value = props[ attr ];
|
value = props[ attr ];
|
||||||
if ( value !== undefined ) {
|
if ( value !== undefined ) {
|
||||||
el.setAttribute( attr, props[ attr ] );
|
el.setAttribute( attr, value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,33 +433,12 @@ function fixCursor ( node, root ) {
|
|||||||
fixer = doc.createTextNode( '' );
|
fixer = doc.createTextNode( '' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if ( !node.querySelector( 'BR' ) ) {
|
||||||
if ( useTextFixer ) {
|
|
||||||
while ( node.nodeType !== TEXT_NODE && !isLeaf( node ) ) {
|
|
||||||
child = node.firstChild;
|
|
||||||
if ( !child ) {
|
|
||||||
fixer = doc.createTextNode( '' );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node = child;
|
|
||||||
}
|
|
||||||
if ( node.nodeType === TEXT_NODE ) {
|
|
||||||
// Opera will collapse the block element if it contains
|
|
||||||
// just spaces (but not if it contains no data at all).
|
|
||||||
if ( /^ +$/.test( node.data ) ) {
|
|
||||||
node.data = '';
|
|
||||||
}
|
|
||||||
} else if ( isLeaf( node ) ) {
|
|
||||||
node.parentNode.insertBefore( doc.createTextNode( '' ), node );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( !node.querySelector( 'BR' ) ) {
|
|
||||||
fixer = createElement( doc, 'BR' );
|
fixer = createElement( doc, 'BR' );
|
||||||
while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
|
while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
|
||||||
node = child;
|
node = child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ( fixer ) {
|
if ( fixer ) {
|
||||||
try {
|
try {
|
||||||
node.appendChild( fixer );
|
node.appendChild( fixer );
|
||||||
@ -500,16 +467,14 @@ function fixContainer ( container, root ) {
|
|||||||
isBR = child.nodeName === 'BR';
|
isBR = child.nodeName === 'BR';
|
||||||
if ( !isBR && isInline( child ) ) {
|
if ( !isBR && isInline( child ) ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc,
|
wrapper = createElement( doc, 'div' );
|
||||||
config.blockTag, config.blockAttributes );
|
|
||||||
}
|
}
|
||||||
wrapper.appendChild( child );
|
wrapper.appendChild( child );
|
||||||
i -= 1;
|
i -= 1;
|
||||||
l -= 1;
|
l -= 1;
|
||||||
} else if ( isBR || wrapper ) {
|
} else if ( isBR || wrapper ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc,
|
wrapper = createElement( doc, 'div' );
|
||||||
config.blockTag, config.blockAttributes );
|
|
||||||
}
|
}
|
||||||
fixCursor( wrapper, root );
|
fixCursor( wrapper, root );
|
||||||
if ( isBR ) {
|
if ( isBR ) {
|
||||||
@ -680,18 +645,6 @@ function mergeWithBlock ( block, next, range, root ) {
|
|||||||
range.setStart( block, offset );
|
range.setStart( block, offset );
|
||||||
range.collapse( true );
|
range.collapse( true );
|
||||||
mergeInlines( block, range );
|
mergeInlines( block, range );
|
||||||
|
|
||||||
// Opera inserts a BR if you delete the last piece of text
|
|
||||||
// in a block-level element. Unfortunately, it then gets
|
|
||||||
// confused when setting the selection subsequently and
|
|
||||||
// refuses to accept the range that finishes just before the
|
|
||||||
// BR. Removing the BR fixes the bug.
|
|
||||||
// Steps to reproduce bug: Type "a-b-c" (where - is return)
|
|
||||||
// then backspace twice. The cursor goes to the top instead
|
|
||||||
// of after "b".
|
|
||||||
if ( isPresto && ( last = block.lastChild ) && last.nodeName === 'BR' ) {
|
|
||||||
block.removeChild( last );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeContainers ( node, root ) {
|
function mergeContainers ( node, root ) {
|
||||||
@ -921,6 +874,7 @@ var deleteContentsOfRange = function ( range, root ) {
|
|||||||
// Contents of range will be deleted.
|
// Contents of range will be deleted.
|
||||||
// After method, range will be around inserted content
|
// After method, range will be around inserted content
|
||||||
var insertTreeFragmentIntoRange = function ( range, frag, root ) {
|
var insertTreeFragmentIntoRange = function ( range, frag, root ) {
|
||||||
|
var firstInFragIsInline = frag.firstChild && isInline( frag.firstChild );
|
||||||
var node, block, blockContentsAfterSplit, stopPoint, container, offset;
|
var node, block, blockContentsAfterSplit, stopPoint, container, offset;
|
||||||
var replaceBlock, firstBlockInFrag, nodeAfterSplit, nodeBeforeSplit;
|
var replaceBlock, firstBlockInFrag, nodeAfterSplit, nodeBeforeSplit;
|
||||||
var tempRange;
|
var tempRange;
|
||||||
@ -946,11 +900,17 @@ var insertTreeFragmentIntoRange = function ( range, frag, root ) {
|
|||||||
|
|
||||||
// Merge the contents of the first block in the frag with the focused block.
|
// Merge the contents of the first block in the frag with the focused block.
|
||||||
// If there are contents in the block after the focus point, collect this
|
// If there are contents in the block after the focus point, collect this
|
||||||
// up to insert in the last block later. If the block is empty, replace
|
// up to insert in the last block later. This preserves the style that was
|
||||||
// it instead of merging.
|
// present in this bit of the page.
|
||||||
|
//
|
||||||
|
// If the block being inserted into is empty though, replace it instead of
|
||||||
|
// merging if the fragment had block contents.
|
||||||
|
// e.g. <blockquote><p>Foo</p></blockquote>
|
||||||
|
// This seems a reasonable approximation of user intent.
|
||||||
|
|
||||||
block = getStartBlockOfRange( range, root );
|
block = getStartBlockOfRange( range, root );
|
||||||
firstBlockInFrag = getNextBlock( frag, frag );
|
firstBlockInFrag = getNextBlock( frag, frag );
|
||||||
replaceBlock = !!block && isEmptyBlock( block );
|
replaceBlock = !firstInFragIsInline && !!block && isEmptyBlock( block );
|
||||||
if ( block && firstBlockInFrag && !replaceBlock &&
|
if ( block && firstBlockInFrag && !replaceBlock &&
|
||||||
// Don't merge table cells or PRE elements into block
|
// Don't merge table cells or PRE elements into block
|
||||||
!getNearest( firstBlockInFrag, frag, 'PRE' ) &&
|
!getNearest( firstBlockInFrag, frag, 'PRE' ) &&
|
||||||
@ -1314,12 +1274,6 @@ var onKey = function ( event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On keypress, delete and '.' both have event.keyCode 46
|
|
||||||
// Must check event.which to differentiate.
|
|
||||||
if ( isPresto && event.which === 46 ) {
|
|
||||||
key = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function keys
|
// Function keys
|
||||||
if ( 111 < code && code < 124 ) {
|
if ( 111 < code && code < 124 ) {
|
||||||
key = 'f' + ( code - 111 );
|
key = 'f' + ( code - 111 );
|
||||||
@ -1426,6 +1380,17 @@ var afterDelete = function ( self, range ) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var detachUneditableNode = function ( node, root ) {
|
||||||
|
var parent;
|
||||||
|
while (( parent = node.parentNode )) {
|
||||||
|
if ( parent === root || parent.isContentEditable ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node = parent;
|
||||||
|
}
|
||||||
|
detach( node );
|
||||||
|
};
|
||||||
|
|
||||||
var handleEnter = function ( self, shiftKey, range ) {
|
var handleEnter = function ( self, shiftKey, range ) {
|
||||||
var root = self._root;
|
var root = self._root;
|
||||||
var block, parent, node, offset, nodeAfterSplit;
|
var block, parent, node, offset, nodeAfterSplit;
|
||||||
@ -1571,7 +1536,7 @@ var handleEnter = function ( self, shiftKey, range ) {
|
|||||||
// If you try to select the contents of a 'BR', FF will not let
|
// If you try to select the contents of a 'BR', FF will not let
|
||||||
// you type anything!
|
// you type anything!
|
||||||
if ( !child || child.nodeName === 'BR' ||
|
if ( !child || child.nodeName === 'BR' ||
|
||||||
( child.nodeType === TEXT_NODE && !isPresto ) ) {
|
child.nodeType === TEXT_NODE ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nodeAfterSplit = child;
|
nodeAfterSplit = child;
|
||||||
@ -1639,7 +1604,7 @@ var keyHandlers = {
|
|||||||
if ( previous ) {
|
if ( previous ) {
|
||||||
// If not editable, just delete whole block.
|
// If not editable, just delete whole block.
|
||||||
if ( !previous.isContentEditable ) {
|
if ( !previous.isContentEditable ) {
|
||||||
detach( previous );
|
detachUneditableNode( previous, root );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Otherwise merge.
|
// Otherwise merge.
|
||||||
@ -1706,7 +1671,7 @@ var keyHandlers = {
|
|||||||
if ( next ) {
|
if ( next ) {
|
||||||
// If not editable, just delete whole block.
|
// If not editable, just delete whole block.
|
||||||
if ( !next.isContentEditable ) {
|
if ( !next.isContentEditable ) {
|
||||||
detach( next );
|
detachUneditableNode( next, root );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Otherwise merge.
|
// Otherwise merge.
|
||||||
@ -1882,24 +1847,6 @@ var fontSizes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var styleToSemantic = {
|
var styleToSemantic = {
|
||||||
backgroundColor: {
|
|
||||||
regexp: notWS,
|
|
||||||
replace: function ( doc, classNames, colour ) {
|
|
||||||
return createElement( doc, 'SPAN', {
|
|
||||||
'class': classNames.highlight,
|
|
||||||
style: 'background-color:' + colour
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
regexp: notWS,
|
|
||||||
replace: function ( doc, classNames, colour ) {
|
|
||||||
return createElement( doc, 'SPAN', {
|
|
||||||
'class': classNames.colour,
|
|
||||||
style: 'color:' + colour
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fontWeight: {
|
fontWeight: {
|
||||||
regexp: /^bold|^700/i,
|
regexp: /^bold|^700/i,
|
||||||
replace: function ( doc ) {
|
replace: function ( doc ) {
|
||||||
@ -1941,6 +1888,12 @@ var styleToSemantic = {
|
|||||||
var replaceWithTag = function ( tag ) {
|
var replaceWithTag = function ( tag ) {
|
||||||
return function ( node, parent ) {
|
return function ( node, parent ) {
|
||||||
var el = createElement( node.ownerDocument, tag );
|
var el = createElement( node.ownerDocument, tag );
|
||||||
|
var attributes = node.attributes;
|
||||||
|
var i, l, attribute;
|
||||||
|
for ( i = 0, l = attributes.length; i < l; i += 1 ) {
|
||||||
|
attribute = attributes[i];
|
||||||
|
el.setAttribute( attribute.name, attribute.value );
|
||||||
|
}
|
||||||
parent.replaceChild( el, node );
|
parent.replaceChild( el, node );
|
||||||
el.appendChild( empty( node ) );
|
el.appendChild( empty( node ) );
|
||||||
return el;
|
return el;
|
||||||
@ -1957,6 +1910,10 @@ var replaceStyles = function ( node, parent, config ) {
|
|||||||
css = style[ attr ];
|
css = style[ attr ];
|
||||||
if ( css && converter.regexp.test( css ) ) {
|
if ( css && converter.regexp.test( css ) ) {
|
||||||
el = converter.replace( doc, config.classNames, css );
|
el = converter.replace( doc, config.classNames, css );
|
||||||
|
if ( el.nodeName === node.nodeName &&
|
||||||
|
el.className === node.className ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = el;
|
newTreeTop = el;
|
||||||
}
|
}
|
||||||
@ -1970,18 +1927,13 @@ var replaceStyles = function ( node, parent, config ) {
|
|||||||
|
|
||||||
if ( newTreeTop ) {
|
if ( newTreeTop ) {
|
||||||
newTreeBottom.appendChild( empty( node ) );
|
newTreeBottom.appendChild( empty( node ) );
|
||||||
if ( node.nodeName === 'SPAN' ) {
|
|
||||||
parent.replaceChild( newTreeTop, node );
|
|
||||||
} else {
|
|
||||||
node.appendChild( newTreeTop );
|
node.appendChild( newTreeTop );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return newTreeBottom || node;
|
return newTreeBottom || node;
|
||||||
};
|
};
|
||||||
|
|
||||||
var stylesRewriters = {
|
var stylesRewriters = {
|
||||||
P: replaceStyles,
|
|
||||||
SPAN: replaceStyles,
|
SPAN: replaceStyles,
|
||||||
STRONG: replaceWithTag( 'B' ),
|
STRONG: replaceWithTag( 'B' ),
|
||||||
EM: replaceWithTag( 'I' ),
|
EM: replaceWithTag( 'I' ),
|
||||||
@ -2602,12 +2554,6 @@ function Squire ( root, config ) {
|
|||||||
this._isFocused = false;
|
this._isFocused = false;
|
||||||
this._lastSelection = null;
|
this._lastSelection = null;
|
||||||
|
|
||||||
// IE loses selection state of iframe on blur, so make sure we
|
|
||||||
// cache it just before it loses focus.
|
|
||||||
if ( losesSelectionOnBlur ) {
|
|
||||||
this.addEventListener( 'beforedeactivate', this.getSelection );
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hasZWS = false;
|
this._hasZWS = false;
|
||||||
|
|
||||||
this._lastAnchorNode = null;
|
this._lastAnchorNode = null;
|
||||||
@ -2654,15 +2600,13 @@ function Squire ( root, config ) {
|
|||||||
// IE sometimes fires the beforepaste event twice; make sure it is not run
|
// IE sometimes fires the beforepaste event twice; make sure it is not run
|
||||||
// again before our after paste function is called.
|
// again before our after paste function is called.
|
||||||
this._awaitingPaste = false;
|
this._awaitingPaste = false;
|
||||||
this.addEventListener( isIElt11 ? 'beforecut' : 'cut', onCut );
|
this.addEventListener( 'cut', onCut );
|
||||||
this.addEventListener( 'copy', onCopy );
|
this.addEventListener( 'copy', onCopy );
|
||||||
this.addEventListener( 'keydown', monitorShiftKey );
|
this.addEventListener( 'keydown', monitorShiftKey );
|
||||||
this.addEventListener( 'keyup', monitorShiftKey );
|
this.addEventListener( 'keyup', monitorShiftKey );
|
||||||
this.addEventListener( isIElt11 ? 'beforepaste' : 'paste', onPaste );
|
this.addEventListener( 'paste', onPaste );
|
||||||
this.addEventListener( 'drop', onDrop );
|
this.addEventListener( 'drop', onDrop );
|
||||||
|
this.addEventListener( 'keydown', onKey );
|
||||||
// Opera does not fire keydown repeatedly.
|
|
||||||
this.addEventListener( isPresto ? 'keypress' : 'keydown', onKey );
|
|
||||||
|
|
||||||
// Add key handlers
|
// Add key handlers
|
||||||
this._keyHandlers = Object.create( keyHandlers );
|
this._keyHandlers = Object.create( keyHandlers );
|
||||||
@ -2670,35 +2614,6 @@ function Squire ( root, config ) {
|
|||||||
// Override default properties
|
// Override default properties
|
||||||
this.setConfig( config );
|
this.setConfig( config );
|
||||||
|
|
||||||
// Fix IE<10's buggy implementation of Text#splitText.
|
|
||||||
// If the split is at the end of the node, it doesn't insert the newly split
|
|
||||||
// node into the document, and sets its value to undefined rather than ''.
|
|
||||||
// And even if the split is not at the end, the original node is removed
|
|
||||||
// from the document and replaced by another, rather than just having its
|
|
||||||
// data shortened.
|
|
||||||
// We used to feature test for this, but then found the feature test would
|
|
||||||
// sometimes pass, but later on the buggy behaviour would still appear.
|
|
||||||
// I think IE10 does not have the same bug, but it doesn't hurt to replace
|
|
||||||
// its native fn too and then we don't need yet another UA category.
|
|
||||||
if ( isIElt11 ) {
|
|
||||||
win.Text.prototype.splitText = function ( offset ) {
|
|
||||||
var afterSplit = this.ownerDocument.createTextNode(
|
|
||||||
this.data.slice( offset ) ),
|
|
||||||
next = this.nextSibling,
|
|
||||||
parent = this.parentNode,
|
|
||||||
toDelete = this.length - offset;
|
|
||||||
if ( next ) {
|
|
||||||
parent.insertBefore( afterSplit, next );
|
|
||||||
} else {
|
|
||||||
parent.appendChild( afterSplit );
|
|
||||||
}
|
|
||||||
if ( toDelete ) {
|
|
||||||
this.deleteData( offset, toDelete );
|
|
||||||
}
|
|
||||||
return afterSplit;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
root.setAttribute( 'contenteditable', 'true' );
|
root.setAttribute( 'contenteditable', 'true' );
|
||||||
|
|
||||||
// Remove Firefox's built-in controls
|
// Remove Firefox's built-in controls
|
||||||
@ -4218,24 +4133,7 @@ proto.getHTML = function ( withBookMark ) {
|
|||||||
if ( withBookMark && ( range = this.getSelection() ) ) {
|
if ( withBookMark && ( range = this.getSelection() ) ) {
|
||||||
this._saveRangeToBookmark( range );
|
this._saveRangeToBookmark( range );
|
||||||
}
|
}
|
||||||
if ( useTextFixer ) {
|
|
||||||
root = this._root;
|
|
||||||
node = root;
|
|
||||||
while ( node = getNextBlock( node, root ) ) {
|
|
||||||
if ( !node.textContent && !node.querySelector( 'BR' ) ) {
|
|
||||||
fixer = this.createElement( 'BR' );
|
|
||||||
node.appendChild( fixer );
|
|
||||||
brs.push( fixer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html = this._getHTML().replace( /\u200B/g, '' );
|
html = this._getHTML().replace( /\u200B/g, '' );
|
||||||
if ( useTextFixer ) {
|
|
||||||
l = brs.length;
|
|
||||||
while ( l-- ) {
|
|
||||||
detach( brs[l] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( range ) {
|
if ( range ) {
|
||||||
this._getRangeAndRemoveBookmark( range );
|
this._getRangeAndRemoveBookmark( range );
|
||||||
}
|
}
|
||||||
@ -4356,7 +4254,57 @@ proto.insertImage = function ( src, attributes ) {
|
|||||||
return img;
|
return img;
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.linkRegExp = /\b((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))|([\w\-.%+]+@(?:[\w\-]+\.)+[A-Z]{2,}\b)(?:\?[^&?\s]+=[^&?\s]+(?:&[^&?\s]+=[^&?\s]+)*)?/i;
|
/*
|
||||||
|
const linkRegExp = new RegExp(
|
||||||
|
// Only look on boundaries
|
||||||
|
'\\b(?:' +
|
||||||
|
// Capture group 1: URLs
|
||||||
|
'(' +
|
||||||
|
// Add links to URLS
|
||||||
|
// Starts with:
|
||||||
|
'(?:' +
|
||||||
|
// http(s):// or ftp://
|
||||||
|
'(?:ht|f)tps?:\\/\\/' +
|
||||||
|
// or
|
||||||
|
'|' +
|
||||||
|
// www.
|
||||||
|
'www\\d{0,3}[.]' +
|
||||||
|
// or
|
||||||
|
'|' +
|
||||||
|
// foo90.com/
|
||||||
|
'[a-z0-9][a-z0-9.\\-]*[.][a-z]{2,}\\/' +
|
||||||
|
')' +
|
||||||
|
// Then we get one or more:
|
||||||
|
'(?:' +
|
||||||
|
// Run of non-spaces, non ()<>
|
||||||
|
'[^\\s()<>]+' +
|
||||||
|
// or
|
||||||
|
'|' +
|
||||||
|
// balanced parentheses (one level deep only)
|
||||||
|
'\\([^\\s()<>]+\\)' +
|
||||||
|
')+' +
|
||||||
|
// And we finish with
|
||||||
|
'(?:' +
|
||||||
|
// Not a space or punctuation character
|
||||||
|
'[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]' +
|
||||||
|
// or
|
||||||
|
'|' +
|
||||||
|
// Balanced parentheses.
|
||||||
|
'\\([^\\s()<>]+\\)' +
|
||||||
|
')' +
|
||||||
|
// Capture group 2: Emails
|
||||||
|
')|(' +
|
||||||
|
// Add links to emails
|
||||||
|
'[\\w\\-.%+]+@(?:[\\w\\-]+\\.)+[a-z]{2,}\\b' +
|
||||||
|
// Allow query parameters in the mailto: style
|
||||||
|
'(?:' +
|
||||||
|
'[?][^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+' +
|
||||||
|
'(?:&[^&?\\s]+=[^\\s?&`!()\\[\\]{};:\'".,<>«»“”‘’]+)*' +
|
||||||
|
')?' +
|
||||||
|
'))', 'i' );
|
||||||
|
*/
|
||||||
|
|
||||||
|
proto.linkRegExp = /\b(?:((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9][a-z0-9.\-]*[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:[^\s?&`!()\[\]{};:'".,<>«»“”‘’]|\([^\s()<>]+\)))|([\w\-.%+]+@(?:[\w\-]+\.)+[a-z]{2,}\b(?:[?][^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+(?:&[^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+)*)?))/i;
|
||||||
|
|
||||||
var addLinks = function ( frag, root, self ) {
|
var addLinks = function ( frag, root, self ) {
|
||||||
var doc = frag.ownerDocument;
|
var doc = frag.ownerDocument;
|
||||||
@ -4482,7 +4430,7 @@ proto.insertHTML = function ( html, isPaste ) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
var escapeHTMLFragement = function ( text ) {
|
var escapeHTML = function ( text ) {
|
||||||
return text.split( '&' ).join( '&' )
|
return text.split( '&' ).join( '&' )
|
||||||
.split( '<' ).join( '<' )
|
.split( '<' ).join( '<' )
|
||||||
.split( '>' ).join( '>' )
|
.split( '>' ).join( '>' )
|
||||||
@ -4532,16 +4480,21 @@ proto.insertPlainText = function ( plainText, isPaste ) {
|
|||||||
|
|
||||||
for ( attr in attributes ) {
|
for ( attr in attributes ) {
|
||||||
openBlock += ' ' + attr + '="' +
|
openBlock += ' ' + attr + '="' +
|
||||||
escapeHTMLFragement( attributes[ attr ] ) +
|
escapeHTML( attributes[ attr ] ) +
|
||||||
'"';
|
'"';
|
||||||
}
|
}
|
||||||
openBlock += '>';
|
openBlock += '>';
|
||||||
|
|
||||||
for ( i = 0, l = lines.length; i < l; i += 1 ) {
|
for ( i = 0, l = lines.length; i < l; i += 1 ) {
|
||||||
line = lines[i];
|
line = lines[i];
|
||||||
line = escapeHTMLFragement( line ).replace( / (?= )/g, ' ' );
|
line = escapeHTML( line ).replace( / (?= )/g, ' ' );
|
||||||
|
// We don't wrap the first line in the block, so if it gets inserted
|
||||||
|
// into a blank line it keeps that line's formatting.
|
||||||
// Wrap each line in <div></div>
|
// Wrap each line in <div></div>
|
||||||
lines[i] = openBlock + ( line || '<BR>' ) + closeBlock;
|
if ( i ) {
|
||||||
|
line = openBlock + ( line || '<BR>' ) + closeBlock;
|
||||||
|
}
|
||||||
|
lines[i] = line;
|
||||||
}
|
}
|
||||||
return this.insertHTML( lines.join( '' ), isPaste );
|
return this.insertHTML( lines.join( '' ), isPaste );
|
||||||
};
|
};
|
||||||
|
@ -65,10 +65,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*.fade-enter-active {*/
|
.fade-enter-active {
|
||||||
animation: fade-in .3s;
|
animation: fade-in .3s;
|
||||||
}
|
}
|
||||||
/*.fade-leave-active {*/
|
.fade-leave-active {
|
||||||
animation: fade-in .1s reverse;
|
animation: fade-in .1s reverse;
|
||||||
}
|
}
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
@ -83,7 +83,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- <transition name="fade"> -->
|
<transition name="fade">
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<div class="slide-container" :style="{ 'background-color':bgColor, 'color':textColor}">
|
<div class="slide-container" :style="{ 'background-color':bgColor, 'color':textColor}">
|
||||||
|
Loading…
Reference in New Issue
Block a user