0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2025-01-03 05:00:13 -05:00

Allow setting default attributes for ul/ol/li/blockquote.

Merges #83, with fixes, tidying and squashing.
This commit is contained in:
Neil Jenkins 2015-05-09 17:14:51 +07:00
parent 1ec7956c97
commit a2ca4a3864
6 changed files with 178 additions and 97 deletions

View file

@ -128,7 +128,15 @@
return; return;
} }
// Create Squire instance // Create Squire instance
editor = new Squire( doc ); editor = new Squire( doc, {
blockTag: 'p',
blockAttributes: {'class': 'paragraph'},
tagAttributes: {
ul: {'class': 'UL'},
ol: {'class': 'OL'},
li: {'class': 'listItem'}
}
});
// Add styles to frame // Add styles to frame
var style = doc.createElement( 'style' ); var style = doc.createElement( 'style' );
style.type = 'text/css'; style.type = 'text/css';

View file

@ -43,9 +43,16 @@ If you load the library into a top-level document (rather than an iframe), it wi
### Setting the default block style ### Setting the default block style
By default, the editor will use a `<div>` for blank lines, as most users have been conditioned by Microsoft Word to expect <kbd>Enter</kbd> to act like pressing <kbd>return</kbd> on a typewriter. If you would like to use `<p>` tags (or anything else) for the default block type instead, then after calling `var editor = new Squire( document )` (or getting your reference to the ready-made `editor` instance if using the simple setup), set `editor.defaultBlockTag = 'P';`. By default, the editor will use a `<div>` for blank lines, as most users have been conditioned by Microsoft Word to expect <kbd>Enter</kbd> to act like pressing <kbd>return</kbd> on a typewriter. If you would like to use `<p>` tags (or anything else) for the default block type instead, you can pass a config object as the second parameter to the squire constructor. You can also
pass a set of attributes to apply to each default block:
You can also set an object of attributes to apply to each default block node by setting the *defaultBlockProperties* property, e.g. `editor.defaultBlockProperties = { style: 'font-size: 16px;' }`. var editor = new Squire( document, {
blockTag: 'P',
blockAttributes: { style: 'font-size: 16px;' }
})
If using the simple setup, call `editor.setConfig(…);` with your
config object instead. Be sure to do this *before* calling `editor.setHTML()`.
### Determining button state ### Determining button state

View file

@ -222,7 +222,7 @@ function getNearest ( node, tag, attributes ) {
function getPath ( node ) { function getPath ( node ) {
var parent = node.parentNode, var parent = node.parentNode,
path, id, className, classNames; path, id, className, classNames, dir;
if ( !parent || node.nodeType !== ELEMENT_NODE ) { if ( !parent || node.nodeType !== ELEMENT_NODE ) {
path = parent ? getPath( parent ) : ''; path = parent ? getPath( parent ) : '';
} else { } else {
@ -237,6 +237,9 @@ function getPath ( node ) {
path += '.'; path += '.';
path += classNames.join( '.' ); path += classNames.join( '.' );
} }
if ( dir = node.dir ) {
path += '[dir=' + dir + ']';
}
} }
return path; return path;
} }
@ -300,14 +303,11 @@ function fixCursor ( node ) {
// cursor to appear. // cursor to appear.
var doc = node.ownerDocument, var doc = node.ownerDocument,
root = node, root = node,
fixer, child, instance; fixer, child;
if ( node.nodeName === 'BODY' ) { if ( node.nodeName === 'BODY' ) {
if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) { if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) {
instance = getSquireInstance( doc ); fixer = getSquireInstance( doc ).createDefaultBlock();
fixer = instance ?
instance.createDefaultBlock() :
createElement( doc, 'DIV' );
if ( child ) { if ( child ) {
node.replaceChild( fixer, child ); node.replaceChild( fixer, child );
} }
@ -373,17 +373,25 @@ function fixContainer ( container ) {
var children = container.childNodes, var children = container.childNodes,
doc = container.ownerDocument, doc = container.ownerDocument,
wrapper = null, wrapper = null,
i, l, child, isBR; i, l, child, isBR,
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 ) { wrapper = createElement( doc, 'DIV' ); } if ( !wrapper ) {
wrapper = createElement( doc,
config.blockTag, config.blockAttributes );
}
wrapper.appendChild( child ); wrapper.appendChild( child );
i -= 1; i -= 1;
l -= 1; l -= 1;
} else if ( isBR || wrapper ) { } else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); } if ( !wrapper ) {
wrapper = createElement( doc,
config.blockTag, config.blockAttributes );
}
fixCursor( wrapper ); fixCursor( wrapper );
if ( isBR ) { if ( isBR ) {
container.replaceChild( wrapper, child ); container.replaceChild( wrapper, child );
@ -1438,6 +1446,20 @@ function getSquireInstance ( doc ) {
return null; return null;
} }
function mergeObjects ( base, extras ) {
var prop, value;
if ( !base ) {
base = {};
}
for ( prop in extras ) {
value = extras[ prop ];
base[ prop ] = ( value && value.constructor === Object ) ?
mergeObjects( base[ prop ], value ) :
value;
}
return base;
}
function Squire ( doc, config ) { function Squire ( doc, config ) {
var win = doc.defaultView; var win = doc.defaultView;
var body = doc.body; var body = doc.body;
@ -1489,9 +1511,6 @@ function Squire ( doc, config ) {
this.addEventListener( 'keyup', this._keyUpDetectChange ); this.addEventListener( 'keyup', this._keyUpDetectChange );
} }
this.defaultBlockTag = 'DIV';
this.defaultBlockProperties = null;
// IE sometimes fires the beforepaste event twice; make sure it is not run // IE sometimes fires the beforepaste event twice; make sure it is not run
// again before our after paste function is called. // again before our after paste function is called.
this._awaitingPaste = false; this._awaitingPaste = false;
@ -1554,11 +1573,22 @@ function Squire ( doc, config ) {
var proto = Squire.prototype; var proto = Squire.prototype;
proto.setConfig = function ( config ) { proto.setConfig = function ( config ) {
for ( var prop in config ) { config = mergeObjects({
if ( config.hasOwnProperty( prop ) ) { blockTag: 'DIV',
this[ prop ] = config[ prop ]; blockAttributes: null,
tagAttributes: {
blockquote: null,
ul: null,
ol: null,
li: null
} }
} }, config );
// Users may specify block tag in lower case
config.blockTag = config.blockTag.toUpperCase();
this._config = config;
return this; return this;
}; };
@ -1567,9 +1597,9 @@ proto.createElement = function ( tag, props, children ) {
}; };
proto.createDefaultBlock = function ( children ) { proto.createDefaultBlock = function ( children ) {
var config = this._config;
return fixCursor( return fixCursor(
this.createElement( this.createElement( config.blockTag, config.blockAttributes, children )
this.defaultBlockTag, this.defaultBlockProperties, children )
); );
}; };
@ -2352,11 +2382,12 @@ var tagAfterSplit = {
var splitBlock = function ( self, block, node, offset ) { var splitBlock = function ( self, block, node, offset ) {
var splitTag = tagAfterSplit[ block.nodeName ], var splitTag = tagAfterSplit[ block.nodeName ],
splitProperties = null, splitProperties = null,
nodeAfterSplit = split( node, offset, block.parentNode ); nodeAfterSplit = split( node, offset, block.parentNode ),
config = self._config;
if ( !splitTag ) { if ( !splitTag ) {
splitTag = self.defaultBlockTag; splitTag = config.blockTag;
splitProperties = self.defaultBlockProperties; splitProperties = config.blockAttributes;
} }
// Make sure the new node is the correct type. // Make sure the new node is the correct type.
@ -2364,7 +2395,6 @@ var splitBlock = function ( self, block, node, offset ) {
block = createElement( nodeAfterSplit.ownerDocument, block = createElement( nodeAfterSplit.ownerDocument,
splitTag, splitProperties ); splitTag, splitProperties );
if ( nodeAfterSplit.dir ) { if ( nodeAfterSplit.dir ) {
block.className = nodeAfterSplit.dir === 'rtl' ? 'dir-rtl' : '';
block.dir = nodeAfterSplit.dir; block.dir = nodeAfterSplit.dir;
} }
replaceWith( nodeAfterSplit, block ); replaceWith( nodeAfterSplit, block );
@ -2451,9 +2481,10 @@ proto.modifyBlocks = function ( modify, range ) {
}; };
var increaseBlockQuoteLevel = function ( frag ) { var increaseBlockQuoteLevel = function ( frag ) {
return this.createElement( 'BLOCKQUOTE', [ return this.createElement( 'BLOCKQUOTE',
frag this._config.tagAttributes.blockquote, [
]); frag
]);
}; };
var decreaseBlockQuoteLevel = function ( frag ) { var decreaseBlockQuoteLevel = function ( frag ) {
@ -2481,15 +2512,19 @@ var removeBlockQuote = function (/* frag */) {
var makeList = function ( self, frag, type ) { var makeList = function ( self, frag, type ) {
var walker = getBlockWalker( frag ), var walker = getBlockWalker( frag ),
node, tag, prev, newLi; node, tag, prev, newLi,
tagAttributes = self._config.tagAttributes,
listAttrs = tagAttributes[ type.toLowerCase() ],
listItemAttrs = tagAttributes.li;
while ( node = walker.nextNode() ) { while ( node = walker.nextNode() ) {
tag = node.parentNode.nodeName; tag = node.parentNode.nodeName;
if ( tag !== 'LI' ) { if ( tag !== 'LI' ) {
newLi = self.createElement( 'LI', { newLi = self.createElement( 'LI', listItemAttrs );
'class': node.dir === 'rtl' ? 'dir-rtl' : undefined, if ( node.dir ) {
dir: node.dir || undefined newLi.dir = node.dir;
}); }
// Have we replaced the previous block with a new <ul>/<ol>? // Have we replaced the previous block with a new <ul>/<ol>?
if ( ( prev = node.previousSibling ) && if ( ( prev = node.previousSibling ) &&
prev.nodeName === type ) { prev.nodeName === type ) {
@ -2499,7 +2534,7 @@ var makeList = function ( self, frag, type ) {
else { else {
replaceWith( replaceWith(
node, node,
self.createElement( type, [ self.createElement( type, listAttrs, [
newLi newLi
]) ])
); );
@ -2510,7 +2545,7 @@ var makeList = function ( self, frag, type ) {
tag = node.nodeName; tag = node.nodeName;
if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) { if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) {
replaceWith( node, replaceWith( node,
self.createElement( type, [ empty( node ) ] ) self.createElement( type, listAttrs, [ empty( node ) ] )
); );
} }
} }
@ -2548,7 +2583,10 @@ var removeList = function ( frag ) {
var increaseListLevel = function ( frag ) { var increaseListLevel = function ( frag ) {
var items = frag.querySelectorAll( 'LI' ), var items = frag.querySelectorAll( 'LI' ),
i, l, item, i, l, item,
type, newParent; type, newParent,
tagAttributes = this._config.tagAttributes,
listItemAttrs = tagAttributes.li,
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 ) ) {
@ -2557,10 +2595,11 @@ var increaseListLevel = function ( frag ) {
newParent = item.previousSibling; newParent = item.previousSibling;
if ( !newParent || !( newParent = newParent.lastChild ) || if ( !newParent || !( newParent = newParent.lastChild ) ||
newParent.nodeName !== type ) { newParent.nodeName !== type ) {
listAttrs = tagAttributes[ type.toLowerCase() ];
replaceWith( replaceWith(
item, item,
this.createElement( 'LI', [ this.createElement( 'LI', listItemAttrs, [
newParent = this.createElement( type ) newParent = this.createElement( type, listAttrs )
]) ])
); );
} }
@ -2976,7 +3015,8 @@ var cleanupBRs = function ( root ) {
proto._ensureBottomLine = function () { proto._ensureBottomLine = function () {
var body = this._body, var body = this._body,
last = body.lastElementChild; last = body.lastElementChild;
if ( !last || last.nodeName !== this.defaultBlockTag || !isBlock( last ) ) { if ( !last ||
last.nodeName !== this._config.blockTag || !isBlock( last ) ) {
body.appendChild( this.createDefaultBlock() ); body.appendChild( this.createDefaultBlock() );
} }
}; };
@ -3347,10 +3387,10 @@ proto.insertElement = function ( el, range ) {
return this; return this;
}; };
proto.insertImage = function ( src ) { proto.insertImage = function ( src, attributes ) {
var img = this.createElement( 'IMG', { var img = this.createElement( 'IMG', mergeObjects({
src: src src: src
}); }, attributes ));
this.insertElement( img ); this.insertElement( img );
return img; return img;
}; };
@ -3547,13 +3587,6 @@ proto.setTextAlignment = function ( alignment ) {
proto.setTextDirection = function ( direction ) { proto.setTextDirection = function ( direction ) {
this.forEachBlock( function ( block ) { this.forEachBlock( function ( block ) {
block.className = ( block.className
.split( /\s+/ )
.filter( function ( klass ) {
return !( /dir/.test( klass ) );
})
.join( ' ' ) +
' dir-' + direction ).trim();
block.dir = direction; block.dir = direction;
}, true ); }, true );
return this.focus(); return this.focus();

File diff suppressed because one or more lines are too long

View file

@ -14,6 +14,20 @@ function getSquireInstance ( doc ) {
return null; return null;
} }
function mergeObjects ( base, extras ) {
var prop, value;
if ( !base ) {
base = {};
}
for ( prop in extras ) {
value = extras[ prop ];
base[ prop ] = ( value && value.constructor === Object ) ?
mergeObjects( base[ prop ], value ) :
value;
}
return base;
}
function Squire ( doc, config ) { function Squire ( doc, config ) {
var win = doc.defaultView; var win = doc.defaultView;
var body = doc.body; var body = doc.body;
@ -65,9 +79,6 @@ function Squire ( doc, config ) {
this.addEventListener( 'keyup', this._keyUpDetectChange ); this.addEventListener( 'keyup', this._keyUpDetectChange );
} }
this.defaultBlockTag = 'DIV';
this.defaultBlockProperties = null;
// IE sometimes fires the beforepaste event twice; make sure it is not run // IE sometimes fires the beforepaste event twice; make sure it is not run
// again before our after paste function is called. // again before our after paste function is called.
this._awaitingPaste = false; this._awaitingPaste = false;
@ -130,11 +141,22 @@ function Squire ( doc, config ) {
var proto = Squire.prototype; var proto = Squire.prototype;
proto.setConfig = function ( config ) { proto.setConfig = function ( config ) {
for ( var prop in config ) { config = mergeObjects({
if ( config.hasOwnProperty( prop ) ) { blockTag: 'DIV',
this[ prop ] = config[ prop ]; blockAttributes: null,
tagAttributes: {
blockquote: null,
ul: null,
ol: null,
li: null
} }
} }, config );
// Users may specify block tag in lower case
config.blockTag = config.blockTag.toUpperCase();
this._config = config;
return this; return this;
}; };
@ -143,9 +165,9 @@ proto.createElement = function ( tag, props, children ) {
}; };
proto.createDefaultBlock = function ( children ) { proto.createDefaultBlock = function ( children ) {
var config = this._config;
return fixCursor( return fixCursor(
this.createElement( this.createElement( config.blockTag, config.blockAttributes, children )
this.defaultBlockTag, this.defaultBlockProperties, children )
); );
}; };
@ -928,11 +950,12 @@ var tagAfterSplit = {
var splitBlock = function ( self, block, node, offset ) { var splitBlock = function ( self, block, node, offset ) {
var splitTag = tagAfterSplit[ block.nodeName ], var splitTag = tagAfterSplit[ block.nodeName ],
splitProperties = null, splitProperties = null,
nodeAfterSplit = split( node, offset, block.parentNode ); nodeAfterSplit = split( node, offset, block.parentNode ),
config = self._config;
if ( !splitTag ) { if ( !splitTag ) {
splitTag = self.defaultBlockTag; splitTag = config.blockTag;
splitProperties = self.defaultBlockProperties; splitProperties = config.blockAttributes;
} }
// Make sure the new node is the correct type. // Make sure the new node is the correct type.
@ -940,7 +963,6 @@ var splitBlock = function ( self, block, node, offset ) {
block = createElement( nodeAfterSplit.ownerDocument, block = createElement( nodeAfterSplit.ownerDocument,
splitTag, splitProperties ); splitTag, splitProperties );
if ( nodeAfterSplit.dir ) { if ( nodeAfterSplit.dir ) {
block.className = nodeAfterSplit.dir === 'rtl' ? 'dir-rtl' : '';
block.dir = nodeAfterSplit.dir; block.dir = nodeAfterSplit.dir;
} }
replaceWith( nodeAfterSplit, block ); replaceWith( nodeAfterSplit, block );
@ -1027,9 +1049,10 @@ proto.modifyBlocks = function ( modify, range ) {
}; };
var increaseBlockQuoteLevel = function ( frag ) { var increaseBlockQuoteLevel = function ( frag ) {
return this.createElement( 'BLOCKQUOTE', [ return this.createElement( 'BLOCKQUOTE',
frag this._config.tagAttributes.blockquote, [
]); frag
]);
}; };
var decreaseBlockQuoteLevel = function ( frag ) { var decreaseBlockQuoteLevel = function ( frag ) {
@ -1057,15 +1080,19 @@ var removeBlockQuote = function (/* frag */) {
var makeList = function ( self, frag, type ) { var makeList = function ( self, frag, type ) {
var walker = getBlockWalker( frag ), var walker = getBlockWalker( frag ),
node, tag, prev, newLi; node, tag, prev, newLi,
tagAttributes = self._config.tagAttributes,
listAttrs = tagAttributes[ type.toLowerCase() ],
listItemAttrs = tagAttributes.li;
while ( node = walker.nextNode() ) { while ( node = walker.nextNode() ) {
tag = node.parentNode.nodeName; tag = node.parentNode.nodeName;
if ( tag !== 'LI' ) { if ( tag !== 'LI' ) {
newLi = self.createElement( 'LI', { newLi = self.createElement( 'LI', listItemAttrs );
'class': node.dir === 'rtl' ? 'dir-rtl' : undefined, if ( node.dir ) {
dir: node.dir || undefined newLi.dir = node.dir;
}); }
// Have we replaced the previous block with a new <ul>/<ol>? // Have we replaced the previous block with a new <ul>/<ol>?
if ( ( prev = node.previousSibling ) && if ( ( prev = node.previousSibling ) &&
prev.nodeName === type ) { prev.nodeName === type ) {
@ -1075,7 +1102,7 @@ var makeList = function ( self, frag, type ) {
else { else {
replaceWith( replaceWith(
node, node,
self.createElement( type, [ self.createElement( type, listAttrs, [
newLi newLi
]) ])
); );
@ -1086,7 +1113,7 @@ var makeList = function ( self, frag, type ) {
tag = node.nodeName; tag = node.nodeName;
if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) { if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) {
replaceWith( node, replaceWith( node,
self.createElement( type, [ empty( node ) ] ) self.createElement( type, listAttrs, [ empty( node ) ] )
); );
} }
} }
@ -1124,7 +1151,10 @@ var removeList = function ( frag ) {
var increaseListLevel = function ( frag ) { var increaseListLevel = function ( frag ) {
var items = frag.querySelectorAll( 'LI' ), var items = frag.querySelectorAll( 'LI' ),
i, l, item, i, l, item,
type, newParent; type, newParent,
tagAttributes = this._config.tagAttributes,
listItemAttrs = tagAttributes.li,
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 ) ) {
@ -1133,10 +1163,11 @@ var increaseListLevel = function ( frag ) {
newParent = item.previousSibling; newParent = item.previousSibling;
if ( !newParent || !( newParent = newParent.lastChild ) || if ( !newParent || !( newParent = newParent.lastChild ) ||
newParent.nodeName !== type ) { newParent.nodeName !== type ) {
listAttrs = tagAttributes[ type.toLowerCase() ];
replaceWith( replaceWith(
item, item,
this.createElement( 'LI', [ this.createElement( 'LI', listItemAttrs, [
newParent = this.createElement( type ) newParent = this.createElement( type, listAttrs )
]) ])
); );
} }
@ -1552,7 +1583,8 @@ var cleanupBRs = function ( root ) {
proto._ensureBottomLine = function () { proto._ensureBottomLine = function () {
var body = this._body, var body = this._body,
last = body.lastElementChild; last = body.lastElementChild;
if ( !last || last.nodeName !== this.defaultBlockTag || !isBlock( last ) ) { if ( !last ||
last.nodeName !== this._config.blockTag || !isBlock( last ) ) {
body.appendChild( this.createDefaultBlock() ); body.appendChild( this.createDefaultBlock() );
} }
}; };
@ -1923,10 +1955,10 @@ proto.insertElement = function ( el, range ) {
return this; return this;
}; };
proto.insertImage = function ( src ) { proto.insertImage = function ( src, attributes ) {
var img = this.createElement( 'IMG', { var img = this.createElement( 'IMG', mergeObjects({
src: src src: src
}); }, attributes ));
this.insertElement( img ); this.insertElement( img );
return img; return img;
}; };
@ -2123,13 +2155,6 @@ proto.setTextAlignment = function ( alignment ) {
proto.setTextDirection = function ( direction ) { proto.setTextDirection = function ( direction ) {
this.forEachBlock( function ( block ) { this.forEachBlock( function ( block ) {
block.className = ( block.className
.split( /\s+/ )
.filter( function ( klass ) {
return !( /dir/.test( klass ) );
})
.join( ' ' ) +
' dir-' + direction ).trim();
block.dir = direction; block.dir = direction;
}, true ); }, true );
return this.focus(); return this.focus();

View file

@ -82,7 +82,7 @@ function getNearest ( node, tag, attributes ) {
function getPath ( node ) { function getPath ( node ) {
var parent = node.parentNode, var parent = node.parentNode,
path, id, className, classNames; path, id, className, classNames, dir;
if ( !parent || node.nodeType !== ELEMENT_NODE ) { if ( !parent || node.nodeType !== ELEMENT_NODE ) {
path = parent ? getPath( parent ) : ''; path = parent ? getPath( parent ) : '';
} else { } else {
@ -97,6 +97,9 @@ function getPath ( node ) {
path += '.'; path += '.';
path += classNames.join( '.' ); path += classNames.join( '.' );
} }
if ( dir = node.dir ) {
path += '[dir=' + dir + ']';
}
} }
return path; return path;
} }
@ -160,14 +163,11 @@ function fixCursor ( node ) {
// cursor to appear. // cursor to appear.
var doc = node.ownerDocument, var doc = node.ownerDocument,
root = node, root = node,
fixer, child, instance; fixer, child;
if ( node.nodeName === 'BODY' ) { if ( node.nodeName === 'BODY' ) {
if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) { if ( !( child = node.firstChild ) || child.nodeName === 'BR' ) {
instance = getSquireInstance( doc ); fixer = getSquireInstance( doc ).createDefaultBlock();
fixer = instance ?
instance.createDefaultBlock() :
createElement( doc, 'DIV' );
if ( child ) { if ( child ) {
node.replaceChild( fixer, child ); node.replaceChild( fixer, child );
} }
@ -233,17 +233,25 @@ function fixContainer ( container ) {
var children = container.childNodes, var children = container.childNodes,
doc = container.ownerDocument, doc = container.ownerDocument,
wrapper = null, wrapper = null,
i, l, child, isBR; i, l, child, isBR,
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 ) { wrapper = createElement( doc, 'DIV' ); } if ( !wrapper ) {
wrapper = createElement( doc,
config.blockTag, config.blockAttributes );
}
wrapper.appendChild( child ); wrapper.appendChild( child );
i -= 1; i -= 1;
l -= 1; l -= 1;
} else if ( isBR || wrapper ) { } else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); } if ( !wrapper ) {
wrapper = createElement( doc,
config.blockTag, config.blockAttributes );
}
fixCursor( wrapper ); fixCursor( wrapper );
if ( isBR ) { if ( isBR ) {
container.replaceChild( wrapper, child ); container.replaceChild( wrapper, child );