From b0cb17cd83dde89753ec159e27c920a7bf22bee1 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Sun, 5 Jul 2015 17:48:18 +0100 Subject: [PATCH] Re-establish caching of results of parsing a tiddler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I switched this optimisation off back in ed35d91be6c6e188c80bc0994fa83acd7526d225, in October 2013, as part of a big refactoring of the parsing and widget mechanism. I’ve been meaning to switch it back on for some time. My rough measurements suggest that this optimisation can reduce rendering time by 5-10%. --- .../parsers/wikiparser/rules/macrodef.js | 11 +-- core/modules/parsers/wikiparser/wikiparser.js | 19 ++++-- core/modules/wiki.js | 68 ++++--------------- 3 files changed, 35 insertions(+), 63 deletions(-) diff --git a/core/modules/parsers/wikiparser/rules/macrodef.js b/core/modules/parsers/wikiparser/rules/macrodef.js index c3ad6e879..1a0f34e01 100644 --- a/core/modules/parsers/wikiparser/rules/macrodef.js +++ b/core/modules/parsers/wikiparser/rules/macrodef.js @@ -78,10 +78,13 @@ exports.parse = function() { } // Save the macro definition return [{ - type: "macrodef", - name: this.match[1], - params: params, - text: text + type: "set", + attributes: { + name: {type: "string", value: this.match[1]}, + value: {type: "string", value: text} + }, + children: [], + params: params }]; }; diff --git a/core/modules/parsers/wikiparser/wikiparser.js b/core/modules/parsers/wikiparser/wikiparser.js index 19a3522fa..2a584b429 100644 --- a/core/modules/parsers/wikiparser/wikiparser.js +++ b/core/modules/parsers/wikiparser/wikiparser.js @@ -48,12 +48,13 @@ var WikiParser = function(type,text,options) { this.blockRules = this.instantiateRules(this.blockRuleClasses,"block",0); this.inlineRules = this.instantiateRules(this.inlineRuleClasses,"inline",0); // Parse any pragmas - this.tree = this.parsePragmas(); + this.tree = []; + var topBranch = this.parsePragmas(); // Parse the text into inline runs or blocks if(options.parseAsInline) { - this.tree.push.apply(this.tree,this.parseInlineRun()); + topBranch.push.apply(topBranch,this.parseInlineRun()); } else { - this.tree.push.apply(this.tree,this.parseBlocks()); + topBranch.push.apply(topBranch,this.parseBlocks()); } // Return the parse tree }; @@ -122,7 +123,7 @@ WikiParser.prototype.findNextMatch = function(rules,startPos) { Parse any pragmas at the beginning of a block of parse text */ WikiParser.prototype.parsePragmas = function() { - var tree = []; + var currentTreeBranch = this.tree; while(true) { // Skip whitespace this.skipWhitespace(); @@ -137,9 +138,15 @@ WikiParser.prototype.parsePragmas = function() { break; } // Process the pragma rule - tree.push.apply(tree,nextMatch.rule.parse()); + var subTree = nextMatch.rule.parse(); + if(subTree.length > 0) { + // Quick hack; we only cope with a single parse tree node being returned, which is true at the moment + currentTreeBranch.push.apply(currentTreeBranch,subTree); + subTree[0].children = []; + currentTreeBranch = subTree[0].children; + } } - return tree; + return currentTreeBranch; }; /* diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 2eef93464..bf1450894 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -705,22 +705,18 @@ exports.clearGlobalCache = function() { // Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it exports.getCacheForTiddler = function(title,cacheName,initializer) { - -// Temporarily disable caching so that tweakParseTreeNode() works -return initializer(); - -// this.caches = this.caches || Object.create(null); -// var caches = this.caches[title]; -// if(caches && caches[cacheName]) { -// return caches[cacheName]; -// } else { -// if(!caches) { -// caches = Object.create(null); -// this.caches[title] = caches; -// } -// caches[cacheName] = initializer(); -// return caches[cacheName]; -// } + this.caches = this.caches || Object.create(null); + var caches = this.caches[title]; + if(caches && caches[cacheName]) { + return caches[cacheName]; + } else { + if(!caches) { + caches = Object.create(null); + this.caches[title] = caches; + } + caches[cacheName] = initializer(); + return caches[cacheName]; + } }; // Clear all caches associated with a particular tiddler @@ -753,7 +749,7 @@ Options include: parseAsInline: if true, the text of the tiddler will be parsed as an inline run _canonical_uri: optional string of the canonical URI of this content */ -exports.old_parseText = function(type,text,options) { +exports.parseText = function(type,text,options) { options = options || {}; // Select a parser var Parser = $tw.Wiki.parsers[type]; @@ -777,7 +773,7 @@ exports.old_parseText = function(type,text,options) { /* Parse a tiddler according to its MIME type */ -exports.old_parseTiddler = function(title,options) { +exports.parseTiddler = function(title,options) { options = $tw.utils.extend({},options); var cacheType = options.parseAsInline ? "newInlineParseTree" : "newBlockParseTree", tiddler = this.getTiddler(title), @@ -786,44 +782,10 @@ exports.old_parseTiddler = function(title,options) { if(tiddler.hasField("_canonical_uri")) { options._canonical_uri = tiddler.fields._canonical_uri; } - return self.old_parseText(tiddler.fields.type,tiddler.fields.text,options); + return self.parseText(tiddler.fields.type,tiddler.fields.text,options); }) : null; }; -var tweakMacroDefinition = function(nodeList) { - if(nodeList && nodeList[0] && nodeList[0].type === "macrodef") { - nodeList[0].type = "set"; - nodeList[0].attributes = { - name: {type: "string", value: nodeList[0].name}, - value: {type: "string", value: nodeList[0].text} - }; - nodeList[0].children = nodeList.slice(1); - nodeList.splice(1,nodeList.length-1); - tweakMacroDefinition(nodeList[0].children); - } -}; - -var tweakParser = function(parser) { - // Move any macro definitions to contain the body tree - tweakMacroDefinition(parser.tree); -}; - -exports.parseText = function(type,text,options) { - var parser = this.old_parseText(type,text,options); - if(parser) { - tweakParser(parser); - } - return parser; -}; - -exports.parseTiddler = function(title,options) { - var parser = this.old_parseTiddler(title,options); - if(parser) { - tweakParser(parser); - } - return parser; -}; - exports.parseTextReference = function(title,field,index,options) { var tiddler,text; if(options.subTiddler) {