Merge pull request #3352 from TimvdLippe/negated-notifying-bindings

Fix negation when a negated binding is changed
This commit is contained in:
Daniel Freedman 2016-02-17 10:18:56 -08:00
commit 8f58ff632b
7 changed files with 23 additions and 107 deletions

View File

@ -189,12 +189,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return name[0].toUpperCase() + name.substring(1);
},
_addAnnotatedListener: function(model, index, property, path, event) {
_addAnnotatedListener: function(model, index, property, path, event, negated) {
if (!model._bindListeners) {
model._bindListeners = [];
}
var fn = this._notedListenerFactory(property, path,
this._isStructured(path));
this._isStructured(path), negated);
var eventName = event ||
(Polymer.CaseMap.camelToDashCase(property) + '-changed');
model._bindListeners.push({
@ -214,7 +214,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return e.path && e.path[0] !== target;
},
_notedListenerFactory: function(property, path, isStructured) {
_notedListenerFactory: function(property, path, isStructured, negated) {
return function(target, value, targetPath) {
if (targetPath) {
this._notifyPath(this._fixPath(path, property, targetPath), value);
@ -225,6 +225,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
// divergence of the passed value from the current value, but we
// really need to track down a specific case where this happens.
value = target[property];
if (negated) {
value = !value;
}
if (!isStructured) {
this[path] = value;
} else {

View File

@ -17,8 +17,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
effect.kind != 'attribute' &&
effect.kind != 'text' &&
!effect.isCompound &&
effect.parts[0].mode === '{' &&
!effect.parts[0].negate;
effect.parts[0].mode === '{';
},
_annotationEffect: function(source, value, effect) {

View File

@ -136,7 +136,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
if (Polymer.Bind._shouldAddListener(note)) {
// <node>.on.<dash-case-property>-changed: <path> = e.detail.value
Polymer.Bind._addAnnotatedListener(this, index,
note.name, note.parts[0].value, note.parts[0].event);
note.name, note.parts[0].value, note.parts[0].event, note.parts[0].negate);
}
for (var i=0; i<note.parts.length; i++) {
var part = note.parts[i];

View File

@ -293,6 +293,9 @@
notifyingvalue="{{computedValue}}"
computedvalue="{{value}}">
</x-basic>
<x-basic id="basic4"
notifyingvalue="{{!negatedValue}}">
</x-basic>
</template>
<script>
Polymer({
@ -313,6 +316,9 @@
},
computedValue: {
computed: 'computeComputedValue(a, b)'
},
negatedValue: {
value: false
}
},
created: function() {

View File

@ -388,6 +388,13 @@ suite('2-way binding effects between elements', function() {
assert.equal(listener.getCalls()[0].args[0].detail.value, 678);
});
test('negated binding update negates value for parent', function() {
assert.equal(el.negatedValue, false);
assert.equal(el.$.basic4.notifyingvalue, true);
el.$.basic4.notifyingvalue = false;
assert.equal(el.negatedValue, true);
});
});
suite('1-way binding effects between elements', function() {

View File

@ -14,7 +14,6 @@
<template>
<x-basic id="basic1" notifying-value="{{obj.value}}" attrvalue$="{{obj.value}}" othervalue="{{obj.value2}}"></x-basic>
<x-basic id="basic2" notifying-value="{{obj.value}}" attrvalue$="{{obj.value}}"></x-basic>
<x-basic id="basic3" notifying-value="{{!obj.value}}" attrvalue$="{{!obj.value}}"></x-basic>
</template>
<script>
Polymer({

View File

@ -234,106 +234,6 @@ suite('basic path bindings', function() {
verifyNonNestedObserversOutput();
});
test('negation', function() {
// Setup
var nested = {
obj: {
value: false
}
};
// Do the thing
el.nested = nested;
// Verify
assert.equal(el.$.basic.notifyingValue, false);
assert.equal(el.$.compose.$.basic1.notifyingValue, false);
assert.equal(el.$.compose.$.basic2.notifyingValue, false);
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, true);
assert.equal(el.$.basic.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), true);
// Do another thing
el.$.basic.notifyingValue = true;
// Verify
assert.equal(el.$.basic.notifyingValue, true);
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.compose.$.basic3.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
// Do another thing
el.$.forward.$.compose.$.basic1.notifyingValue = false;
// Verify
assert.equal(el.$.basic.notifyingValue, false);
assert.equal(el.$.compose.$.basic1.notifyingValue, false);
assert.equal(el.$.compose.$.basic2.notifyingValue, false);
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, true);
assert.equal(el.$.basic.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), false);
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), true);
// Do another thing
el.set('nested.obj.value', true);
// Verify
assert.equal(el.$.basic.notifyingValue, true);
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.compose.$.basic3.notifyingValue, false);
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
// Do another thing
// no two way binding through negation
el.$.compose.$.basic3.notifyingValue = true;
// Verify
assert.equal(el.$.basic.notifyingValue, true);
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
});
test('simlarly named properties', function() {
var nested = {
obj: {