mirror of
https://github.com/fastmail/Squire.git
synced 2025-01-03 05:00:13 -05:00
Made JSCS checking much, much stricter, brought code into line with checking.
This commit is contained in:
parent
0ec3c43791
commit
a88e7018da
10 changed files with 242 additions and 224 deletions
24
.jscsrc
24
.jscsrc
|
@ -1,6 +1,22 @@
|
||||||
{
|
{
|
||||||
"disallowSpacesInsideParentheses": false,
|
"requireCamelCaseOrUpperCaseIdentifiers": true,
|
||||||
"disallowSpacesInFunctionDeclaration": {
|
"requireCapitalizedConstructors": true,
|
||||||
"beforeOpeningRoundBrace": false
|
"requireCurlyBraces": true,
|
||||||
}
|
"requireDotNotation": true,
|
||||||
|
"requireLineBreakAfterVariableAssignment": true,
|
||||||
|
"requireLineFeedAtFileEnd": true,
|
||||||
|
"requireSpaceAfterBinaryOperators": true,
|
||||||
|
"requireSpaceBeforeBinaryOperators": true,
|
||||||
|
"requireSpaceBeforeBlockStatements": true,
|
||||||
|
"requireSpaceBetweenArguments": true,
|
||||||
|
"requireSpaceBeforeKeywords": true,
|
||||||
|
"requireSpacesInConditionalExpression": true,
|
||||||
|
"requireSpacesInForStatement": true,
|
||||||
|
"requireSpacesInFunction": {
|
||||||
|
"beforeOpeningRoundBrace": true,
|
||||||
|
"beforeOpeningCurlyBrace": true
|
||||||
|
},
|
||||||
|
"requireSpacesInsideBrackets": true,
|
||||||
|
"requireSpacesInsideParentheses": "all",
|
||||||
|
"validateQuoteMarks": "'"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
( function ( doc, undefined ) {
|
( function ( doc, undefined ) {
|
||||||
|
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
var DOCUMENT_POSITION_PRECEDING = 2; // Node.DOCUMENT_POSITION_PRECEDING
|
var DOCUMENT_POSITION_PRECEDING = 2; // Node.DOCUMENT_POSITION_PRECEDING
|
||||||
var ELEMENT_NODE = 1; // Node.ELEMENT_NODE;
|
var ELEMENT_NODE = 1; // Node.ELEMENT_NODE;
|
||||||
|
@ -180,7 +180,7 @@ var leafNodeNames = {
|
||||||
function every ( nodeList, fn ) {
|
function every ( nodeList, fn ) {
|
||||||
var l = nodeList.length;
|
var l = nodeList.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( !fn( nodeList[l] ) ) {
|
if ( !fn( nodeList[ l ] ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,15 +200,6 @@ function hasTagAttributes ( node, tag, attributes ) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
function areAlike ( node, node2 ) {
|
|
||||||
return !isLeaf( node ) && (
|
|
||||||
node.nodeType === node2.nodeType &&
|
|
||||||
node.nodeName === node2.nodeName &&
|
|
||||||
node.className === node2.className &&
|
|
||||||
( ( !node.style && !node2.style ) ||
|
|
||||||
node.style.cssText === node2.style.cssText )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isLeaf ( node ) {
|
function isLeaf ( node ) {
|
||||||
return node.nodeType === ELEMENT_NODE &&
|
return node.nodeType === ELEMENT_NODE &&
|
||||||
|
@ -228,6 +219,16 @@ function isContainer ( node ) {
|
||||||
!isInline( node ) && !isBlock( node );
|
!isInline( node ) && !isBlock( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function areAlike ( node, node2 ) {
|
||||||
|
return !isLeaf( node ) && (
|
||||||
|
node.nodeType === node2.nodeType &&
|
||||||
|
node.nodeName === node2.nodeName &&
|
||||||
|
node.className === node2.className &&
|
||||||
|
( ( !node.style && !node2.style ) ||
|
||||||
|
node.style.cssText === node2.style.cssText )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function getBlockWalker ( node ) {
|
function getBlockWalker ( node ) {
|
||||||
var doc = node.ownerDocument,
|
var doc = node.ownerDocument,
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
|
@ -321,7 +322,7 @@ function createElement ( doc, tag, props, children ) {
|
||||||
}
|
}
|
||||||
if ( children ) {
|
if ( children ) {
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
el.appendChild( children[i] );
|
el.appendChild( children[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
|
@ -408,7 +409,7 @@ function fixContainer ( container ) {
|
||||||
config = getSquireInstance( doc )._config;
|
config = getSquireInstance( doc )._config;
|
||||||
|
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
child = children[i];
|
child = children[ i ];
|
||||||
isBR = child.nodeName === 'BR';
|
isBR = child.nodeName === 'BR';
|
||||||
if ( !isBR && isInline( child ) ) {
|
if ( !isBR && isInline( child ) ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
|
@ -503,7 +504,7 @@ function mergeInlines ( node, range ) {
|
||||||
frags = [],
|
frags = [],
|
||||||
child, prev, len;
|
child, prev, len;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
child = children[l];
|
child = children[ l ];
|
||||||
prev = l && children[ l - 1 ];
|
prev = l && children[ l - 1 ];
|
||||||
if ( l && isInline( child ) && areAlike( child, prev ) &&
|
if ( l && isInline( child ) && areAlike( child, prev ) &&
|
||||||
!leafNodeNames[ child.nodeName ] ) {
|
!leafNodeNames[ child.nodeName ] ) {
|
||||||
|
@ -698,7 +699,7 @@ var insertNodeInRange = function ( range, node ) {
|
||||||
|
|
||||||
childCount = children.length;
|
childCount = children.length;
|
||||||
|
|
||||||
if ( startOffset === childCount) {
|
if ( startOffset === childCount ) {
|
||||||
startContainer.appendChild( node );
|
startContainer.appendChild( node );
|
||||||
} else {
|
} else {
|
||||||
startContainer.insertBefore( node, children[ startOffset ] );
|
startContainer.insertBefore( node, children[ startOffset ] );
|
||||||
|
@ -817,7 +818,7 @@ var insertTreeFragmentIntoRange = function ( range, frag ) {
|
||||||
children = frag.childNodes,
|
children = frag.childNodes,
|
||||||
l = children.length;
|
l = children.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( !isInline( children[l] ) ) {
|
if ( !isInline( children[ l ] ) ) {
|
||||||
allInline = false;
|
allInline = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1083,7 +1084,7 @@ var getEndBlockOfRange = function ( range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var contentWalker = new TreeWalker( null,
|
var contentWalker = new TreeWalker( null,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return node.nodeType === TEXT_NODE ?
|
return node.nodeType === TEXT_NODE ?
|
||||||
notWS.test( node.data ) :
|
notWS.test( node.data ) :
|
||||||
|
@ -1633,7 +1634,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'highlight',
|
'class': 'highlight',
|
||||||
style: 'background-color: ' + colour
|
style: 'background-color: ' + colour
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
|
@ -1642,7 +1643,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
style: 'color:' + colour
|
style: 'color:' + colour
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fontWeight: {
|
fontWeight: {
|
||||||
|
@ -1663,7 +1664,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:' + family
|
style: 'font-family:' + family
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
|
@ -1672,7 +1673,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
style: 'font-size:' + size
|
style: 'font-size:' + size
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1728,7 +1729,7 @@ var stylesRewriters = {
|
||||||
fontSpan = createElement( doc, 'SPAN', {
|
fontSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:' + face
|
style: 'font-family:' + face
|
||||||
});
|
} );
|
||||||
newTreeTop = fontSpan;
|
newTreeTop = fontSpan;
|
||||||
newTreeBottom = fontSpan;
|
newTreeBottom = fontSpan;
|
||||||
}
|
}
|
||||||
|
@ -1736,7 +1737,7 @@ var stylesRewriters = {
|
||||||
sizeSpan = createElement( doc, 'SPAN', {
|
sizeSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
style: 'font-size:' + fontSizes[ size ] + 'px'
|
style: 'font-size:' + fontSizes[ size ] + 'px'
|
||||||
});
|
} );
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = sizeSpan;
|
newTreeTop = sizeSpan;
|
||||||
}
|
}
|
||||||
|
@ -1752,7 +1753,7 @@ var stylesRewriters = {
|
||||||
colourSpan = createElement( doc, 'SPAN', {
|
colourSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
style: 'color:' + colour
|
style: 'color:' + colour
|
||||||
});
|
} );
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = colourSpan;
|
newTreeTop = colourSpan;
|
||||||
}
|
}
|
||||||
|
@ -1772,7 +1773,7 @@ var stylesRewriters = {
|
||||||
var el = createElement( node.ownerDocument, 'SPAN', {
|
var el = createElement( node.ownerDocument, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:menlo,consolas,"courier new",monospace'
|
style: 'font-family:menlo,consolas,"courier new",monospace'
|
||||||
});
|
} );
|
||||||
parent.replaceChild( el, node );
|
parent.replaceChild( el, node );
|
||||||
el.appendChild( empty( node ) );
|
el.appendChild( empty( node ) );
|
||||||
return el;
|
return el;
|
||||||
|
@ -1783,9 +1784,9 @@ var allowedBlock = /^(?:A(?:DDRESS|RTICLE|SIDE|UDIO)|BLOCKQUOTE|CAPTION|D(?:[DLT
|
||||||
|
|
||||||
var blacklist = /^(?:HEAD|META|STYLE)/;
|
var blacklist = /^(?:HEAD|META|STYLE)/;
|
||||||
|
|
||||||
var walker = new TreeWalker( null, SHOW_TEXT|SHOW_ELEMENT, function () {
|
var walker = new TreeWalker( null, SHOW_TEXT | SHOW_ELEMENT, function () {
|
||||||
return true;
|
return true;
|
||||||
});
|
} );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Two purposes:
|
Two purposes:
|
||||||
|
@ -1806,7 +1807,7 @@ var cleanTree = function cleanTree ( node ) {
|
||||||
walker.root = nonInlineParent;
|
walker.root = nonInlineParent;
|
||||||
|
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
child = children[i];
|
child = children[ i ];
|
||||||
nodeName = child.nodeName;
|
nodeName = child.nodeName;
|
||||||
nodeType = child.nodeType;
|
nodeType = child.nodeType;
|
||||||
rewriter = stylesRewriters[ nodeName ];
|
rewriter = stylesRewriters[ nodeName ];
|
||||||
|
@ -1893,7 +1894,7 @@ var removeEmptyInlines = function removeEmptyInlines ( root ) {
|
||||||
l = children.length,
|
l = children.length,
|
||||||
child;
|
child;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
child = children[l];
|
child = children[ l ];
|
||||||
if ( child.nodeType === ELEMENT_NODE && !isLeaf( child ) ) {
|
if ( child.nodeType === ELEMENT_NODE && !isLeaf( child ) ) {
|
||||||
removeEmptyInlines( child );
|
removeEmptyInlines( child );
|
||||||
if ( isInline( child ) && !child.firstChild ) {
|
if ( isInline( child ) && !child.firstChild ) {
|
||||||
|
@ -1919,7 +1920,7 @@ var isLineBreak = function ( br ) {
|
||||||
block = block.parentNode;
|
block = block.parentNode;
|
||||||
}
|
}
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode );
|
block, SHOW_ELEMENT | SHOW_TEXT, notWSTextNode );
|
||||||
walker.currentNode = br;
|
walker.currentNode = br;
|
||||||
return !!walker.nextNode();
|
return !!walker.nextNode();
|
||||||
};
|
};
|
||||||
|
@ -1942,10 +1943,10 @@ var cleanupBRs = function ( root ) {
|
||||||
// therefore seem to not be a line break. But in its original context it
|
// therefore seem to not be a line break. But in its original context it
|
||||||
// was, so we should also convert it to a block split.
|
// was, so we should also convert it to a block split.
|
||||||
for ( i = 0; i < l; i += 1 ) {
|
for ( i = 0; i < l; i += 1 ) {
|
||||||
brBreaksLine[i] = isLineBreak( brs[i] );
|
brBreaksLine[ i ] = isLineBreak( brs[ i ] );
|
||||||
}
|
}
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
br = brs[l];
|
br = brs[ l ];
|
||||||
// Cleanup may have removed it
|
// Cleanup may have removed it
|
||||||
parent = br.parentNode;
|
parent = br.parentNode;
|
||||||
if ( !parent ) { continue; }
|
if ( !parent ) { continue; }
|
||||||
|
@ -1953,7 +1954,7 @@ var cleanupBRs = function ( root ) {
|
||||||
// anything useful. We'll add it back later if required by the
|
// anything useful. We'll add it back later if required by the
|
||||||
// browser. If it breaks a line, wrap the content in div tags
|
// browser. If it breaks a line, wrap the content in div tags
|
||||||
// and replace the brs.
|
// and replace the brs.
|
||||||
if ( !brBreaksLine[l] ) {
|
if ( !brBreaksLine[ l ] ) {
|
||||||
detach( br );
|
detach( br );
|
||||||
} else if ( !isInline( parent ) ) {
|
} else if ( !isInline( parent ) ) {
|
||||||
fixContainer( parent );
|
fixContainer( parent );
|
||||||
|
@ -1995,13 +1996,13 @@ var onPaste = function ( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
l = items.length;
|
l = items.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
item = items[l];
|
item = items[ l ];
|
||||||
type = item.type;
|
type = item.type;
|
||||||
if ( type === 'text/html' ) {
|
if ( type === 'text/html' ) {
|
||||||
/*jshint loopfunc: true */
|
/*jshint loopfunc: true */
|
||||||
item.getAsString( function ( html ) {
|
item.getAsString( function ( html ) {
|
||||||
self.insertHTML( html, true );
|
self.insertHTML( html, true );
|
||||||
});
|
} );
|
||||||
/*jshint loopfunc: false */
|
/*jshint loopfunc: false */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2021,16 +2022,16 @@ var onPaste = function ( event ) {
|
||||||
fireDrop = true;
|
fireDrop = true;
|
||||||
}
|
}
|
||||||
/*jshint loopfunc: false */
|
/*jshint loopfunc: false */
|
||||||
});
|
} );
|
||||||
if ( fireDrop ) {
|
if ( fireDrop ) {
|
||||||
this.fireEvent( 'drop', {
|
this.fireEvent( 'drop', {
|
||||||
dataTransfer: clipboardData
|
dataTransfer: clipboardData
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
} else if ( plainItem ) {
|
} else if ( plainItem ) {
|
||||||
item.getAsString( function ( text ) {
|
item.getAsString( function ( text ) {
|
||||||
self.insertPlainText( text, true );
|
self.insertPlainText( text, true );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2050,9 +2051,9 @@ var onPaste = function ( event ) {
|
||||||
// Abiword on Linux copies a plain text and html version, but the HTML
|
// Abiword on Linux copies a plain text and html version, but the HTML
|
||||||
// version is the empty string! So always try to get HTML, but if none,
|
// version is the empty string! So always try to get HTML, but if none,
|
||||||
// insert plain text instead.
|
// insert plain text instead.
|
||||||
if (( data = clipboardData.getData( 'text/html' ) )) {
|
if ( ( data = clipboardData.getData( 'text/html' ) ) ) {
|
||||||
this.insertHTML( data, true );
|
this.insertHTML( data, true );
|
||||||
} else if (( data = clipboardData.getData( 'text/plain' ) )) {
|
} else if ( ( data = clipboardData.getData( 'text/plain' ) ) ) {
|
||||||
this.insertPlainText( data, true );
|
this.insertPlainText( data, true );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2078,7 +2079,7 @@ var onPaste = function ( event ) {
|
||||||
( body.scrollTop +
|
( body.scrollTop +
|
||||||
( startBlock ? startBlock.getBoundingClientRect().top : 0 ) ) +
|
( startBlock ? startBlock.getBoundingClientRect().top : 0 ) ) +
|
||||||
'px; right: 150%; width: 1px; height: 1px;'
|
'px; right: 150%; width: 1px; height: 1px;'
|
||||||
});
|
} );
|
||||||
body.appendChild( pasteArea );
|
body.appendChild( pasteArea );
|
||||||
range.selectNodeContents( pasteArea );
|
range.selectNodeContents( pasteArea );
|
||||||
this.setSelection( range );
|
this.setSelection( range );
|
||||||
|
@ -2130,7 +2131,7 @@ function getSquireInstance ( doc ) {
|
||||||
var l = instances.length,
|
var l = instances.length,
|
||||||
instance;
|
instance;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
instance = instances[l];
|
instance = instances[ l ];
|
||||||
if ( instance._doc === doc ) {
|
if ( instance._doc === doc ) {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -2197,7 +2198,7 @@ function Squire ( doc, config ) {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
characterData: true,
|
characterData: true,
|
||||||
subtree: true
|
subtree: true
|
||||||
});
|
} );
|
||||||
this._mutation = mutation;
|
this._mutation = mutation;
|
||||||
} else {
|
} else {
|
||||||
this.addEventListener( 'keyup', this._keyUpDetectChange );
|
this.addEventListener( 'keyup', this._keyUpDetectChange );
|
||||||
|
@ -2265,7 +2266,7 @@ function Squire ( doc, config ) {
|
||||||
var proto = Squire.prototype;
|
var proto = Squire.prototype;
|
||||||
|
|
||||||
proto.setConfig = function ( config ) {
|
proto.setConfig = function ( config ) {
|
||||||
config = mergeObjects({
|
config = mergeObjects( {
|
||||||
blockTag: 'DIV',
|
blockTag: 'DIV',
|
||||||
blockAttributes: null,
|
blockAttributes: null,
|
||||||
tagAttributes: {
|
tagAttributes: {
|
||||||
|
@ -2327,7 +2328,7 @@ proto.fireEvent = function ( type, event ) {
|
||||||
handlers = handlers.slice();
|
handlers = handlers.slice();
|
||||||
l = handlers.length;
|
l = handlers.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
obj = handlers[l];
|
obj = handlers[ l ];
|
||||||
try {
|
try {
|
||||||
if ( obj.handleEvent ) {
|
if ( obj.handleEvent ) {
|
||||||
obj.handleEvent( event );
|
obj.handleEvent( event );
|
||||||
|
@ -2360,7 +2361,7 @@ proto.destroy = function () {
|
||||||
}
|
}
|
||||||
var l = instances.length;
|
var l = instances.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( instances[l] === this ) {
|
if ( instances[ l ] === this ) {
|
||||||
instances.splice( l, 1 );
|
instances.splice( l, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2373,10 +2374,10 @@ proto.handleEvent = function ( event ) {
|
||||||
proto.addEventListener = function ( type, fn ) {
|
proto.addEventListener = function ( type, fn ) {
|
||||||
var handlers = this._events[ type ];
|
var handlers = this._events[ type ];
|
||||||
if ( !fn ) {
|
if ( !fn ) {
|
||||||
this.didError({
|
this.didError( {
|
||||||
name: 'Squire: addEventListener with null or undefined fn',
|
name: 'Squire: addEventListener with null or undefined fn',
|
||||||
message: 'Event type: ' + type
|
message: 'Event type: ' + type
|
||||||
});
|
} );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
if ( !handlers ) {
|
if ( !handlers ) {
|
||||||
|
@ -2395,7 +2396,7 @@ proto.removeEventListener = function ( type, fn ) {
|
||||||
if ( handlers ) {
|
if ( handlers ) {
|
||||||
l = handlers.length;
|
l = handlers.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( handlers[l] === fn ) {
|
if ( handlers[ l ] === fn ) {
|
||||||
handlers.splice( l, 1 );
|
handlers.splice( l, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2484,7 +2485,7 @@ proto.getSelectedText = function () {
|
||||||
var range = this.getSelection(),
|
var range = this.getSelection(),
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
range.commonAncestorContainer,
|
range.commonAncestorContainer,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return isNodeContainedInRange( range, node, true );
|
return isNodeContainedInRange( range, node, true );
|
||||||
}
|
}
|
||||||
|
@ -2625,11 +2626,11 @@ proto._saveRangeToBookmark = function ( range ) {
|
||||||
var startNode = this.createElement( 'INPUT', {
|
var startNode = this.createElement( 'INPUT', {
|
||||||
id: startSelectionId,
|
id: startSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
endNode = this.createElement( 'INPUT', {
|
endNode = this.createElement( 'INPUT', {
|
||||||
id: endSelectionId,
|
id: endSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
temp;
|
temp;
|
||||||
|
|
||||||
insertNodeInRange( range, startNode );
|
insertNodeInRange( range, startNode );
|
||||||
|
@ -2705,7 +2706,7 @@ proto._keyUpDetectChange = function ( event ) {
|
||||||
// 3. The key pressed is not in range 33<=x<=45 (navigation keys)
|
// 3. The key pressed is not in range 33<=x<=45 (navigation keys)
|
||||||
if ( !event.ctrlKey && !event.metaKey && !event.altKey &&
|
if ( !event.ctrlKey && !event.metaKey && !event.altKey &&
|
||||||
( code < 16 || code > 20 ) &&
|
( code < 16 || code > 20 ) &&
|
||||||
( code < 33 || code > 45 ) ) {
|
( code < 33 || code > 45 ) ) {
|
||||||
this._docWasChanged();
|
this._docWasChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2720,7 +2721,7 @@ proto._docWasChanged = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: true,
|
canUndo: true,
|
||||||
canRedo: false
|
canRedo: false
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
};
|
};
|
||||||
|
@ -2734,7 +2735,7 @@ proto._recordUndoState = function ( range ) {
|
||||||
undoStack = this._undoStack;
|
undoStack = this._undoStack;
|
||||||
|
|
||||||
// Truncate stack if longer (i.e. if has been previously undone)
|
// Truncate stack if longer (i.e. if has been previously undone)
|
||||||
if ( undoIndex < this._undoStackLength) {
|
if ( undoIndex < this._undoStackLength ) {
|
||||||
undoStack.length = this._undoStackLength = undoIndex;
|
undoStack.length = this._undoStackLength = undoIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2764,7 +2765,7 @@ proto.undo = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: this._undoIndex !== 0,
|
canUndo: this._undoIndex !== 0,
|
||||||
canRedo: true
|
canRedo: true
|
||||||
});
|
} );
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -2785,7 +2786,7 @@ proto.redo = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: true,
|
canUndo: true,
|
||||||
canRedo: undoIndex + 2 < undoStackLength
|
canRedo: undoIndex + 2 < undoStackLength
|
||||||
});
|
} );
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -2895,10 +2896,10 @@ proto._addFormat = function ( tag, attributes, range ) {
|
||||||
// and adding other styles is harmless.
|
// and adding other styles is harmless.
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
range.commonAncestorContainer,
|
range.commonAncestorContainer,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return ( node.nodeType === TEXT_NODE ||
|
return ( node.nodeType === TEXT_NODE ||
|
||||||
node.nodeName === 'BR'||
|
node.nodeName === 'BR' ||
|
||||||
node.nodeName === 'IMG' ) &&
|
node.nodeName === 'IMG' ) &&
|
||||||
isNodeContainedInRange( range, node, true );
|
isNodeContainedInRange( range, node, true );
|
||||||
},
|
},
|
||||||
|
@ -3015,7 +3016,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
// Ignore bookmarks and empty text nodes
|
// Ignore bookmarks and empty text nodes
|
||||||
if ( node.nodeName !== 'INPUT' &&
|
if ( node.nodeName !== 'INPUT' &&
|
||||||
( !isText || node.data ) ) {
|
( !isText || node.data ) ) {
|
||||||
toWrap.push([ exemplar, node ]);
|
toWrap.push( [ exemplar, node ] );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3023,11 +3024,11 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
// Split any partially selected text nodes.
|
// Split any partially selected text nodes.
|
||||||
if ( isText ) {
|
if ( isText ) {
|
||||||
if ( node === endContainer && endOffset !== node.length ) {
|
if ( node === endContainer && endOffset !== node.length ) {
|
||||||
toWrap.push([ exemplar, node.splitText( endOffset ) ]);
|
toWrap.push( [ exemplar, node.splitText( endOffset ) ] );
|
||||||
}
|
}
|
||||||
if ( node === startContainer && startOffset ) {
|
if ( node === startContainer && startOffset ) {
|
||||||
node.splitText( startOffset );
|
node.splitText( startOffset );
|
||||||
toWrap.push([ exemplar, node ]);
|
toWrap.push( [ exemplar, node ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If not a text node, recurse onto all children.
|
// If not a text node, recurse onto all children.
|
||||||
|
@ -3050,21 +3051,21 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
if ( !partial ) {
|
if ( !partial ) {
|
||||||
formatTags.forEach( function ( node ) {
|
formatTags.forEach( function ( node ) {
|
||||||
examineNode( node, node );
|
examineNode( node, node );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now wrap unselected nodes in the tag
|
// Now wrap unselected nodes in the tag
|
||||||
toWrap.forEach( function ( item ) {
|
toWrap.forEach( function ( item ) {
|
||||||
// [ exemplar, node ] tuple
|
// [ exemplar, node ] tuple
|
||||||
var el = item[0].cloneNode( false ),
|
var el = item[ 0 ].cloneNode( false ),
|
||||||
node = item[1];
|
node = item[ 1 ];
|
||||||
replaceWith( node, el );
|
replaceWith( node, el );
|
||||||
el.appendChild( node );
|
el.appendChild( node );
|
||||||
});
|
} );
|
||||||
// and remove old formatting tags.
|
// and remove old formatting tags.
|
||||||
formatTags.forEach( function ( el ) {
|
formatTags.forEach( function ( el ) {
|
||||||
replaceWith( el, empty( el ) );
|
replaceWith( el, empty( el ) );
|
||||||
});
|
} );
|
||||||
|
|
||||||
// Merge adjacent inlines:
|
// Merge adjacent inlines:
|
||||||
this._getRangeAndRemoveBookmark( range );
|
this._getRangeAndRemoveBookmark( range );
|
||||||
|
@ -3227,30 +3228,30 @@ var increaseBlockQuoteLevel = function ( frag ) {
|
||||||
return this.createElement( 'BLOCKQUOTE',
|
return this.createElement( 'BLOCKQUOTE',
|
||||||
this._config.tagAttributes.blockquote, [
|
this._config.tagAttributes.blockquote, [
|
||||||
frag
|
frag
|
||||||
]);
|
] );
|
||||||
};
|
};
|
||||||
|
|
||||||
var decreaseBlockQuoteLevel = function ( frag ) {
|
var decreaseBlockQuoteLevel = function ( frag ) {
|
||||||
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
||||||
Array.prototype.filter.call( blockquotes, function ( el ) {
|
Array.prototype.filter.call( blockquotes, function ( el ) {
|
||||||
return !getNearest( el.parentNode, 'BLOCKQUOTE' );
|
return !getNearest( el.parentNode, 'BLOCKQUOTE' );
|
||||||
}).forEach( function ( el ) {
|
} ).forEach( function ( el ) {
|
||||||
replaceWith( el, empty( el ) );
|
replaceWith( el, empty( el ) );
|
||||||
});
|
} );
|
||||||
return frag;
|
return frag;
|
||||||
};
|
};
|
||||||
|
|
||||||
var removeBlockQuote = function (/* frag */) {
|
var removeBlockQuote = function ( /* frag */ ) {
|
||||||
return this.createDefaultBlock([
|
return this.createDefaultBlock( [
|
||||||
this.createElement( 'INPUT', {
|
this.createElement( 'INPUT', {
|
||||||
id: startSelectionId,
|
id: startSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
this.createElement( 'INPUT', {
|
this.createElement( 'INPUT', {
|
||||||
id: endSelectionId,
|
id: endSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
})
|
} )
|
||||||
]);
|
] );
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeList = function ( self, frag, type ) {
|
var makeList = function ( self, frag, type ) {
|
||||||
|
@ -3279,7 +3280,7 @@ var makeList = function ( self, frag, type ) {
|
||||||
node,
|
node,
|
||||||
self.createElement( type, listAttrs, [
|
self.createElement( type, listAttrs, [
|
||||||
newLi
|
newLi
|
||||||
])
|
] )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
newLi.appendChild( node );
|
newLi.appendChild( node );
|
||||||
|
@ -3309,12 +3310,12 @@ var removeList = function ( frag ) {
|
||||||
var lists = frag.querySelectorAll( 'UL, OL' ),
|
var lists = frag.querySelectorAll( 'UL, OL' ),
|
||||||
i, l, ll, list, listFrag, children, child;
|
i, l, ll, list, listFrag, children, child;
|
||||||
for ( i = 0, l = lists.length; i < l; i += 1 ) {
|
for ( i = 0, l = lists.length; i < l; i += 1 ) {
|
||||||
list = lists[i];
|
list = lists[ i ];
|
||||||
listFrag = empty( list );
|
listFrag = empty( list );
|
||||||
children = listFrag.childNodes;
|
children = listFrag.childNodes;
|
||||||
ll = children.length;
|
ll = children.length;
|
||||||
while ( ll-- ) {
|
while ( ll-- ) {
|
||||||
child = children[ll];
|
child = children[ ll ];
|
||||||
replaceWith( child, empty( child ) );
|
replaceWith( child, empty( child ) );
|
||||||
}
|
}
|
||||||
fixContainer( listFrag );
|
fixContainer( listFrag );
|
||||||
|
@ -3331,7 +3332,7 @@ var increaseListLevel = function ( frag ) {
|
||||||
listItemAttrs = tagAttributes.li,
|
listItemAttrs = tagAttributes.li,
|
||||||
listAttrs;
|
listAttrs;
|
||||||
for ( i = 0, l = items.length; i < l; i += 1 ) {
|
for ( i = 0, l = items.length; i < l; i += 1 ) {
|
||||||
item = items[i];
|
item = items[ i ];
|
||||||
if ( !isContainer( item.firstChild ) ) {
|
if ( !isContainer( item.firstChild ) ) {
|
||||||
// type => 'UL' or 'OL'
|
// type => 'UL' or 'OL'
|
||||||
type = item.parentNode.nodeName;
|
type = item.parentNode.nodeName;
|
||||||
|
@ -3343,7 +3344,7 @@ var increaseListLevel = function ( frag ) {
|
||||||
item,
|
item,
|
||||||
this.createElement( 'LI', listItemAttrs, [
|
this.createElement( 'LI', listItemAttrs, [
|
||||||
newParent = this.createElement( type, listAttrs )
|
newParent = this.createElement( type, listAttrs )
|
||||||
])
|
] )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
newParent.appendChild( item );
|
newParent.appendChild( item );
|
||||||
|
@ -3356,7 +3357,7 @@ var decreaseListLevel = function ( frag ) {
|
||||||
var items = frag.querySelectorAll( 'LI' );
|
var items = frag.querySelectorAll( 'LI' );
|
||||||
Array.prototype.filter.call( items, function ( el ) {
|
Array.prototype.filter.call( items, function ( el ) {
|
||||||
return !isContainer( el.firstChild );
|
return !isContainer( el.firstChild );
|
||||||
}).forEach( function ( item ) {
|
} ).forEach( function ( item ) {
|
||||||
var parent = item.parentNode,
|
var parent = item.parentNode,
|
||||||
newParent = parent.parentNode,
|
newParent = parent.parentNode,
|
||||||
first = item.firstChild,
|
first = item.firstChild,
|
||||||
|
@ -3437,7 +3438,7 @@ proto.getHTML = function ( withBookMark ) {
|
||||||
if ( useTextFixer ) {
|
if ( useTextFixer ) {
|
||||||
l = brs.length;
|
l = brs.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
detach( brs[l] );
|
detach( brs[ l ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( range ) {
|
if ( range ) {
|
||||||
|
@ -3543,9 +3544,9 @@ proto.insertElement = function ( el, range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.insertImage = function ( src, attributes ) {
|
proto.insertImage = function ( src, attributes ) {
|
||||||
var img = this.createElement( 'IMG', mergeObjects({
|
var img = this.createElement( 'IMG', mergeObjects( {
|
||||||
src: src
|
src: src
|
||||||
}, attributes ));
|
}, attributes ) );
|
||||||
this.insertElement( img );
|
this.insertElement( img );
|
||||||
return img;
|
return img;
|
||||||
};
|
};
|
||||||
|
@ -3564,18 +3565,18 @@ var addLinks = function ( frag ) {
|
||||||
parent = node.parentNode;
|
parent = node.parentNode;
|
||||||
while ( match = linkRegExp.exec( data ) ) {
|
while ( match = linkRegExp.exec( data ) ) {
|
||||||
index = match.index;
|
index = match.index;
|
||||||
endIndex = index + match[0].length;
|
endIndex = index + match[ 0 ].length;
|
||||||
if ( index ) {
|
if ( index ) {
|
||||||
child = doc.createTextNode( data.slice( 0, index ) );
|
child = doc.createTextNode( data.slice( 0, index ) );
|
||||||
parent.insertBefore( child, node );
|
parent.insertBefore( child, node );
|
||||||
}
|
}
|
||||||
child = doc.createElement( 'A' );
|
child = doc.createElement( 'A' );
|
||||||
child.textContent = data.slice( index, endIndex );
|
child.textContent = data.slice( index, endIndex );
|
||||||
child.href = match[1] ?
|
child.href = match[ 1 ] ?
|
||||||
/^(?:ht|f)tps?:/.test( match[1] ) ?
|
/^(?:ht|f)tps?:/.test( match[ 1 ] ) ?
|
||||||
match[1] :
|
match[ 1 ] :
|
||||||
'http://' + match[1] :
|
'http://' + match[ 1 ] :
|
||||||
'mailto:' + match[2];
|
'mailto:' + match[ 2 ];
|
||||||
parent.insertBefore( child, node );
|
parent.insertBefore( child, node );
|
||||||
node.data = data = data.slice( endIndex );
|
node.data = data = data.slice( endIndex );
|
||||||
}
|
}
|
||||||
|
@ -3643,11 +3644,11 @@ proto.insertPlainText = function ( plainText, isPaste ) {
|
||||||
var lines = plainText.split( '\n' ),
|
var lines = plainText.split( '\n' ),
|
||||||
i, l;
|
i, l;
|
||||||
for ( i = 1, l = lines.length - 1; i < l; i += 1 ) {
|
for ( i = 1, l = lines.length - 1; i < l; i += 1 ) {
|
||||||
lines[i] = '<DIV>' +
|
lines[ i ] = '<DIV>' +
|
||||||
lines[i].split( '&' ).join( '&' )
|
lines[ i ].split( '&' ).join( '&' )
|
||||||
.split( '<' ).join( '<' )
|
.split( '<' ).join( '<' )
|
||||||
.split( '>' ).join( '>' )
|
.split( '>' ).join( '>' )
|
||||||
.replace( / (?= )/g, ' ' ) +
|
.replace( / (?= )/g, ' ' ) +
|
||||||
'</DIV>';
|
'</DIV>';
|
||||||
}
|
}
|
||||||
return this.insertHTML( lines.join( '' ), isPaste );
|
return this.insertHTML( lines.join( '' ), isPaste );
|
||||||
|
@ -3667,7 +3668,7 @@ proto.addStyles = function ( styles ) {
|
||||||
var head = this._doc.documentElement.firstChild,
|
var head = this._doc.documentElement.firstChild,
|
||||||
style = this.createElement( 'STYLE', {
|
style = this.createElement( 'STYLE', {
|
||||||
type: 'text/css'
|
type: 'text/css'
|
||||||
});
|
} );
|
||||||
style.appendChild( this._doc.createTextNode( styles ) );
|
style.appendChild( this._doc.createTextNode( styles ) );
|
||||||
head.appendChild( style );
|
head.appendChild( style );
|
||||||
}
|
}
|
||||||
|
@ -3706,7 +3707,7 @@ proto.makeLink = function ( url, attributes ) {
|
||||||
}
|
}
|
||||||
attributes.href = url;
|
attributes.href = url;
|
||||||
|
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'A',
|
tag: 'A',
|
||||||
attributes: attributes
|
attributes: attributes
|
||||||
}, {
|
}, {
|
||||||
|
@ -3722,7 +3723,7 @@ proto.removeLink = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setFontFace = function ( name ) {
|
proto.setFontFace = function ( name ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
|
@ -3731,11 +3732,11 @@ proto.setFontFace = function ( name ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'font' }
|
attributes: { 'class': 'font' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
proto.setFontSize = function ( size ) {
|
proto.setFontSize = function ( size ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
|
@ -3745,12 +3746,12 @@ proto.setFontSize = function ( size ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'size' }
|
attributes: { 'class': 'size' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setTextColour = function ( colour ) {
|
proto.setTextColour = function ( colour ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
|
@ -3759,12 +3760,12 @@ proto.setTextColour = function ( colour ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'colour' }
|
attributes: { 'class': 'colour' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setHighlightColour = function ( colour ) {
|
proto.setHighlightColour = function ( colour ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'highlight',
|
'class': 'highlight',
|
||||||
|
@ -3773,7 +3774,7 @@ proto.setHighlightColour = function ( colour ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'highlight' }
|
attributes: { 'class': 'highlight' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3783,7 +3784,7 @@ proto.setTextAlignment = function ( alignment ) {
|
||||||
.split( /\s+/ )
|
.split( /\s+/ )
|
||||||
.filter( function ( klass ) {
|
.filter( function ( klass ) {
|
||||||
return !( /align/.test( klass ) );
|
return !( /align/.test( klass ) );
|
||||||
})
|
} )
|
||||||
.join( ' ' ) +
|
.join( ' ' ) +
|
||||||
' align-' + alignment ).trim();
|
' align-' + alignment ).trim();
|
||||||
block.style.textAlign = alignment;
|
block.style.textAlign = alignment;
|
||||||
|
@ -3808,10 +3809,10 @@ function removeFormatting ( self, root, clean ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if ( isBlock( node ) ) {
|
} else if ( isBlock( node ) ) {
|
||||||
clean.appendChild( self.createDefaultBlock([
|
clean.appendChild( self.createDefaultBlock( [
|
||||||
removeFormatting(
|
removeFormatting(
|
||||||
self, node, self._doc.createDocumentFragment() )
|
self, node, self._doc.createDocumentFragment() )
|
||||||
]));
|
] ) );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
removeFormatting( self, node, clean );
|
removeFormatting( self, node, clean );
|
||||||
|
@ -3919,7 +3920,7 @@ if ( typeof exports === 'object' ) {
|
||||||
} else if ( typeof define === 'function' && define.amd ) {
|
} else if ( typeof define === 'function' && define.amd ) {
|
||||||
define( function () {
|
define( function () {
|
||||||
return Squire;
|
return Squire;
|
||||||
});
|
} );
|
||||||
} else {
|
} else {
|
||||||
win.Squire = Squire;
|
win.Squire = Squire;
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'highlight',
|
'class': 'highlight',
|
||||||
style: 'background-color: ' + colour
|
style: 'background-color: ' + colour
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
|
@ -26,7 +26,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
style: 'color:' + colour
|
style: 'color:' + colour
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fontWeight: {
|
fontWeight: {
|
||||||
|
@ -47,7 +47,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:' + family
|
style: 'font-family:' + family
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
|
@ -56,7 +56,7 @@ var spanToSemantic = {
|
||||||
return createElement( doc, 'SPAN', {
|
return createElement( doc, 'SPAN', {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
style: 'font-size:' + size
|
style: 'font-size:' + size
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -112,7 +112,7 @@ var stylesRewriters = {
|
||||||
fontSpan = createElement( doc, 'SPAN', {
|
fontSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:' + face
|
style: 'font-family:' + face
|
||||||
});
|
} );
|
||||||
newTreeTop = fontSpan;
|
newTreeTop = fontSpan;
|
||||||
newTreeBottom = fontSpan;
|
newTreeBottom = fontSpan;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ var stylesRewriters = {
|
||||||
sizeSpan = createElement( doc, 'SPAN', {
|
sizeSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
style: 'font-size:' + fontSizes[ size ] + 'px'
|
style: 'font-size:' + fontSizes[ size ] + 'px'
|
||||||
});
|
} );
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = sizeSpan;
|
newTreeTop = sizeSpan;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ var stylesRewriters = {
|
||||||
colourSpan = createElement( doc, 'SPAN', {
|
colourSpan = createElement( doc, 'SPAN', {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
style: 'color:' + colour
|
style: 'color:' + colour
|
||||||
});
|
} );
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = colourSpan;
|
newTreeTop = colourSpan;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ var stylesRewriters = {
|
||||||
var el = createElement( node.ownerDocument, 'SPAN', {
|
var el = createElement( node.ownerDocument, 'SPAN', {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
style: 'font-family:menlo,consolas,"courier new",monospace'
|
style: 'font-family:menlo,consolas,"courier new",monospace'
|
||||||
});
|
} );
|
||||||
parent.replaceChild( el, node );
|
parent.replaceChild( el, node );
|
||||||
el.appendChild( empty( node ) );
|
el.appendChild( empty( node ) );
|
||||||
return el;
|
return el;
|
||||||
|
@ -167,9 +167,9 @@ var allowedBlock = /^(?:A(?:DDRESS|RTICLE|SIDE|UDIO)|BLOCKQUOTE|CAPTION|D(?:[DLT
|
||||||
|
|
||||||
var blacklist = /^(?:HEAD|META|STYLE)/;
|
var blacklist = /^(?:HEAD|META|STYLE)/;
|
||||||
|
|
||||||
var walker = new TreeWalker( null, SHOW_TEXT|SHOW_ELEMENT, function () {
|
var walker = new TreeWalker( null, SHOW_TEXT | SHOW_ELEMENT, function () {
|
||||||
return true;
|
return true;
|
||||||
});
|
} );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Two purposes:
|
Two purposes:
|
||||||
|
@ -190,7 +190,7 @@ var cleanTree = function cleanTree ( node ) {
|
||||||
walker.root = nonInlineParent;
|
walker.root = nonInlineParent;
|
||||||
|
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
child = children[i];
|
child = children[ i ];
|
||||||
nodeName = child.nodeName;
|
nodeName = child.nodeName;
|
||||||
nodeType = child.nodeType;
|
nodeType = child.nodeType;
|
||||||
rewriter = stylesRewriters[ nodeName ];
|
rewriter = stylesRewriters[ nodeName ];
|
||||||
|
@ -277,7 +277,7 @@ var removeEmptyInlines = function removeEmptyInlines ( root ) {
|
||||||
l = children.length,
|
l = children.length,
|
||||||
child;
|
child;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
child = children[l];
|
child = children[ l ];
|
||||||
if ( child.nodeType === ELEMENT_NODE && !isLeaf( child ) ) {
|
if ( child.nodeType === ELEMENT_NODE && !isLeaf( child ) ) {
|
||||||
removeEmptyInlines( child );
|
removeEmptyInlines( child );
|
||||||
if ( isInline( child ) && !child.firstChild ) {
|
if ( isInline( child ) && !child.firstChild ) {
|
||||||
|
@ -303,7 +303,7 @@ var isLineBreak = function ( br ) {
|
||||||
block = block.parentNode;
|
block = block.parentNode;
|
||||||
}
|
}
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode );
|
block, SHOW_ELEMENT | SHOW_TEXT, notWSTextNode );
|
||||||
walker.currentNode = br;
|
walker.currentNode = br;
|
||||||
return !!walker.nextNode();
|
return !!walker.nextNode();
|
||||||
};
|
};
|
||||||
|
@ -326,10 +326,10 @@ var cleanupBRs = function ( root ) {
|
||||||
// therefore seem to not be a line break. But in its original context it
|
// therefore seem to not be a line break. But in its original context it
|
||||||
// was, so we should also convert it to a block split.
|
// was, so we should also convert it to a block split.
|
||||||
for ( i = 0; i < l; i += 1 ) {
|
for ( i = 0; i < l; i += 1 ) {
|
||||||
brBreaksLine[i] = isLineBreak( brs[i] );
|
brBreaksLine[ i ] = isLineBreak( brs[ i ] );
|
||||||
}
|
}
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
br = brs[l];
|
br = brs[ l ];
|
||||||
// Cleanup may have removed it
|
// Cleanup may have removed it
|
||||||
parent = br.parentNode;
|
parent = br.parentNode;
|
||||||
if ( !parent ) { continue; }
|
if ( !parent ) { continue; }
|
||||||
|
@ -337,7 +337,7 @@ var cleanupBRs = function ( root ) {
|
||||||
// anything useful. We'll add it back later if required by the
|
// anything useful. We'll add it back later if required by the
|
||||||
// browser. If it breaks a line, wrap the content in div tags
|
// browser. If it breaks a line, wrap the content in div tags
|
||||||
// and replace the brs.
|
// and replace the brs.
|
||||||
if ( !brBreaksLine[l] ) {
|
if ( !brBreaksLine[ l ] ) {
|
||||||
detach( br );
|
detach( br );
|
||||||
} else if ( !isInline( parent ) ) {
|
} else if ( !isInline( parent ) ) {
|
||||||
fixContainer( parent );
|
fixContainer( parent );
|
||||||
|
|
|
@ -34,13 +34,13 @@ var onPaste = function ( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
l = items.length;
|
l = items.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
item = items[l];
|
item = items[ l ];
|
||||||
type = item.type;
|
type = item.type;
|
||||||
if ( type === 'text/html' ) {
|
if ( type === 'text/html' ) {
|
||||||
/*jshint loopfunc: true */
|
/*jshint loopfunc: true */
|
||||||
item.getAsString( function ( html ) {
|
item.getAsString( function ( html ) {
|
||||||
self.insertHTML( html, true );
|
self.insertHTML( html, true );
|
||||||
});
|
} );
|
||||||
/*jshint loopfunc: false */
|
/*jshint loopfunc: false */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -60,16 +60,16 @@ var onPaste = function ( event ) {
|
||||||
fireDrop = true;
|
fireDrop = true;
|
||||||
}
|
}
|
||||||
/*jshint loopfunc: false */
|
/*jshint loopfunc: false */
|
||||||
});
|
} );
|
||||||
if ( fireDrop ) {
|
if ( fireDrop ) {
|
||||||
this.fireEvent( 'drop', {
|
this.fireEvent( 'drop', {
|
||||||
dataTransfer: clipboardData
|
dataTransfer: clipboardData
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
} else if ( plainItem ) {
|
} else if ( plainItem ) {
|
||||||
item.getAsString( function ( text ) {
|
item.getAsString( function ( text ) {
|
||||||
self.insertPlainText( text, true );
|
self.insertPlainText( text, true );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ var onPaste = function ( event ) {
|
||||||
// Abiword on Linux copies a plain text and html version, but the HTML
|
// Abiword on Linux copies a plain text and html version, but the HTML
|
||||||
// version is the empty string! So always try to get HTML, but if none,
|
// version is the empty string! So always try to get HTML, but if none,
|
||||||
// insert plain text instead.
|
// insert plain text instead.
|
||||||
if (( data = clipboardData.getData( 'text/html' ) )) {
|
if ( ( data = clipboardData.getData( 'text/html' ) ) ) {
|
||||||
this.insertHTML( data, true );
|
this.insertHTML( data, true );
|
||||||
} else if (( data = clipboardData.getData( 'text/plain' ) )) {
|
} else if ( ( data = clipboardData.getData( 'text/plain' ) ) ) {
|
||||||
this.insertPlainText( data, true );
|
this.insertPlainText( data, true );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -117,7 +117,7 @@ var onPaste = function ( event ) {
|
||||||
( body.scrollTop +
|
( body.scrollTop +
|
||||||
( startBlock ? startBlock.getBoundingClientRect().top : 0 ) ) +
|
( startBlock ? startBlock.getBoundingClientRect().top : 0 ) ) +
|
||||||
'px; right: 150%; width: 1px; height: 1px;'
|
'px; right: 150%; width: 1px; height: 1px;'
|
||||||
});
|
} );
|
||||||
body.appendChild( pasteArea );
|
body.appendChild( pasteArea );
|
||||||
range.selectNodeContents( pasteArea );
|
range.selectNodeContents( pasteArea );
|
||||||
this.setSelection( range );
|
this.setSelection( range );
|
||||||
|
|
134
source/Editor.js
134
source/Editor.js
|
@ -6,7 +6,7 @@ function getSquireInstance ( doc ) {
|
||||||
var l = instances.length,
|
var l = instances.length,
|
||||||
instance;
|
instance;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
instance = instances[l];
|
instance = instances[ l ];
|
||||||
if ( instance._doc === doc ) {
|
if ( instance._doc === doc ) {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ function Squire ( doc, config ) {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
characterData: true,
|
characterData: true,
|
||||||
subtree: true
|
subtree: true
|
||||||
});
|
} );
|
||||||
this._mutation = mutation;
|
this._mutation = mutation;
|
||||||
} else {
|
} else {
|
||||||
this.addEventListener( 'keyup', this._keyUpDetectChange );
|
this.addEventListener( 'keyup', this._keyUpDetectChange );
|
||||||
|
@ -141,7 +141,7 @@ function Squire ( doc, config ) {
|
||||||
var proto = Squire.prototype;
|
var proto = Squire.prototype;
|
||||||
|
|
||||||
proto.setConfig = function ( config ) {
|
proto.setConfig = function ( config ) {
|
||||||
config = mergeObjects({
|
config = mergeObjects( {
|
||||||
blockTag: 'DIV',
|
blockTag: 'DIV',
|
||||||
blockAttributes: null,
|
blockAttributes: null,
|
||||||
tagAttributes: {
|
tagAttributes: {
|
||||||
|
@ -203,7 +203,7 @@ proto.fireEvent = function ( type, event ) {
|
||||||
handlers = handlers.slice();
|
handlers = handlers.slice();
|
||||||
l = handlers.length;
|
l = handlers.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
obj = handlers[l];
|
obj = handlers[ l ];
|
||||||
try {
|
try {
|
||||||
if ( obj.handleEvent ) {
|
if ( obj.handleEvent ) {
|
||||||
obj.handleEvent( event );
|
obj.handleEvent( event );
|
||||||
|
@ -236,7 +236,7 @@ proto.destroy = function () {
|
||||||
}
|
}
|
||||||
var l = instances.length;
|
var l = instances.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( instances[l] === this ) {
|
if ( instances[ l ] === this ) {
|
||||||
instances.splice( l, 1 );
|
instances.splice( l, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,10 +249,10 @@ proto.handleEvent = function ( event ) {
|
||||||
proto.addEventListener = function ( type, fn ) {
|
proto.addEventListener = function ( type, fn ) {
|
||||||
var handlers = this._events[ type ];
|
var handlers = this._events[ type ];
|
||||||
if ( !fn ) {
|
if ( !fn ) {
|
||||||
this.didError({
|
this.didError( {
|
||||||
name: 'Squire: addEventListener with null or undefined fn',
|
name: 'Squire: addEventListener with null or undefined fn',
|
||||||
message: 'Event type: ' + type
|
message: 'Event type: ' + type
|
||||||
});
|
} );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
if ( !handlers ) {
|
if ( !handlers ) {
|
||||||
|
@ -271,7 +271,7 @@ proto.removeEventListener = function ( type, fn ) {
|
||||||
if ( handlers ) {
|
if ( handlers ) {
|
||||||
l = handlers.length;
|
l = handlers.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( handlers[l] === fn ) {
|
if ( handlers[ l ] === fn ) {
|
||||||
handlers.splice( l, 1 );
|
handlers.splice( l, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ proto.getSelectedText = function () {
|
||||||
var range = this.getSelection(),
|
var range = this.getSelection(),
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
range.commonAncestorContainer,
|
range.commonAncestorContainer,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return isNodeContainedInRange( range, node, true );
|
return isNodeContainedInRange( range, node, true );
|
||||||
}
|
}
|
||||||
|
@ -501,11 +501,11 @@ proto._saveRangeToBookmark = function ( range ) {
|
||||||
var startNode = this.createElement( 'INPUT', {
|
var startNode = this.createElement( 'INPUT', {
|
||||||
id: startSelectionId,
|
id: startSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
endNode = this.createElement( 'INPUT', {
|
endNode = this.createElement( 'INPUT', {
|
||||||
id: endSelectionId,
|
id: endSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
temp;
|
temp;
|
||||||
|
|
||||||
insertNodeInRange( range, startNode );
|
insertNodeInRange( range, startNode );
|
||||||
|
@ -581,7 +581,7 @@ proto._keyUpDetectChange = function ( event ) {
|
||||||
// 3. The key pressed is not in range 33<=x<=45 (navigation keys)
|
// 3. The key pressed is not in range 33<=x<=45 (navigation keys)
|
||||||
if ( !event.ctrlKey && !event.metaKey && !event.altKey &&
|
if ( !event.ctrlKey && !event.metaKey && !event.altKey &&
|
||||||
( code < 16 || code > 20 ) &&
|
( code < 16 || code > 20 ) &&
|
||||||
( code < 33 || code > 45 ) ) {
|
( code < 33 || code > 45 ) ) {
|
||||||
this._docWasChanged();
|
this._docWasChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -596,7 +596,7 @@ proto._docWasChanged = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: true,
|
canUndo: true,
|
||||||
canRedo: false
|
canRedo: false
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
};
|
};
|
||||||
|
@ -610,7 +610,7 @@ proto._recordUndoState = function ( range ) {
|
||||||
undoStack = this._undoStack;
|
undoStack = this._undoStack;
|
||||||
|
|
||||||
// Truncate stack if longer (i.e. if has been previously undone)
|
// Truncate stack if longer (i.e. if has been previously undone)
|
||||||
if ( undoIndex < this._undoStackLength) {
|
if ( undoIndex < this._undoStackLength ) {
|
||||||
undoStack.length = this._undoStackLength = undoIndex;
|
undoStack.length = this._undoStackLength = undoIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +640,7 @@ proto.undo = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: this._undoIndex !== 0,
|
canUndo: this._undoIndex !== 0,
|
||||||
canRedo: true
|
canRedo: true
|
||||||
});
|
} );
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -661,7 +661,7 @@ proto.redo = function () {
|
||||||
this.fireEvent( 'undoStateChange', {
|
this.fireEvent( 'undoStateChange', {
|
||||||
canUndo: true,
|
canUndo: true,
|
||||||
canRedo: undoIndex + 2 < undoStackLength
|
canRedo: undoIndex + 2 < undoStackLength
|
||||||
});
|
} );
|
||||||
this.fireEvent( 'input' );
|
this.fireEvent( 'input' );
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -771,10 +771,10 @@ proto._addFormat = function ( tag, attributes, range ) {
|
||||||
// and adding other styles is harmless.
|
// and adding other styles is harmless.
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
range.commonAncestorContainer,
|
range.commonAncestorContainer,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return ( node.nodeType === TEXT_NODE ||
|
return ( node.nodeType === TEXT_NODE ||
|
||||||
node.nodeName === 'BR'||
|
node.nodeName === 'BR' ||
|
||||||
node.nodeName === 'IMG' ) &&
|
node.nodeName === 'IMG' ) &&
|
||||||
isNodeContainedInRange( range, node, true );
|
isNodeContainedInRange( range, node, true );
|
||||||
},
|
},
|
||||||
|
@ -891,7 +891,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
// Ignore bookmarks and empty text nodes
|
// Ignore bookmarks and empty text nodes
|
||||||
if ( node.nodeName !== 'INPUT' &&
|
if ( node.nodeName !== 'INPUT' &&
|
||||||
( !isText || node.data ) ) {
|
( !isText || node.data ) ) {
|
||||||
toWrap.push([ exemplar, node ]);
|
toWrap.push( [ exemplar, node ] );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -899,11 +899,11 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
// Split any partially selected text nodes.
|
// Split any partially selected text nodes.
|
||||||
if ( isText ) {
|
if ( isText ) {
|
||||||
if ( node === endContainer && endOffset !== node.length ) {
|
if ( node === endContainer && endOffset !== node.length ) {
|
||||||
toWrap.push([ exemplar, node.splitText( endOffset ) ]);
|
toWrap.push( [ exemplar, node.splitText( endOffset ) ] );
|
||||||
}
|
}
|
||||||
if ( node === startContainer && startOffset ) {
|
if ( node === startContainer && startOffset ) {
|
||||||
node.splitText( startOffset );
|
node.splitText( startOffset );
|
||||||
toWrap.push([ exemplar, node ]);
|
toWrap.push( [ exemplar, node ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If not a text node, recurse onto all children.
|
// If not a text node, recurse onto all children.
|
||||||
|
@ -926,21 +926,21 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
if ( !partial ) {
|
if ( !partial ) {
|
||||||
formatTags.forEach( function ( node ) {
|
formatTags.forEach( function ( node ) {
|
||||||
examineNode( node, node );
|
examineNode( node, node );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now wrap unselected nodes in the tag
|
// Now wrap unselected nodes in the tag
|
||||||
toWrap.forEach( function ( item ) {
|
toWrap.forEach( function ( item ) {
|
||||||
// [ exemplar, node ] tuple
|
// [ exemplar, node ] tuple
|
||||||
var el = item[0].cloneNode( false ),
|
var el = item[ 0 ].cloneNode( false ),
|
||||||
node = item[1];
|
node = item[ 1 ];
|
||||||
replaceWith( node, el );
|
replaceWith( node, el );
|
||||||
el.appendChild( node );
|
el.appendChild( node );
|
||||||
});
|
} );
|
||||||
// and remove old formatting tags.
|
// and remove old formatting tags.
|
||||||
formatTags.forEach( function ( el ) {
|
formatTags.forEach( function ( el ) {
|
||||||
replaceWith( el, empty( el ) );
|
replaceWith( el, empty( el ) );
|
||||||
});
|
} );
|
||||||
|
|
||||||
// Merge adjacent inlines:
|
// Merge adjacent inlines:
|
||||||
this._getRangeAndRemoveBookmark( range );
|
this._getRangeAndRemoveBookmark( range );
|
||||||
|
@ -1103,30 +1103,30 @@ var increaseBlockQuoteLevel = function ( frag ) {
|
||||||
return this.createElement( 'BLOCKQUOTE',
|
return this.createElement( 'BLOCKQUOTE',
|
||||||
this._config.tagAttributes.blockquote, [
|
this._config.tagAttributes.blockquote, [
|
||||||
frag
|
frag
|
||||||
]);
|
] );
|
||||||
};
|
};
|
||||||
|
|
||||||
var decreaseBlockQuoteLevel = function ( frag ) {
|
var decreaseBlockQuoteLevel = function ( frag ) {
|
||||||
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
||||||
Array.prototype.filter.call( blockquotes, function ( el ) {
|
Array.prototype.filter.call( blockquotes, function ( el ) {
|
||||||
return !getNearest( el.parentNode, 'BLOCKQUOTE' );
|
return !getNearest( el.parentNode, 'BLOCKQUOTE' );
|
||||||
}).forEach( function ( el ) {
|
} ).forEach( function ( el ) {
|
||||||
replaceWith( el, empty( el ) );
|
replaceWith( el, empty( el ) );
|
||||||
});
|
} );
|
||||||
return frag;
|
return frag;
|
||||||
};
|
};
|
||||||
|
|
||||||
var removeBlockQuote = function (/* frag */) {
|
var removeBlockQuote = function ( /* frag */ ) {
|
||||||
return this.createDefaultBlock([
|
return this.createDefaultBlock( [
|
||||||
this.createElement( 'INPUT', {
|
this.createElement( 'INPUT', {
|
||||||
id: startSelectionId,
|
id: startSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
} ),
|
||||||
this.createElement( 'INPUT', {
|
this.createElement( 'INPUT', {
|
||||||
id: endSelectionId,
|
id: endSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
})
|
} )
|
||||||
]);
|
] );
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeList = function ( self, frag, type ) {
|
var makeList = function ( self, frag, type ) {
|
||||||
|
@ -1155,7 +1155,7 @@ var makeList = function ( self, frag, type ) {
|
||||||
node,
|
node,
|
||||||
self.createElement( type, listAttrs, [
|
self.createElement( type, listAttrs, [
|
||||||
newLi
|
newLi
|
||||||
])
|
] )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
newLi.appendChild( node );
|
newLi.appendChild( node );
|
||||||
|
@ -1185,12 +1185,12 @@ var removeList = function ( frag ) {
|
||||||
var lists = frag.querySelectorAll( 'UL, OL' ),
|
var lists = frag.querySelectorAll( 'UL, OL' ),
|
||||||
i, l, ll, list, listFrag, children, child;
|
i, l, ll, list, listFrag, children, child;
|
||||||
for ( i = 0, l = lists.length; i < l; i += 1 ) {
|
for ( i = 0, l = lists.length; i < l; i += 1 ) {
|
||||||
list = lists[i];
|
list = lists[ i ];
|
||||||
listFrag = empty( list );
|
listFrag = empty( list );
|
||||||
children = listFrag.childNodes;
|
children = listFrag.childNodes;
|
||||||
ll = children.length;
|
ll = children.length;
|
||||||
while ( ll-- ) {
|
while ( ll-- ) {
|
||||||
child = children[ll];
|
child = children[ ll ];
|
||||||
replaceWith( child, empty( child ) );
|
replaceWith( child, empty( child ) );
|
||||||
}
|
}
|
||||||
fixContainer( listFrag );
|
fixContainer( listFrag );
|
||||||
|
@ -1207,7 +1207,7 @@ var increaseListLevel = function ( frag ) {
|
||||||
listItemAttrs = tagAttributes.li,
|
listItemAttrs = tagAttributes.li,
|
||||||
listAttrs;
|
listAttrs;
|
||||||
for ( i = 0, l = items.length; i < l; i += 1 ) {
|
for ( i = 0, l = items.length; i < l; i += 1 ) {
|
||||||
item = items[i];
|
item = items[ i ];
|
||||||
if ( !isContainer( item.firstChild ) ) {
|
if ( !isContainer( item.firstChild ) ) {
|
||||||
// type => 'UL' or 'OL'
|
// type => 'UL' or 'OL'
|
||||||
type = item.parentNode.nodeName;
|
type = item.parentNode.nodeName;
|
||||||
|
@ -1219,7 +1219,7 @@ var increaseListLevel = function ( frag ) {
|
||||||
item,
|
item,
|
||||||
this.createElement( 'LI', listItemAttrs, [
|
this.createElement( 'LI', listItemAttrs, [
|
||||||
newParent = this.createElement( type, listAttrs )
|
newParent = this.createElement( type, listAttrs )
|
||||||
])
|
] )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
newParent.appendChild( item );
|
newParent.appendChild( item );
|
||||||
|
@ -1232,7 +1232,7 @@ var decreaseListLevel = function ( frag ) {
|
||||||
var items = frag.querySelectorAll( 'LI' );
|
var items = frag.querySelectorAll( 'LI' );
|
||||||
Array.prototype.filter.call( items, function ( el ) {
|
Array.prototype.filter.call( items, function ( el ) {
|
||||||
return !isContainer( el.firstChild );
|
return !isContainer( el.firstChild );
|
||||||
}).forEach( function ( item ) {
|
} ).forEach( function ( item ) {
|
||||||
var parent = item.parentNode,
|
var parent = item.parentNode,
|
||||||
newParent = parent.parentNode,
|
newParent = parent.parentNode,
|
||||||
first = item.firstChild,
|
first = item.firstChild,
|
||||||
|
@ -1313,7 +1313,7 @@ proto.getHTML = function ( withBookMark ) {
|
||||||
if ( useTextFixer ) {
|
if ( useTextFixer ) {
|
||||||
l = brs.length;
|
l = brs.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
detach( brs[l] );
|
detach( brs[ l ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( range ) {
|
if ( range ) {
|
||||||
|
@ -1419,9 +1419,9 @@ proto.insertElement = function ( el, range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.insertImage = function ( src, attributes ) {
|
proto.insertImage = function ( src, attributes ) {
|
||||||
var img = this.createElement( 'IMG', mergeObjects({
|
var img = this.createElement( 'IMG', mergeObjects( {
|
||||||
src: src
|
src: src
|
||||||
}, attributes ));
|
}, attributes ) );
|
||||||
this.insertElement( img );
|
this.insertElement( img );
|
||||||
return img;
|
return img;
|
||||||
};
|
};
|
||||||
|
@ -1440,18 +1440,18 @@ var addLinks = function ( frag ) {
|
||||||
parent = node.parentNode;
|
parent = node.parentNode;
|
||||||
while ( match = linkRegExp.exec( data ) ) {
|
while ( match = linkRegExp.exec( data ) ) {
|
||||||
index = match.index;
|
index = match.index;
|
||||||
endIndex = index + match[0].length;
|
endIndex = index + match[ 0 ].length;
|
||||||
if ( index ) {
|
if ( index ) {
|
||||||
child = doc.createTextNode( data.slice( 0, index ) );
|
child = doc.createTextNode( data.slice( 0, index ) );
|
||||||
parent.insertBefore( child, node );
|
parent.insertBefore( child, node );
|
||||||
}
|
}
|
||||||
child = doc.createElement( 'A' );
|
child = doc.createElement( 'A' );
|
||||||
child.textContent = data.slice( index, endIndex );
|
child.textContent = data.slice( index, endIndex );
|
||||||
child.href = match[1] ?
|
child.href = match[ 1 ] ?
|
||||||
/^(?:ht|f)tps?:/.test( match[1] ) ?
|
/^(?:ht|f)tps?:/.test( match[ 1 ] ) ?
|
||||||
match[1] :
|
match[ 1 ] :
|
||||||
'http://' + match[1] :
|
'http://' + match[ 1 ] :
|
||||||
'mailto:' + match[2];
|
'mailto:' + match[ 2 ];
|
||||||
parent.insertBefore( child, node );
|
parent.insertBefore( child, node );
|
||||||
node.data = data = data.slice( endIndex );
|
node.data = data = data.slice( endIndex );
|
||||||
}
|
}
|
||||||
|
@ -1519,11 +1519,11 @@ proto.insertPlainText = function ( plainText, isPaste ) {
|
||||||
var lines = plainText.split( '\n' ),
|
var lines = plainText.split( '\n' ),
|
||||||
i, l;
|
i, l;
|
||||||
for ( i = 1, l = lines.length - 1; i < l; i += 1 ) {
|
for ( i = 1, l = lines.length - 1; i < l; i += 1 ) {
|
||||||
lines[i] = '<DIV>' +
|
lines[ i ] = '<DIV>' +
|
||||||
lines[i].split( '&' ).join( '&' )
|
lines[ i ].split( '&' ).join( '&' )
|
||||||
.split( '<' ).join( '<' )
|
.split( '<' ).join( '<' )
|
||||||
.split( '>' ).join( '>' )
|
.split( '>' ).join( '>' )
|
||||||
.replace( / (?= )/g, ' ' ) +
|
.replace( / (?= )/g, ' ' ) +
|
||||||
'</DIV>';
|
'</DIV>';
|
||||||
}
|
}
|
||||||
return this.insertHTML( lines.join( '' ), isPaste );
|
return this.insertHTML( lines.join( '' ), isPaste );
|
||||||
|
@ -1543,7 +1543,7 @@ proto.addStyles = function ( styles ) {
|
||||||
var head = this._doc.documentElement.firstChild,
|
var head = this._doc.documentElement.firstChild,
|
||||||
style = this.createElement( 'STYLE', {
|
style = this.createElement( 'STYLE', {
|
||||||
type: 'text/css'
|
type: 'text/css'
|
||||||
});
|
} );
|
||||||
style.appendChild( this._doc.createTextNode( styles ) );
|
style.appendChild( this._doc.createTextNode( styles ) );
|
||||||
head.appendChild( style );
|
head.appendChild( style );
|
||||||
}
|
}
|
||||||
|
@ -1582,7 +1582,7 @@ proto.makeLink = function ( url, attributes ) {
|
||||||
}
|
}
|
||||||
attributes.href = url;
|
attributes.href = url;
|
||||||
|
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'A',
|
tag: 'A',
|
||||||
attributes: attributes
|
attributes: attributes
|
||||||
}, {
|
}, {
|
||||||
|
@ -1598,7 +1598,7 @@ proto.removeLink = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setFontFace = function ( name ) {
|
proto.setFontFace = function ( name ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'font',
|
'class': 'font',
|
||||||
|
@ -1607,11 +1607,11 @@ proto.setFontFace = function ( name ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'font' }
|
attributes: { 'class': 'font' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
proto.setFontSize = function ( size ) {
|
proto.setFontSize = function ( size ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'size',
|
'class': 'size',
|
||||||
|
@ -1621,12 +1621,12 @@ proto.setFontSize = function ( size ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'size' }
|
attributes: { 'class': 'size' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setTextColour = function ( colour ) {
|
proto.setTextColour = function ( colour ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'colour',
|
'class': 'colour',
|
||||||
|
@ -1635,12 +1635,12 @@ proto.setTextColour = function ( colour ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'colour' }
|
attributes: { 'class': 'colour' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setHighlightColour = function ( colour ) {
|
proto.setHighlightColour = function ( colour ) {
|
||||||
this.changeFormat({
|
this.changeFormat( {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: {
|
attributes: {
|
||||||
'class': 'highlight',
|
'class': 'highlight',
|
||||||
|
@ -1649,7 +1649,7 @@ proto.setHighlightColour = function ( colour ) {
|
||||||
}, {
|
}, {
|
||||||
tag: 'SPAN',
|
tag: 'SPAN',
|
||||||
attributes: { 'class': 'highlight' }
|
attributes: { 'class': 'highlight' }
|
||||||
});
|
} );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1659,7 +1659,7 @@ proto.setTextAlignment = function ( alignment ) {
|
||||||
.split( /\s+/ )
|
.split( /\s+/ )
|
||||||
.filter( function ( klass ) {
|
.filter( function ( klass ) {
|
||||||
return !( /align/.test( klass ) );
|
return !( /align/.test( klass ) );
|
||||||
})
|
} )
|
||||||
.join( ' ' ) +
|
.join( ' ' ) +
|
||||||
' align-' + alignment ).trim();
|
' align-' + alignment ).trim();
|
||||||
block.style.textAlign = alignment;
|
block.style.textAlign = alignment;
|
||||||
|
@ -1684,10 +1684,10 @@ function removeFormatting ( self, root, clean ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if ( isBlock( node ) ) {
|
} else if ( isBlock( node ) ) {
|
||||||
clean.appendChild( self.createDefaultBlock([
|
clean.appendChild( self.createDefaultBlock( [
|
||||||
removeFormatting(
|
removeFormatting(
|
||||||
self, node, self._doc.createDocumentFragment() )
|
self, node, self._doc.createDocumentFragment() )
|
||||||
]));
|
] ) );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
removeFormatting( self, node, clean );
|
removeFormatting( self, node, clean );
|
||||||
|
|
|
@ -11,7 +11,7 @@ var leafNodeNames = {
|
||||||
function every ( nodeList, fn ) {
|
function every ( nodeList, fn ) {
|
||||||
var l = nodeList.length;
|
var l = nodeList.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( !fn( nodeList[l] ) ) {
|
if ( !fn( nodeList[ l ] ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,15 +31,6 @@ function hasTagAttributes ( node, tag, attributes ) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
function areAlike ( node, node2 ) {
|
|
||||||
return !isLeaf( node ) && (
|
|
||||||
node.nodeType === node2.nodeType &&
|
|
||||||
node.nodeName === node2.nodeName &&
|
|
||||||
node.className === node2.className &&
|
|
||||||
( ( !node.style && !node2.style ) ||
|
|
||||||
node.style.cssText === node2.style.cssText )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isLeaf ( node ) {
|
function isLeaf ( node ) {
|
||||||
return node.nodeType === ELEMENT_NODE &&
|
return node.nodeType === ELEMENT_NODE &&
|
||||||
|
@ -59,6 +50,16 @@ function isContainer ( node ) {
|
||||||
!isInline( node ) && !isBlock( node );
|
!isInline( node ) && !isBlock( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function areAlike ( node, node2 ) {
|
||||||
|
return !isLeaf( node ) && (
|
||||||
|
node.nodeType === node2.nodeType &&
|
||||||
|
node.nodeName === node2.nodeName &&
|
||||||
|
node.className === node2.className &&
|
||||||
|
( ( !node.style && !node2.style ) ||
|
||||||
|
node.style.cssText === node2.style.cssText )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function getBlockWalker ( node ) {
|
function getBlockWalker ( node ) {
|
||||||
var doc = node.ownerDocument,
|
var doc = node.ownerDocument,
|
||||||
walker = new TreeWalker(
|
walker = new TreeWalker(
|
||||||
|
@ -152,7 +153,7 @@ function createElement ( doc, tag, props, children ) {
|
||||||
}
|
}
|
||||||
if ( children ) {
|
if ( children ) {
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
el.appendChild( children[i] );
|
el.appendChild( children[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
|
@ -239,7 +240,7 @@ function fixContainer ( container ) {
|
||||||
config = getSquireInstance( doc )._config;
|
config = getSquireInstance( doc )._config;
|
||||||
|
|
||||||
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
for ( i = 0, l = children.length; i < l; i += 1 ) {
|
||||||
child = children[i];
|
child = children[ i ];
|
||||||
isBR = child.nodeName === 'BR';
|
isBR = child.nodeName === 'BR';
|
||||||
if ( !isBR && isInline( child ) ) {
|
if ( !isBR && isInline( child ) ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
|
@ -334,7 +335,7 @@ function mergeInlines ( node, range ) {
|
||||||
frags = [],
|
frags = [],
|
||||||
child, prev, len;
|
child, prev, len;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
child = children[l];
|
child = children[ l ];
|
||||||
prev = l && children[ l - 1 ];
|
prev = l && children[ l - 1 ];
|
||||||
if ( l && isInline( child ) && areAlike( child, prev ) &&
|
if ( l && isInline( child ) && areAlike( child, prev ) &&
|
||||||
!leafNodeNames[ child.nodeName ] ) {
|
!leafNodeNames[ child.nodeName ] ) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ var insertNodeInRange = function ( range, node ) {
|
||||||
|
|
||||||
childCount = children.length;
|
childCount = children.length;
|
||||||
|
|
||||||
if ( startOffset === childCount) {
|
if ( startOffset === childCount ) {
|
||||||
startContainer.appendChild( node );
|
startContainer.appendChild( node );
|
||||||
} else {
|
} else {
|
||||||
startContainer.insertBefore( node, children[ startOffset ] );
|
startContainer.insertBefore( node, children[ startOffset ] );
|
||||||
|
@ -185,7 +185,7 @@ var insertTreeFragmentIntoRange = function ( range, frag ) {
|
||||||
children = frag.childNodes,
|
children = frag.childNodes,
|
||||||
l = children.length;
|
l = children.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
if ( !isInline( children[l] ) ) {
|
if ( !isInline( children[ l ] ) ) {
|
||||||
allInline = false;
|
allInline = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -451,7 +451,7 @@ var getEndBlockOfRange = function ( range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var contentWalker = new TreeWalker( null,
|
var contentWalker = new TreeWalker( null,
|
||||||
SHOW_TEXT|SHOW_ELEMENT,
|
SHOW_TEXT | SHOW_ELEMENT,
|
||||||
function ( node ) {
|
function ( node ) {
|
||||||
return node.nodeType === TEXT_NODE ?
|
return node.nodeType === TEXT_NODE ?
|
||||||
notWS.test( node.data ) :
|
notWS.test( node.data ) :
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
|
|
||||||
( function ( doc, undefined ) {
|
( function ( doc, undefined ) {
|
||||||
|
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
|
@ -5,7 +5,7 @@ if ( typeof exports === 'object' ) {
|
||||||
} else if ( typeof define === 'function' && define.amd ) {
|
} else if ( typeof define === 'function' && define.amd ) {
|
||||||
define( function () {
|
define( function () {
|
||||||
return Squire;
|
return Squire;
|
||||||
});
|
} );
|
||||||
} else {
|
} else {
|
||||||
win.Squire = Squire;
|
win.Squire = Squire;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue