From 110b248ce1344a0cda7792566ecca3aab9aeadad Mon Sep 17 00:00:00 2001 From: Brian M Hunt Date: Thu, 14 Aug 2014 19:39:05 -0400 Subject: [PATCH 1/2] Add caching of data-bind string functions --- dist/knockout-secure-binding.js | 11 ++++++--- spec/knockout_secure_binding_spec.js | 37 ++++++++++++++++++++++++++++ src/provider.js | 11 ++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/dist/knockout-secure-binding.js b/dist/knockout-secure-binding.js index 789df57..17cc1a0 100644 --- a/dist/knockout-secure-binding.js +++ b/dist/knockout-secure-binding.js @@ -904,9 +904,8 @@ function secureBindingsProvider(options) { // the binding classes -- defaults to ko bindingsHandlers this.bindings = options.bindings || ko.bindingHandlers; - // Cache the result of parsing binding strings. - // TODO - // this.cache = {}; + // A cache across the bindings provider instance. + this.cache = {} } function registerBindings(newBindings) { @@ -974,7 +973,11 @@ function getBindingAccessors(node, context) { } if (sbind_string) { - bindings = parser.parse(sbind_string || ''); + bindings = this.cache[sbind_string]; + if (!bindings) { + bindings = this.cache[sbind_string] + = parser.parse(sbind_string || ''); + } } // emulate ko.components.addBindingsForCustomElement(bindings, node, diff --git a/spec/knockout_secure_binding_spec.js b/spec/knockout_secure_binding_spec.js index 7dc71f5..72bd158 100644 --- a/spec/knockout_secure_binding_spec.js +++ b/spec/knockout_secure_binding_spec.js @@ -728,6 +728,43 @@ describe("the bindings parser", function () { }) }) +describe("the parser cache", function () { + var instance, div; + beforeEach(function () { + instance = new ko.secureBindingsProvider(); + div = document.createElement("div"); + }); + it("caches binding strings", function () { + div.setAttribute('data-sbind', 'x: 123'); + instance.getBindingAccessors(div, {}) + assert.deepEqual(Object.keys(instance.cache), ["x: 123"]) + }) + it("repeated calls return same item", function () { + var key = 'x: 2'; + div.setAttribute('data-sbind', key); + var ba1 = instance.getBindingAccessors(div, {}); + var ba2 = instance.getBindingAccessors(div, {}); + assert.strictEqual(ba1, ba2, 'bak') + assert.strictEqual(ba1, instance.cache[key], 'bik') + }) + it("respects nested lookups"), function () { + ko.bindingProvider.instance = instance; + div.innerHTML = + "" + + "" + + "" + + ""; + var view = { + X: ko.observable(3), + Y: { + X: ko.observable(4), + } + }; + ko.applyBindings(view, div); + assert.equal(div.innerHTML, '') + }) +}) + describe("the parsing of expressions", function () { it("works with explicit braces ( )", function () { var binding = "attr : (x)", diff --git a/src/provider.js b/src/provider.js index e9c1ebc..104bf26 100644 --- a/src/provider.js +++ b/src/provider.js @@ -17,9 +17,8 @@ function secureBindingsProvider(options) { // the binding classes -- defaults to ko bindingsHandlers this.bindings = options.bindings || ko.bindingHandlers; - // Cache the result of parsing binding strings. - // TODO - // this.cache = {}; + // A cache across the bindings provider instance. + this.cache = {} } function registerBindings(newBindings) { @@ -87,7 +86,11 @@ function getBindingAccessors(node, context) { } if (sbind_string) { - bindings = parser.parse(sbind_string || ''); + bindings = this.cache[sbind_string]; + if (!bindings) { + bindings = this.cache[sbind_string] + = parser.parse(sbind_string || ''); + } } // emulate ko.components.addBindingsForCustomElement(bindings, node, From 3ea0ab8adf6501c62d1753acf818609ec9d9e647 Mon Sep 17 00:00:00 2001 From: Brian M Hunt Date: Fri, 15 Aug 2014 09:23:29 -0400 Subject: [PATCH 2/2] fix syntax error --- spec/knockout_secure_binding_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/knockout_secure_binding_spec.js b/spec/knockout_secure_binding_spec.js index 72bd158..44bfee3 100644 --- a/spec/knockout_secure_binding_spec.js +++ b/spec/knockout_secure_binding_spec.js @@ -747,7 +747,7 @@ describe("the parser cache", function () { assert.strictEqual(ba1, ba2, 'bak') assert.strictEqual(ba1, instance.cache[key], 'bik') }) - it("respects nested lookups"), function () { + it("respects nested lookups", function () { ko.bindingProvider.instance = instance; div.innerHTML = "" +