jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/398895 )

Change subject: Linter: Use extension mechanism to provide ext-specific lint 
handers
......................................................................


Linter: Use extension mechanism to provide ext-specific lint handers

* <ref> content ends up in references section. The original <ref>
  site only has a backlink to that references section.

* Given this, when the references tag itself comes from a template,
  this throws off the linter attribution code. It assigns the
  references template's DSR to the lints from the <ref> tags.

* A clean way of dealing with this would be to treat extension
  content as its own independent document (which we are already doing
  currently in our wt2html code path) and asking the extension to process
  its content while giving it the handler for linting an individual node.

* This patch implements special handlers for <ref> and <references> content
  in the Cite extension and registers them.

* Move cite-specific lint handling code to the Cite extension.

* New mocha tests spec this behavior.

Change-Id: Ib57f0303605a73408333e133f8051be0b8d45d69
---
M lib/ext/Cite/index.js
M lib/wt2html/pp/processors/linter.js
M tests/mocha/linter.js
3 files changed, 114 insertions(+), 15 deletions(-)

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



diff --git a/lib/ext/Cite/index.js b/lib/ext/Cite/index.js
index ced0b51..4679ce8 100644
--- a/lib/ext/Cite/index.js
+++ b/lib/ext/Cite/index.js
@@ -168,6 +168,13 @@
        }),
 };
 
+Ref.prototype.lintHandler = function(ref, env, tplInfo, domLinter) {
+       var linkBackId = ref.firstChild.getAttribute('href').replace(/[^#]*#/, 
'');
+       var refContent = ref.ownerDocument.getElementById(linkBackId).lastChild;
+       domLinter(refContent, env, tplInfo.isTemplated ? tplInfo : null);
+       return ref.nextNode;
+};
+
 /**
  * Helper class used by <references> implementation
  */
@@ -664,6 +671,22 @@
        },
 };
 
+References.prototype.lintHandler = function(refs, env, tplInfo, domLinter) {
+       // Nothing to do
+       //
+       // FIXME: Not entirely true for scenarios where the <ref> tags
+       // are defined in the references section that is itself templated.
+       //
+       // {{1x|<references>\n<ref name='x'><b>foo</ref>\n</references>}}
+       //
+       // In this example, the references tag has the right tplInfo and
+       // when the <ref> tag is processed in the body of the article where
+       // it is accessed, there is no relevant template or dsr info available.
+       //
+       // Ignoring for now.
+       return refs.nextNode;
+};
+
 /* --------------------------------------------
  * This handles wikitext like this:
  *
@@ -766,10 +789,12 @@
                                name: 'ref',
                                tokenHandler: 
this.ref.tokenHandler.bind(this.ref),
                                serialHandler: this.ref.serialHandler,
+                               lintHandler: this.ref.lintHandler,
                        }, {
                                name: 'references',
                                tokenHandler: 
this.references.tokenHandler.bind(this.references),
                                serialHandler: this.references.serialHandler,
+                               lintHandler: this.references.lintHandler,
                        },
                ],
                styles: [
diff --git a/lib/wt2html/pp/processors/linter.js 
b/lib/wt2html/pp/processors/linter.js
index e40b685..f705cab 100644
--- a/lib/wt2html/pp/processors/linter.js
+++ b/lib/wt2html/pp/processors/linter.js
@@ -882,37 +882,55 @@
                        continue;
                }
 
-               // Identify the first template/extension node.
-               // You'd think the !tplInfo check isn't necessary since
-               // we don't have nested transclusions, however, you can
-               // get extensions in transclusions.
+               var nodeTypeOf = null;
+
+               // !tplInfo check is to protect against templated content in
+               // extensions which might in turn be nested in templated 
content.
                if (!tplInfo && DU.isFirstEncapsulationWrapperNode(node)) {
-                       var about = node.getAttribute("about");
+                       nodeTypeOf = node.getAttribute('typeof');
                        tplInfo = {
                                first: node,
-                               last: 
JSUtils.lastItem(DU.getAboutSiblings(node, about)),
+                               last: 
JSUtils.lastItem(DU.getAboutSiblings(node, node.getAttribute("about"))),
                                dsr: DU.getDataParsoid(node).dsr,
+                               isTemplated: 
/\bmw:Transclusion\b/.test(nodeTypeOf),
                                clear: false,
                        };
                }
 
-               // Lint this node
-               var nextNode = logWikitextFixups(node, env, tplInfo);
-               if (tplInfo && tplInfo.clear) {
-                       tplInfo = null;
+               // Let native extensions lint their content
+               var nextNode;
+               var done = false;
+               var match = (nodeTypeOf || '').match(/\bmw:Extension\/(.+?)\b/);
+               if (match) {
+                       var extTag = match[1];
+                       var nativeExt = env.conf.wiki.extensionTags.get(extTag);
+                       if (nativeExt && nativeExt.lintHandler) {
+                               nextNode = nativeExt.lintHandler(node, env, 
tplInfo, findLints);
+                               done = true;
+                       }
                }
 
-               // Lint subtree
-               if (!nextNode) {
-                       findLints(node, env, tplInfo);
-                       nextNode = node.nextSibling;
+               // Default node handler
+               // Don't rely on the presence or well-behavedness of the native 
lint handler
+               // That is the reason for if (!done) instead of if (!nextNode)
+               if (!done) {
+                       // Lint this node
+                       nextNode = logWikitextFixups(node, env, tplInfo);
+                       if (tplInfo && tplInfo.clear) {
+                               tplInfo = null;
+                       }
+
+                       // Lint subtree
+                       if (!nextNode) {
+                               findLints(node, env, tplInfo);
+                       }
                }
 
                if (tplInfo && tplInfo.last === node) {
                        tplInfo = null;
                }
 
-               node = nextNode;
+               node = nextNode || node.nextSibling;
        }
 }
 
diff --git a/tests/mocha/linter.js b/tests/mocha/linter.js
index 7599a20..afe4183 100644
--- a/tests/mocha/linter.js
+++ b/tests/mocha/linter.js
@@ -887,4 +887,60 @@
                        return expectEmptyResults("a 
<ref><table>\n<tr><td>b</td></tr>\n</table></ref> <references />");
                });
        });
+       describe('LINT ISSUES IN <ref> TAGS', function() {
+               it('should attribute linter issues to the ref tag', function() {
+                       return parseWT('a <ref><b>x</ref> 
<references/>').then(function(result) {
+                               result.should.have.length(1);
+                               result[0].should.have.a.property("type", 
"missing-end-tag");
+                               result[0].dsr.should.deep.equal([ 7, 11, 3, 0 
]);
+                               result[0].should.have.a.property("params");
+                               result[0].params.should.have.a.property("name", 
"b");
+                       });
+               });
+               it('should attribute linter issues to the ref tag even if 
references is templated', function() {
+                       return parseWT('a <ref><b>x</ref> 
{{1x|<references/>}}').then(function(result) {
+                               result.should.have.length(1);
+                               result[0].should.have.a.property("type", 
"missing-end-tag");
+                               result[0].dsr.should.deep.equal([ 7, 11, 3, 0 
]);
+                               result[0].should.have.a.property("params");
+                               result[0].params.should.have.a.property("name", 
"b");
+                       });
+               });
+               it('should attribute linter issues to the ref tag even when ref 
and references are both templated', function() {
+                       return parseWT('a <ref><b>x</ref> b 
<ref>{{1x|<b>x}}</ref> c {{1x|<ref><b>y</ref>}} 
{{1x|<references/>}}').then(function(result) {
+                               result.should.have.length(3);
+                               result[0].should.have.a.property("type", 
"missing-end-tag");
+                               result[0].dsr.should.deep.equal([ 7, 11, 3, 0 
]);
+                               result[0].should.have.a.property("params");
+                               result[0].params.should.have.a.property("name", 
"b");
+                               result[1].should.have.a.property("type", 
"missing-end-tag");
+                               result[1].dsr.should.deep.equal([ 25, 36, null, 
null]);
+                               result[1].should.have.a.property("params");
+                               result[1].params.should.have.a.property("name", 
"b");
+                               
result[1].should.have.a.property("templateInfo");
+                               
result[1].templateInfo.should.have.a.property("name", "Template:1x");
+                               result[2].should.have.a.property("type", 
"missing-end-tag");
+                               result[2].dsr.should.deep.equal([ 45, 67, null, 
null]);
+                               result[2].should.have.a.property("params");
+                               result[2].params.should.have.a.property("name", 
"b");
+                               
result[2].should.have.a.property("templateInfo");
+                               
result[2].templateInfo.should.have.a.property("name", "Template:1x");
+                       });
+               });
+               it('should attribute linter issues properly when ref tags are 
in non-templated references tag', function() {
+                       return parseWT("a <ref><s>x</ref> b <ref name='x' /> 
<references> <ref name='x'>{{1x|<b>boo}}</ref> 
</references>").then(function(result) {
+                               result.should.have.length(2);
+                               result[0].should.have.a.property("type", 
"missing-end-tag");
+                               result[0].dsr.should.deep.equal([ 7, 11, 3, 0 
]);
+                               result[0].should.have.a.property("params");
+                               result[0].params.should.have.a.property("name", 
"s");
+                               result[1].should.have.a.property("type", 
"missing-end-tag");
+                               result[1].dsr.should.deep.equal([ 64, 77, null, 
null]);
+                               result[1].should.have.a.property("params");
+                               result[1].params.should.have.a.property("name", 
"b");
+                               
result[1].should.have.a.property("templateInfo");
+                               
result[1].templateInfo.should.have.a.property("name", "Template:1x");
+                       });
+               });
+       });
 });

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib57f0303605a73408333e133f8051be0b8d45d69
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: Arlolra <[email protected]>
Gerrit-Reviewer: C. Scott Ananian <[email protected]>
Gerrit-Reviewer: Sbailey <[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