Skip to content

Commit

Permalink
Process paths regardless of accessor, & loop on computeLinkedPaths.
Browse files Browse the repository at this point in the history
Fixes #4542
  • Loading branch information
kevinpschaaf committed Apr 18, 2017
1 parent 1478a06 commit e2d1702
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 37 deletions.
60 changes: 25 additions & 35 deletions lib/mixins/property-effects.html
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions test/unit/path-effects.html
Expand Up @@ -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() {
Expand Down

0 comments on commit e2d1702

Please sign in to comment.