Skip to content

Commit 21383a3

Browse files
committed
Fix negation when a negated binding is changed
1 parent 9968266 commit 21383a3

File tree

7 files changed

+26
-110
lines changed

7 files changed

+26
-110
lines changed

src/lib/bind/accessors.html

+11-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
_notifyChange: function(source, event, value) {
2424
value = value === undefined ? this[source] : value;
2525
event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed';
26-
this.fire(event, {value: value},
26+
this.fire(event, {value: value},
2727
{bubbles: false, cancelable: false, _useCache: true});
2828
},
2929

@@ -189,12 +189,12 @@
189189
return name[0].toUpperCase() + name.substring(1);
190190
},
191191

192-
_addAnnotatedListener: function(model, index, property, path, event) {
192+
_addAnnotatedListener: function(model, index, property, path, event, negated) {
193193
if (!model._bindListeners) {
194194
model._bindListeners = [];
195195
}
196196
var fn = this._notedListenerFactory(property, path,
197-
this._isStructured(path));
197+
this._isStructured(path), negated);
198198
var eventName = event ||
199199
(Polymer.CaseMap.camelToDashCase(property) + '-changed');
200200
model._bindListeners.push({
@@ -214,17 +214,22 @@
214214
return e.path && e.path[0] !== target;
215215
},
216216

217-
_notedListenerFactory: function(property, path, isStructured) {
217+
_notedListenerFactory: function(property, path, isStructured, negated) {
218218
return function(target, value, targetPath) {
219219
if (targetPath) {
220220
this._notifyPath(this._fixPath(path, property, targetPath), value);
221221
} else {
222222
// TODO(sorvell): even though we have a `value` argument, we *must*
223223
// lookup the current value of the property. Multiple listeners and
224-
// queued events during configuration can theoretically lead to
225-
// divergence of the passed value from the current value, but we
224+
// queued events during configuration can theoretically lead to
225+
// divergence of the passed value from the current value, but we
226226
// really need to track down a specific case where this happens.
227227
value = target[property];
228+
229+
if (negated) {
230+
value = !value;
231+
}
232+
228233
if (!isStructured) {
229234
this[path] = value;
230235
} else {

src/lib/bind/effects.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
effect.kind != 'attribute' &&
1818
effect.kind != 'text' &&
1919
!effect.isCompound &&
20-
effect.parts[0].mode === '{' &&
21-
!effect.parts[0].negate;
20+
effect.parts[0].mode === '{';
2221
},
2322

2423
_annotationEffect: function(source, value, effect) {

src/standard/effectBuilder.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
if (Polymer.Bind._shouldAddListener(note)) {
137137
// <node>.on.<dash-case-property>-changed: <path> = e.detail.value
138138
Polymer.Bind._addAnnotatedListener(this, index,
139-
note.name, note.parts[0].value, note.parts[0].event);
139+
note.name, note.parts[0].value, note.parts[0].event, note.parts[0].negate);
140140
}
141141
for (var i=0; i<note.parts.length; i++) {
142142
var part = note.parts[i];

test/unit/bind-elements.html

+6
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@
293293
notifyingvalue="{{computedValue}}"
294294
computedvalue="{{value}}">
295295
</x-basic>
296+
<x-basic id="basic4"
297+
notifyingvalue="{{!negatedValue}}">
298+
</x-basic>
296299
</template>
297300
<script>
298301
Polymer({
@@ -313,6 +316,9 @@
313316
},
314317
computedValue: {
315318
computed: 'computeComputedValue(a, b)'
319+
},
320+
negatedValue: {
321+
value: false
316322
}
317323
},
318324
created: function() {

test/unit/bind.html

+7
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,13 @@
388388
assert.equal(listener.getCalls()[0].args[0].detail.value, 678);
389389
});
390390

391+
test('negated binding update negates value for parent', function() {
392+
assert.equal(el.negatedValue, false);
393+
assert.equal(el.$.basic4.notifyingvalue, true);
394+
el.$.basic4.notifyingvalue = false;
395+
assert.equal(el.negatedValue, true);
396+
});
397+
391398
});
392399

393400
suite('1-way binding effects between elements', function() {

test/unit/notify-path-elements.html

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
<template>
1515
<x-basic id="basic1" notifying-value="{{obj.value}}" attrvalue$="{{obj.value}}" othervalue="{{obj.value2}}"></x-basic>
1616
<x-basic id="basic2" notifying-value="{{obj.value}}" attrvalue$="{{obj.value}}"></x-basic>
17-
<x-basic id="basic3" notifying-value="{{!obj.value}}" attrvalue$="{{!obj.value}}"></x-basic>
1817
</template>
1918
<script>
2019
Polymer({

test/unit/notify-path.html

-100
Original file line numberDiff line numberDiff line change
@@ -234,106 +234,6 @@
234234
verifyNonNestedObserversOutput();
235235
});
236236

237-
test('negation', function() {
238-
// Setup
239-
var nested = {
240-
obj: {
241-
value: false
242-
}
243-
};
244-
// Do the thing
245-
el.nested = nested;
246-
// Verify
247-
assert.equal(el.$.basic.notifyingValue, false);
248-
assert.equal(el.$.compose.$.basic1.notifyingValue, false);
249-
assert.equal(el.$.compose.$.basic2.notifyingValue, false);
250-
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
251-
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, false);
252-
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, false);
253-
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, true);
254-
assert.equal(el.$.basic.hasAttribute('attrvalue'), false);
255-
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), false);
256-
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), false);
257-
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), true);
258-
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), false);
259-
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), false);
260-
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), true);
261-
262-
// Do another thing
263-
el.$.basic.notifyingValue = true;
264-
// Verify
265-
assert.equal(el.$.basic.notifyingValue, true);
266-
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
267-
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
268-
assert.equal(el.$.compose.$.basic3.notifyingValue, false);
269-
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
270-
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
271-
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
272-
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
273-
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
274-
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
275-
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
276-
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
277-
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
278-
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
279-
280-
// Do another thing
281-
el.$.forward.$.compose.$.basic1.notifyingValue = false;
282-
// Verify
283-
assert.equal(el.$.basic.notifyingValue, false);
284-
assert.equal(el.$.compose.$.basic1.notifyingValue, false);
285-
assert.equal(el.$.compose.$.basic2.notifyingValue, false);
286-
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
287-
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, false);
288-
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, false);
289-
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, true);
290-
assert.equal(el.$.basic.hasAttribute('attrvalue'), false);
291-
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), false);
292-
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), false);
293-
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), true);
294-
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), false);
295-
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), false);
296-
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), true);
297-
298-
// Do another thing
299-
el.set('nested.obj.value', true);
300-
// Verify
301-
assert.equal(el.$.basic.notifyingValue, true);
302-
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
303-
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
304-
assert.equal(el.$.compose.$.basic3.notifyingValue, false);
305-
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
306-
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
307-
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
308-
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
309-
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
310-
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
311-
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
312-
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
313-
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
314-
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
315-
316-
// Do another thing
317-
// no two way binding through negation
318-
el.$.compose.$.basic3.notifyingValue = true;
319-
// Verify
320-
assert.equal(el.$.basic.notifyingValue, true);
321-
assert.equal(el.$.compose.$.basic1.notifyingValue, true);
322-
assert.equal(el.$.compose.$.basic2.notifyingValue, true);
323-
assert.equal(el.$.compose.$.basic3.notifyingValue, true);
324-
assert.equal(el.$.forward.$.compose.$.basic1.notifyingValue, true);
325-
assert.equal(el.$.forward.$.compose.$.basic2.notifyingValue, true);
326-
assert.equal(el.$.forward.$.compose.$.basic3.notifyingValue, false);
327-
assert.equal(el.$.basic.hasAttribute('attrvalue'), true);
328-
assert.equal(el.$.compose.$.basic1.hasAttribute('attrvalue'), true);
329-
assert.equal(el.$.compose.$.basic2.hasAttribute('attrvalue'), true);
330-
assert.equal(el.$.compose.$.basic3.hasAttribute('attrvalue'), false);
331-
assert.equal(el.$.forward.$.compose.$.basic1.hasAttribute('attrvalue'), true);
332-
assert.equal(el.$.forward.$.compose.$.basic2.hasAttribute('attrvalue'), true);
333-
assert.equal(el.$.forward.$.compose.$.basic3.hasAttribute('attrvalue'), false);
334-
335-
});
336-
337237
test('simlarly named properties', function() {
338238
var nested = {
339239
obj: {

0 commit comments

Comments
 (0)