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