mirror of
https://github.com/fastmail/Squire.git
synced 2025-01-03 05:00:13 -05:00
parent
239b7d19e9
commit
48fabd491a
6 changed files with 200 additions and 246 deletions
|
@ -265,6 +265,10 @@ function getNextBlock ( node, root ) {
|
|||
return node !== root ? node : null;
|
||||
}
|
||||
|
||||
function isEmptyBlock ( block ) {
|
||||
return !block.textContent && !block.querySelector( 'IMG' );
|
||||
}
|
||||
|
||||
function areAlike ( node, node2 ) {
|
||||
return !isLeaf( node ) && (
|
||||
node.nodeType === node2.nodeType &&
|
||||
|
@ -348,7 +352,7 @@ function getPath ( node, root ) {
|
|||
|
||||
function getLength ( node ) {
|
||||
var nodeType = node.nodeType;
|
||||
return nodeType === ELEMENT_NODE ?
|
||||
return nodeType === ELEMENT_NODE || nodeType === DOCUMENT_FRAGMENT_NODE ?
|
||||
node.childNodes.length : node.length || 0;
|
||||
}
|
||||
|
||||
|
@ -651,11 +655,14 @@ function mergeInlines ( node, range ) {
|
|||
}
|
||||
}
|
||||
|
||||
function mergeWithBlock ( block, next, range ) {
|
||||
var container = next,
|
||||
last, offset;
|
||||
while ( container.parentNode.childNodes.length === 1 ) {
|
||||
container = container.parentNode;
|
||||
function mergeWithBlock ( block, next, range, root ) {
|
||||
var container = next;
|
||||
var parent, last, offset;
|
||||
while ( ( parent = container.parentNode ) &&
|
||||
parent !== root &&
|
||||
parent.nodeType === ELEMENT_NODE &&
|
||||
parent.childNodes.length === 1 ) {
|
||||
container = parent;
|
||||
}
|
||||
detach( container );
|
||||
|
||||
|
@ -879,7 +886,7 @@ var deleteContentsOfRange = function ( range, root ) {
|
|||
// endBlock will have been split, so need to refetch
|
||||
endBlock = getEndBlockOfRange( range, root );
|
||||
if ( startBlock && endBlock && startBlock !== endBlock ) {
|
||||
mergeWithBlock( startBlock, endBlock, range );
|
||||
mergeWithBlock( startBlock, endBlock, range, root );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -901,134 +908,107 @@ var deleteContentsOfRange = function ( range, root ) {
|
|||
|
||||
// ---
|
||||
|
||||
// Contents of range will be deleted.
|
||||
// After method, range will be around inserted content
|
||||
var insertTreeFragmentIntoRange = function ( range, frag, root ) {
|
||||
// Check if it's all inline content
|
||||
var allInline = true,
|
||||
children = frag.childNodes,
|
||||
l = children.length;
|
||||
while ( l-- ) {
|
||||
if ( !isInline( children[l] ) ) {
|
||||
allInline = false;
|
||||
break;
|
||||
}
|
||||
var node, block, blockContentsAfterSplit, stopPoint, container, offset;
|
||||
var nodeAfterSplit, nodeBeforeSplit, tempRange;
|
||||
|
||||
// Fixup content: ensure no top-level inline, and add cursor fix elements.
|
||||
fixContainer( frag, root );
|
||||
node = frag;
|
||||
while ( ( node = getNextBlock( node, root ) ) ) {
|
||||
fixCursor( node, root );
|
||||
}
|
||||
|
||||
// Delete any selected content
|
||||
// Delete any selected content.
|
||||
if ( !range.collapsed ) {
|
||||
deleteContentsOfRange( range, root );
|
||||
}
|
||||
|
||||
// Move range down into text nodes
|
||||
// Move range down into text nodes.
|
||||
moveRangeBoundariesDownTree( range );
|
||||
range.collapse( false ); // collapse to end
|
||||
|
||||
if ( allInline ) {
|
||||
// If inline, just insert at the current position.
|
||||
insertNodeInRange( range, frag );
|
||||
if ( range.startContainer !== range.endContainer ) {
|
||||
mergeInlines( range.endContainer, range );
|
||||
}
|
||||
mergeInlines( range.startContainer, range );
|
||||
range.collapse( false );
|
||||
} else {
|
||||
// Otherwise...
|
||||
// 1. Split up to blockquote (if a parent) or root
|
||||
var splitPoint = range.startContainer,
|
||||
// Where will we split up to? First blockquote parent, otherwise root.
|
||||
stopPoint = getNearest( range.endContainer, root, 'BLOCKQUOTE' ) || root;
|
||||
|
||||
// Merge the contents of the first block in the frag with the focused block.
|
||||
// If there are contents in the block after the focus point, collect this
|
||||
// up to insert in the last block later
|
||||
block = getStartBlockOfRange( range );
|
||||
if ( block ) {
|
||||
moveRangeBoundariesUpTree( range, block, block, root );
|
||||
range.collapse( true ); // collapse to start
|
||||
container = range.endContainer;
|
||||
offset = range.endOffset;
|
||||
// Remove trailing <br> – we don't want this considered content to be
|
||||
// inserted again later
|
||||
cleanupBRs( block, root, false );
|
||||
if ( isInline( container ) ) {
|
||||
// Split up to block parent.
|
||||
nodeAfterSplit = split(
|
||||
splitPoint,
|
||||
range.startOffset,
|
||||
getNearest( splitPoint.parentNode, root, 'BLOCKQUOTE' ) || root,
|
||||
root
|
||||
),
|
||||
nodeBeforeSplit = nodeAfterSplit.previousSibling,
|
||||
startContainer = nodeBeforeSplit,
|
||||
startOffset = startContainer.childNodes.length,
|
||||
endContainer = nodeAfterSplit,
|
||||
endOffset = 0,
|
||||
parent = nodeAfterSplit.parentNode,
|
||||
child, node, prev, next, startAnchor;
|
||||
|
||||
// 2. Move down into edge either side of split and insert any inline
|
||||
// nodes at the beginning/end of the fragment
|
||||
while ( ( child = startContainer.lastChild ) &&
|
||||
child.nodeType === ELEMENT_NODE ) {
|
||||
if ( child.nodeName === 'BR' ) {
|
||||
startOffset -= 1;
|
||||
break;
|
||||
container, offset, getPreviousBlock( container, root ), root );
|
||||
container = nodeAfterSplit.parentNode;
|
||||
offset = indexOf.call( container.childNodes, nodeAfterSplit );
|
||||
}
|
||||
if ( /*isBlock( container ) && */offset !== getLength( container ) ) {
|
||||
// Collect any inline contents of the block after the range point
|
||||
blockContentsAfterSplit =
|
||||
root.ownerDocument.createDocumentFragment();
|
||||
while ( ( node = container.childNodes[ offset ] ) ) {
|
||||
blockContentsAfterSplit.appendChild( node );
|
||||
}
|
||||
startContainer = child;
|
||||
startOffset = startContainer.childNodes.length;
|
||||
}
|
||||
while ( ( child = endContainer.firstChild ) &&
|
||||
child.nodeType === ELEMENT_NODE &&
|
||||
child.nodeName !== 'BR' ) {
|
||||
endContainer = child;
|
||||
}
|
||||
startAnchor = startContainer.childNodes[ startOffset ] || null;
|
||||
while ( ( child = frag.firstChild ) && isInline( child ) ) {
|
||||
startContainer.insertBefore( child, startAnchor );
|
||||
}
|
||||
while ( ( child = frag.lastChild ) && isInline( child ) ) {
|
||||
endContainer.insertBefore( child, endContainer.firstChild );
|
||||
endOffset += 1;
|
||||
}
|
||||
// And merge the first block in.
|
||||
mergeWithBlock( container, getNextBlock( frag, frag ), range, root );
|
||||
|
||||
// 3. Fix cursor then insert block(s) in the fragment
|
||||
node = frag;
|
||||
while ( node = getNextBlock( node, root ) ) {
|
||||
fixCursor( node, root );
|
||||
}
|
||||
parent.insertBefore( frag, nodeAfterSplit );
|
||||
// And where we will insert
|
||||
offset = indexOf.call( container.parentNode.childNodes, container ) + 1;
|
||||
container = container.parentNode;
|
||||
range.setEnd( container, offset );
|
||||
}
|
||||
|
||||
// 4. Remove empty nodes created either side of split, then
|
||||
// merge containers at the edges.
|
||||
next = nodeBeforeSplit.nextSibling;
|
||||
node = getPreviousBlock( next, root );
|
||||
if ( node && !/\S/.test( node.textContent ) ) {
|
||||
do {
|
||||
parent = node.parentNode;
|
||||
parent.removeChild( node );
|
||||
node = parent;
|
||||
} while ( node && !node.lastChild && node !== root );
|
||||
}
|
||||
if ( !nodeBeforeSplit.parentNode ) {
|
||||
nodeBeforeSplit = next.previousSibling;
|
||||
}
|
||||
if ( !startContainer.parentNode ) {
|
||||
startContainer = nodeBeforeSplit || next.parentNode;
|
||||
startOffset = nodeBeforeSplit ?
|
||||
nodeBeforeSplit.childNodes.length : 0;
|
||||
}
|
||||
// Merge inserted containers with edges of split
|
||||
if ( isContainer( next ) ) {
|
||||
mergeContainers( next, root );
|
||||
// Is there still any content in the fragment?
|
||||
if ( getLength( frag ) ) {
|
||||
moveRangeBoundariesUpTree( range, stopPoint, stopPoint, root );
|
||||
// Now split after block up to blockquote (if a parent) or root
|
||||
nodeAfterSplit = split(
|
||||
range.endContainer, range.endOffset, stopPoint, root );
|
||||
nodeBeforeSplit = nodeAfterSplit ?
|
||||
nodeAfterSplit.previousSibling :
|
||||
stopPoint.lastChild;
|
||||
stopPoint.insertBefore( frag, nodeAfterSplit );
|
||||
if ( nodeAfterSplit ) {
|
||||
range.setEndBefore( nodeAfterSplit );
|
||||
} else {
|
||||
range.setEnd( stopPoint, getLength( stopPoint ) );
|
||||
}
|
||||
block = getEndBlockOfRange( range, root );
|
||||
|
||||
// Get a reference that won't be invalidated if we merge containers.
|
||||
moveRangeBoundariesDownTree( range );
|
||||
container = range.endContainer;
|
||||
offset = range.endOffset;
|
||||
|
||||
prev = nodeAfterSplit.previousSibling;
|
||||
node = isBlock( nodeAfterSplit ) ?
|
||||
nodeAfterSplit : getNextBlock( nodeAfterSplit, root );
|
||||
if ( node && !/\S/.test( node.textContent ) ) {
|
||||
do {
|
||||
parent = node.parentNode;
|
||||
parent.removeChild( node );
|
||||
node = parent;
|
||||
} while ( node && !node.lastChild && node !== root );
|
||||
}
|
||||
if ( !nodeAfterSplit.parentNode ) {
|
||||
nodeAfterSplit = prev.nextSibling;
|
||||
}
|
||||
if ( !endOffset ) {
|
||||
endContainer = prev;
|
||||
endOffset = prev.childNodes.length;
|
||||
}
|
||||
// Merge inserted containers with edges of split
|
||||
if ( nodeAfterSplit && isContainer( nodeAfterSplit ) ) {
|
||||
mergeContainers( nodeAfterSplit, root );
|
||||
}
|
||||
|
||||
range.setStart( startContainer, startOffset );
|
||||
range.setEnd( endContainer, endOffset );
|
||||
moveRangeBoundariesDownTree( range );
|
||||
nodeAfterSplit = nodeBeforeSplit && nodeBeforeSplit.nextSibling;
|
||||
if ( nodeAfterSplit && isContainer( nodeAfterSplit ) ) {
|
||||
mergeContainers( nodeAfterSplit, root );
|
||||
}
|
||||
range.setEnd( container, offset );
|
||||
}
|
||||
|
||||
// Insert inline content saved from before.
|
||||
if ( blockContentsAfterSplit ) {
|
||||
tempRange = range.cloneRange();
|
||||
mergeWithBlock( block, blockContentsAfterSplit, tempRange, root );
|
||||
range.setEnd( tempRange.endContainer, tempRange.endOffset );
|
||||
}
|
||||
moveRangeBoundariesDownTree( range );
|
||||
};
|
||||
|
||||
// ---
|
||||
|
@ -1467,7 +1447,7 @@ var keyHandlers = {
|
|||
block = parent;
|
||||
}
|
||||
|
||||
if ( !block.textContent ) {
|
||||
if ( isEmptyBlock( block ) ) {
|
||||
// Break list
|
||||
if ( getNearest( block, root, 'UL' ) ||
|
||||
getNearest( block, root, 'OL' ) ) {
|
||||
|
@ -1560,7 +1540,7 @@ var keyHandlers = {
|
|||
return;
|
||||
}
|
||||
// Otherwise merge.
|
||||
mergeWithBlock( previous, current, range );
|
||||
mergeWithBlock( previous, current, range, root );
|
||||
// If deleted line between containers, merge newly adjacent
|
||||
// containers.
|
||||
current = previous.parentNode;
|
||||
|
@ -1627,7 +1607,7 @@ var keyHandlers = {
|
|||
return;
|
||||
}
|
||||
// Otherwise merge.
|
||||
mergeWithBlock( current, next, range );
|
||||
mergeWithBlock( current, next, range, root );
|
||||
// If deleted line between containers, merge newly adjacent
|
||||
// containers.
|
||||
next = current.parentNode;
|
||||
|
@ -4306,11 +4286,8 @@ proto.insertPlainText = function ( plainText, isPaste ) {
|
|||
for ( i = 0, l = lines.length; i < l; i += 1 ) {
|
||||
line = lines[i];
|
||||
line = escapeHTMLFragement( line ).replace( / (?= )/g, ' ' );
|
||||
// Wrap all but first/last lines in <div></div>
|
||||
if ( i && i + 1 < l ) {
|
||||
line = openBlock + ( line || '<BR>' ) + closeBlock;
|
||||
}
|
||||
lines[i] = line;
|
||||
// Wrap each line in <div></div>
|
||||
lines[i] = openBlock + ( line || '<BR>' ) + closeBlock;
|
||||
}
|
||||
return this.insertHTML( lines.join( '' ), isPaste );
|
||||
};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1852,11 +1852,8 @@ proto.insertPlainText = function ( plainText, isPaste ) {
|
|||
for ( i = 0, l = lines.length; i < l; i += 1 ) {
|
||||
line = lines[i];
|
||||
line = escapeHTMLFragement( line ).replace( / (?= )/g, ' ' );
|
||||
// Wrap all but first/last lines in <div></div>
|
||||
if ( i && i + 1 < l ) {
|
||||
line = openBlock + ( line || '<BR>' ) + closeBlock;
|
||||
}
|
||||
lines[i] = line;
|
||||
// Wrap each line in <div></div>
|
||||
lines[i] = openBlock + ( line || '<BR>' ) + closeBlock;
|
||||
}
|
||||
return this.insertHTML( lines.join( '' ), isPaste );
|
||||
};
|
||||
|
|
|
@ -188,7 +188,7 @@ var keyHandlers = {
|
|||
block = parent;
|
||||
}
|
||||
|
||||
if ( !block.textContent ) {
|
||||
if ( isEmptyBlock( block ) ) {
|
||||
// Break list
|
||||
if ( getNearest( block, root, 'UL' ) ||
|
||||
getNearest( block, root, 'OL' ) ) {
|
||||
|
@ -281,7 +281,7 @@ var keyHandlers = {
|
|||
return;
|
||||
}
|
||||
// Otherwise merge.
|
||||
mergeWithBlock( previous, current, range );
|
||||
mergeWithBlock( previous, current, range, root );
|
||||
// If deleted line between containers, merge newly adjacent
|
||||
// containers.
|
||||
current = previous.parentNode;
|
||||
|
@ -348,7 +348,7 @@ var keyHandlers = {
|
|||
return;
|
||||
}
|
||||
// Otherwise merge.
|
||||
mergeWithBlock( current, next, range );
|
||||
mergeWithBlock( current, next, range, root );
|
||||
// If deleted line between containers, merge newly adjacent
|
||||
// containers.
|
||||
next = current.parentNode;
|
||||
|
|
|
@ -85,6 +85,10 @@ function getNextBlock ( node, root ) {
|
|||
return node !== root ? node : null;
|
||||
}
|
||||
|
||||
function isEmptyBlock ( block ) {
|
||||
return !block.textContent && !block.querySelector( 'IMG' );
|
||||
}
|
||||
|
||||
function areAlike ( node, node2 ) {
|
||||
return !isLeaf( node ) && (
|
||||
node.nodeType === node2.nodeType &&
|
||||
|
@ -168,7 +172,7 @@ function getPath ( node, root ) {
|
|||
|
||||
function getLength ( node ) {
|
||||
var nodeType = node.nodeType;
|
||||
return nodeType === ELEMENT_NODE ?
|
||||
return nodeType === ELEMENT_NODE || nodeType === DOCUMENT_FRAGMENT_NODE ?
|
||||
node.childNodes.length : node.length || 0;
|
||||
}
|
||||
|
||||
|
@ -471,11 +475,14 @@ function mergeInlines ( node, range ) {
|
|||
}
|
||||
}
|
||||
|
||||
function mergeWithBlock ( block, next, range ) {
|
||||
var container = next,
|
||||
last, offset;
|
||||
while ( container.parentNode.childNodes.length === 1 ) {
|
||||
container = container.parentNode;
|
||||
function mergeWithBlock ( block, next, range, root ) {
|
||||
var container = next;
|
||||
var parent, last, offset;
|
||||
while ( ( parent = container.parentNode ) &&
|
||||
parent !== root &&
|
||||
parent.nodeType === ELEMENT_NODE &&
|
||||
parent.childNodes.length === 1 ) {
|
||||
container = parent;
|
||||
}
|
||||
detach( container );
|
||||
|
||||
|
|
189
source/Range.js
189
source/Range.js
|
@ -154,7 +154,7 @@ var deleteContentsOfRange = function ( range, root ) {
|
|||
// endBlock will have been split, so need to refetch
|
||||
endBlock = getEndBlockOfRange( range, root );
|
||||
if ( startBlock && endBlock && startBlock !== endBlock ) {
|
||||
mergeWithBlock( startBlock, endBlock, range );
|
||||
mergeWithBlock( startBlock, endBlock, range, root );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,134 +176,107 @@ var deleteContentsOfRange = function ( range, root ) {
|
|||
|
||||
// ---
|
||||
|
||||
// Contents of range will be deleted.
|
||||
// After method, range will be around inserted content
|
||||
var insertTreeFragmentIntoRange = function ( range, frag, root ) {
|
||||
// Check if it's all inline content
|
||||
var allInline = true,
|
||||
children = frag.childNodes,
|
||||
l = children.length;
|
||||
while ( l-- ) {
|
||||
if ( !isInline( children[l] ) ) {
|
||||
allInline = false;
|
||||
break;
|
||||
}
|
||||
var node, block, blockContentsAfterSplit, stopPoint, container, offset;
|
||||
var nodeAfterSplit, nodeBeforeSplit, tempRange;
|
||||
|
||||
// Fixup content: ensure no top-level inline, and add cursor fix elements.
|
||||
fixContainer( frag, root );
|
||||
node = frag;
|
||||
while ( ( node = getNextBlock( node, root ) ) ) {
|
||||
fixCursor( node, root );
|
||||
}
|
||||
|
||||
// Delete any selected content
|
||||
// Delete any selected content.
|
||||
if ( !range.collapsed ) {
|
||||
deleteContentsOfRange( range, root );
|
||||
}
|
||||
|
||||
// Move range down into text nodes
|
||||
// Move range down into text nodes.
|
||||
moveRangeBoundariesDownTree( range );
|
||||
range.collapse( false ); // collapse to end
|
||||
|
||||
if ( allInline ) {
|
||||
// If inline, just insert at the current position.
|
||||
insertNodeInRange( range, frag );
|
||||
if ( range.startContainer !== range.endContainer ) {
|
||||
mergeInlines( range.endContainer, range );
|
||||
}
|
||||
mergeInlines( range.startContainer, range );
|
||||
range.collapse( false );
|
||||
} else {
|
||||
// Otherwise...
|
||||
// 1. Split up to blockquote (if a parent) or root
|
||||
var splitPoint = range.startContainer,
|
||||
// Where will we split up to? First blockquote parent, otherwise root.
|
||||
stopPoint = getNearest( range.endContainer, root, 'BLOCKQUOTE' ) || root;
|
||||
|
||||
// Merge the contents of the first block in the frag with the focused block.
|
||||
// If there are contents in the block after the focus point, collect this
|
||||
// up to insert in the last block later
|
||||
block = getStartBlockOfRange( range );
|
||||
if ( block ) {
|
||||
moveRangeBoundariesUpTree( range, block, block, root );
|
||||
range.collapse( true ); // collapse to start
|
||||
container = range.endContainer;
|
||||
offset = range.endOffset;
|
||||
// Remove trailing <br> – we don't want this considered content to be
|
||||
// inserted again later
|
||||
cleanupBRs( block, root, false );
|
||||
if ( isInline( container ) ) {
|
||||
// Split up to block parent.
|
||||
nodeAfterSplit = split(
|
||||
splitPoint,
|
||||
range.startOffset,
|
||||
getNearest( splitPoint.parentNode, root, 'BLOCKQUOTE' ) || root,
|
||||
root
|
||||
),
|
||||
nodeBeforeSplit = nodeAfterSplit.previousSibling,
|
||||
startContainer = nodeBeforeSplit,
|
||||
startOffset = startContainer.childNodes.length,
|
||||
endContainer = nodeAfterSplit,
|
||||
endOffset = 0,
|
||||
parent = nodeAfterSplit.parentNode,
|
||||
child, node, prev, next, startAnchor;
|
||||
|
||||
// 2. Move down into edge either side of split and insert any inline
|
||||
// nodes at the beginning/end of the fragment
|
||||
while ( ( child = startContainer.lastChild ) &&
|
||||
child.nodeType === ELEMENT_NODE ) {
|
||||
if ( child.nodeName === 'BR' ) {
|
||||
startOffset -= 1;
|
||||
break;
|
||||
container, offset, getPreviousBlock( container, root ), root );
|
||||
container = nodeAfterSplit.parentNode;
|
||||
offset = indexOf.call( container.childNodes, nodeAfterSplit );
|
||||
}
|
||||
if ( /*isBlock( container ) && */offset !== getLength( container ) ) {
|
||||
// Collect any inline contents of the block after the range point
|
||||
blockContentsAfterSplit =
|
||||
root.ownerDocument.createDocumentFragment();
|
||||
while ( ( node = container.childNodes[ offset ] ) ) {
|
||||
blockContentsAfterSplit.appendChild( node );
|
||||
}
|
||||
startContainer = child;
|
||||
startOffset = startContainer.childNodes.length;
|
||||
}
|
||||
while ( ( child = endContainer.firstChild ) &&
|
||||
child.nodeType === ELEMENT_NODE &&
|
||||
child.nodeName !== 'BR' ) {
|
||||
endContainer = child;
|
||||
}
|
||||
startAnchor = startContainer.childNodes[ startOffset ] || null;
|
||||
while ( ( child = frag.firstChild ) && isInline( child ) ) {
|
||||
startContainer.insertBefore( child, startAnchor );
|
||||
}
|
||||
while ( ( child = frag.lastChild ) && isInline( child ) ) {
|
||||
endContainer.insertBefore( child, endContainer.firstChild );
|
||||
endOffset += 1;
|
||||
}
|
||||
// And merge the first block in.
|
||||
mergeWithBlock( container, getNextBlock( frag, frag ), range, root );
|
||||
|
||||
// 3. Fix cursor then insert block(s) in the fragment
|
||||
node = frag;
|
||||
while ( node = getNextBlock( node, root ) ) {
|
||||
fixCursor( node, root );
|
||||
}
|
||||
parent.insertBefore( frag, nodeAfterSplit );
|
||||
// And where we will insert
|
||||
offset = indexOf.call( container.parentNode.childNodes, container ) + 1;
|
||||
container = container.parentNode;
|
||||
range.setEnd( container, offset );
|
||||
}
|
||||
|
||||
// 4. Remove empty nodes created either side of split, then
|
||||
// merge containers at the edges.
|
||||
next = nodeBeforeSplit.nextSibling;
|
||||
node = getPreviousBlock( next, root );
|
||||
if ( node && !/\S/.test( node.textContent ) ) {
|
||||
do {
|
||||
parent = node.parentNode;
|
||||
parent.removeChild( node );
|
||||
node = parent;
|
||||
} while ( node && !node.lastChild && node !== root );
|
||||
}
|
||||
if ( !nodeBeforeSplit.parentNode ) {
|
||||
nodeBeforeSplit = next.previousSibling;
|
||||
}
|
||||
if ( !startContainer.parentNode ) {
|
||||
startContainer = nodeBeforeSplit || next.parentNode;
|
||||
startOffset = nodeBeforeSplit ?
|
||||
nodeBeforeSplit.childNodes.length : 0;
|
||||
}
|
||||
// Merge inserted containers with edges of split
|
||||
if ( isContainer( next ) ) {
|
||||
mergeContainers( next, root );
|
||||
// Is there still any content in the fragment?
|
||||
if ( getLength( frag ) ) {
|
||||
moveRangeBoundariesUpTree( range, stopPoint, stopPoint, root );
|
||||
// Now split after block up to blockquote (if a parent) or root
|
||||
nodeAfterSplit = split(
|
||||
range.endContainer, range.endOffset, stopPoint, root );
|
||||
nodeBeforeSplit = nodeAfterSplit ?
|
||||
nodeAfterSplit.previousSibling :
|
||||
stopPoint.lastChild;
|
||||
stopPoint.insertBefore( frag, nodeAfterSplit );
|
||||
if ( nodeAfterSplit ) {
|
||||
range.setEndBefore( nodeAfterSplit );
|
||||
} else {
|
||||
range.setEnd( stopPoint, getLength( stopPoint ) );
|
||||
}
|
||||
block = getEndBlockOfRange( range, root );
|
||||
|
||||
// Get a reference that won't be invalidated if we merge containers.
|
||||
moveRangeBoundariesDownTree( range );
|
||||
container = range.endContainer;
|
||||
offset = range.endOffset;
|
||||
|
||||
prev = nodeAfterSplit.previousSibling;
|
||||
node = isBlock( nodeAfterSplit ) ?
|
||||
nodeAfterSplit : getNextBlock( nodeAfterSplit, root );
|
||||
if ( node && !/\S/.test( node.textContent ) ) {
|
||||
do {
|
||||
parent = node.parentNode;
|
||||
parent.removeChild( node );
|
||||
node = parent;
|
||||
} while ( node && !node.lastChild && node !== root );
|
||||
}
|
||||
if ( !nodeAfterSplit.parentNode ) {
|
||||
nodeAfterSplit = prev.nextSibling;
|
||||
}
|
||||
if ( !endOffset ) {
|
||||
endContainer = prev;
|
||||
endOffset = prev.childNodes.length;
|
||||
}
|
||||
// Merge inserted containers with edges of split
|
||||
if ( nodeAfterSplit && isContainer( nodeAfterSplit ) ) {
|
||||
mergeContainers( nodeAfterSplit, root );
|
||||
}
|
||||
|
||||
range.setStart( startContainer, startOffset );
|
||||
range.setEnd( endContainer, endOffset );
|
||||
moveRangeBoundariesDownTree( range );
|
||||
nodeAfterSplit = nodeBeforeSplit && nodeBeforeSplit.nextSibling;
|
||||
if ( nodeAfterSplit && isContainer( nodeAfterSplit ) ) {
|
||||
mergeContainers( nodeAfterSplit, root );
|
||||
}
|
||||
range.setEnd( container, offset );
|
||||
}
|
||||
|
||||
// Insert inline content saved from before.
|
||||
if ( blockContentsAfterSplit ) {
|
||||
tempRange = range.cloneRange();
|
||||
mergeWithBlock( block, blockContentsAfterSplit, tempRange, root );
|
||||
range.setEnd( tempRange.endContainer, tempRange.endOffset );
|
||||
}
|
||||
moveRangeBoundariesDownTree( range );
|
||||
};
|
||||
|
||||
// ---
|
||||
|
|
Loading…
Reference in a new issue