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

Reply via email to