diff --git a/lib/mixins/property-effects.html b/lib/mixins/property-effects.html
index 7241725d1f..560d9cf312 100644
--- a/lib/mixins/property-effects.html
+++ b/lib/mixins/property-effects.html
@@ -371,12 +371,13 @@
*/
function runComputedEffects(inst, changedProps, oldProps, hasPaths) {
let computeEffects = inst.__computeEffects;
- if (computeEffects) {
- let inputProps = changedProps;
- while (runEffects(inst, computeEffects, inputProps, oldProps, hasPaths)) {
+ let inputProps = changedProps;
+ while (inputProps) {
+ computeEffects && runEffects(inst, computeEffects, inputProps, oldProps, hasPaths);
+ computeLinkedPaths(inst, inputProps, hasPaths);
+ if ((inputProps = inst.__dataPending)) {
Object.assign(oldProps, inst.__dataOld);
Object.assign(changedProps, inst.__dataPending);
- inputProps = inst.__dataPending;
inst.__dataPending = null;
}
}
@@ -416,21 +417,16 @@
function computeLinkedPaths(inst, changedProps, hasPaths) {
let links;
if (hasPaths && (links = inst.__dataLinkedPaths)) {
- const cache = inst.__dataTemp;
let link;
for (let a in links) {
let b = links[a];
for (let path in changedProps) {
if (Polymer.Path.isDescendant(a, path)) {
link = Polymer.Path.translate(a, b, path);
- cache[link] = changedProps[link] = changedProps[path];
- let notifyProps = inst.__dataToNotify || (inst.__dataToNotify = {});
- notifyProps[link] = true;
+ inst._setPendingPropertyOrPath(link, changedProps[path], true, true);
} else if (Polymer.Path.isDescendant(b, path)) {
link = Polymer.Path.translate(b, a, path);
- cache[link] = changedProps[link] = changedProps[path];
- let notifyProps = inst.__dataToNotify || (inst.__dataToNotify = {});
- notifyProps[link] = true;
+ inst._setPendingPropertyOrPath(link, changedProps[path], true, true);
}
}
}
@@ -1292,32 +1288,28 @@
*/
_setPendingPropertyOrPath(path, value, shouldNotify, isPathNotification) {
let rootProperty = Polymer.Path.root(Array.isArray(path) ? path[0] : path);
- let hasAccessor = this.__dataHasAccessor && this.__dataHasAccessor[rootProperty];
- let isPath = (rootProperty !== path);
- if (hasAccessor) {
- if (isPath) {
- if (!isPathNotification) {
- // Dirty check changes being set to a path against the actual object,
- // since this is the entry point for paths into the system; from here
- // the only dirty checks are against the `__dataTemp` cache to prevent
- // duplicate work in the same turn only. Note, if this was a notification
- // of a change already set to a path (isPathNotification: true),
- // we always let the change through and skip the `set` since it was
- // already dirty checked at the point of entry and the underlying
- // object has already been updated
- let old = Polymer.Path.get(this, path);
- path = /** @type {string} */ (Polymer.Path.set(this, path, value));
- // Use property-accessor's simpler dirty check
- if (!path || !super._shouldPropertyChange(path, value, old)) {
- return false;
- }
+ if (rootProperty !== path) {
+ if (!isPathNotification) {
+ // Dirty check changes being set to a path against the actual object,
+ // since this is the entry point for paths into the system; from here
+ // the only dirty checks are against the `__dataTemp` cache to prevent
+ // duplicate work in the same turn only. Note, if this was a notification
+ // of a change already set to a path (isPathNotification: true),
+ // we always let the change through and skip the `set` since it was
+ // already dirty checked at the point of entry and the underlying
+ // object has already been updated
+ let old = Polymer.Path.get(this, path);
+ path = /** @type {string} */ (Polymer.Path.set(this, path, value));
+ // Use property-accessor's simpler dirty check
+ if (!path || !super._shouldPropertyChange(path, value, old)) {
+ return false;
}
- this.__dataHasPaths = true;
}
+ this.__dataHasPaths = true;
return this._setPendingProperty(path, value, shouldNotify);
} else {
- if (isPath) {
- Polymer.Path.set(this, path, value);
+ if (this.__dataHasAccessor && this.__dataHasAccessor[rootProperty]) {
+ return this._setPendingProperty(path, value, shouldNotify);
} else {
this[path] = value;
}
@@ -1548,8 +1540,6 @@
this.__dataHasPaths = false;
// Compute properties
runComputedEffects(this, changedProps, oldProps, hasPaths);
- // Compute linked paths
- computeLinkedPaths(this, changedProps, hasPaths);
// Clear notify properties prior to possible reentry (propagate, observe),
// but after computing effects have a chance to add to them
let notifyProps = this.__dataToNotify;
diff --git a/test/unit/path-effects.html b/test/unit/path-effects.html
index b2db181140..c208b2d8b9 100644
--- a/test/unit/path-effects.html
+++ b/test/unit/path-effects.html
@@ -898,11 +898,15 @@
assert.equal(el.xChanged.callCount, 1);
assert.equal(el.yChanged.callCount, 1);
assert.equal(el.aChanged.callCount, 1);
- el.unlinkPaths('y');
el.set('a.foo', 2);
assert.equal(el.xChanged.callCount, 2);
- assert.equal(el.yChanged.callCount, 1);
+ assert.equal(el.yChanged.callCount, 2);
assert.equal(el.aChanged.callCount, 2);
+ el.unlinkPaths('y');
+ el.set('a.foo', 3);
+ assert.equal(el.xChanged.callCount, 3);
+ assert.equal(el.yChanged.callCount, 2);
+ assert.equal(el.aChanged.callCount, 3);
});
test('link two arrays', function() {