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":"<translate>123</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
