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

Change subject: Fix quote minimization to deal with edits more comprehensively
......................................................................


Fix quote minimization to deal with edits more comprehensively

* Merge adjacent quote nodes in all cases, not just if they are new.

* There was a FIXME that anticipated this but for some reason, we never
  addressed this. This patch addresses that and also applies the
  transformation even when there is no DOM diff information for reasons
  that have been documented in the algorithm.

* This improves selser serialization in a number of edit scenarios.

* New parser tests with edit changes capture the expectations
  represented in this patch.

  TODO: We still need tests that verify that the merging happens even
  when the DOM has DOM-diff information. To be done in a later patch
  by upgrading the parser tests framework. This is tracked in T72722.

Change-Id: Id85af3c67ea6c77e5e98c0bdbdcd18d9d483acb7
---
M lib/mediawiki.DOMUtils.js
M lib/mediawiki.WikitextSerializer.js
M lib/wts.minimizeWTQuoteTags.js
M tests/parserTests-blacklist.js
M tests/parserTests.txt
5 files changed, 87 insertions(+), 33 deletions(-)

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



diff --git a/lib/mediawiki.DOMUtils.js b/lib/mediawiki.DOMUtils.js
index 167c8ef..1346064 100644
--- a/lib/mediawiki.DOMUtils.js
+++ b/lib/mediawiki.DOMUtils.js
@@ -1023,6 +1023,9 @@
                        };
                }
 
+               // Clear out the loaded value
+               this.getNodeData(node)["parsoid-diff"] = undefined;
+
                // Add serialization info to this node
                this.setJSONAttribute(node, 'data-parsoid-diff', dpd);
        },
@@ -1114,6 +1117,17 @@
                return next;
        },
 
+       numNonDeletedChildNodes: function(node) {
+               var n = 0, child = node.firstChild;
+               while (child) {
+                       if (!this.isMarkerMeta(child, "mw:DiffMarker")) {
+                               n++;
+                       }
+                       child = child.nextSibling;
+               }
+               return n;
+       },
+
        /**
         * Get the first mw:DiffMarker child of node
         */
diff --git a/lib/mediawiki.WikitextSerializer.js 
b/lib/mediawiki.WikitextSerializer.js
index 8ac9133..0e114db 100644
--- a/lib/mediawiki.WikitextSerializer.js
+++ b/lib/mediawiki.WikitextSerializer.js
@@ -1250,7 +1250,7 @@
        var state = new SerializerState(this, this.options);
        try {
                // Minimize I/B tags
-               minimizeWTQuoteTags(body);
+               minimizeWTQuoteTags(body, state.env);
 
                // Don't serialize the DOM if debugging is disabled
                this.env.log(this.logType, function() {
diff --git a/lib/wts.minimizeWTQuoteTags.js b/lib/wts.minimizeWTQuoteTags.js
index a63a294..ea1edc2 100644
--- a/lib/wts.minimizeWTQuoteTags.js
+++ b/lib/wts.minimizeWTQuoteTags.js
@@ -25,24 +25,28 @@
  * For example: a='<b><i>x</i></b>' b='<i>y</i>' => '<i><b>x</b>y</i>'
  */
 function swappable(a, b) {
-       return a.childNodes.length === 1 &&
-               similar(a, a.firstChild) &&
-               mergable(a.firstChild, b);
+       return DU.numNonDeletedChildNodes(a) === 1 &&
+               similar(a, DU.firstNonDeletedChildNode(a)) &&
+               mergable(DU.firstNonDeletedChildNode(a), b);
 }
 
 /** Transfer all of b's children to a and delete b */
-function merge(a, b) {
+function merge(env, a, b) {
        DU.migrateChildren(b, a);
        b.parentNode.removeChild(b);
 
+       DU.setDiffMark(a, env, "children-changed");
        return a;
 }
 
-/** b is a's sole child.  Switch them around. */
-function swap(a, b) {
+/** b is a's sole non-deleted child.  Switch them around. */
+function swap(env, a, b) {
        DU.migrateChildren(b, a);
        a.parentNode.insertBefore(b, a);
        b.appendChild(a);
+
+       DU.setDiffMark(a, env, "children-changed");
+       DU.setDiffMark(b, env, "children-changed");
 
        return b;
 }
@@ -61,7 +65,7 @@
  * 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 minimizeTags(node, rewriteablePair, recurse) {
+function minimizeTags(env, node, rewriteablePair, recurse) {
        if (DU.isFirstEncapsulationWrapperNode(node) || !node.firstChild) {
                return;
        }
@@ -72,17 +76,17 @@
        var a = node.firstChild, b;
 
        if (DU.isElt(a) && recurse) {
-               minimizeTags(a, rewriteablePair, true);
+               minimizeTags(env, a, rewriteablePair, true);
        }
 
        while (a) {
-               b = a.nextSibling;
+               b = DU.nextNonDeletedSibling(a);
                if (!b) {
                        break;
                }
 
                if (DU.isElt(b) && recurse) {
-                       minimizeTags(b, rewriteablePair, true);
+                       minimizeTags(env, b, rewriteablePair, true);
                }
 
                // If 'a' and 'b' make a rewriteable tag-pair and neither of 
them
@@ -92,21 +96,21 @@
                        !DU.isFirstEncapsulationWrapperNode(b))
                {
                        if (mergable(a, b)) {
-                               a = merge(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.
-                               minimizeTags(a, rewriteablePair, false);
+                               minimizeTags(env, a, rewriteablePair, false);
                        } else if (swappable(a, b)) {
-                               a = merge(swap(a, a.firstChild), b);
+                               a = merge(env, swap(env, a, 
DU.firstNonDeletedChildNode(a)), b);
                                // again, a has new children, but the grandkids 
have already
                                // been minimized.
-                               minimizeTags(a, rewriteablePair, false);
+                               minimizeTags(env, a, rewriteablePair, false);
                        } else if (swappable(b, a)) {
-                               a = merge(a, swap(b, b.firstChild));
+                               a = merge(env, a, swap(env, b, 
DU.firstNonDeletedChildNode(b)));
                                // again, a has new children, but the grandkids 
have already
                                // been minimized.
-                               minimizeTags(a, rewriteablePair, false);
+                               minimizeTags(env, a, rewriteablePair, false);
                        } else {
                                a = b;
                        }
@@ -119,16 +123,24 @@
        return node;
 }
 
-function minimizeWTQuoteTags(node) {
-       return minimizeTags(node, function(a, b) {
+// NOTE: We need not check whether the node being transformed
+// are new / edited, etc. since these minimization scenarios can
+// never show up in HTML that came from parsed wikitext
+//
+// <i>..</i><i>..</i> can never show up without a <nowiki/> in between.
+// Similarly for <b>..</b><b>..</b> and <b><i>..</i></b><i>..</i>.
+//
+// This is because a sequence of 4 quotes is not parsed as ..</i><i>..
+// Neither is a sequence of 7 quotes parsed as ..</i></b><i>..
+//
+// So, if we see a minimizable pair of nodes, it is because the HTML
+// didn't originate from wikitext OR the HTML has been subsequently edited.
+// In both cases, we want to apply the transformation below.
+function minimizeWTQuoteTags(node, env) {
+       return minimizeTags(env, node, function(a, b) {
                        // - 'a' and 'b' are both B/I tags
-                       // - at least one of them is new
-                       //   FIXME: What if neither is new, but one of them is 
modified?
-                       //   Do we want to minimize and introduce a dirty diff?
-                       // - neither is an encapsulated elt
                        return Consts.WTQuoteTags.has( a.nodeName ) &&
-                               Consts.WTQuoteTags.has( b.nodeName ) &&
-                               (DU.isNewElt(a) || DU.isNewElt(b));
+                               Consts.WTQuoteTags.has( b.nodeName );
                }, true);
 }
 
diff --git a/tests/parserTests-blacklist.js b/tests/parserTests-blacklist.js
index 293ee8d..2e459c4 100644
--- a/tests/parserTests-blacklist.js
+++ b/tests/parserTests-blacklist.js
@@ -1805,7 +1805,7 @@
 add("selser", "Italics and possessives (1) [[4,1,4]]", 
"nahe6nth1skedn29''[[Lunar Prospector]]'''tw799rbafavsfw29");
 add("selser", "Italics and possessives (1) [[3,0,0]]", "''[[Lunar 
Prospector]]'''s gamma-ray spectrometer");
 add("selser", "Italics and possessives (2) [1]", "'''''Flaming Pie''''' is ... 
released in 1997. In ''Flaming Pie'''s liner notes");
-add("selser", "Italics and possessives (2) [[2,3,0,0]]", 
"0zb8t8umky2pgb9'''''Flaming Pie'''''''Flaming Pie'''s liner notes");
+add("selser", "Italics and possessives (2) [[2,3,0,0]]", 
"0zb8t8umky2pgb9'''''Flaming Pie'''Flaming Pie'''s liner notes");
 add("selser", "Italics and possessives (2) [[[[4]],4,0,3]]", 
"'''''d312q2axy1fw29'''''5w7rrd5xccndygb9''Flaming Pie'''\n");
 add("selser", "Italics and possessives (2) [[[[4]],0,0,0]]", 
"'''''1qqtc3s8ljl9pb9''''' is ... released in 1997. In ''Flaming Pie'''s liner 
notes");
 add("selser", "Italics and possessives (2) [2]", 
"tci84mu6dedpwrk9\n\n'''''Flaming Pie''''' is ... released in 1997. In 
''Flaming Pie'''s liner notes");
@@ -2051,14 +2051,14 @@
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[3,0,[2],0,3,4,3,[0,[0,[1]],4],0,1]]", "\n[http://example.com 
4n2162e1fd730udi'''text''']'''rgd08hyitua0pb9''Something [http://example.com 
mixed''''', even bold''''']l55strlralri19k9''\n'''''Now [http://example.com 
both'''''<nowiki/>''''']'''''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid [1]", 
"''[http://example.com text'']\n[http://example.com '''text]'''\n''Something 
[http://example.com in italic'']\n''Something [http://example.com mixed''''', 
even bold]'''\n'''''Now [http://example.com both''''']");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid [2]", 
"ypjgrwin4revcxr\n\n''[http://example.com text'']\n[http://example.com 
'''text]'''\n''Something [http://example.com in italic'']\n''Something 
[http://example.com mixed''''', even bold]'''\n'''''Now [http://example.com 
both''''']");
-add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[[[0,1]],0,3,1,4,1,3,[0,[0,[[3]]],3],4,3]]", "''[http://example.com 
text''<nowiki/>'']''\n'''<nowiki/>'''7qwqa9229ey7gb9''Something 
[http://example.com in italic'']''''Something [http://example.com 
mixed'''''<nowiki/>''''']''counvgra3151xlxr\n");
+add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[[[0,1]],0,3,1,4,1,3,[0,[0,[[3]]],3],4,3]]", "''[http://example.com 
text''<nowiki/>'']''\n'''<nowiki/>'''7qwqa9229ey7gb9''Something 
[http://example.com in italic'']Something [http://example.com 
mixed'''''<nowiki/>''''']''counvgra3151xlxr\n");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[2,0,4,4,2,1,0,3,0,4]]", "fxsbmxalr8f9wwmi''[http://example.com 
text'']\ng1cxmyk709vygb9kr3b7p92rmg0t3xrc6f6w79eiwfjemi\n''Something 
[http://example.com in italic''<nowiki/>'']''\n\nxqwjvsy7ltvgqfr\n");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[4,0,0,0,0,4,4,4,0,[3]]]", "0zdw3pkk57hnnrk9\n[http://example.com 
'''text]'''\nizanpf6huff20529vfp1wv58jce1xlxry331mymvx0cc8fr\n'''<nowiki/>'''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[1,3,2,2,0,1,4,[0,3,0],0,[4]]]", "''[http://example.com 
text'']''9ois0yoxiebfbt9[http://example.com 
'''text]saoppxketkic0udi'''\n''Something [http://example.com in 
italic'']''o0hyqnpaq38cwhfr''Something '<nowiki/>''\n'''hyq0ggqn4hzadcxr'''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[3,0,3,3,4,[3,[4,0]],0,[0,1,3],0,[[3,[0,2]]]]]", 
"\nsjft3sgyl0i9t3xr''[http://example.com 
spz6gumbba84zpvi''<nowiki/>'']''\n''Something [http://example.com mixed''''', 
even bold]''\n'''''[http://example.com 
bothi78rcmgoegtoi529'''''<nowiki/>''''']'''''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[[3],0,[2],0,4,1,0,4,3,3]]", "''<nowiki/>''\n[http://example.com 
rgkc3a28h38cwhfr'''text]'''fuoqrsdna64dkj4i''Something [http://example.com in 
italic'']''\nmsb55932ah7rdx6r\n");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[3,0,3,1,0,2,4,3,3,[[0,[0,1]]]]]", 
"\n'''<nowiki/>'''\nz032w7z1kdo0f6r''Something [http://example.com in 
italic'']o88q9qaoc6ljif6r'''''Now [http://example.com 
both'''''<nowiki/>''''']'''''");
-add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[2,2,[2],1,0,[3,0],3,[3,[0,[[4]]],0],0,3]]", 
"o9nab4h230tnvcxr''[http://example.com 
text'']u5sfhyznivd3g14i\n[http://example.com 
isdro1map7qa1yvi'''text]'''<nowiki/>'''\n''[http://example.com in 
italic'']''''[http://example.com mixed'''''o08ug21d18h3erk9''''']'''\n");
+add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[2,2,[2],1,0,[3,0],3,[3,[0,[[4]]],0],0,3]]", 
"o9nab4h230tnvcxr''[http://example.com 
text'']u5sfhyznivd3g14i\n[http://example.com 
isdro1map7qa1yvi'''text]'''<nowiki/>'''\n''[http://example.com in 
italic''][http://example.com mixed'''''o08ug21d18h3erk9''''']'''\n");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[[2],4,[[4]],0,4,[0,4],2,2,3,[4]]]", "''kndlu276kxz5b3xr[http://example.com 
text'']''66fz4jk56gtd42t9[http://example.com 
'''hbtqecdqt5oecdi''']'''sr9o6vidsk5u3di''Something 
81gi1py5yann4s4i''i1h0s35lu287iudi\nr1c3unvdylanhfr''Something 
[http://example.com mixed''''', even bold]''''''cwiw4wazt6kfn7b9'''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[2,0,3,0,3,2,0,[3,2,0],2,[3]]]", "rxaa2sxf4o8yqfr''[http://example.com 
text'']\n'''mtebxw1xl4x11yvi''Something [http://example.com in 
italic'']\n''vt2hxx23uta3v7vi[http://example.com mixed''''', even 
bold]'''fr3tlqbb4piizfr\n'''<nowiki/>'''");
 add("selser", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid 
[[4,2,0,0,4,[2,[4,1]],0,1,2,1]]", 
"uypp3nxnupst6gvi5lixlomwktb4vx6r\n[http://example.com 
'''text]'''1euo2nqbj6mvx6r''s5ucqw1bludz33diSomething [http://example.com 
iqi27jd7nxoxyldi''<nowiki/>'']''\n''Something [http://example.com mixed''''', 
even bold]'''3rrma1jx3c70hpvi\n'''''Now [http://example.com both''''']'''");
@@ -2598,8 +2598,6 @@
 add("selser", "Mixing markup for italics and bold [[0,0,[4,[4]]]]", 
"'<nowiki/>''bold''''''ofte4w4zkeh77gb9''xbrpnwqlrllerk9'''''");
 add("selser", "Mixing markup for italics and bold [[0,2,1]]", 
"'7hmry58pm8to6r''bold''''''bold''bolditalics'''''");
 add("selser", "Mixing markup for italics and bold [[0,0,4]]", 
"'<nowiki/>''bold'''vs6oe9iomie8kt9");
-add("selser", "Mixing markup for italics and bold [[2,0,[3,[2]]]]", 
"9rfbagd91q44e7b9'<nowiki/>''bold'''<nowiki/>'''''dwszs7lpqhvvx6rbolditalics'''''");
-add("selser", "Mixing markup for italics and bold [[2,2,[3,0]]]", 
"3gqsk0fqzf6crf6r'asugzbokcr3323xr''bold'''<nowiki/>'''''bolditalics'''''");
 add("selser", "Section extraction, <pre> around bogus header (bug 10309) 
[[2],2,[3],3,0,0,2]", "==0mqyujy54j1qbyb9 Section One 
==\nyzn329uexnp3z0k9\n<pre></pre>\n\n== Section Two 
==\nppzttjn4r8gp66r\n\nstuff");
 add("selser", "Handling of &#x0A; in URLs [[[2]]]", "*a1yhylbtfjgrdx6r\n* 
irc://&#x0A;a");
 add("selser", "Handling of &#x0A; in URLs [[[[2]]]]", "** 0r68g30euvbfn7b9\n* 
irc://&#x0A;a");
@@ -2818,11 +2816,11 @@
 add("selser", "Entities in ref name [1]", "<ref name=\"test &amp; 
me\">hi</ref>");
 add("selser", "Headings: 5. Empty headings [[2],3,2,0,4,4,0,2,1,3,0]", 
"=hnjo2713bjvjwcdi<nowiki/>=\nx2d05yq3dapaxlxr\n==<nowiki/>==\n\nkaovt9si227ta9k9\n\nb2688fvzpaocrf6r\n====<nowiki/>====\nljshl952j0emte29\n\n=====<nowiki/>=====\n\n======<nowiki/>======");
 add("selser", "Headings: 6a. Heading chars in SOL context (with trailing 
spaces) [4,0,1,0,4,4,[2],3]", "o4fu7yz6zedvlsor\n\n<nowiki>=a=</nowiki> 
\n\nfzi337zwgfmbzkt9\n\nrziif3qr3rspp66r\n\nzm9kz709iqpsnhfr<nowiki>=a=</nowiki>
 \t");
-add("selser", "1. Quotes inside <b> and <i> 
[[2,3,[1],4,0,0,[3],0,2,2,0,4,0,0,4,1,0,0,0,0,3,1,4,3,2,4,0,0,0,0,0,0,0,2,1,0,2,[2],0,3,0,0,4,0,0,1]]",
 
"b9ve2r72aq44e7b9''<nowiki/>'foo'<nowiki/>''''<nowiki>''foo''</nowiki>''jduad2jvmauac3di''<nowiki>'''foo'''</nowiki>''\n''<nowiki/>''<nowiki/>hb7ucb9xukofajor's\nimf9p1zrvbbdfgvi'''<nowiki/>'foo'<nowiki/>'''\nd92wpym0cizwu3di\n'''<nowiki>'''foo'''</nowiki>'''4mia6l6nhzolxr'''foo'<nowiki/>''bar'<nowiki/>''baz'''\n'''foo'''<nowiki/>'s\n'''foo''6wag5p5b648l4n29rs74ede4dxiuow29<nowiki/>s455j5uyzl0daemi<nowiki/>''foo''<nowiki/>'\n'<nowiki/>'''foo'''\nc9hosabzbqhbyb9'''foo'''<nowiki/>'\n'1yl4yeqhhtr19k9<nowiki/>'''9k3pgwyb0uvaq0k9foo'''<nowiki/>''fools'<span>
 errand</span>''\n3mwa3kwctc8r529\na|!*#-:;+-~[]{}b'<nowiki/>''x''");
-add("selser", "1. Quotes inside <b> and <i> 
[[[2,0,3],0,[[3]],4,4,2,[3],3,0,[0,3,1],3,[2],3,[[3]],3,[0,1,2,2],3,3,0,4,4,4,0,[4],0,0,0,0,4,0,2,1,0,3,0,2,0,2,4,2,[3,1],4,1,2,0,4]]",
 
"''rou4oqqj45pwg66r<nowiki/>'foo'''\n''<nowiki></nowiki>''6o82gwbgw9xxn7b9n4fc723rbxtg9zfr2po5rm4z5rhehfr\n''<nowiki/>''<nowiki/>'s\n'''<nowiki/><nowiki/>''''''8vtzkg2u8wnopqfr<nowiki>''foo''</nowiki>''''''<nowiki></nowiki>''''''foo'<nowiki/>ipon7rm9iy0hpvi''bar'<nowiki/>''jsehige2uxov42t9baz'''<nowiki/>dinfburnti0ms4ibximthck3qgaxlxrrbhllev1hoo2mx6r\n''tvi87wnpldblc8fr''<nowiki/>'\n'<nowiki/>''foo''mans72mc33csdcxr'\n'dnvvbq5ayqc6usor<nowiki/>'''foo'''\n<nowiki/>9293k6dvvmoq1tt9'\n'<nowiki/>zs5z7v3q0qaug14i'''foo'''deu4ioyka97fogvii2578yu6svt5ipb9'\n''<span
 data-foobar=\"ntagvrajvtoqolxr\"> 
errand</span>''icug3imme9mjkyb9''<span>fool</span>'s 
errand''wglst0tvcv2w3ik9\na|!*#-:;+-~[]{}b'<nowiki/>i9b91kkaoiggb9");
+add("selser", "1. Quotes inside <b> and <i> 
[[2,3,[1],4,0,0,[3],0,2,2,0,4,0,0,4,1,0,0,0,0,3,1,4,3,2,4,0,0,0,0,0,0,0,2,1,0,2,[2],0,3,0,0,4,0,0,1]]",
 
"b9ve2r72aq44e7b9''<nowiki/>'foo'<nowiki/><nowiki>''foo''</nowiki>''jduad2jvmauac3di''<nowiki>'''foo'''</nowiki>''\n''<nowiki/>''<nowiki/>hb7ucb9xukofajor's\nimf9p1zrvbbdfgvi'''<nowiki/>'foo'<nowiki/>'''\nd92wpym0cizwu3di\n'''<nowiki>'''foo'''</nowiki>'''4mia6l6nhzolxr'''foo'<nowiki/>''bar'<nowiki/>''baz'''\n'''foo'''<nowiki/>'s\n'''foo''6wag5p5b648l4n29rs74ede4dxiuow29<nowiki/>s455j5uyzl0daemi<nowiki/>''foo''<nowiki/>'\n'<nowiki/>'''foo'''\nc9hosabzbqhbyb9'''foo'''<nowiki/>'\n'1yl4yeqhhtr19k9<nowiki/>'''9k3pgwyb0uvaq0k9foo'''<nowiki/>''fools'<span>
 errand</span>''\n3mwa3kwctc8r529\na|!*#-:;+-~[]{}b'<nowiki/>''x''");
+add("selser", "1. Quotes inside <b> and <i> 
[[[2,0,3],0,[[3]],4,4,2,[3],3,0,[0,3,1],3,[2],3,[[3]],3,[0,1,2,2],3,3,0,4,4,4,0,[4],0,0,0,0,4,0,2,1,0,3,0,2,0,2,4,2,[3,1],4,1,2,0,4]]",
 
"''rou4oqqj45pwg66r<nowiki/>'foo'''\n''<nowiki></nowiki>''6o82gwbgw9xxn7b9n4fc723rbxtg9zfr2po5rm4z5rhehfr\n''<nowiki/>''<nowiki/>'s\n'''<nowiki/><nowiki/>8vtzkg2u8wnopqfr<nowiki>''foo''</nowiki><nowiki></nowiki>foo'<nowiki/>ipon7rm9iy0hpvi''bar'<nowiki/>''jsehige2uxov42t9baz'''<nowiki/>dinfburnti0ms4ibximthck3qgaxlxrrbhllev1hoo2mx6r\n''tvi87wnpldblc8fr''<nowiki/>'\n'<nowiki/>''foo''mans72mc33csdcxr'\n'dnvvbq5ayqc6usor<nowiki/>'''foo'''\n<nowiki/>9293k6dvvmoq1tt9'\n'<nowiki/>zs5z7v3q0qaug14i'''foo'''deu4ioyka97fogvii2578yu6svt5ipb9'\n''<span
 data-foobar=\"ntagvrajvtoqolxr\"> 
errand</span>''icug3imme9mjkyb9''<span>fool</span>'s 
errand''wglst0tvcv2w3ik9\na|!*#-:;+-~[]{}b'<nowiki/>i9b91kkaoiggb9");
 add("selser", "1. Quotes inside <b> and <i> 
[[3,0,[[4]],4,0,0,3,0,0,[2,0,3],0,2,0,[4],0,[0,0,1,2],4,0,0,2,0,1,2,0,0,3,0,[4],0,0,3,[2],3,4,3,4,0,[4],1,3,1,3,3,4,0,2]]",
 
"\n''<nowiki>9du4tukpxr5p14i</nowiki>''a3oxn4o6xuoez5mi''<nowiki>'''foo'''</nowiki>''\n<nowiki/>'s\n'''zb6b8p4dsrgj5rk9<nowiki/>'foo''''\nn5g2nainzi9evcxr'''<nowiki>''foo''</nowiki>'''\n'''fjf9en2rxyw1xlxr'''\n'''foo'<nowiki/>''bar'<nowiki/>''3t058jjruq4wvcxrbaz'''w3assj8fjchm2t9'''foo'''<nowiki/>406bo4oovs3sdcxr's\n'<nowiki/>''foo''l8ur9en9wqe8w7b9\n''foo''<nowiki/><nowiki/>''upyarw5tif1rlik9''<nowiki/>'\n''''xf76q2gb9hmbcsorfoo'''zeaqonfmvysexw295dvwath003dqjjor<nowiki/>'''q5arckx2cdk4vx6r'''<nowiki/>''fools'<span>
 errand</span>''4prh3f1lk2j7cik9<nowiki/>wyd9n604zjafko6r''x''");
 add("selser", "1. Quotes inside <b> and <i> 
[[4,2,0,0,[2],0,1,0,4,[0,0,3],2,0,2,[[3]],0,[0,1,[3,0],0],0,4,4,0,1,2,0,[3],0,0,1,0,4,4,3,0,4,[2],0,4,4,3,0,4,4,4,[[4],3],0,4,0]]",
 
"acy673rinovfgviplr0nwpq14079zfr\n''<nowiki>''foo''</nowiki>''\n''x9s8roz7iecul3di<nowiki>'''foo'''</nowiki>''\n''foo''<nowiki/>ncaawjaqbiall3di'''<nowiki/>'foo''''7mofib93ncj714i\n'''<nowiki>''foo''</nowiki>'''a0h559r0kaf9a4i\n'''<nowiki></nowiki>'''\n'''foo'<nowiki/>''<nowiki/>''baz'''\n265zz6wn68zg2e29dcfy6wfyuuonipb9's\n'<nowiki/>n0so9m9gubthjjor''foo''\n''<nowiki/>''<nowiki/>'\n'<nowiki/>''foo''eu8bi30kt40lik9enwlc3t7myt4kj4i'''foo'''x6ngpya7ros10pb9'''pil88s26p0mp9zfrfoo'''<nowiki/>guy0jrmki6v18aor79cji1kde00jxlxr<nowiki/>ce9yefc1ixp3nmiudh3zchhff94fgvi41nysayj1hsemi''<span>6nuqrvo7e9qtcsor</span>''\na|!*#-:;+-~[]{}b'j80zfyt47psyvi''x''");
-add("selser", "1. Quotes inside <b> and <i> 
[[4,0,4,0,0,2,1,4,2,1,3,[3],3,[[2]],3,3,3,0,4,0,3,4,0,[3],0,0,4,[2],3,0,0,[4],0,3,0,0,1,[3],0,0,[0,4],2,[0,4],4,0,3]]",
 
"bcv9t18xvahh0k9\n7j4ebaxa7o9ftj4i\n''<nowiki>'''foo'''</nowiki>''mry7gwh281tt9\n''foo''6z57b2fhe9yn9udi7d4vr8m4oxcivn29's\n'''<nowiki/>'foo'<nowiki/>''''''<nowiki/>''''''<nowiki>x4ljrkxn00jxlxr'''foo'''</nowiki>''''''foo'''eg408kyvbtck57b9's\n'72iu8q6iuihehfr\n''<nowiki/>''<nowiki/>'\n'hs9psbz3fcdw8kt9''hpob0uhvs0885mifoo'''\n'<nowiki/>'''1ikpa9oovowghkt9'''\n<nowiki/>'\n'<nowiki/>'''<nowiki/>'''<nowiki/>'\n''fools'2cecdk1nov927qfr''qgboi2cpqmovquxr\n''<span>fool</span>kx25x3hw1m7vi''8qfgpvlpg7v9ggb9<nowiki/>\n");
+add("selser", "1. Quotes inside <b> and <i> 
[[4,0,4,0,0,2,1,4,2,1,3,[3],3,[[2]],3,3,3,0,4,0,3,4,0,[3],0,0,4,[2],3,0,0,[4],0,3,0,0,1,[3],0,0,[0,4],2,[0,4],4,0,3]]",
 
"bcv9t18xvahh0k9\n7j4ebaxa7o9ftj4i\n''<nowiki>'''foo'''</nowiki>''mry7gwh281tt9\n''foo''6z57b2fhe9yn9udi7d4vr8m4oxcivn29's\n'''<nowiki/>'foo'<nowiki/><nowiki>x4ljrkxn00jxlxr'''foo'''</nowiki>foo'''eg408kyvbtck57b9's\n'72iu8q6iuihehfr\n''<nowiki/>''<nowiki/>'\n'hs9psbz3fcdw8kt9''hpob0uhvs0885mifoo'''\n'<nowiki/>'''1ikpa9oovowghkt9'''\n<nowiki/>'\n'<nowiki/>'''<nowiki/>'''<nowiki/>'\n''fools'2cecdk1nov927qfr''qgboi2cpqmovquxr\n''<span>fool</span>kx25x3hw1m7vi''8qfgpvlpg7v9ggb9<nowiki/>\n");
 add("selser", "HTML tag with broken attribute value quoting [1]", "<span 
title=\"Hello world>Foo</span>");
 add("selser", "HTML tag with broken attribute value quoting [2]", 
"zlkpme7jgj76tj4i\n\n<span title=\"Hello world>Foo</span>");
 add("selser", "HTML tag with broken attribute value quoting [[2]]", 
"19ydfukj49zoajor<span title=\"Hello world>Foo</span>");
diff --git a/tests/parserTests.txt b/tests/parserTests.txt
index 5941121..18fdb70 100644
--- a/tests/parserTests.txt
+++ b/tests/parserTests.txt
@@ -22369,6 +22369,36 @@
 <p><i>A</i><b><i>B</i></b></p>
 !! end
 
+!! test
+5a. Merge adjacent quote nodes if they've been edited
+!! options
+parsoid={
+  "modes": ["wt2wt"],
+  "changes": [
+    ["p", "contents", "remove", ":contains('b')"]
+  ]
+}
+!! wikitext
+''a''b''c''
+!! wikitext/edited
+''ac''
+!! end
+
+!! test
+5b. Merge adjacent quote nodes if they've been edited
+!! options
+parsoid={
+  "modes": ["wt2wt"],
+  "changes": [
+    ["#x", "remove"]
+  ]
+}
+!! wikitext
+''a''<span id="x">b</span>''c''
+!! wikitext/edited
+''ac''
+!! end
+
 #------------------------------------
 # End of I/B quote minimization tests
 #------------------------------------

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Id85af3c67ea6c77e5e98c0bdbdcd18d9d483acb7
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