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

Change subject: Permit extension tags in xmlish attribute values
......................................................................


Permit extension tags in xmlish attribute values

Fixes the render of the reported page in the task,
http://localhost:8000/meta.wikimedia.org/v3/page/html/Global_Collaboration%2FNewsletter%2FIssues%2F2016%2F10/17071642

Bug: T183515
Authored-by: Arlo Breault <[email protected]>
Authored-by: Shannon Bailey <[email protected]>
Change-Id: I311d0fbbd2cdcf2a0c0a3dbf698912e6df5f3356
---
M lib/wt2html/pegTokenizer.pegjs
M lib/wt2html/tt/AttributeExpander.js
M tests/mockAPI.js
M tests/parserTests.txt
4 files changed, 46 insertions(+), 13 deletions(-)

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



diff --git a/lib/wt2html/pegTokenizer.pegjs b/lib/wt2html/pegTokenizer.pegjs
index 17c6300..60ab34c 100644
--- a/lib/wt2html/pegTokenizer.pegjs
+++ b/lib/wt2html/pegTokenizer.pegjs
@@ -1394,10 +1394,17 @@
     return [' '].concat(l);
 }
 
-// This is only used in directive, but maybe that should be accepting extension
-// tags in general?
+extension_tag =
+  &{ return !stops.onStack('extTag'); }
+  extToken:xmlish_tag
+  // Account for `maybeExtensionTag` returning unmatched start / end tags
+  &{ return extToken.name === 'extension'; }
+  { return extToken; }
+
 nowiki
-  = &("<" "/"? "nowiki"i !tag_name_chars) x:xmlish_tag { return x; }
+  = extToken:extension_tag
+    &{ return extToken.getAttribute('name') === 'nowiki'; }
+    { return extToken; }
 
 // Used by nowiki extension to tokenize html entities.
 nowiki_content "nowiki_content"
@@ -1407,8 +1414,6 @@
 // conversion strings.
 nowiki_text
   = extToken:nowiki
-    // Account for `maybeExtensionTag` returning unmatched start / end tags
-    &{ return extToken.name === 'extension'; }
   {
     var txt = Util.getArgInfo(extToken).dict.body.extsrc;
     return Util.decodeEntities(txt);
@@ -2226,7 +2231,7 @@
 // plain-text content.
 directive
   = comment
-  / nowiki
+  / extension_tag
   / tplarg_or_template
   / & "-{" v:lang_variant_or_tpl { return v; }
   / & "&" e:htmlentity { return e; }
diff --git a/lib/wt2html/tt/AttributeExpander.js 
b/lib/wt2html/tt/AttributeExpander.js
index 9a76502..59d88e8 100644
--- a/lib/wt2html/tt/AttributeExpander.js
+++ b/lib/wt2html/tt/AttributeExpander.js
@@ -122,7 +122,7 @@
  * This helper method strips all meta tags introduced by
  * transclusions, etc. and returns the content.
  * ---------------------------------------------------------- */
-function stripMetaTags(tokens, wrapTemplates) {
+function stripMetaTags(env, tokens, wrapTemplates) {
        var buf = [];
        var isPushed = false;
        var hasGeneratedContent = false;
@@ -130,6 +130,20 @@
        for (var i = 0, l = tokens.length; i < l; i++) {
                var t = tokens[i];
                if ([TagTk, SelfclosingTagTk].indexOf(t.constructor) !== -1) {
+                       // Reinsert expanded extension content that's been 
parsed to DOM
+                       // as a string.  This should match what the php parser 
does since
+                       // extension content is html being placed in an 
attribute context.
+                       if (t.getAttribute('typeof') === 'mw:DOMFragment') {
+                               var nodes = 
env.fragmentMap.get(t.dataAttribs.html);
+                               var str = nodes.reduce(function(prev, next) {
+                                       // We strip tags since the sanitizer 
would normally drop
+                                       // tokens but we're already at html
+                                       return prev + next.textContent;
+                               }, '');
+                               buf.push(str);
+                               // TODO: Maybe cleanup the remaining about 
sibbling wrappers
+                               // but the sanitizer will drop them anyways
+                       }
                        isPushed = false;
                        if (wrapTemplates) {
                                // Strip all meta tags.
@@ -348,7 +362,7 @@
                                                metaTokens = 
updatedK.metaTokens;
                                        } else {
                                                // Scenario 2 from the 
documentation comment above.
-                                               updatedK = 
stripMetaTags(expandedK, wrapTemplates);
+                                               updatedK = stripMetaTags(env, 
expandedK, wrapTemplates);
                                                expandedK = updatedK.value;
                                        }
 
@@ -438,7 +452,7 @@
                                                metaTokens = 
updatedV.metaTokens;
                                        } else {
                                                // Scenario 2 from the 
documentation comment above.
-                                               updatedV = 
stripMetaTags(attrValTokens, wrapTemplates);
+                                               updatedV = stripMetaTags(env, 
attrValTokens, wrapTemplates);
                                                attrValTokens = updatedV.value;
                                        }
                                        expandedA.v = attrValTokens;
diff --git a/tests/mockAPI.js b/tests/mockAPI.js
index 217b60b..0735ee7 100644
--- a/tests/mockAPI.js
+++ b/tests/mockAPI.js
@@ -436,10 +436,15 @@
                return { text: text.replace(/\{\{subst:echo\|([^}]+)\}\}/, 
"$1") };
        }
        // Render to html the contents of known extension tags
-       if (/<(indicator|section)/.test(text)) {
-               return { text: '\n' };
-       } else {
-               throw new Error("Unhandled extension type encountered in: " + 
text);
+       var match = text.match(/<([A-Za-z][^\t\n\v />\0]*)/);
+       switch ((match && match[1]) || '') {
+               case 'translate':
+                       return { text: text };
+               case 'indicator':
+               case 'section':
+                       return { text: '\n' };
+               default:
+                       throw new Error("Unhandled extension type encountered 
in: " + text);
        }
 };
 
diff --git a/tests/parserTests.txt b/tests/parserTests.txt
index 2cf6aca..c1b893c 100644
--- a/tests/parserTests.txt
+++ b/tests/parserTests.txt
@@ -17386,6 +17386,15 @@
 <div id="title=" data-parsoid='{"stx":"html"}'>HTML rocks</div>
 !! end
 
+## QUESTION: Should this have ExpandedAttrs?
+!! test
+Extension tag in attribute value
+!! wikitext
+<span title="<translate>123</translate>">ok</span>
+!! html/parsoid
+<p><span title="123" 
data-parsoid='{"stx":"html","a":{"title":"123"},"sa":{"title":"&lt;translate>123&lt;/translate>"}}'>ok</span></p>
+!! end
+
 !! test
 table with multiple empty attribute values
 !! options

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I311d0fbbd2cdcf2a0c0a3dbf698912e6df5f3356
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <[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