| @@ -493,6 +493,7 @@ | |||||
| */ | */ | ||||
| function Writer () { | function Writer () { | ||||
| this.cache = {}; | this.cache = {}; | ||||
| this.cacheEnabled = true; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -502,19 +503,34 @@ | |||||
| this.cache = {}; | this.cache = {}; | ||||
| }; | }; | ||||
| /** | |||||
| * Disables or enables template caching for this writer. | |||||
| */ | |||||
| Writer.prototype.toggleCache = function toggleCache (enable) { | |||||
| // If we are disabling the cache, clear it. | |||||
| if (!enable) { | |||||
| this.clearCache(); | |||||
| } | |||||
| this.cacheEnabled = !!enable; | |||||
| }; | |||||
| /** | /** | ||||
| * Parses and caches the given `template` according to the given `tags` or | * Parses and caches the given `template` according to the given `tags` or | ||||
| * `mustache.tags` if `tags` is omitted, and returns the array of tokens | * `mustache.tags` if `tags` is omitted, and returns the array of tokens | ||||
| * that is generated from the parse. | * that is generated from the parse. | ||||
| */ | */ | ||||
| Writer.prototype.parse = function parse (template, tags) { | Writer.prototype.parse = function parse (template, tags) { | ||||
| var tokens = null; | |||||
| var cache = this.cache; | var cache = this.cache; | ||||
| var cacheKey = template + ':' + (tags || mustache.tags).join(':'); | var cacheKey = template + ':' + (tags || mustache.tags).join(':'); | ||||
| var tokens = cache[cacheKey]; | |||||
| if (tokens == null) | |||||
| tokens = cache[cacheKey] = parseTemplate(template, tags); | |||||
| tokens = this.cacheEnabled ? cache[cacheKey] : null; | |||||
| if (tokens == null) { | |||||
| tokens = parseTemplate(template, tags); | |||||
| if (this.cacheEnabled) { | |||||
| cache[cacheKey] = tokens; | |||||
| } | |||||
| } | |||||
| return tokens; | return tokens; | ||||
| }; | }; | ||||
| @@ -669,6 +685,13 @@ | |||||
| return defaultWriter.clearCache(); | return defaultWriter.clearCache(); | ||||
| }; | }; | ||||
| /** | |||||
| * Disables or enables template caching for this writer. | |||||
| */ | |||||
| mustache.toggleCache = function toggleCache (value) { | |||||
| return defaultWriter.toggleCache(value); | |||||
| }; | |||||
| /** | /** | ||||
| * Parses and caches the given template in the default writer and returns the | * Parses and caches the given template in the default writer and returns the | ||||
| * array of tokens it contains. Doing this ahead of time avoids the need to | * array of tokens it contains. Doing this ahead of time avoids the need to | ||||
| @@ -58,6 +58,7 @@ var expectations = { | |||||
| beforeEach(function (){ | beforeEach(function (){ | ||||
| Mustache.clearCache(); | Mustache.clearCache(); | ||||
| Mustache.toggleCache(true); | |||||
| }); | }); | ||||
| describe('Mustache.parse', function () { | describe('Mustache.parse', function () { | ||||
| @@ -153,4 +154,43 @@ 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.toggleCache(false); | |||||
| 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.toggleCache(false); | |||||
| var parse = Mustache.Writer.prototype.parse; | |||||
| var cache = new Map(); | |||||
| Mustache.Writer.prototype.parse = function (template, tags) { | |||||
| var cacheKey = template + ':' + (tags || Mustache.tags).join(':'); | |||||
| var fromCache = cache.get(cacheKey); | |||||
| if (fromCache) { | |||||
| return fromCache; | |||||
| } else { | |||||
| var tokens = parse.call(this, template, tags); | |||||
| cache.set(cacheKey, tokens); | |||||
| return tokens; | |||||
| } | |||||
| }; | |||||
| var template = '{{foo}}[bar]'; | |||||
| var parsedResult1 = Mustache.parse(template); | |||||
| var parsedResult2 = Mustache.parse(template); | |||||
| assert.deepEqual(parsedResult1, parsedResult2); | |||||
| assert.ok(parsedResult1 === parsedResult2); | |||||
| }); | |||||
| }); | |||||
| }); | }); | ||||