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

Ignore saved selection if not in document

The browser will rewrite the range if the nodes it refers to are removed from
the document, so check that it's still in the document before returning.
This commit is contained in:
Neil Jenkins 2017-07-07 11:48:42 +10:00
parent 0ae8322d04
commit 239b7d19e9
3 changed files with 41 additions and 21 deletions

View file

@ -2917,7 +2917,7 @@ proto.setSelection = function ( range ) {
proto.getSelection = function () {
var sel = getWindowSelection( this );
var root = this._root;
var selection, startContainer, endContainer;
var selection, startContainer, endContainer, node;
// If not focused, always rely on cached selection; another function may
// have set it but the DOM is not modified until focus again
if ( this._isFocused && sel && sel.rangeCount ) {
@ -2937,6 +2937,12 @@ proto.getSelection = function () {
this._lastSelection = selection;
} else {
selection = this._lastSelection;
node = selection.commonAncestorContainer;
// Check the editor is in the live document; if not, the range has
// probably been rewritten by the browser and is bogus
if ( !isOrContains( node.ownerDocument, node ) ) {
selection = null;
}
}
if ( !selection ) {
selection = this._createRange( root.firstChild, 0 );
@ -2957,20 +2963,23 @@ function restoreSelection () {
}
proto.getSelectedText = function () {
var range = this.getSelection(),
walker = new TreeWalker(
var range = this.getSelection();
if ( !range || range.collapsed ) {
return '';
}
var walker = new TreeWalker(
range.commonAncestorContainer,
SHOW_TEXT|SHOW_ELEMENT,
function ( node ) {
return isNodeContainedInRange( range, node, true );
}
),
startContainer = range.startContainer,
endContainer = range.endContainer,
node = walker.currentNode = startContainer,
textContent = '',
addedTextInBlock = false,
value;
);
var startContainer = range.startContainer;
var endContainer = range.endContainer;
var node = walker.currentNode = startContainer;
var textContent = '';
var addedTextInBlock = false;
var value;
if ( !walker.filter( node ) ) {
node = walker.nextNode();
@ -3049,6 +3058,9 @@ proto._removeZWS = function () {
// --- Path change events ---
proto._updatePath = function ( range, force ) {
if ( !range ) {
return;
}
var anchor = range.startContainer,
focus = range.endContainer,
newPath;
@ -3071,9 +3083,9 @@ proto._updatePath = function ( range, force ) {
// selectionchange is fired synchronously in IE when removing current selection
// and when setting new selection; keyup/mouseup may have processing we want
// to do first. Either way, send to next event loop.
proto._updatePathOnEvent = function () {
proto._updatePathOnEvent = function ( event ) {
var self = this;
if ( !self._willUpdatePath ) {
if ( self._isFocused && !self._willUpdatePath ) {
self._willUpdatePath = true;
setTimeout( function () {
self._willUpdatePath = false;
@ -4093,7 +4105,9 @@ proto.setHTML = function ( html ) {
};
proto.insertElement = function ( el, range ) {
if ( !range ) { range = this.getSelection(); }
if ( !range ) {
range = this.getSelection();
}
range.collapse( true );
if ( isInline( el ) ) {
insertNodeInRange( range, el );

File diff suppressed because one or more lines are too long

View file

@ -463,7 +463,7 @@ proto.setSelection = function ( range ) {
proto.getSelection = function () {
var sel = getWindowSelection( this );
var root = this._root;
var selection, startContainer, endContainer;
var selection, startContainer, endContainer, node;
// If not focused, always rely on cached selection; another function may
// have set it but the DOM is not modified until focus again
if ( this._isFocused && sel && sel.rangeCount ) {
@ -483,6 +483,12 @@ proto.getSelection = function () {
this._lastSelection = selection;
} else {
selection = this._lastSelection;
node = selection.commonAncestorContainer;
// Check the editor is in the live document; if not, the range has
// probably been rewritten by the browser and is bogus
if ( !isOrContains( node.ownerDocument, node ) ) {
selection = null;
}
}
if ( !selection ) {
selection = this._createRange( root.firstChild, 0 );