These changes allows the internal template cache to be customised, either by disabling it complete or providing a custom implementation of how templates are cached.tags/v4.0.0
| @@ -486,14 +486,27 @@ | |||
| * avoid the need to parse the same template twice. | |||
| */ | |||
| function Writer () { | |||
| this.cache = {}; | |||
| this.templateCache = { | |||
| _cache: {}, | |||
| set: function set (key, value) { | |||
| this._cache[key] = value; | |||
| }, | |||
| get: function get (key) { | |||
| return this._cache[key]; | |||
| }, | |||
| clear: function clear () { | |||
| this._cache = {}; | |||
| } | |||
| }; | |||
| } | |||
| /** | |||
| * Clears all cached templates in this writer. | |||
| */ | |||
| Writer.prototype.clearCache = function clearCache () { | |||
| this.cache = {}; | |||
| if (typeof this.templateCache !== 'undefined') { | |||
| this.templateCache.clear(); | |||
| } | |||
| }; | |||
| /** | |||
| @@ -502,13 +515,15 @@ | |||
| * that is generated from the parse. | |||
| */ | |||
| Writer.prototype.parse = function parse (template, tags) { | |||
| var cache = this.cache; | |||
| var cache = this.templateCache; | |||
| var cacheKey = template + ':' + (tags || mustache.tags).join(':'); | |||
| var tokens = cache[cacheKey]; | |||
| if (tokens == null) | |||
| tokens = cache[cacheKey] = parseTemplate(template, tags); | |||
| var isCacheEnabled = typeof cache !== 'undefined'; | |||
| var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined; | |||
| if (tokens == undefined) { | |||
| tokens = parseTemplate(template, tags); | |||
| isCacheEnabled && cache.set(cacheKey, tokens); | |||
| } | |||
| return tokens; | |||
| }; | |||
| @@ -660,7 +675,21 @@ | |||
| to_html: undefined, | |||
| Scanner: undefined, | |||
| Context: undefined, | |||
| Writer: undefined | |||
| Writer: undefined, | |||
| /** | |||
| * Allows a user to override the default caching strategy, by providing an | |||
| * object with set, get and clear methods. This can also be used to disable | |||
| * the cache by setting it to the literal `undefined`. | |||
| */ | |||
| set templateCache (cache) { | |||
| defaultWriter.templateCache = cache; | |||
| }, | |||
| /** | |||
| * Gets the default or overridden caching object from the default writer. | |||
| */ | |||
| get templateCache () { | |||
| return defaultWriter.templateCache; | |||
| } | |||
| }; | |||
| // All high-level mustache.* functions use this writer. | |||
| @@ -479,14 +479,27 @@ Context.prototype.lookup = function lookup (name) { | |||
| * avoid the need to parse the same template twice. | |||
| */ | |||
| function Writer () { | |||
| this.cache = {}; | |||
| this.templateCache = { | |||
| _cache: {}, | |||
| set: function set (key, value) { | |||
| this._cache[key] = value; | |||
| }, | |||
| get: function get (key) { | |||
| return this._cache[key]; | |||
| }, | |||
| clear: function clear () { | |||
| this._cache = {}; | |||
| } | |||
| }; | |||
| } | |||
| /** | |||
| * Clears all cached templates in this writer. | |||
| */ | |||
| Writer.prototype.clearCache = function clearCache () { | |||
| this.cache = {}; | |||
| if (typeof this.templateCache !== 'undefined') { | |||
| this.templateCache.clear(); | |||
| } | |||
| }; | |||
| /** | |||
| @@ -495,13 +508,15 @@ Writer.prototype.clearCache = function clearCache () { | |||
| * that is generated from the parse. | |||
| */ | |||
| Writer.prototype.parse = function parse (template, tags) { | |||
| var cache = this.cache; | |||
| var cache = this.templateCache; | |||
| var cacheKey = template + ':' + (tags || mustache.tags).join(':'); | |||
| var tokens = cache[cacheKey]; | |||
| if (tokens == null) | |||
| tokens = cache[cacheKey] = parseTemplate(template, tags); | |||
| var isCacheEnabled = typeof cache !== 'undefined'; | |||
| var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined; | |||
| if (tokens == undefined) { | |||
| tokens = parseTemplate(template, tags); | |||
| isCacheEnabled && cache.set(cacheKey, tokens); | |||
| } | |||
| return tokens; | |||
| }; | |||
| @@ -653,7 +668,21 @@ var mustache = { | |||
| to_html: undefined, | |||
| Scanner: undefined, | |||
| Context: undefined, | |||
| Writer: undefined | |||
| Writer: undefined, | |||
| /** | |||
| * Allows a user to override the default caching strategy, by providing an | |||
| * object with set, get and clear methods. This can also be used to disable | |||
| * the cache by setting it to the literal `undefined`. | |||
| */ | |||
| set templateCache (cache) { | |||
| defaultWriter.templateCache = cache; | |||
| }, | |||
| /** | |||
| * Gets the default or overridden caching object from the default writer. | |||
| */ | |||
| get templateCache () { | |||
| return defaultWriter.templateCache; | |||
| } | |||
| }; | |||
| // All high-level mustache.* functions use this writer. | |||
| @@ -56,8 +56,14 @@ var expectations = { | |||
| : [ [ '#', 'foo', 0, 8, [ [ '#', 'a', 11, 17, [ [ 'text', ' ', 18, 22 ], [ 'name', 'b', 22, 27 ], [ 'text', '\n', 27, 28 ] ], 30 ] ], 37 ] ] | |||
| }; | |||
| var originalTemplateCache; | |||
| before(function () { | |||
| originalTemplateCache = Mustache.templateCache; | |||
| }); | |||
| beforeEach(function (){ | |||
| Mustache.clearCache(); | |||
| Mustache.templateCache = originalTemplateCache; | |||
| }); | |||
| describe('Mustache.parse', function () { | |||
| @@ -153,4 +159,47 @@ describe('Mustache.parse', function () { | |||
| }); | |||
| }); | |||
| describe('when parsing a template with caching disabled and the same tags second time, do not return the cached tokens', function () { | |||
| it('returns different tokens for the latter parse', function () { | |||
| Mustache.templateCache = undefined; | |||
| var template = '{{foo}}[bar]'; | |||
| var parsedResult1 = Mustache.parse(template); | |||
| var parsedResult2 = Mustache.parse(template); | |||
| assert.deepEqual(parsedResult1, parsedResult2); | |||
| assert.ok(parsedResult1 !== parsedResult2); | |||
| }); | |||
| }); | |||
| describe('when parsing a template with custom caching and the same tags second time, do not return the cached tokens', function () { | |||
| it('returns the same tokens for the latter parse', function () { | |||
| Mustache.templateCache = { | |||
| _cache: [], | |||
| set: function set (key, value) { | |||
| this._cache.push([key, value]); | |||
| }, | |||
| get: function get (key) { | |||
| var cacheLength = this._cache.length; | |||
| for (var i = 0; i < cacheLength; i++) { | |||
| var entry = this._cache[i]; | |||
| if (entry[0] === key) { | |||
| return entry[1]; | |||
| } | |||
| } | |||
| return undefined; | |||
| }, | |||
| clear: function clear () { | |||
| this._cache = []; | |||
| } | |||
| }; | |||
| var template = '{{foo}}[bar]'; | |||
| var parsedResult1 = Mustache.parse(template); | |||
| var parsedResult2 = Mustache.parse(template); | |||
| assert.deepEqual(parsedResult1, parsedResult2); | |||
| assert.ok(parsedResult1 === parsedResult2); | |||
| }); | |||
| }); | |||
| }); | |||