Subramanya Sastry has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/77357


Change subject: (Bug 51678) Fixed bug in dom-diff algorithm
......................................................................

(Bug 51678) Fixed bug in dom-diff algorithm

* The dom-diff algorithm was occasionally recursing into
  template transclusion HTML.  Since transclusion HTML can never
  be directly modified by editors and template updates are
  transmitted via the data-mw object in the wrapper, it is not
  necessary to compare transclusion content.  It can in fact
  introduce bugs as in the itwp examples in the bug report because
  DOM-diff might insert deleted-content-markers and break the
  continuity in template about markers (which is important to
  skip over transclusion content during serialization correctly).

  This bug also only surfaces because of the peculiarities of how
  updated template HTML is modified in VE (see bug report for
  more details).

* Tested this with HTML (old and edited) dumped from VE via
  Chrome's console.  Verified bug without patch and a fix with
  the patch.

  Currently, we don't have direct dom-diff tests, only indirect
  tests via selser.

  Even if we did have, it would be hard to write a test for this
  bug fix becuase it depends on template content HTML getting
  deleted on edit (see bug report for details).

  But, it would be possible with a jasmine testing framework which
  we could consider resurrecting.

  To cut a long story short: no change in parsertest results,
  and no new tests added.

Change-Id: I886161d981a0c79b8300d88c5281514b4248cff2
---
M js/lib/mediawiki.DOMDiff.js
M js/lib/mediawiki.DOMUtils.js
M js/lib/mediawiki.WikitextSerializer.js
3 files changed, 34 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid 
refs/changes/57/77357/1

diff --git a/js/lib/mediawiki.DOMDiff.js b/js/lib/mediawiki.DOMDiff.js
index 5d4814e..39a90c4 100644
--- a/js/lib/mediawiki.DOMDiff.js
+++ b/js/lib/mediawiki.DOMDiff.js
@@ -231,31 +231,48 @@
                                if (origNode.nodeName === baseNode.nodeName) {
                                        // Identical wrapper-type, but modified.
                                        // Mark as modified, and recurse.
+                                       this.debug("--found diff: 
modified-wrapper--");
                                        this.markNode(origNode, 
'modified-wrapper');
-                                       this.doDOMDiff(baseNode, origNode);
+                                       if (!DU.isTplElementNode(this.env, 
baseNode) && !DU.isTplElementNode(this.env, origNode)) {
+                                               // Dont recurse into 
template-like-content
+                                               this.doDOMDiff(baseNode, 
origNode);
+                                       }
                                } else {
                                        // Mark the sub-tree as modified since
                                        // we have two entirely different nodes 
here
+                                       this.debug("--found diff: modified--");
                                        this.markNode(origNode, 'modified');
                                }
                        }
 
                        // Record the fact that direct children changed in the 
parent node
+                       this.debug("--found diff: modified-children--");
                        this.markNode(newParentNode, 'modified-children');
 
                        foundDiffOverall = true;
-               } else if (!DU.isTplElementNode(this.env, newNode)) {
+               } else if (!DU.isTplElementNode(this.env, baseNode) && 
!DU.isTplElementNode(this.env, newNode)) {
+                       this.debug("--equal: recursing--");
                        // Recursively diff subtrees if not template-like 
content
                        var subtreeDiffers = this.doDOMDiff(baseNode, newNode);
                        if (subtreeDiffers) {
+                               this.debug("--found diff: subtree-changed--");
                                this.markNode(newNode, 'subtree-changed');
                        }
                        foundDiffOverall = subtreeDiffers || foundDiffOverall;
                }
 
-               // And move on to the next pair
-               baseNode = baseNode.nextSibling;
-               newNode = newNode.nextSibling;
+               // And move on to the next pair (skipping over template HTML)
+               if (DU.isTplElementNode(this.env, baseNode)) {
+                       baseNode = DU.skipOverEncapsulatedContent(baseNode);
+               } else {
+                       baseNode = baseNode.nextSibling;
+               }
+
+               if (DU.isTplElementNode(this.env, newNode)) {
+                       newNode = DU.skipOverEncapsulatedContent(newNode);
+               } else {
+                       newNode = newNode.nextSibling;
+               }
        }
 
        // mark extra new nodes as modified
diff --git a/js/lib/mediawiki.DOMUtils.js b/js/lib/mediawiki.DOMUtils.js
index 0dd729e..e701a04 100644
--- a/js/lib/mediawiki.DOMUtils.js
+++ b/js/lib/mediawiki.DOMUtils.js
@@ -4,6 +4,7 @@
  * General DOM utilities
  */
 
+require('./core-upgrade.js');
 var Util = require('./mediawiki.Util.js').Util,
        Node = require('./mediawiki.wikitext.constants.js').Node,
        pd = require('./mediawiki.parser.defines.js');
@@ -681,6 +682,15 @@
                return nodes;
        },
 
+       skipOverEncapsulatedContent: function(node) {
+               var about = node.getAttribute('about');
+               if (!about) {
+                       return node;
+               }
+
+               return this.getAboutSiblings(node, about).last().nextSibling;
+       },
+
        /**
         * Extract transclusion and extension expansions from a DOM, and return
         * them in a structure like this:
diff --git a/js/lib/mediawiki.WikitextSerializer.js 
b/js/lib/mediawiki.WikitextSerializer.js
index bcf736b..651752e 100644
--- a/js/lib/mediawiki.WikitextSerializer.js
+++ b/js/lib/mediawiki.WikitextSerializer.js
@@ -3109,15 +3109,6 @@
        return srcParts.join('');
 };
 
-WSP.skipOverEncapsulatedContent = function(node) {
-       var about = node.getAttribute('about');
-       if (!about) {
-               return node;
-       }
-
-       return DU.getAboutSiblings(node, about).last().nextSibling;
-};
-
 /**
  * Get a DOM-based handler for an element node
  */
@@ -3168,7 +3159,7 @@
 
                                if (src !== undefined) {
                                        self.emitWikitext(src, state, cb, node);
-                                       return 
self.skipOverEncapsulatedContent(node);
+                                       return 
DU.skipOverEncapsulatedContent(node);
                                } else {
                                        console.error("ERROR: No handler for: " 
+ node.outerHTML);
                                        console.error("Serializing as HTML.");
@@ -3944,7 +3935,7 @@
                                        // Skip over encapsulated content since 
it has already been serialized
                                        var typeOf = node.getAttribute( 
'typeof' ) || '';
                                        if 
(/\bmw:(?:Transclusion\b|Param\b|Extension\/[^\s]+)/.test(typeOf)) {
-                                               nextNode = 
this.skipOverEncapsulatedContent(node);
+                                               nextNode = 
DU.skipOverEncapsulatedContent(node);
                                        }
                                } else if (DU.onlySubtreeChanged(node, 
this.env) &&
                                        hasValidTagWidths(dp.dsr) &&

-- 
To view, visit https://gerrit.wikimedia.org/r/77357
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I886161d981a0c79b8300d88c5281514b4248cff2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to