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

Better, simpler cleanup of zero-width space placeholders.

Fixes issue applying multiple inline formats at the same time with a collapsed
selection in WebKit. Much more robust than previous method.
This commit is contained in:
Neil Jenkins 2014-04-16 18:06:10 +10:00
parent 712104cd99
commit 0d5398868f
4 changed files with 48 additions and 84 deletions

View file

@ -318,7 +318,7 @@ function fixCursor ( node ) {
if ( cantFocusEmptyTextNodes ) {
fixer = doc.createTextNode( '\u200B' );
if ( win.editor ) {
win.editor._setPlaceholderTextNode( fixer );
win.editor._didAddZWS();
}
} else {
fixer = doc.createTextNode( '' );
@ -445,7 +445,7 @@ function mergeInlines ( node, range ) {
}
detach( child );
if ( child.nodeType === TEXT_NODE ) {
prev.appendData( child.data.replace( /\u200B/g, '' ) );
prev.appendData( child.data );
}
else {
frags.push( empty( child ) );
@ -1145,9 +1145,7 @@ function Squire ( doc ) {
this.addEventListener( 'beforedeactivate', this.getSelection );
}
this._placeholderTextNode = null;
this._mayRemovePlaceholder = true;
this._willEnablePlaceholderRemoval = false;
this._hasZWS = false;
this._lastAnchorNode = null;
this._lastFocusNode = null;
@ -1376,50 +1374,28 @@ proto.getPath = function () {
// WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=15256
proto._enablePlaceholderRemoval = function () {
this._mayRemovePlaceholder = true;
this._willEnablePlaceholderRemoval = false;
this.removeEventListener( 'keydown', this._enablePlaceholderRemoval );
proto._didAddZWS = function () {
this._hasZWS = true;
};
proto._removePlaceholderTextNode = function () {
if ( !this._mayRemovePlaceholder ) { return; }
var node = this._placeholderTextNode,
index;
this._placeholderTextNode = null;
if ( node.parentNode ) {
proto._removeZWS = function () {
if ( !this._hasZWS ) {
return;
}
var walker = new TreeWalker( this._body, SHOW_TEXT, function () {
return FILTER_ACCEPT;
}, false ),
node, index;
while ( node = walker.nextNode() ) {
while ( ( index = node.data.indexOf( '\u200B' ) ) > -1 ) {
node.deleteData( index, 1 );
}
if ( !node.data && !node.nextSibling && !node.previousSibling &&
isInline( node.parentNode ) ) {
detach( node.parentNode );
}
}
};
proto._setPlaceholderTextNode = function ( node ) {
if ( this._placeholderTextNode ) {
this._mayRemovePlaceholder = true;
this._removePlaceholderTextNode();
}
if ( !this._willEnablePlaceholderRemoval ) {
this.addEventListener( 'keydown', this._enablePlaceholderRemoval );
this._willEnablePlaceholderRemoval = true;
}
this._mayRemovePlaceholder = false;
this._placeholderTextNode = node;
this._hasZWS = false;
};
// --- Path change events ---
proto._updatePath = function ( range, force ) {
if ( this._placeholderTextNode && !force ) {
this._removePlaceholderTextNode( range );
}
var anchor = range.startContainer,
focus = range.endContainer,
newPath;
@ -1763,7 +1739,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
if ( range.collapsed ) {
if ( cantFocusEmptyTextNodes ) {
fixer = doc.createTextNode( '\u200B' );
this._setPlaceholderTextNode( fixer );
this._didAddZWS();
} else {
fixer = doc.createTextNode( '' );
}
@ -3039,6 +3015,12 @@ var keyHandlers = {
addLinks( range.startContainer );
self._getRangeAndRemoveBookmark( range );
self.setSelection( range );
},
left: function ( self ) {
self._removeZWS();
},
right: function ( self ) {
self._removeZWS();
}
};
// Firefox incorrectly handles Cmd-left/Cmd-right on Mac:
@ -3137,7 +3119,7 @@ proto.getHTML = function ( withBookMark ) {
}
}
}
html = this._getHTML();
html = this._getHTML().replace( /\u200B/g, '' );
if ( useTextFixer ) {
l = brs.length;
while ( l-- ) {

File diff suppressed because one or more lines are too long

View file

@ -83,9 +83,7 @@ function Squire ( doc ) {
this.addEventListener( 'beforedeactivate', this.getSelection );
}
this._placeholderTextNode = null;
this._mayRemovePlaceholder = true;
this._willEnablePlaceholderRemoval = false;
this._hasZWS = false;
this._lastAnchorNode = null;
this._lastFocusNode = null;
@ -314,50 +312,28 @@ proto.getPath = function () {
// WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=15256
proto._enablePlaceholderRemoval = function () {
this._mayRemovePlaceholder = true;
this._willEnablePlaceholderRemoval = false;
this.removeEventListener( 'keydown', this._enablePlaceholderRemoval );
proto._didAddZWS = function () {
this._hasZWS = true;
};
proto._removePlaceholderTextNode = function () {
if ( !this._mayRemovePlaceholder ) { return; }
var node = this._placeholderTextNode,
index;
this._placeholderTextNode = null;
if ( node.parentNode ) {
proto._removeZWS = function () {
if ( !this._hasZWS ) {
return;
}
var walker = new TreeWalker( this._body, SHOW_TEXT, function () {
return FILTER_ACCEPT;
}, false ),
node, index;
while ( node = walker.nextNode() ) {
while ( ( index = node.data.indexOf( '\u200B' ) ) > -1 ) {
node.deleteData( index, 1 );
}
if ( !node.data && !node.nextSibling && !node.previousSibling &&
isInline( node.parentNode ) ) {
detach( node.parentNode );
}
}
};
proto._setPlaceholderTextNode = function ( node ) {
if ( this._placeholderTextNode ) {
this._mayRemovePlaceholder = true;
this._removePlaceholderTextNode();
}
if ( !this._willEnablePlaceholderRemoval ) {
this.addEventListener( 'keydown', this._enablePlaceholderRemoval );
this._willEnablePlaceholderRemoval = true;
}
this._mayRemovePlaceholder = false;
this._placeholderTextNode = node;
this._hasZWS = false;
};
// --- Path change events ---
proto._updatePath = function ( range, force ) {
if ( this._placeholderTextNode && !force ) {
this._removePlaceholderTextNode( range );
}
var anchor = range.startContainer,
focus = range.endContainer,
newPath;
@ -701,7 +677,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
if ( range.collapsed ) {
if ( cantFocusEmptyTextNodes ) {
fixer = doc.createTextNode( '\u200B' );
this._setPlaceholderTextNode( fixer );
this._didAddZWS();
} else {
fixer = doc.createTextNode( '' );
}
@ -1977,6 +1953,12 @@ var keyHandlers = {
addLinks( range.startContainer );
self._getRangeAndRemoveBookmark( range );
self.setSelection( range );
},
left: function ( self ) {
self._removeZWS();
},
right: function ( self ) {
self._removeZWS();
}
};
// Firefox incorrectly handles Cmd-left/Cmd-right on Mac:
@ -2075,7 +2057,7 @@ proto.getHTML = function ( withBookMark ) {
}
}
}
html = this._getHTML();
html = this._getHTML().replace( /\u200B/g, '' );
if ( useTextFixer ) {
l = brs.length;
while ( l-- ) {

View file

@ -176,7 +176,7 @@ function fixCursor ( node ) {
if ( cantFocusEmptyTextNodes ) {
fixer = doc.createTextNode( '\u200B' );
if ( win.editor ) {
win.editor._setPlaceholderTextNode( fixer );
win.editor._didAddZWS();
}
} else {
fixer = doc.createTextNode( '' );
@ -303,7 +303,7 @@ function mergeInlines ( node, range ) {
}
detach( child );
if ( child.nodeType === TEXT_NODE ) {
prev.appendData( child.data.replace( /\u200B/g, '' ) );
prev.appendData( child.data );
}
else {
frags.push( empty( child ) );