0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 15:23:29 -05:00

Fix Range#get(Start|End)Block.

This commit is contained in:
Neil Jenkins 2011-11-02 16:31:46 +11:00
parent f89490736e
commit 9dcbf45f4a
3 changed files with 49 additions and 34 deletions

View file

@ -998,10 +998,18 @@ document.addEventListener( 'DOMContentLoaded', function () {
var splitNode = range.startContainer, var splitNode = range.startContainer,
splitOffset = range.startOffset, splitOffset = range.startOffset,
block = range.getStartBlock(), block = range.getStartBlock(),
tag = block.nodeName, tag = block ? block.nodeName : 'DIV',
splitTag = nextTag[ tag ], splitTag = nextTag[ tag ],
nodeAfterSplit; nodeAfterSplit;
if ( !block || event.shift ) {
range._insertNode( createElement( 'BR' ) );
range.collapse( false );
setSelection( range );
docWasChanged();
return;
}
if ( !block.textContent ) { if ( !block.textContent ) {
// Break list // Break list
if ( block.nearest( 'UL' ) ) { if ( block.nearest( 'UL' ) ) {

View file

@ -45,7 +45,6 @@ var swap = function( node, node2 ) {
var ELEMENT_NODE = 1, // Node.ELEMENT_NODE, var ELEMENT_NODE = 1, // Node.ELEMENT_NODE,
TEXT_NODE = 3, // Node.TEXT_NODE, TEXT_NODE = 3, // Node.TEXT_NODE,
DOCUMENT_FRAGMENT_NODE = 11, // Node.DOCUMENT_FRAGMENT_NODE
SHOW_ELEMENT = 1, // NodeFilter.SHOW_ELEMENT, SHOW_ELEMENT = 1, // NodeFilter.SHOW_ELEMENT,
FILTER_ACCEPT = 1, // NodeFilter.FILTER_ACCEPT, FILTER_ACCEPT = 1, // NodeFilter.FILTER_ACCEPT,
FILTER_SKIP = 3; // NodeFilter.FILTER_SKIP; FILTER_SKIP = 3; // NodeFilter.FILTER_SKIP;

View file

@ -116,8 +116,6 @@ implement( Range, {
this._extractContents(); this._extractContents();
// If we split into two different blocks, merge the blocks. // If we split into two different blocks, merge the blocks.
this.moveBoundariesDownTree();
var startBlock = this.getStartBlock(), var startBlock = this.getStartBlock(),
endBlock = this.getEndBlock(); endBlock = this.getEndBlock();
if ( startBlock && endBlock && startBlock !== endBlock ) { if ( startBlock && endBlock && startBlock !== endBlock ) {
@ -125,7 +123,7 @@ implement( Range, {
} }
// Ensure body has a block-level element in it. // Ensure body has a block-level element in it.
var doc = startBlock.ownerDocument, var doc = this.endContainer.ownerDocument,
body = doc.body, body = doc.body,
bodyFirstChild = body.firstChild; bodyFirstChild = body.firstChild;
if ( !bodyFirstChild || bodyFirstChild.nodeName === 'BR' ) { if ( !bodyFirstChild || bodyFirstChild.nodeName === 'BR' ) {
@ -325,42 +323,49 @@ implement( Range, {
return this; return this;
}, },
// First block that starts before or at range beginning. // Returns the first block at least partially contained by the range,
// or null if no block is contained by the range.
getStartBlock: function () { getStartBlock: function () {
// 1. Find first node after range start.
var node = this.startContainer, var node = this.startContainer,
offset = this.startOffset, offset = this.startOffset,
children = node.childNodes; children = node.childNodes;
if ( node.nodeType === ELEMENT_NODE && if ( node.nodeType === ELEMENT_NODE ) {
offset < children.length ) {
node = children[ offset ];
}
if ( !node.isBlock() ) {
node = node.getPreviousBlock() ||
this.startContainer.ownerDocument.body.getNextBlock();
}
return node;
},
// First block that starts before the range ends.
getEndBlock: function () {
var node = this.endContainer,
offset = this.endOffset,
children = node.childNodes;
if ( offset < children.length ) { if ( offset < children.length ) {
node = children[ offset ].getPreviousBlock(); node = children[ offset ];
} else { } else {
while ( node && !node.nextSibling ) { while ( node && !node.nextSibling ) {
node = node.parentNode; node = node.parentNode;
} }
if ( node ) { if ( node ) { node = node.nextSibling; }
node = node.nextSibling.getPreviousBlock();
} else {
node = this.startContainer.ownerDocument.body.lastChild;
if ( node ) { node = node.getPreviousBlock(); }
} }
} }
return node; // 2. If not a block, get previous block.
if ( node && !node.isBlock() ) {
node = node.getPreviousBlock();
}
// 3. Check the block does not end before range begins.
return node && this.containsNode( node, true ) ? node : null;
},
// Returns the last block at least partially contained by the range,
// or null if no block is contained by the range.
getEndBlock: function () {
// 1. Find first node before range end.
var node = this.endContainer,
offset = this.startOffset,
children = node.childNodes;
while ( offset && node.nodeType === ELEMENT_NODE ) {
node = children[ offset - 1 ];
children = node.childNodes;
offset = children.length;
}
// 2. If not a block, get previous block.
if ( !node.isBlock() ) {
node = node.getPreviousBlock();
}
// 3. Check the block does not end before range ends.
return node && this.containsNode( node, true ) ? node : null;
}, },
startsAtBlockBoundary: function () { startsAtBlockBoundary: function () {
@ -412,11 +417,14 @@ implement( Range, {
expandToBlockBoundaries: function () { expandToBlockBoundaries: function () {
var start = this.getStartBlock(), var start = this.getStartBlock(),
end = this.getEndBlock(), end = this.getEndBlock(),
parent = start.parentNode; parent;
if ( start && end ) {
parent = start.parentNode;
this.setStart( parent, indexOf.call( parent.childNodes, start ) ); this.setStart( parent, indexOf.call( parent.childNodes, start ) );
parent = end.parentNode; parent = end.parentNode;
this.setEnd( parent, indexOf.call( parent.childNodes, end ) + 1 ); this.setEnd( parent, indexOf.call( parent.childNodes, end ) + 1 );
}
return this; return this;
} }