mirror of
https://github.com/fastmail/Squire.git
synced 2024-12-22 15:23:29 -05:00
Improve detection of range at begin/end of block.
This commit is contained in:
parent
4a8152d280
commit
a280cb4946
3 changed files with 72 additions and 58 deletions
|
@ -615,6 +615,7 @@ function createElement ( doc, tag, props, children ) {
|
||||||
START_TO_END,
|
START_TO_END,
|
||||||
END_TO_END,
|
END_TO_END,
|
||||||
END_TO_START,
|
END_TO_START,
|
||||||
|
notWS,
|
||||||
indexOf,
|
indexOf,
|
||||||
|
|
||||||
TreeWalker,
|
TreeWalker,
|
||||||
|
@ -1059,50 +1060,56 @@ var getEndBlockOfRange = function ( range ) {
|
||||||
return block && isNodeContainedInRange( range, block, true ) ? block : null;
|
return block && isNodeContainedInRange( range, block, true ) ? block : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var contentWalker = new TreeWalker( null,
|
||||||
|
SHOW_TEXT|SHOW_ELEMENT,
|
||||||
|
function ( node ) {
|
||||||
|
return node.nodeType === TEXT_NODE ?
|
||||||
|
notWS.test( node.data ) :
|
||||||
|
node.nodeName === 'IMG';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
var rangeDoesStartAtBlockBoundary = function ( range ) {
|
var rangeDoesStartAtBlockBoundary = function ( range ) {
|
||||||
var startContainer = range.startContainer,
|
var startContainer = range.startContainer,
|
||||||
startOffset = range.startOffset,
|
startOffset = range.startOffset;
|
||||||
parent, child;
|
|
||||||
|
|
||||||
while ( isInline( startContainer ) ) {
|
// If in the middle or end of a text node, we're not at the boundary.
|
||||||
|
if ( startContainer.nodeType === TEXT_NODE ) {
|
||||||
if ( startOffset ) {
|
if ( startOffset ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
parent = startContainer.parentNode;
|
contentWalker.currentNode = startContainer;
|
||||||
startOffset = indexOf.call( parent.childNodes, startContainer );
|
} else {
|
||||||
startContainer = parent;
|
contentWalker.currentNode = getNodeAfter( startContainer, startOffset );
|
||||||
}
|
}
|
||||||
// Skip empty text nodes and <br>s.
|
|
||||||
while ( startOffset &&
|
// Otherwise, look for any previous content in the same block.
|
||||||
( child = startContainer.childNodes[ startOffset - 1 ] ) &&
|
contentWalker.root = getStartBlockOfRange( range );
|
||||||
( child.data === '' || child.nodeName === 'BR' ) ) {
|
|
||||||
startOffset -= 1;
|
return !contentWalker.previousNode();
|
||||||
}
|
|
||||||
return !startOffset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var rangeDoesEndAtBlockBoundary = function ( range ) {
|
var rangeDoesEndAtBlockBoundary = function ( range ) {
|
||||||
var endContainer = range.endContainer,
|
var endContainer = range.endContainer,
|
||||||
endOffset = range.endOffset,
|
endOffset = range.endOffset,
|
||||||
length = getLength( endContainer ),
|
length;
|
||||||
parent, child;
|
|
||||||
|
|
||||||
while ( isInline( endContainer ) ) {
|
// If in a text node with content, and not at the end, we're not
|
||||||
if ( endOffset !== length ) {
|
// at the boundary
|
||||||
|
if ( endContainer.nodeType === TEXT_NODE ) {
|
||||||
|
length = endContainer.data.length;
|
||||||
|
if ( length && endOffset < length ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
parent = endContainer.parentNode;
|
contentWalker.currentNode = endContainer;
|
||||||
endOffset = indexOf.call( parent.childNodes, endContainer ) + 1;
|
} else {
|
||||||
endContainer = parent;
|
contentWalker.currentNode = getNodeBefore( endContainer, endOffset );
|
||||||
length = endContainer.childNodes.length;
|
|
||||||
}
|
}
|
||||||
// Skip empty text nodes and <br>s.
|
|
||||||
while ( endOffset < length &&
|
// Otherwise, look for any further content in the same block.
|
||||||
( child = endContainer.childNodes[ endOffset ] ) &&
|
contentWalker.root = getEndBlockOfRange( range );
|
||||||
( child.data === '' || child.nodeName === 'BR' ) ) {
|
|
||||||
endOffset += 1;
|
return !contentWalker.nextNode();
|
||||||
}
|
|
||||||
return endOffset === length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var expandRangeToBlockBoundaries = function ( range ) {
|
var expandRangeToBlockBoundaries = function ( range ) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,6 +7,7 @@
|
||||||
START_TO_END,
|
START_TO_END,
|
||||||
END_TO_END,
|
END_TO_END,
|
||||||
END_TO_START,
|
END_TO_START,
|
||||||
|
notWS,
|
||||||
indexOf,
|
indexOf,
|
||||||
|
|
||||||
TreeWalker,
|
TreeWalker,
|
||||||
|
@ -451,50 +452,56 @@ var getEndBlockOfRange = function ( range ) {
|
||||||
return block && isNodeContainedInRange( range, block, true ) ? block : null;
|
return block && isNodeContainedInRange( range, block, true ) ? block : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var contentWalker = new TreeWalker( null,
|
||||||
|
SHOW_TEXT|SHOW_ELEMENT,
|
||||||
|
function ( node ) {
|
||||||
|
return node.nodeType === TEXT_NODE ?
|
||||||
|
notWS.test( node.data ) :
|
||||||
|
node.nodeName === 'IMG';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
var rangeDoesStartAtBlockBoundary = function ( range ) {
|
var rangeDoesStartAtBlockBoundary = function ( range ) {
|
||||||
var startContainer = range.startContainer,
|
var startContainer = range.startContainer,
|
||||||
startOffset = range.startOffset,
|
startOffset = range.startOffset;
|
||||||
parent, child;
|
|
||||||
|
|
||||||
while ( isInline( startContainer ) ) {
|
// If in the middle or end of a text node, we're not at the boundary.
|
||||||
|
if ( startContainer.nodeType === TEXT_NODE ) {
|
||||||
if ( startOffset ) {
|
if ( startOffset ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
parent = startContainer.parentNode;
|
contentWalker.currentNode = startContainer;
|
||||||
startOffset = indexOf.call( parent.childNodes, startContainer );
|
} else {
|
||||||
startContainer = parent;
|
contentWalker.currentNode = getNodeAfter( startContainer, startOffset );
|
||||||
}
|
}
|
||||||
// Skip empty text nodes and <br>s.
|
|
||||||
while ( startOffset &&
|
// Otherwise, look for any previous content in the same block.
|
||||||
( child = startContainer.childNodes[ startOffset - 1 ] ) &&
|
contentWalker.root = getStartBlockOfRange( range );
|
||||||
( child.data === '' || child.nodeName === 'BR' ) ) {
|
|
||||||
startOffset -= 1;
|
return !contentWalker.previousNode();
|
||||||
}
|
|
||||||
return !startOffset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var rangeDoesEndAtBlockBoundary = function ( range ) {
|
var rangeDoesEndAtBlockBoundary = function ( range ) {
|
||||||
var endContainer = range.endContainer,
|
var endContainer = range.endContainer,
|
||||||
endOffset = range.endOffset,
|
endOffset = range.endOffset,
|
||||||
length = getLength( endContainer ),
|
length;
|
||||||
parent, child;
|
|
||||||
|
|
||||||
while ( isInline( endContainer ) ) {
|
// If in a text node with content, and not at the end, we're not
|
||||||
if ( endOffset !== length ) {
|
// at the boundary
|
||||||
|
if ( endContainer.nodeType === TEXT_NODE ) {
|
||||||
|
length = endContainer.data.length;
|
||||||
|
if ( length && endOffset < length ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
parent = endContainer.parentNode;
|
contentWalker.currentNode = endContainer;
|
||||||
endOffset = indexOf.call( parent.childNodes, endContainer ) + 1;
|
} else {
|
||||||
endContainer = parent;
|
contentWalker.currentNode = getNodeBefore( endContainer, endOffset );
|
||||||
length = endContainer.childNodes.length;
|
|
||||||
}
|
}
|
||||||
// Skip empty text nodes and <br>s.
|
|
||||||
while ( endOffset < length &&
|
// Otherwise, look for any further content in the same block.
|
||||||
( child = endContainer.childNodes[ endOffset ] ) &&
|
contentWalker.root = getEndBlockOfRange( range );
|
||||||
( child.data === '' || child.nodeName === 'BR' ) ) {
|
|
||||||
endOffset += 1;
|
return !contentWalker.nextNode();
|
||||||
}
|
|
||||||
return endOffset === length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var expandRangeToBlockBoundaries = function ( range ) {
|
var expandRangeToBlockBoundaries = function ( range ) {
|
||||||
|
|
Loading…
Reference in a new issue