From 8751d91a80f5e16e1aaf017177bd456a28459375 Mon Sep 17 00:00:00 2001 From: Blagovest Dachev Date: Sun, 8 Aug 2010 22:53:28 -0500 Subject: [PATCH] added code to delete cached path and trail variables from elements on DOM mutation --- lib/dominiq.js | 51 +++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/lib/dominiq.js b/lib/dominiq.js index da7a2a3..674c86e 100644 --- a/lib/dominiq.js +++ b/lib/dominiq.js @@ -95,7 +95,7 @@ HTMLDocument.prototype.createElement = function(name) { }; HTMLDocument.prototype.createComment = function() { - //FIXME: libxmljs doesn't provide the means to do this. It also adopting nodes is problematic + //FIXME: libxmljs doesn't provide the means to do this. Also adopting nodes is problematic var doc = libxml.parseHtmlString(''), body = doc.root().child(0), node = body.child(0); @@ -108,11 +108,8 @@ HTMLDocument.prototype.createComment = function() { }; HTMLDocument.prototype.createTextNode = function(text) { - //FIXME: libxmljs doesn't provide the means to do this. It also adopting nodes is problematic - var doc = libxml.parseHtmlString('' + text + ''), - body = doc.root().child(0), - node = body.child(0); - + var node = new libxml.Element(this._d, 'span', {}, text).childNodes()[0]; + node.remove(); node._d = this._d; node._dd = this; @@ -121,7 +118,7 @@ HTMLDocument.prototype.createTextNode = function(text) { } HTMLDocument.prototype.createDocumentFragment = function() { - //FIXME: libxmljs doesn't provide the means to do this. It also adopting nodes is problematic + //FIXME: libxmljs doesn't provide the means to do this. Also adopting nodes is problematic return createHTMLFragment(this); } @@ -282,7 +279,7 @@ HTMLElement.prototype.__defineGetter__('innerHTML', function() { }); HTMLElement.prototype.__defineSetter__('innerHTML', function(html) { - //FIXME: libxmljs doesn't provide the means to do this. It also sucks at adopting nodes + //FIXME: libxmljs doesn't provide the means to do this. Also sucks at adopting nodes // clear element var nodes = this._n.childNodes(); @@ -327,20 +324,23 @@ HTMLElement.prototype.toString = function() { } HTMLElement.prototype.insertBefore = function(newElement, referenceElement) { - // TODO: update path and trail caches if (newElement._n._isFragment === true) { var nodes = newElement._n.childNodes(); for (var i = 0; i < nodes.length; i++) { + delete nodes[i].path; + delete nodes[i].trail; referenceElement._n.addPrevSibling(nodes[i]); } } else { + delete newElement.path; + delete newElement.trail; referenceElement._n.addPrevSibling(newElement._n); } }; HTMLElement.prototype.cloneNode = function(deep) { - //FIXME: libxmljs doesn't provide the means to do this. It also adopting nodes is problematic + //FIXME: libxmljs doesn't provide the means to do this. Also adopting nodes is problematic var html = this._n.toString(); @@ -373,19 +373,22 @@ HTMLElement.prototype.cloneNode = function(deep) { }; HTMLElement.prototype.appendChild = function(newElement) { - // TODO: update path and trail caches if (newElement._n._isFragment === true) { var nodes = newElement._n._childNodes(); for (var i = 0; i < nodes.length; i++) { - this._n.addChild(nodes[i]); + delete nodes[i].path; + delete nodes[i].trail; nodes[i]._d = this._d; nodes[i]._dd = this._dd; + this._n.addChild(nodes[i]); } } else { + delete newElement.path; + delete newElement.trail; newElement._d = this._d; newElement._dd = this._dd; - this._n.addChild(newElement._n) + this._n.addChild(newElement._n); } var newestElement = this.lastChild; @@ -394,7 +397,9 @@ HTMLElement.prototype.appendChild = function(newElement) { }; HTMLElement.prototype.removeChild = function(child) { - // TODO: update path and trail caches + delete child.path; + delete child.trail; + child._n.remove(); return child; @@ -468,19 +473,19 @@ HTMLElement.prototype.compareDocumentPosition = function(other) { dTrail.push(tTrail[idx++]); } - // given '/html/head/style'.compareDocumentPosition('/html/head/script') - var commonDescendant = this._n.get(dTrail.join('/')), // /html/head - thisDescendant = commonDescendant.get(tTrail[idx]), // /html/head/style - otherDescendant = commonDescendant.get(oTrail[idx]), // /html/head/script - descendantSiblings = commonDescendant.childNodes(); // /html/head/* + // given '/html/head/style'.compareDocumentPosition('/html/body/div/span') + var commonAncestor = this._n.get(dTrail.join('/')), // /html + thisAncestor = commonAncestor.get(tTrail[idx]), // /html/head + otherAncestor = commonAncestor.get(oTrail[idx]), // /html/body + ancestorSiblings = commonAncestor.childNodes(); // /html/* - for (var i = 0; i < descendantSiblings.length; i++) { - var sibling = descendantSiblings[i]; + for (var i = 0; i < ancestorSiblings.length; i++) { + var sibling = ancestorSiblings[i]; - if (sibling === thisDescendant) { + if (sibling === thisAncestor) { return order.DOCUMENT_POSITION_FOLLOWING; } - if (sibling === otherDescendant) { + if (sibling === otherAncestor) { return order.DOCUMENT_POSITION_PRECEDING; } }