Skip to content

Commit

Permalink
Expose bare minimum to add effects dynamically.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaste committed Feb 28, 2016
1 parent 4f3f463 commit 37e987f
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/lib/template/templatizer.html
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,14 @@
_createHostPropEffector: function(prop) {
var prefix = this._parentPropPrefix;
return function(source, value) {
if (source !== prop) return;
this.dataHost._templatized[prefix + prop] = value;
};
},

_createInstancePropEffector: function(prop) {
return function(source, value, old, fromAbove) {
if (source !== prop) return;
if (!fromAbove) {
this.dataHost._forwardInstanceProp(this, prop, value);
}
Expand Down
27 changes: 27 additions & 0 deletions src/standard/effectBuilder.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,33 @@
var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect);
// memoize path function for faster lookup.
prop.pathFn = this['_' + prop.kind + 'PathEffect'];
return prop;
},

addCustomEffect: function(property, fn) {
// In case this is the first effect of the property, we MUST create the
// underlying trigger machinery by hand.
var effects = Polymer.Bind.ensurePropertyEffects(this, property);
if (effects.length === 0) {
// The current value will be masked by the descriptor, read it ...
var val = this[property];
Polymer.Bind._createAccessors(this, property, effects);
// ... and apply on our data store
this.__data__[property] = val;
}
// Theoretically the effects must be sorted again, but `function`-effects
// are executed last, so we can skip this for now.
return this._addPropertyEffect(property, 'function', fn);
},

removeCustomEffect: function(property, fx) {
var effects = this._propertyEffects && this._propertyEffects[property];
if (effects) {
var index = effects.indexOf(fx);
if (index !== -1) {
effects.splice(index, 1);
}
}
},

// prototyping
Expand Down
4 changes: 4 additions & 0 deletions src/standard/notify-path.html
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@
}
},

_functionPathEffect: function(path, value, effect) {
Polymer.Bind._functionEffect.call(this, path, value, effect);
},

_pathMatchesEffect: function(path, effect) {
var effectArg = effect.trigger.name;
return (effectArg == path) ||
Expand Down
4 changes: 4 additions & 0 deletions test/unit/bind-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,7 @@
});
</script>
</dom-module>

<script>
Polymer({is: 'x-custom-effect'});
</script>
75 changes: 75 additions & 0 deletions test/unit/bind.html
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,81 @@
});
});

suite('custom user effects', function() {

test('Add custom effect', function() {
var el = document.createElement('x-custom-effect');

var called = 0;
el.addCustomEffect('foo', function(path, value, old) {
called += 1;
assert.equal(path, 'foo');
assert.equal(value, 'bar');
assert.equal(old, undefined);
});

el.foo = 'bar';
assert.equal(called, 1);
});

test('Remove custom effect', function() {
var el = document.createElement('x-custom-effect');

var called = 0;
var fx = el.addCustomEffect('foo', function() {
called += 1;
});

el.removeCustomEffect('foo', fx);

el.foo = 'bar';
assert.equal(called, 0);
});

test('Ensure old values are sent', function() {
var el = document.createElement('x-custom-effect');
el.foo = 'bar';

var called = 0;
el.addCustomEffect('foo', function(path, value, old) {
called += 1;
assert.equal(old, 'bar');
});

el.foo = 'quux';
assert.equal(called, 1);
});

test('Ensure path effects can be seen', function() {
var el = document.createElement('x-custom-effect');
el.foo = {bar: 'quux'};

var called = 0;
el.addCustomEffect('foo', function(path, value, old) {
called += 1;
assert.equal(path, 'foo.bar');
assert.equal(value, 'quod');
assert.equal(old, undefined); // always undefined for structured paths!
});

el.set('foo.bar', 'quod');
assert.equal(called, 1);
});

test('Ensure independence', function() {
var el1 = document.createElement('x-custom-effect');
var called = 0;
el1.addCustomEffect('foo', function() {
called += 1;
});

var el2 = document.createElement('x-custom-effect');

el2.foo = 'bar';
assert.equal(called, 0);
});
});

</script>

</body>
Expand Down

0 comments on commit 37e987f

Please sign in to comment.