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

Change subject: T88495: Part 1 of 2: Handle more templated <td>-attr scenarios
......................................................................


T88495: Part 1 of 2: Handle more templated <td>-attr scenarios

* Removed some artificial limitations in the handling of
  templated <td> attributes and simplified / documented the logic.

* Re-orged some if-then-else nests to make the code more readable.

* Testing:
  * The example in the bug report now parses and RTs correctly.
  * http://localhost:8000/_rt/enwiki/List_of_largest_container_ships
    now parses and renders properly.
  * Added a new test that captures the scenario seen in that page.

* The more complex scenario (which actually has a failing test in
  parserTests.txt) of multiple cells on the same line separated by
  || is not implemented yet. That will be part 2.

Change-Id: Ib4ad0a63b97463fbc3944d674945c12ead23f944
---
M lib/dom.t.TableFixups.js
M lib/mediawiki.DOMUtils.js
M tests/parserTests-blacklist.js
M tests/parserTests.txt
4 files changed, 226 insertions(+), 119 deletions(-)

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



diff --git a/lib/dom.t.TableFixups.js b/lib/dom.t.TableFixups.js
index 326f939..38437da 100644
--- a/lib/dom.t.TableFixups.js
+++ b/lib/dom.t.TableFixups.js
@@ -1,9 +1,9 @@
 "use strict";
 
 var DU = require('./mediawiki.DOMUtils.js').DOMUtils,
-    PegTokenizer = require('./mediawiki.tokenizer.peg.js').PegTokenizer,
+       PegTokenizer = require('./mediawiki.tokenizer.peg.js').PegTokenizer,
        Sanitizer = require('./ext.core.Sanitizer.js').Sanitizer,
-    defines = require('./mediawiki.parser.defines.js');
+       defines = require('./mediawiki.parser.defines.js');
 
 
 // define some constructor shortcuts
@@ -113,9 +113,10 @@
 TableFixups.prototype.collectAttributishContent = function (node) {
        var buf = [],
                nodes = [],
-               transclusionNode,
-               // Build the result.
-               buildRes = function () {
+               transclusionNode = DU.hasTypeOf(node, 'mw:Transclusion') ? node 
: null;
+
+       // Build the result.
+       var buildRes = function () {
                        return {
                                txt: buf.join(''),
                                nodes: nodes,
@@ -123,37 +124,64 @@
                        };
                },
                child = node.firstChild;
+
+       /*
+        * In this loop below, where we are trying to collect text content,
+        * it is safe to use child.textContent since textContent skips over
+        * comments. See this transcript of a node session:
+        *
+        *   > d.body.childNodes[0].outerHTML
+        *   '<span><!--foo-->bar</span>'
+        *   > d.body.childNodes[0].textContent
+        *   'bar'
+        *
+        * PHP parser strips comments during parsing, i.e. they don't impact
+        * how other wikitext constructs are parsed. So, in this code below,
+        * we have to skip over comments.
+        */
        while (child) {
-               if (!transclusionNode &&
-                       (DU.isComment(child) ||
-                       DU.isText(child) && !/[|]/.test(child.nodeValue)))
-               {
+               if (DU.isComment(child)) { /* jshint noempty:false */
+                       // <!--foo--> are not comments in CSS and PHP parser 
strips them
+               } else if (DU.isText(child)) {
                        buf.push(child.nodeValue);
+               } else if (child.nodeName !== 'SPAN') {
+                       // The idea here is that style attributes can only
+                       // be text/comment nodes, and nowiki-spans at best.
+                       // So, if we hit anything else, there is nothing more
+                       // to do here!
+                       return buildRes();
+               } else if (transclusionNode && DU.hasTypeOf(child, 
'mw:Nowiki')) {
+                       // Nowiki span added in the template to protect 
otherwise
+                       // meaningful wikitext chars used in attributes.
+                       buf.push(child.textContent);
+               } else if (DU.hasTypeOf(child, 'mw:Transclusion') &&
+                               DU.allChildrenAreTextOrComments(child))
+               {
+                       // We encountered a transclusion wrapper
+                       console.assert(!transclusionNode);
+                       buf.push(child.textContent);
+                       transclusionNode = child;
                } else if (transclusionNode &&
-                               child.nodeName === 'SPAN' &&
-                               DU.hasTypeOf(child, 'mw:Nowiki'))
+                               child.getAttribute('typeof') === null &&
+                               child.getAttribute('about') === 
transclusionNode.getAttribute('about') &&
+                               DU.allChildrenAreTextOrComments(child))
                {
+                       // Continue accumulating only if we hit grouped 
template content
                        buf.push(child.textContent);
-               } else if (child.nodeName === 'SPAN' &&
-                               child.childNodes.length === 1 &&
-                               (child.getAttribute('typeof') === null &&
-                                transclusionNode &&
-                                child.getAttribute('about') === 
transclusionNode.getAttribute('about') ||
-                                DU.hasTypeOf(child, 'mw:Transclusion')))
-               {
-                       buf.push(child.textContent);
-                       if (!transclusionNode && DU.hasTypeOf(child, 
'mw:Transclusion')) {
-                               transclusionNode = child;
-                       }
                } else {
                        return buildRes();
                }
+
                nodes.push(child);
-               if (/[|]/.test(buf.last())) {
+
+               // Are we done accumulating?
+               if (/(?:^|[^|])\|(?:[^|]|$)/.test(buf.last())) {
                        return buildRes();
                }
+
                child = child.nextSibling;
        }
+
        return buildRes();
 };
 
@@ -183,114 +211,146 @@
  * - There is only a single transclusion in the table cell content. This
  *   limitation can be lifted with more advanced data-mw construction.
  */
+
+// SSS FIXME: It is silly to examine every fricking <td> for possible fixup.
+// We only need to examine <td>s that either have mw:Transclusion typeof or
+// have a child (not descendent) with a mw:Transclusion typeof.
+//
+// This info is not readily available right now, but perhaps could be provided
+// based on annotating nodes via a tmp attribute during tpl wrapping.
+//
+// Or, perhaps the tokenizer can mark <td>s that have a transclusion node
+// on the same wikitext line.
+//
+// TO BE DONE.
+
 TableFixups.prototype.reparseTemplatedAttributes = function (env, node) {
        var dp = DU.getDataParsoid( node );
 
-       // Cheap checks first
-       if (!DU.isLiteralHTMLNode(node) &&
-               // We use the dsr start tag width as a proxy for 'has no 
attributes
-               // yet'. We accept '|' and '||' (row-based syntax), so at most 
two
-               // chars.
-               dp.dsr && dp.dsr[2] !== null && dp.dsr[2] <= 2)
+       // Cheap checks first:
+       // * Don't bother with literal HTML nodes
+       // * Don't bother with <td>s that already have attrs.
+       //   We use the dsr start tag width
+       //   as a proxy for 'has no attributes yet'.
+       //   We accept '|' and '||' (row-based syntax),
+       //   so at most two chars.
+       if (DU.isLiteralHTMLNode(node) ||
+               !(dp.dsr && dp.dsr[2] !== null && dp.dsr[2] <= 2))
        {
-               // Now actually look at the content
-               var attributishContent = this.collectAttributishContent(node),
-                       transclusionNode = attributishContent.transclusionNode;
+               return true;
+       }
 
-                       // First of all make sure we have a transclusion that 
produces leading
-                       // text content
-               if ( transclusionNode &&
-                               // Check for the pipe character in the 
attributish text.
-                               // Also make sure that we only trigger for 
simple
-                               // attribute-only cases for now.  Don't handle 
|{{multicells}}
-                               // where multicells expands to something like 
style="foo"| Bar
-                               // || Baz
-                               /^[^|]+[|][^|]*$/.test(attributishContent.txt) 
&&
-                               // And only handle a single nested transclusion 
for now
-                               // TODO: Handle data-mw construction for 
multi-transclusion content as
-                               // well, then relax this restriction.
-                               this.hasOnlyOneTransclusionChild(node)
-                  )
-               {
-                       //console.log(node.data.parsoid.dsr, 
JSON.stringify(attributishText));
+       // Collect attribute content and examine it
+       var attributishContent = this.collectAttributishContent(node),
+               transclusionNode = attributishContent.transclusionNode;
 
-                       // Try to re-parse the attributish text content
-                       var attributishPrefix = 
attributishContent.txt.match(/^[^|]+\|/)[0],
-                               // re-parse the attributish prefix
-                               attributeTokens = this.tokenizer
-                                       
.tokenizeTableCellAttributes(attributishPrefix);
-                       if (attributeTokens) {
-                               // Found attributes.
+       // First of all make sure we have a transclusion
+       // that produces leading text content
+       if (!transclusionNode
+               // Check for the pipe character in the attributish text.
+               || 
!/^[^|]+\|[^|]*([^|]\|\|[^|]*)*$/.test(attributishContent.txt)
+               // And only handle a single nested transclusion for now.
+               // TODO: Handle data-mw construction for multi-transclusion 
content
+               // as well, then relax this restriction.
+               || !this.hasOnlyOneTransclusionChild(node)
+          )
+       {
+               return true;
+       }
 
-                               // Sanitize them
-                               var sanitizedToken = this.sanitizer
-                                       .sanitizeTokens(
-                                                       [new 
TagTk(node.nodeName.toLowerCase(),
-                                                               
attributeTokens[0])])[0];
-                               //console.log(JSON.stringify(sanitizedToken));
+       // Try to re-parse the attributish text content
+       var attributishPrefix = attributishContent.txt.match(/^[^|]+\|/)[0];
+       // re-parse the attributish prefix
+       var attributeTokens = this.tokenizer
+                       .tokenizeTableCellAttributes(attributishPrefix);
 
-                               // and transfer the sanitized attributes to the 
td node
-                               sanitizedToken.attribs.forEach(function(kv) {
-                                       node.setAttribute(kv.k, kv.v);
-                               });
+       // No attributes => nothing more to do!
+       if (!attributeTokens) {
+               return true;
+       }
 
-                               // Update the template encapsulation including 
data-mw
+       // Found attributes.
+       // Sanitize them
+       var sanitizedToken = this.sanitizer
+               .sanitizeTokens(
+                       [ new TagTk(node.nodeName.toLowerCase(), 
attributeTokens[0]) ]
+               )[0];
 
-                               // Lift up the about group to our td node.
-                               node.setAttribute('typeof', 
transclusionNode.getAttribute('typeof'));
-                               node.setAttribute('about', 
transclusionNode.getAttribute('about'));
-                               var dataMW = DU.getDataMw(transclusionNode),
-                                       parts = dataMW.parts,
-                                       tnDP = DU.getDataParsoid( 
transclusionNode );
+       // and transfer the sanitized attributes to the td node
+       sanitizedToken.attribs.forEach(function(kv) {
+               node.setAttribute(kv.k, kv.v);
+       });
 
-                               // Get the td and content source up to the 
transclusion start
-                               if (dp.dsr[0] < tnDP.dsr[0]) {
-                                       parts.unshift(env.page.src.substring( 
dp.dsr[0], tnDP.dsr[0] ));
-                               }
+       // Update the template encapsulation including data-mw
 
-                               // Add wikitext for the table cell content 
following the
-                               // transclusion. This is safe as we are 
currently only
-                               // handling a single transclusion in the 
content, which is
-                               // guaranteed to have a dsr that covers the 
transclusion
-                               // itself.
-                               if (tnDP.dsr[1] < dp.dsr[1]) {
-                                       parts.push(env.page.src.substring( 
tnDP.dsr[1], dp.dsr[1] ));
-                               }
+       // If the transclusion node was embedded within the td node,
+       // lift up the about group to the td node.
+       if (node !== transclusionNode) {
+               node.setAttribute('typeof', 
transclusionNode.getAttribute('typeof'));
+               node.setAttribute('about', 
transclusionNode.getAttribute('about'));
+               var dataMW = DU.getDataMw(transclusionNode),
+                       parts = dataMW.parts,
+                       tnDP = DU.getDataParsoid( transclusionNode );
 
-                               // Save the new data-mw on the td node
-                               DU.setDataMw(node, { parts: parts });
-                               dp.pi = tnDP.pi;
+               // Get the td and content source up to the transclusion start
+               if (dp.dsr[0] < tnDP.dsr[0]) {
+                       parts.unshift(env.page.src.substring( dp.dsr[0], 
tnDP.dsr[0] ));
+               }
 
-                               // Remove the span wrapper
-                               var attributishNodes = attributishContent.nodes;
-                               while(attributishNodes.length) {
-                                       var n = attributishNodes.shift();
-                                       if (/[|]/.test(n.textContent)) {
-                                               // Remove the consumed prefix 
from the text node
-                                               var nValue;
-                                               if (n.nodeName === '#text') {
-                                                       nValue = n.nodeValue;
-                                               } else {
-                                                       nValue = n.textContent;
-                                               }
-                                               // and convert it into a simple 
text node
-                                               
node.replaceChild(node.ownerDocument.createTextNode(nValue.replace(/^[^|]*[|]/, 
'')), n);
-                                       } else {
-                                               // content was consumed by 
attributes, so just drop it
-                                               // from the cell
-                                               node.removeChild(n);
-                                       }
-                               }
-                               // Remove template encapsulation from other 
children. The
-                               // table cell wraps everything now.
-                               node.childNodes.forEach(function(childNode) {
-                                       if (childNode.getAttribute && 
childNode.getAttribute('about')) {
-                                               
childNode.removeAttribute('about');
-                                       }
-                               });
+               // Add wikitext for the table cell content following the
+               // transclusion. This is safe as we are currently only
+               // handling a single transclusion in the content, which is
+               // guaranteed to have a dsr that covers the transclusion
+               // itself.
+               if (tnDP.dsr[1] < dp.dsr[1]) {
+                       parts.push(env.page.src.substring( tnDP.dsr[1], 
dp.dsr[1] ));
+               }
+
+               // Save the new data-mw on the td node
+               DU.setDataMw(node, { parts: parts });
+               dp.pi = tnDP.pi;
+       }
+
+       // Remove the span wrapper
+       var attributishNodes = attributishContent.nodes;
+       while(attributishNodes.length) {
+               var n = attributishNodes.shift();
+               if (/[|]/.test(n.textContent)) {
+                       // Remove the consumed prefix from the text node
+                       var nValue;
+                       if (n.nodeName === '#text') {
+                               nValue = n.nodeValue;
+                       } else {
+                               nValue = n.textContent;
+                       }
+                       // and convert it into a simple text node
+                       
node.replaceChild(node.ownerDocument.createTextNode(nValue.replace(/^[^|]*[|]/, 
'')), n);
+               } else {
+                       // content was consumed by attributes, so just drop it 
from the cell
+                       node.removeChild(n);
+               }
+       }
+
+       if (node !== transclusionNode) {
+               // Remove template encapsulation from other children.
+               // The td node wraps everything now.
+               var child = node.firstChild;
+               while (child) {
+                       // Remove the span wrapper -- this simplifies the 
problem of
+                       // analyzing the <td> for additional fixups (|| Boo || 
Baz) by
+                       // potentially invoking 'reparseTemplatedAttributes' 
recursively
+                       // with some modifications.
+                       if (child.nodeName === 'SPAN' && 
child.getAttribute('about')) {
+                               var next = child.firstChild || 
child.nextSibling;
+                               DU.migrateChildren(child, node, child);
+                               DU.deleteNode(child);
+                               child = next;
+                       } else {
+                               child = child.nextSibling;
                        }
                }
        }
+
        return true;
 };
 
diff --git a/lib/mediawiki.DOMUtils.js b/lib/mediawiki.DOMUtils.js
index 54a2d6c..67f5475 100644
--- a/lib/mediawiki.DOMUtils.js
+++ b/lib/mediawiki.DOMUtils.js
@@ -1190,6 +1190,23 @@
        },
 
        /**
+        * Are all children of this node text or comment nodes?
+        */
+       allChildrenAreTextOrComments: function (node) {
+               var child = node.firstChild;
+               while (child) {
+                       if (!this.isMarkerMeta(child, "mw:DiffMarker")
+                               && !this.isText(child)
+                               && !this.isComment(child))
+                       {
+                               return false;
+                       }
+                       child = child.nextSibling;
+               }
+               return true;
+       },
+
+       /**
         * Are all children of this node text nodes?
         */
        allChildrenAreText: function (node) {
diff --git a/tests/parserTests-blacklist.js b/tests/parserTests-blacklist.js
index dde5fba..fb057a3 100644
--- a/tests/parserTests-blacklist.js
+++ b/tests/parserTests-blacklist.js
@@ -54,7 +54,7 @@
 add("wt2html", "Definition Lists: colons and tables 1", "<dl 
data-parsoid='{\"dsr\":[0,21,0,0]}'><dd 
data-parsoid='{\"dsr\":[0,10,1,0]}'><table 
data-parsoid='{\"dsr\":[1,10,2,2]}'>\n<tbody 
data-parsoid='{\"dsr\":[4,8,0,0]}'><tr 
data-parsoid='{\"autoInsertedEnd\":true,\"autoInsertedStart\":true,\"dsr\":[4,7,0,0]}'><td
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[4,7,1,0]}'> 
x</td></tr>\n</tbody></table></dd>\n<dd 
data-parsoid='{\"dsr\":[11,21,1,0]}'><table 
data-parsoid='{\"dsr\":[12,21,2,2]}'>\n<tbody 
data-parsoid='{\"dsr\":[15,19,0,0]}'><tr 
data-parsoid='{\"autoInsertedEnd\":true,\"autoInsertedStart\":true,\"dsr\":[15,18,0,0]}'><td
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[15,18,1,0]}'> 
y</td></tr>\n</tbody></table></dd></dl>");
 add("wt2html", "Bug 2702: Mismatched <i>, <b> and <a> tags are invalid", "<p 
data-parsoid='{\"dsr\":[0,204,0,0]}'><i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[0,29,2,0]}'><a 
rel=\"mw:ExtLink\" href=\"http://example.com\"; 
data-parsoid='{\"targetOff\":22,\"contentOffsets\":[22,28],\"dsr\":[2,29,20,1]}'>text<i
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[26,28,2,0]}'></i></a></i>\n<a 
rel=\"mw:ExtLink\" href=\"http://example.com\"; 
data-parsoid='{\"targetOff\":50,\"contentOffsets\":[50,57],\"dsr\":[30,58,20,1]}'><b
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[50,57,3,0]}'>text</b></a><b 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[58,61,3,0]}'></b>\n<i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[62,106,2,0]}'>Something <a 
rel=\"mw:ExtLink\" href=\"http://example.com\"; 
data-parsoid='{\"targetOff\":94,\"contentOffsets\":[94,105],\"dsr\":[74,106,20,1]}'>in
 italic<i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[103,105,2,0]}'></i></a></i>\n<i
 data-parsoid='{\"dsr\":[107,164,2,2]}'>Something <a rel=\"mw:ExtLink\" 
href=\"http://example.com\"; 
data-parsoid='{\"targetOff\":139,\"contentOffsets\":[139,160],\"dsr\":[119,161,20,1]}'>mixed<b
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[144,160,3,0]}'><i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[147,160,2,0]}'>, even 
bold</i></b></a>'</i>\n<b 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[165,204,3,0]}'><i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[168,204,2,0]}'>Now <a 
rel=\"mw:ExtLink\" href=\"http://example.com\"; 
data-parsoid='{\"targetOff\":194,\"contentOffsets\":[194,203],\"dsr\":[174,204,20,1]}'>both<b
 data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[198,203,3,0]}'><i 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[201,203,2,0]}'></i></b></a></i></b></p>");
 add("wt2html", "External link containing double-single-quotes in text embedded 
in italics (bug 4598 sanity check)", "<p data-parsoid='{\"dsr\":[0,60,0,0]}'><i 
data-parsoid='{\"dsr\":[0,60,2,2]}'>Some <a rel=\"mw:ExtLink\" 
href=\"http://example.com/\"; 
data-parsoid='{\"targetOff\":28,\"contentOffsets\":[28,56],\"dsr\":[7,57,21,1]}'>pretty
 <i data-parsoid='{\"dsr\":[35,46,2,2]}'>italics</i> and stuff</a>!</i></p>");
-add("wt2html", "Template-generated table cell attributes and cell content 
(2)", "<table data-parsoid='{\"dsr\":[0,35,2,2]}'>\n<tbody 
data-parsoid='{\"dsr\":[3,33,0,0]}'><tr 
data-parsoid='{\"autoInsertedEnd\":true,\"autoInsertedStart\":true,\"dsr\":[3,32,0,0]}'><td
 align=\"center\" style=\"color: red\" typeof=\"mw:Transclusion\" 
about=\"#mwt1\" 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[3,32,1,0],\"pi\":[[]]}' 
data-mw='{\"parts\":[\"|align=center 
\",{\"template\":{\"target\":{\"wt\":\"table_cells\",\"href\":\"./Template:Table_cells\"},\"params\":{},\"i\":0}}]}'>
 Foo<span> || Bar || Baz</span></td></tr>\n</tbody></table>");
+add("wt2html", "3. Template-generated table cell attributes and cell content", 
"<table data-parsoid='{\"dsr\":[0,35,2,2]}'>\n<tbody 
data-parsoid='{\"dsr\":[3,33,0,0]}'><tr 
data-parsoid='{\"autoInsertedEnd\":true,\"autoInsertedStart\":true,\"dsr\":[3,32,0,0]}'><td
 align=\"center\" style=\"color: red\" typeof=\"mw:Transclusion\" 
about=\"#mwt1\" 
data-parsoid='{\"autoInsertedEnd\":true,\"dsr\":[3,32,1,0],\"pi\":[[]]}' 
data-mw='{\"parts\":[\"|align=center 
\",{\"template\":{\"target\":{\"wt\":\"table_cells\",\"href\":\"./Template:Table_cells\"},\"params\":{},\"i\":0}}]}'>
 Foo || Bar || Baz</td></tr>\n</tbody></table>");
 add("wt2html", "Self-link to numeric title", "<p 
data-parsoid='{\"dsr\":[0,5,0,0]}'><a rel=\"mw:WikiLink\" href=\"./0\" 
title=\"0\" 
data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./0\"},\"sa\":{\"href\":\"0\"},\"dsr\":[0,5,2,2]}'>0</a></p>");
 add("wt2html", "<nowiki> inside a link", "<p 
data-parsoid='{\"dsr\":[0,96,0,0]}'><a rel=\"mw:WikiLink\" href=\"./Main_Page\" 
title=\"Main Page\" 
data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main_Page\"},\"sa\":{\"href\":\"Main&lt;nowiki>
 Page&lt;/nowiki>\"},\"dsr\":[0,30,2,2]}'>Main Page</a> <a rel=\"mw:WikiLink\" 
href=\"./Main_Page\" title=\"Main Page\" 
data-parsoid='{\"stx\":\"piped\",\"a\":{\"href\":\"./Main_Page\"},\"sa\":{\"href\":\"Main
 Page\"},\"dsr\":[31,96,12,2]}'>the main page <span typeof=\"mw:Nowiki\" 
data-parsoid='{\"dsr\":[57,94,8,9]}'>[it's not very good]</span></a></p>");
 add("wt2html", "2. Lists with start-of-line-transparent tokens before bullets: 
Template close", "<ul about=\"#mwt1\" typeof=\"mw:Transclusion\" 
data-parsoid='{\"dsr\":[0,18,0,0],\"pi\":[[{\"k\":\"1\",\"spc\":[\"\",\"\",\"\",\"\"]}]]}'
 data-mw='{\"parts\":[\"*foo 
\",{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"bar\\n\"}},\"i\":0}}]}'><li>foo
 bar</li></ul><span about=\"#mwt1\">\n</span><p 
data-parsoid='{\"dsr\":[18,22,0,0]}'>*baz</p>");
@@ -1055,8 +1055,8 @@
 add("html2wt", "Nested table", "{| border=\"1\"\n\n| α\n\n|\n{| 
bgcolor=\"#ABCDEF\" border=\"2\"\n\n|nested\n\n|-\n|table\n|}\n\n|the original 
table again\n|}\n");
 add("html2wt", "Invalid attributes in table cell (bug 1830)", 
"{|\n\n|broken\n|}\n");
 add("html2wt", "Indented table markup mixed with indented pre content 
(proposed in bug 6200)", " {|\n \n |\n Text that should be rendered 
preformatted \n \n |}\n");
-add("html2wt", "Template-generated table cell attributes and cell content", 
"{|\n\n| style=\"color: red\" | Foo\n\n| style=\"color: red\" | Foo\n\n| 
style=\"color: red\" | Foo\n\n| align=\"center\" style=\"color: red\" | 
Foo\n\n| align=\"center\" style=\"color: red\" | Foo\n|}\n");
-add("html2wt", "Template-generated table cell attributes and cell content 
(2)", "{|\n\n| align=\"center\" style=\"color: red\" | Foo \n| Bar \n| 
Baz\n|}\n");
+add("html2wt", "1. Template-generated table cell attributes and cell content", 
"{|\n\n| style=\"color: red\" | Foo\n\n| style=\"color: red\" | Foo\n\n| 
style=\"color: red\" | Foo\n\n| align=\"center\" style=\"color: red\" | 
Foo\n\n| align=\"center\" style=\"color: red\" | Foo\n|}\n");
+add("html2wt", "3. Template-generated table cell attributes and cell content", 
"{|\n\n| align=\"center\" style=\"color: red\" | Foo \n| Bar \n| Baz\n|}\n");
 add("html2wt", "Table with row followed by newlines and table heading", 
"{|\n\n! foo\n|}\n");
 add("html2wt", "Table with empty line following the start tag", "{|\n\n| 
foo\n|}\n");
 add("html2wt", "Table attributes with empty value", "{|\n\n| style=\"\" | 
hello\n|}\n");
diff --git a/tests/parserTests.txt b/tests/parserTests.txt
index 8a0fef6..d4a8996 100644
--- a/tests/parserTests.txt
+++ b/tests/parserTests.txt
@@ -119,6 +119,14 @@
 !! endarticle
 
 !! article
+Template:table_attribs_2
+!! text
+<noinclude>
+|</noinclude>style="color: red"| Foo
+|Bar||Baz
+!! endarticle
+
+!! article
 Template:table_cells
 !! text
 {{table_attribs}} || Bar || Baz
@@ -5615,7 +5623,7 @@
 !! end
 
 !! test
-Template-generated table cell attributes and cell content
+1. Template-generated table cell attributes and cell content
 !! wikitext
 {|
 |{{table_attribs}}
@@ -5641,7 +5649,29 @@
 !! end
 
 !! test
-Template-generated table cell attributes and cell content (2)
+2. Template-generated table cell attributes and cell content
+!! wikitext
+{|
+|{{table_attribs_2}}
+|}
+!! html/php
+<table>
+<tr>
+<td style="color: red"> Foo
+</td>
+<td>Bar</td>
+<td>Baz
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td about="#mwt1" typeof="mw:Transclusion" style="color: red" 
data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_2","href":"./Template:Table_attribs_2"},"params":{},"i":0}}]}'>
 Foo</td>
+<td about="#mwt1">Bar</td><td about="#mwt1">Baz</td></tr>
+</tbody></table>
+!! end
+
+!! test
+3. Template-generated table cell attributes and cell content
 !! wikitext
 {|
 |align=center {{table_cells}}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib4ad0a63b97463fbc3944d674945c12ead23f944
Gerrit-PatchSet: 11
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: GWicke <[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