0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Better fix up of mixed inline/block content.

This commit is contained in:
Neil Jenkins 2014-05-27 11:31:06 +10:00
parent 46706db889
commit aca8fd4fab
4 changed files with 96 additions and 78 deletions

View file

@ -508,7 +508,7 @@ function mergeContainers ( node ) {
var prev = node.previousSibling,
first = node.firstChild,
isListItem = ( node.nodeName === 'LI' ),
block;
needsFix, block;
// Do not merge LIs, unless it only contains a UL
if ( isListItem && ( !first || !/^[OU]L$/.test( first.nodeName ) ) ) {
@ -526,7 +526,11 @@ function mergeContainers ( node ) {
}
}
detach( node );
needsFix = !isContainer( node );
prev.appendChild( empty( node ) );
if ( needsFix ) {
fixContainer( prev );
}
if ( first ) {
mergeContainers( first );
}
@ -537,6 +541,42 @@ function mergeContainers ( node ) {
}
}
// Recursively examine container nodes and wrap any inline children.
function fixContainer ( container ) {
var children = container.childNodes,
doc = container.ownerDocument,
wrapper = null,
i, l, child, isBR;
for ( i = 0, l = children.length; i < l; i += 1 ) {
child = children[i];
isBR = child.nodeName === 'BR';
if ( !isBR && isInline( child ) ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
wrapper.appendChild( child );
i -= 1;
l -= 1;
} else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
fixCursor( wrapper );
if ( isBR ) {
container.replaceChild( wrapper, child );
} else {
container.insertBefore( wrapper, child );
i += 1;
l += 1;
}
wrapper = null;
}
if ( isContainer( child ) ) {
fixContainer( child );
}
}
if ( wrapper ) {
container.appendChild( fixCursor( wrapper ) );
}
return container;
}
function createElement ( doc, tag, props, children ) {
var el = doc.createElement( tag ),
attr, value, i, l;
@ -1114,6 +1154,7 @@ var expandRangeToBlockBoundaries = function ( range ) {
mergeInlines,
mergeWithBlock,
mergeContainers,
fixContainer,
createElement,
forEachTextNodeInRange,
@ -2092,7 +2133,7 @@ var removeList = function ( frag ) {
child = children[ll];
replaceWith( child, empty( child ) );
}
wrapTopLevelInline( listFrag, 'DIV' );
fixContainer( listFrag );
replaceWith( list, listFrag );
}
return frag;
@ -2153,7 +2194,7 @@ var decreaseListLevel = function ( frag ) {
item = parent;
}
}, this );
wrapTopLevelInline( frag, 'DIV' );
fixContainer( frag );
return frag;
};
@ -2450,38 +2491,6 @@ var cleanTree = function ( node, allowStyles ) {
return node;
};
var wrapTopLevelInline = function ( root, tag ) {
var children = root.childNodes,
doc = root.ownerDocument,
wrapper = null,
i, l, child, isBR;
for ( i = 0, l = children.length; i < l; i += 1 ) {
child = children[i];
isBR = child.nodeName === 'BR';
if ( !isBR && isInline( child ) ) {
if ( !wrapper ) { wrapper = createElement( doc, tag ); }
wrapper.appendChild( child );
i -= 1;
l -= 1;
} else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, tag ); }
fixCursor( wrapper );
if ( isBR ) {
root.replaceChild( wrapper, child );
} else {
root.insertBefore( wrapper, child );
i += 1;
l += 1;
}
wrapper = null;
}
}
if ( wrapper ) {
root.appendChild( fixCursor( wrapper ) );
}
return root;
};
var notWSTextNode = function ( node ) {
return ( node.nodeType === ELEMENT_NODE ?
node.nodeName === 'BR' :
@ -2532,7 +2541,7 @@ var cleanupBRs = function ( root ) {
// If this is not inside a block, replace it by wrapping
// inlines in DIV.
if ( !isBlock( block ) || !tagAfterSplit[ block.nodeName ] ) {
wrapTopLevelInline( block, 'DIV' );
fixContainer( block );
}
// If in a block we can split, split it instead, but only if there
// is actual text content in the block. Otherwise, the <br> is a
@ -2833,7 +2842,7 @@ var keyHandlers = {
}
}
}
wrapTopLevelInline( block, 'DIV' );
fixContainer( block );
splitTag = 'DIV';
if ( !splitNode ) {
splitNode = block.firstChild;
@ -3188,7 +3197,7 @@ proto.setHTML = function ( html ) {
cleanTree( frag, true );
cleanupBRs( frag );
wrapTopLevelInline( frag, 'DIV' );
fixContainer( frag );
// Fix cursor
var node = frag;

File diff suppressed because one or more lines are too long

View file

@ -42,6 +42,7 @@
mergeInlines,
mergeWithBlock,
mergeContainers,
fixContainer,
createElement,
forEachTextNodeInRange,
@ -1020,7 +1021,7 @@ var removeList = function ( frag ) {
child = children[ll];
replaceWith( child, empty( child ) );
}
wrapTopLevelInline( listFrag, 'DIV' );
fixContainer( listFrag );
replaceWith( list, listFrag );
}
return frag;
@ -1081,7 +1082,7 @@ var decreaseListLevel = function ( frag ) {
item = parent;
}
}, this );
wrapTopLevelInline( frag, 'DIV' );
fixContainer( frag );
return frag;
};
@ -1378,38 +1379,6 @@ var cleanTree = function ( node, allowStyles ) {
return node;
};
var wrapTopLevelInline = function ( root, tag ) {
var children = root.childNodes,
doc = root.ownerDocument,
wrapper = null,
i, l, child, isBR;
for ( i = 0, l = children.length; i < l; i += 1 ) {
child = children[i];
isBR = child.nodeName === 'BR';
if ( !isBR && isInline( child ) ) {
if ( !wrapper ) { wrapper = createElement( doc, tag ); }
wrapper.appendChild( child );
i -= 1;
l -= 1;
} else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, tag ); }
fixCursor( wrapper );
if ( isBR ) {
root.replaceChild( wrapper, child );
} else {
root.insertBefore( wrapper, child );
i += 1;
l += 1;
}
wrapper = null;
}
}
if ( wrapper ) {
root.appendChild( fixCursor( wrapper ) );
}
return root;
};
var notWSTextNode = function ( node ) {
return ( node.nodeType === ELEMENT_NODE ?
node.nodeName === 'BR' :
@ -1460,7 +1429,7 @@ var cleanupBRs = function ( root ) {
// If this is not inside a block, replace it by wrapping
// inlines in DIV.
if ( !isBlock( block ) || !tagAfterSplit[ block.nodeName ] ) {
wrapTopLevelInline( block, 'DIV' );
fixContainer( block );
}
// If in a block we can split, split it instead, but only if there
// is actual text content in the block. Otherwise, the <br> is a
@ -1761,7 +1730,7 @@ var keyHandlers = {
}
}
}
wrapTopLevelInline( block, 'DIV' );
fixContainer( block );
splitTag = 'DIV';
if ( !splitNode ) {
splitNode = block.firstChild;
@ -2116,7 +2085,7 @@ proto.setHTML = function ( html ) {
cleanTree( frag, true );
cleanupBRs( frag );
wrapTopLevelInline( frag, 'DIV' );
fixContainer( frag );
// Fix cursor
var node = frag;

View file

@ -366,7 +366,7 @@ function mergeContainers ( node ) {
var prev = node.previousSibling,
first = node.firstChild,
isListItem = ( node.nodeName === 'LI' ),
block;
needsFix, block;
// Do not merge LIs, unless it only contains a UL
if ( isListItem && ( !first || !/^[OU]L$/.test( first.nodeName ) ) ) {
@ -384,7 +384,11 @@ function mergeContainers ( node ) {
}
}
detach( node );
needsFix = !isContainer( node );
prev.appendChild( empty( node ) );
if ( needsFix ) {
fixContainer( prev );
}
if ( first ) {
mergeContainers( first );
}
@ -395,6 +399,42 @@ function mergeContainers ( node ) {
}
}
// Recursively examine container nodes and wrap any inline children.
function fixContainer ( container ) {
var children = container.childNodes,
doc = container.ownerDocument,
wrapper = null,
i, l, child, isBR;
for ( i = 0, l = children.length; i < l; i += 1 ) {
child = children[i];
isBR = child.nodeName === 'BR';
if ( !isBR && isInline( child ) ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
wrapper.appendChild( child );
i -= 1;
l -= 1;
} else if ( isBR || wrapper ) {
if ( !wrapper ) { wrapper = createElement( doc, 'DIV' ); }
fixCursor( wrapper );
if ( isBR ) {
container.replaceChild( wrapper, child );
} else {
container.insertBefore( wrapper, child );
i += 1;
l += 1;
}
wrapper = null;
}
if ( isContainer( child ) ) {
fixContainer( child );
}
}
if ( wrapper ) {
container.appendChild( fixCursor( wrapper ) );
}
return container;
}
function createElement ( doc, tag, props, children ) {
var el = doc.createElement( tag ),
attr, value, i, l;