Marcoil has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/126739

Change subject: DOM tpl params: Avoid going async if all params are simple 
strings
......................................................................

DOM tpl params: Avoid going async if all params are simple strings

Change-Id: Id2d068da3df45b5ecb7bba3dfff83c0a1b86449f
---
M lib/ext.core.TemplateHandler.js
1 file changed, 85 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid 
refs/changes/39/126739/1

diff --git a/lib/ext.core.TemplateHandler.js b/lib/ext.core.TemplateHandler.js
index 824e996..df08c98 100644
--- a/lib/ext.core.TemplateHandler.js
+++ b/lib/ext.core.TemplateHandler.js
@@ -679,7 +679,6 @@
 
        if (this.options.wrapTemplates) {
                if (!state.emittedFirstChunk && !this.options.inTemplate) {
-                       state.accum = new TokenAccumulator(this.manager, cb);
                        chunk = this.addEncapsulationInfo(state, chunk );
                        state.emittedFirstChunk = true;
 
@@ -693,10 +692,68 @@
 
                                // Add its HTML conversion to a parameter. The 
eachCb is only
                                // used to signal an error to async.each
-                               var getParamHTML = function (paramInfo, eachCb) 
{
-                                       var param = argDict.params[paramInfo.k],
-                                               paramWt = param.wt,
-                                               paramTokens, paramSrcOffsets;
+                               var getParamHTML = function (paramData, eachCb) 
{
+                                       var param = paramData.param,
+                                               paramTokens = paramData.tokens,
+                                               srcStart = 
paramData.info.srcOffsets[2],
+                                               srcEnd = 
paramData.info.srcOffsets[3];
+                                       if (paramData.info.spc) {
+                                               srcStart += 
paramData.info.spc[2].length;
+                                               srcEnd -= 
paramData.info.spc[3].length;
+                                       } else if (paramData.info.named) {
+                                               // The default spacing for 
named arguments is one
+                                               // space after the '='
+                                               srcStart++;
+                                       }
+
+                                       Util.processContentInPipeline(
+                                               this.manager.env, 
this.manager.frame,
+                                               param.wt,
+                                               {
+                                                       pipelineType: 
"text/x-mediawiki/full",
+                                                       pipelineOpts: {
+                                                               isInclude: true,
+                                                               wrapTemplates: 
true,
+                                                               inBlockToken: 
true,
+                                                               // TODO: This 
helps in the case of unnamed
+                                                               // parameters 
which start with whitespace,
+                                                               // but it's not 
be the correct solution
+                                                               // for cases 
with significant start-of-line
+                                                               // chars 
inserted after "\n".
+                                                               noPre: true
+                                                       },
+                                                       srcOffsets: [ srcStart, 
srcEnd ],
+                                                       documentCB: function 
(html) {
+                                                               // Remove DSR 
from children
+                                                               for (var c = 0; 
c < html.body.children.length; c++) {
+                                                                       var 
node = html.body.children[c],
+                                                                               
dp = DU.getDataParsoid(node);
+                                                                       if 
(dp.dsr) {
+                                                                               
delete (dp.dsr);
+                                                                               
// If data-parsoid only had dsr, remove it completely
+                                                                               
if (Object.keys(dp).length === 0) {
+                                                                               
        node.removeAttribute('data-parsoid');
+                                                                               
} else {
+                                                                               
        DU.setDataParsoid(node, dp);
+                                                                               
}
+                                                                       }
+                                                               }
+
+                                                               param.html = 
html.body.innerHTML;
+                                                               eachCb(null);
+                                                       }
+                                               });
+                               };
+
+                               // Collect the parameters that need parsing 
into HTML, that is,
+                               // those that are not simple strings.
+                               // This optimizes for the common case where all 
are simple strings,
+                               // in which we don't need to go async.
+                               var params = [];
+                               for (i = 0, n = argInfo.paramInfos.length; i < 
n; i++) {
+                                       var paramInfo = argInfo.paramInfos[i],
+                                               param = 
argDict.params[paramInfo.k],
+                                               paramTokens;
                                        if (paramInfo.named) {
                                                paramTokens = 
state.token.getAttribute(paramInfo.k);
                                        } else {
@@ -704,71 +761,34 @@
                                        }
 
                                        if (paramTokens && 
paramTokens.constructor === String) {
+                                               // No need to parse to HTML
                                                param.html = paramTokens;
-                                               eachCb(null);
                                        } else {
-                                               var srcStart = 
paramInfo.srcOffsets[2],
-                                                       srcEnd = 
paramInfo.srcOffsets[3];
-                                               if (paramInfo.spc) {
-                                                       srcStart += 
paramInfo.spc[2].length;
-                                                       srcEnd -= 
paramInfo.spc[3].length;
-                                               } else if (paramInfo.named) {
-                                                       // The default spacing 
for named arguments is one
-                                                       // space after the '='
-                                                       srcStart++;
-                                               }
-
-                                               Util.processContentInPipeline(
-                                                       this.manager.env, 
this.manager.frame,
-                                                       paramWt,
-                                                       {
-                                                               pipelineType: 
"text/x-mediawiki/full",
-                                                               pipelineOpts: {
-                                                                       
isInclude: true,
-                                                                       
wrapTemplates: true,
-                                                                       
inBlockToken: true,
-                                                                       // 
TODO: This helps in the case of unnamed
-                                                                       // 
parameters which start with whitespace,
-                                                                       // but 
it's not be the correct solution
-                                                                       // for 
cases with significant start-of-line
-                                                                       // 
chars inserted after "\n".
-                                                                       noPre: 
true
-                                                               },
-                                                               srcOffsets: [ 
srcStart, srcEnd ],
-                                                               documentCB: 
function (html) {
-                                                                       // 
Remove DSR from children
-                                                                       for 
(var c = 0; c < html.body.children.length; c++) {
-                                                                               
var node = html.body.children[c],
-                                                                               
        dp = DU.getDataParsoid(node);
-                                                                               
if (dp.dsr) {
-                                                                               
        delete (dp.dsr);
-                                                                               
        // If data-parsoid only had dsr, remove it completely
-                                                                               
        if (Object.keys(dp).length === 0) {
-                                                                               
                node.removeAttribute('data-parsoid');
-                                                                               
        } else {
-                                                                               
                DU.setDataParsoid(node, dp);
-                                                                               
        }
-                                                                               
}
-                                                                       }
-
-                                                                       
param.html = html.body.innerHTML;
-                                                                       
eachCb(null);
-                                                               }
-                                                       });
+                                               // Prepare the data needed to 
parse to HTML
+                                               params.push({
+                                                       param: param,
+                                                       info: paramInfo,
+                                                       tokens: paramTokens
+                                               });
                                        }
-                               };
+                               }
 
-                               // TODO: We could avoid going async by checking 
if all params are strings
-                               // and, in that case returning them immediately.
-                               async.each(argInfo.paramInfos, 
getParamHTML.bind(this), function (err) {
-                                       // Use a data-attribute to prevent the 
sanitizer from stripping this
-                                       // attribute before it reaches the DOM 
pass where it is needed.
+                               if (params.length) {
+                                       state.accum = new 
TokenAccumulator(this.manager, cb);
+                                       // TODO: We could avoid going async by 
checking if all params are strings
+                                       // and, in that case returning them 
immediately.
+                                       async.each(params, 
getParamHTML.bind(this), function (err) {
+                                               // Use a data-attribute to 
prevent the sanitizer from stripping this
+                                               // attribute before it reaches 
the DOM pass where it is needed.
+                                               chunk[0].attribs.push(new 
KV("data-mw-arginfo", JSON.stringify(argInfo)));
+                                               env.dp( 
'TemplateHandler._onChunk', chunk );
+                                               
state.accum.receiveToksFromChild({tokens: chunk});
+                                       }.bind(this));
+
+                                       return;
+                               } else {
                                        chunk[0].attribs.push(new 
KV("data-mw-arginfo", JSON.stringify(argInfo)));
-                                       env.dp( 'TemplateHandler._onChunk', 
chunk );
-                                       
state.accum.receiveToksFromChild({tokens: chunk});
-                               }.bind(this));
-
-                               return;
+                               }
                        }
                } else {
                        chunk = this.addAboutToTableElements( state, chunk );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id2d068da3df45b5ecb7bba3dfff83c0a1b86449f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: dom_tpl_params_3
Gerrit-Owner: Marcoil <marc...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to