From f4486a263c9b64b562939ff111aa125e2d3f18cb Mon Sep 17 00:00:00 2001 From: herr kaste Date: Wed, 3 Feb 2016 23:02:25 +0100 Subject: [PATCH] Generalized approach supporting compute and observers --- src/lib/bind/effects.html | 34 ++++++++++++++----- src/standard/annotations.html | 4 --- src/standard/effectBuilder.html | 35 ++++++++++++++++++-- test/unit/bind.html | 58 +++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 16 deletions(-) diff --git a/src/lib/bind/effects.html b/src/lib/bind/effects.html index 06be143364..be9b38936d 100644 --- a/src/lib/bind/effects.html +++ b/src/lib/bind/effects.html @@ -67,6 +67,10 @@ if (args) { fn.apply(this, args); } + } else if (effect.dynamicFn) { + // dynamic functions can be just like every other property `undefined` + // so we MUST ignore an undefined value here. (That's totally the + // same guard we use within `_marshalArgs` and part of the spec.) } else { this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined')); @@ -74,15 +78,20 @@ }, _computeEffect: function(source, value, effect) { - var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); - if (args) { - var fn = this[effect.method]; - if (fn) { - this.__setProperty(effect.name, fn.apply(this, args)); - } else { - this._warn(this._logf('_computeEffect', 'compute method `' + - effect.method + '` not defined')); + var fn = this[effect.method]; + if (fn) { + var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); + if (args) { + var computedvalue = fn.apply(this, args); + this.__setProperty(effect.name, computedvalue); } + } else if (effect.dynamicFn) { + // dynamic functions can be just like every other property `undefined` + // so we MUST ignore an undefined value here. (That's totally the + // same guard we use within `_marshalArgs` and part of the spec.) + } else { + this._warn(this._logf('_computeEffect', 'compute method `' + + effect.method + '` not defined')); } }, @@ -98,6 +107,10 @@ } this._applyEffectValue(effect, computedvalue); } + } else if (effect.dynamicFn) { + // dynamic functions can be just like every other property `undefined` + // so we MUST ignore an undefined value here. (That's totally the + // same guard we use within `_marshalArgs` and part of the spec.) } else { computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined')); @@ -109,6 +122,9 @@ _marshalArgs: function(model, effect, path, value) { var values = []; var args = effect.args; + // Actually we should return early as soon as we see an `undefined`, + // but dom-repeat relies on this behavior. + var bailoutEarly = (args.length > 1 || effect.dynamicFn); for (var i=0, l=args.length; i 1 && v === undefined) { + if (bailoutEarly && v === undefined) { return; } if (arg.wildcard) { diff --git a/src/standard/annotations.html b/src/standard/annotations.html index 8c14137fa9..3743c48af0 100644 --- a/src/standard/annotations.html +++ b/src/standard/annotations.html @@ -147,10 +147,6 @@ if (!p.literal) { var signature = this._parseMethod(p.value); if (signature) { - if (this.properties[signature.method]) { - signature.dynamicFn = true; - signature.static = false; - } p.signature = signature; } else { p.model = this._modelForPath(p.value); diff --git a/src/standard/effectBuilder.html b/src/standard/effectBuilder.html index 0363527581..749addc0fe 100644 --- a/src/standard/effectBuilder.html +++ b/src/standard/effectBuilder.html @@ -79,14 +79,27 @@ _addComputedEffect: function(name, expression) { var sig = this._parseMethod(expression); + + var dynamicFn = sig.dynamicFn; + for (var i=0, arg; (i