jenkins-bot has submitted this change and it was merged.

Change subject: Restructure normalization code
......................................................................


Restructure normalization code

* Restructured the normalization code to not be solely
  focused on the pairwise I/B tag minimization logic.
* Made it simpler to implement other normalizations.
* Fixed code styles for this file.

Change-Id: Ib82cf9ad3df4dd3dcce5ed7042aaca2b1619b1a7
---
M lib/wts.normalizeDOM.js
1 file changed, 113 insertions(+), 70 deletions(-)

Approvals:
  Arlolra: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/wts.normalizeDOM.js b/lib/wts.normalizeDOM.js
index 829e108..1a2e2ff 100644
--- a/lib/wts.normalizeDOM.js
+++ b/lib/wts.normalizeDOM.js
@@ -1,17 +1,17 @@
-"use strict";
+'use strict';
 
 require('./core-upgrade.js');
-var DU = require('./mediawiki.DOMUtils.js').DOMUtils,
-       Consts = require('./mediawiki.wikitext.constants.js').WikitextConstants;
+var DU = require('./mediawiki.DOMUtils.js').DOMUtils;
+var Consts = require('./mediawiki.wikitext.constants.js').WikitextConstants;
 
 var ignoreableAttribs = new Set(['data-parsoid', 'data-parsoid-diff']);
 
 function similar(a, b) {
-       var isHtml_a = DU.isLiteralHTMLNode(a);
-       var isHtml_b = DU.isLiteralHTMLNode(b);
+       var aIsHtml = DU.isLiteralHTMLNode(a);
+       var bIsHtml = DU.isLiteralHTMLNode(b);
 
-       return (!isHtml_a && !isHtml_b) ||
-               (isHtml_a && isHtml_b && DU.attribsEquals(a, b, 
ignoreableAttribs));
+       return (!aIsHtml && !bIsHtml) ||
+               (aIsHtml && bIsHtml && DU.attribsEquals(a, b, 
ignoreableAttribs));
 }
 
 /** Can a and b be merged into a single node? */
@@ -36,7 +36,7 @@
        DU.migrateChildren(b, a);
        b.parentNode.removeChild(b);
 
-       DU.setDiffMark(a, env, "children-changed");
+       DU.setDiffMark(a, env, 'children-changed');
        return a;
 }
 
@@ -46,11 +46,42 @@
        a.parentNode.insertBefore(b, a);
        b.appendChild(a);
 
-       DU.setDiffMark(a, env, "children-changed");
-       DU.setDiffMark(b, env, "children-changed");
+       DU.setDiffMark(a, env, 'children-changed');
+       DU.setDiffMark(b, env, 'children-changed');
 
        return b;
 }
+
+// Forward declaration
+var _normalizeDOM;
+
+/**
+ * Normalizations implemented right now:
+ * -------------------------------------
+ * 1. Tag minimization (I/B tags) in normalizeSiblingPair
+ */
+
+function normalizeNode(env, node) {
+       // Nothing to see here right now.
+       return node;
+}
+
+/*
+ * Tag minimization
+ * ----------------
+ * Minimize a pair of tags in the dom tree rooted at node.
+ *
+ * This function merges adjacent nodes of the same type
+ * and swaps nodes where possible to enable further merging.
+ *
+ * See examples below for a (B, I) tag-pair:
+ *
+ * 1. <b>X</b><b>Y</b>
+ *    ==> <b>XY</b>
+ *
+ * 2. <i>A</i><b><i>X</i></b><b><i>Y</i></b><i>Z</i>
+ *    ==> <i>A<b>XY</b>Z</i>
+ */
 
 function rewriteablePair(a, b) {
        // Currently supported: 'a' and 'b' are both B/I tags
@@ -73,83 +104,95 @@
                Consts.WTQuoteTags.has(b.nodeName);
 }
 
-/**
- * The only normalization implemented right now is I/B tag minimization.
- *
- * Minimize a pair of tags in the dom tree rooted at node.
- *
- * This function merges adjacent nodes of the same type
- * and swaps nodes where possible to enable further merging.
- *
- * See examples below for a (B, I) tag-pair:
- *
- * 1. <b>X</b><b>Y</b>
- *    ==> <b>XY</b>
- *
- * 2. <i>A</i><b><i>X</i></b><b><i>Y</i></b><i>Z</i>
- *    ==> <i>A<b>XY</b>Z</i>
- */
-function _normalizeDOM(env, node, recurse) {
-       if (DU.isFirstEncapsulationWrapperNode(node) || !node.firstChild) {
-               return;
+function normalizeSiblingPair(env, a, b) {
+       // If 'a' and 'b' make a rewriteable tag-pair,
+       // we are good to go.
+       if (rewriteablePair(a, b)) {
+               if (mergable(a, b)) {
+                       a = merge(env, a, b);
+                       // The new a's children have new siblings. So let's look
+                       // at a again. But their grandkids haven't changed,
+                       // so we don't need to recurse further.
+                       _normalizeDOM(env, a, false);
+               } else if (swappable(a, b)) {
+                       a = merge(env, swap(env, a, 
DU.firstNonDeletedChildNode(a)), b);
+                       // Again, a has new children, but the grandkids have 
already
+                       // been minimized.
+                       _normalizeDOM(env, a, false);
+               } else if (swappable(b, a)) {
+                       a = merge(env, a, swap(env, b, 
DU.firstNonDeletedChildNode(b)));
+                       // Again, a has new children, but the grandkids have 
already
+                       // been minimized.
+                       _normalizeDOM(env, a, false);
+               } else {
+                       a = b;
+               }
+       } else {
+               a = b;
        }
 
-       // Minimize the children of `node`.
-       // recurse = true  => recurse to ensure the children are also minimized
-       // recurse = false => assume the children are already minimized
-       var a = node.firstChild, b;
+       return a;
+}
 
-       if (DU.isElt(a) && recurse) {
-               _normalizeDOM(env, a, true);
+function processNode(env, a, recurse) {
+       // Normalize 'a' and the subtree rooted at 'a'
+       // recurse = true  => recurse and normalize subtree
+       // recurse = false => assume the subtree is already normalized
+
+       // Skip templated content
+       if (a && DU.isFirstEncapsulationWrapperNode(a)) {
+               a = DU.skipOverEncapsulatedContent(a);
        }
 
+       if (a) {
+               // Normalize node till it stabilizes
+               var next = normalizeNode(env, a);
+               while (next !== a) {
+                       if (!next) {
+                               return null;
+                       }
+                       a = next;
+                       next = normalizeNode(env, a);
+               }
+
+               // Process DOM rooted at 'a'
+               if (recurse && DU.isElt(a)) {
+                       _normalizeDOM(env, a, true);
+               }
+       }
+
+       return a;
+}
+
+_normalizeDOM = function(env, node, recurse) {
+       // Process the first child outside the loop.
+       var a = DU.firstNonDeletedChildNode(node);
+       a = processNode(env, a, recurse);
        while (a) {
-               b = DU.nextNonDeletedSibling(a);
+               // We need a pair of adjacent siblings for tag minimization.
+               var b = DU.nextNonDeletedSibling(a);
                if (!b) {
                        break;
                }
 
-               if (DU.isElt(b) && recurse) {
-                       _normalizeDOM(env, b, true);
-               }
+               // Process subtree rooted at 'b'.
+               b = processNode(env, b, recurse);
 
-               // If 'a' and 'b' make a rewriteable tag-pair and neither of 
them
-               // is an encapsulated element, we are good to go.
-               if (rewriteablePair(a, b) &&
-                       !DU.isFirstEncapsulationWrapperNode(a) &&
-                       !DU.isFirstEncapsulationWrapperNode(b)) {
-                       if (mergable(a, b)) {
-                               a = merge(env, a, b);
-                               // The new a's children have new siblings. So 
let's look
-                               // at a again. But the children themselves 
haven't changed,
-                               // so we don't need to recurse.
-                               _normalizeDOM(env, a, false);
-                       } else if (swappable(a, b)) {
-                               a = merge(env, swap(env, a, 
DU.firstNonDeletedChildNode(a)), b);
-                               // Again, a has new children, but the grandkids 
have already
-                               // been minimized.
-                               _normalizeDOM(env, a, false);
-                       } else if (swappable(b, a)) {
-                               a = merge(env, a, swap(env, b, 
DU.firstNonDeletedChildNode(b)));
-                               // Again, a has new children, but the grandkids 
have already
-                               // been minimized.
-                               _normalizeDOM(env, a, false);
-                       } else {
-                               a = b;
-                       }
+               // If we skipped over a bunch of nodes in the middle,
+               // we no longer have a pair of adjacent siblings.
+               if (b && DU.previousNonDeletedSibling(b) === a) {
+                       // Process the pair.
+                       a = normalizeSiblingPair(env, a, b);
                } else {
                        a = b;
                }
        }
+};
 
-       // return node to enable chaining
-       return node;
+function normalizeDOM(body, env) {
+       return _normalizeDOM(env, body, true);
 }
 
-function normalizeDOM(node, env) {
-       return _normalizeDOM(env, node, true);
-}
-
-if (typeof module === "object") {
+if (typeof module === 'object') {
        module.exports.normalizeDOM = normalizeDOM;
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib82cf9ad3df4dd3dcce5ed7042aaca2b1619b1a7
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: Arlolra <[email protected]>
Gerrit-Reviewer: Cscott <[email protected]>
Gerrit-Reviewer: Marcoil <[email protected]>
Gerrit-Reviewer: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to