Subramanya Sastry has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/335192 )
Change subject: TemplateHandler: Remove duplicate code during template resolution ...................................................................... TemplateHandler: Remove duplicate code during template resolution * Followup on previous refactoring commits that centralized all template resolution logic in one place. * Additional work here to enable removal of duplicated logic and cleanup of code to better reflect functionality. Change-Id: Ieecad80ff9b9cc093fb03b69553f2547f34100f7 --- M lib/wt2html/tt/TemplateHandler.js M lib/wt2html/tt/TokenStreamPatcher.js 2 files changed, 61 insertions(+), 103 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid refs/changes/92/335192/1 diff --git a/lib/wt2html/tt/TemplateHandler.js b/lib/wt2html/tt/TemplateHandler.js index 89967ae..f1275d4 100644 --- a/lib/wt2html/tt/TemplateHandler.js +++ b/lib/wt2html/tt/TemplateHandler.js @@ -85,14 +85,12 @@ }; var tgt = this.resolveTemplateTarget(state, token.attribs[0].k); - if (tgt && (tgt.magicWord || tgt.isSpecialMagicWord)) { - // magic word variables can be mistaken for templates + if (tgt && tgt.magicWordType) { try { - var magicWord = this.checkForMagicWordVariable(token); - if (magicWord) { - cb({ tokens: Array.isArray(magicWord) ? magicWord : [magicWord] }); - return; - } + var toks = this.processSpecialMagicWord(token, tgt); + console.assert(toks !== null); + cb({ tokens: Array.isArray(toks) ? toks : [toks] }); + return; } catch (e) { env.log("error", "Exception ", e, " checking magic word for token: ", token); } @@ -232,15 +230,16 @@ }; /** - * Check if token is a magic word masquerading as a template - * - currently only DEFAULTSORT and DISPLAYTITLE are considered + * Process the special magic word as specified by resolvedTgt.magicWordType + * magicWordType === '!' => {{!}} is the magic word + * magicWordtype === 'MASQ' => DEFAULTSORT, DISPLAYTITLE are the magic words + * (Util.magicMasqs.has(..)) */ -TemplateHandler.prototype.checkForMagicWordVariable = function(tplToken) { +TemplateHandler.prototype.processSpecialMagicWord = function(tplToken, resolvedTgt) { var env = this.manager.env; - var magicWord = tplToken.attribs[0].k; // special case for {{!}} magic word - if (magicWord === "!") { + if ((resolvedTgt && resolvedTgt.magicWordType === '!') || tplToken.attribs[0].k === "!") { // If we're not at the top level, return a table cell. This will always // be the case. Either {{!}} was tokenized as a td, or it is tokenized // as template but the recursive call to fetch its content returns a @@ -263,105 +262,59 @@ return toks; } - // Deal with the following scenarios: - // - // 1. Normal string: {{DEFAULTSORT:foo}} - // 2. String with entities: {{DEFAULTSORT:"foo"bar}} - // 3. Templated key: {{DEFAULTSORT:{{foo}}bar}} - - var property, key, propAndKey, keyToks; - if (magicWord.constructor === String) { - // Scenario 1. above -- common case - propAndKey = magicWord.match(/^([^:]+:?)(.*)$/); - if (propAndKey) { - property = propAndKey[1]; - key = propAndKey[2]; - } - } else if (Array.isArray(magicWord)) { - // Scenario 2. or 3. above -- uncommon case - - property = magicWord[0]; - if (!property || property.constructor !== String) { - // FIXME: We don't know if this is a magic word at this point. - // Ex: {{ {{echo|DEFAULTSORT}}:foo }} - // {{ {{echo|lc}}:foo }} - // This requires more info from the preprocessor than - // we have currently. This will be handled at a later point. - return null; - } - - propAndKey = property.match(/^([^:]+:?)(.*)$/); - if (propAndKey) { - property = propAndKey[1]; - key = propAndKey[2]; - } - - keyToks = [key].concat(magicWord.slice(1)); - } - - // TODO gwicke: factor out generic magic word (and parser function) round-tripping logic! - - if (!property) { + if (resolvedTgt === null || resolvedTgt.magicWordType !== 'MASQ') { + // Nothing to do return null; } - property = property.trim(); - var name = env.conf.wiki.magicWords[property]; - - // try without the colon - if (!name) { - name = env.conf.wiki.magicWords[property.slice(0, -1)]; + var magicWord = resolvedTgt.prefix.toLowerCase(); + var key = resolvedTgt.pfArg; + var keyToks = resolvedTgt.pfArgToks; + var templatedKey = false; + if (keyToks) { + // Check if any part of the key is templated + for (var i = 0, n = keyToks.length; i < n; i++) { + if (Util.isTemplateToken(keyToks[i])) { + templatedKey = true; + break; + } + } + key = Util.tokensToString(keyToks); } - if (Util.magicMasqs.has(name)) { - var templatedKey = false; - if (keyToks) { - // Check if any part of the key is templated - for (var i = 0, n = keyToks.length; i < n; i++) { - if (Util.isTemplateToken(keyToks[i])) { - templatedKey = true; - break; - } - } - key = Util.tokensToString(keyToks); - } + var pageProp = 'mw:PageProp/'; + if (magicWord === 'defaultsort') { + pageProp += 'category'; + } + pageProp += magicWord; - var pageProp = 'mw:PageProp/'; - if (name === 'defaultsort') { - pageProp += 'category'; - } - pageProp += name; + var metaToken = new SelfclosingTagTk('meta', + [ new KV('property', pageProp) ], + Util.clone(tplToken.dataAttribs) + ); - var metaToken = new SelfclosingTagTk( - 'meta', [ new KV('property', pageProp) ], - Util.clone(tplToken.dataAttribs) - ); + if (templatedKey) { + // No shadowing if templated + // + // SSS FIXME: post-tpl-expansion, WS won't be trimmed. How do we handle this? + metaToken.addAttribute("content", keyToks); + } else { + // Leading/trailing WS should be stripped + key = key.trim(); - if (templatedKey) { - // No shadowing if templated - // - // SSS FIXME: post-tpl-expansion, WS won't be trimmed. How do we handle this? - metaToken.addAttribute("content", keyToks); + var src = (tplToken.dataAttribs || {}).src; + if (src) { + // If the token has original wikitext, shadow the sort-key + var origKey = src.replace(/[^:]+:?/, '').replace(/}}$/, ''); + metaToken.addNormalizedAttribute("content", key, origKey); } else { - // Leading/trailing WS should be stripped - key = key.trim(); - - var src = (tplToken.dataAttribs || {}).src; - if (src) { - // If the token has original wikitext, shadow the sort-key - var origKey = src.replace(/[^:]+:?/, '').replace(/}}$/, ''); - metaToken.addNormalizedAttribute("content", key, origKey); - } else { - // If not, this token came from an extension/template - // in which case, dont bother with shadowing since the token - // will never be edited directly. - metaToken.addAttribute("content", key); - } + // If not, this token came from an extension/template + // in which case, dont bother with shadowing since the token + // will never be edited directly. + metaToken.addAttribute("content", key); } - return metaToken; } - - return null; + return metaToken; }; TemplateHandler.prototype.resolveTemplateTarget = function(state, targetToks) { @@ -406,6 +359,9 @@ } } + // Normalize to an array + targetToks = !Array.isArray(targetToks) ? [targetToks] : targetToks; + var env = this.manager.env; var wiki = env.conf.wiki; var isTemplate = true; @@ -443,10 +399,12 @@ state.parserFunctionName = translatedPrefix; return { isPF: true, - magicWord: target, prefix: prefix, + magicWordType: Util.magicMasqs.has(lowerPrefix) ? 'MASQ' : null, target: 'pf_' + translatedPrefix, pfArg: target.substr(prefix.length + 1), + // Extract toks that make up pfArg + pfArgToks: [targetToks[0].replace(/^[^:]*:?/, '')].concat(targetToks.slice(1)), }; } @@ -485,7 +443,7 @@ return { isPF: false, - isSpecialMagicWord: isSpecialMagicWord, + magicWordType: isSpecialMagicWord ? '!' : null, target: title.getPrefixedDBKey(), }; diff --git a/lib/wt2html/tt/TokenStreamPatcher.js b/lib/wt2html/tt/TokenStreamPatcher.js index 9edbc81..ddf656e 100644 --- a/lib/wt2html/tt/TokenStreamPatcher.js +++ b/lib/wt2html/tt/TokenStreamPatcher.js @@ -117,7 +117,7 @@ // All of these need uniform handling. To be addressed separately // if this proves to be a real problem on production pages. if (t.constructor === SelfclosingTagTk && t.name === 'template') { - t = TemplateHandler.prototype.checkForMagicWordVariable.call(this, t) || t; + t = TemplateHandler.prototype.processSpecialMagicWord.call(this, t) || t; } ret = ret.concat(t); } -- To view, visit https://gerrit.wikimedia.org/r/335192 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ieecad80ff9b9cc093fb03b69553f2547f34100f7 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/services/parsoid Gerrit-Branch: master Gerrit-Owner: Subramanya Sastry <ssas...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits