Skip to content

Commit

Permalink
Fixes node.normalize polyfill failing to restore cursor in some cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Pulges committed Aug 18, 2015
1 parent 907b7de commit e60e81a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/polyfills.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,20 +367,24 @@ wysihtml5.polyfills = function(win, doc) {
return all;
};



var normalizeFix = function() {
var f = Node.prototype.normalize;
var nf = function() {
var texts = getTextNodes(this),
s = this.ownerDocument.defaultView.getSelection(),
anode = s.anchorNode,
aoffset = s.anchorOffset,
aelement = anode && anode.nodeType === 1 && anode.childNodes.length > 0 ? anode.childNodes[aoffset] : undefined,
fnode = s.focusNode,
foffset = s.focusOffset,
felement = fnode && fnode.nodeType === 1 && foffset > 0 ? fnode.childNodes[foffset -1] : undefined,
r = this.ownerDocument.createRange(),
prevTxt = texts.shift(),
curText = prevTxt ? texts.shift() : null;

if ((anode === fnode && foffset < aoffset) || (anode !== fnode && (anode.compareDocumentPosition(fnode) & Node.DOCUMENT_POSITION_PRECEDING))) {
if ((anode === fnode && foffset < aoffset) || (anode !== fnode && (anode.compareDocumentPosition(fnode) & Node.DOCUMENT_POSITION_PRECEDING) && !(anode.compareDocumentPosition(fnode) & Node.DOCUMENT_POSITION_CONTAINS))) {
fnode = [anode, anode = fnode][0];
foffset = [aoffset, aoffset = foffset][0];
}
Expand All @@ -404,13 +408,20 @@ wysihtml5.polyfills = function(win, doc) {
}
}

if (felement) {
foffset = Array.prototype.indexOf.call(felement.parentNode.childNodes, felement) + 1;
}

if (aelement) {
aoffset = Array.prototype.indexOf.call(aelement.parentNode.childNodes, aelement);
}

if (anode && anode.parentNode && fnode && fnode.parentNode) {
r.setStart(anode, aoffset);
r.setEnd(fnode, foffset);
s.removeAllRanges();
s.addRange(r);
}

};
Node.prototype.normalize = nf;
};
Expand Down
60 changes: 60 additions & 0 deletions test/polyfills_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,63 @@ test("Check element.normalize is preserving caret position", function() {
ok(s.anchorNode === this.editable.firstChild, "Anchor element is correct after normalize");
ok(s.anchorOffset === 7 , "Anchor offset is correct after normalize");
});

test("Check element.normalize is preserving selection", function() {
var text1 = document.createTextNode('test'),
text2 = document.createTextNode('foo'),
text3 = document.createTextNode('third'),
text4 = document.createTextNode('fourth'),
br = document.createElement('br'),
r = rangy.createRange(),
s;

this.editable.appendChild(text1);
this.editable.appendChild(text2);
this.editable.appendChild(br);
this.editable.appendChild(text3);
this.editable.appendChild(text4);

r.setStart(text2, 0);
r.setEndAfter(br);
r.select();

this.editable.normalize();
s = rangy.getSelection();

ok(this.editable.childNodes.length === 3, "Normalize merged nodes");
equal(s.anchorNode, this.editable.firstChild, "Anchor element is correct after normalize");
equal(s.anchorOffset, 4 , "Anchor offset is correct after normalize");
equal(s.focusNode, this.editable, "Focus element is correct after normalize");
equal(s.focusOffset, 2 , "Focus offset is correct after normalize");
});


test("Check element.normalize is preserving selection 2", function() {
var text1 = document.createTextNode('test'),
text2 = document.createTextNode('foo'),
text3 = document.createTextNode('third'),
text4 = document.createTextNode('fourth'),
br = document.createElement('br'),
r = rangy.createRange(),
s;

this.editable.appendChild(text1);
this.editable.appendChild(text2);
this.editable.appendChild(br);
this.editable.appendChild(text3);
this.editable.appendChild(text4);

r.setStartBefore(br);
r.setEnd(text4, 0);
r.select();

this.editable.normalize();
s = rangy.getSelection();

ok(this.editable.childNodes.length === 3, "Normalize merged nodes");
equal(s.anchorNode, this.editable, "Anchor element is correct after normalize");
equal(s.anchorOffset, 1, "Anchor offset is correct after normalize");
equal(s.focusNode, this.editable.childNodes[2], "Focus element is correct after normalize");
equal(s.focusOffset, 5 , "Focus offset is correct after normalize");
});

0 comments on commit e60e81a

Please sign in to comment.