Skip to content

Commit

Permalink
Ensure properties are set one-by-one at startup.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpschaaf committed Feb 20, 2019
1 parent 4658b08 commit add7784
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 30 deletions.
48 changes: 41 additions & 7 deletions lib/mixins/property-effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,9 @@ function applyBindingValue(inst, node, binding, part, value) {
inst._enqueueClient(node);
}
}
} else {
} else if (!legacyNoBatch || inst.__dataReady) {
// In legacy no-batching mode, bindings applied before dataReady are
// equivalent to the "apply config" phase, which only set managed props
inst._setUnmanagedPropertyToNode(node, prop, value);
}
}
Expand Down Expand Up @@ -1555,7 +1557,30 @@ export const PropertyEffects = dedupingMixin(superClass => {
*/
_flushProperties() {
this.__dataCounter++;
super._flushProperties();
if (legacyNoBatch && !this.__dataReady) {
// The first time this element is being flushed, propagate pending
// data down the tree first; this approximates 1.x's distributeConfig
this._propagatePropertyChanges(this.__dataPending, {}, false);
// Flushing clients causes this element to become __dataReady
this._flushClients();
// Capture element data and flush properties one-by one to defeat
// Polymer 2.x's batched _propertiesChanged scheme; this approximates
// 1.x's applyConfig
const changedProps = this.__data;
const notify = this.__dataToNotify;
this.__data = {};
this.__dataPending = this.__dataToNotify = null;
for (let prop in changedProps) {
const value = changedProps[prop];
this.__data[prop] = value;
this.__dataPending = {[prop]: value};
this.__dataOld = {};
this.__dataToNotify = {[prop]: notify && notify[prop]};
super._flushProperties();
}
} else {
super._flushProperties();
}
this.__dataCounter--;
}

Expand Down Expand Up @@ -1698,12 +1723,21 @@ export const PropertyEffects = dedupingMixin(superClass => {
// ----------------------------
let hasPaths = this.__dataHasPaths;
this.__dataHasPaths = false;
let notifyProps;
// Compute properties
runComputedEffects(this, changedProps, oldProps, 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;
this.__dataToNotify = null;
if (legacyNoBatch) {
// When not batching, computed effects may re-enter, so capture
// notifying properties early
notifyProps = this.__dataToNotify;
this.__dataToNotify = null;
runEffects(this, this[TYPES.COMPUTE], changedProps, oldProps, hasPaths);
} else {
runComputedEffects(this, changedProps, oldProps, hasPaths);
// Clear notify properties prior to possible reentry (propagate, observe),
// but after computing effects have a chance to add to them
notifyProps = this.__dataToNotify;
this.__dataToNotify = null;
}
// Propagate properties to clients
this._propagatePropertyChanges(changedProps, oldProps, hasPaths);
// Flush clients
Expand Down
2 changes: 2 additions & 0 deletions test/runner.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
'unit/template-stamp.html',
'unit/strict-template-policy.html',
'unit/property-effects.html',
'unit/property-effects.html?legacyUndefined=true',
'unit/property-effects.html?legacyUndefined=true&legacyNoBatch=true',
'unit/property-effects-template.html',
'unit/path-effects.html',
'unit/shady.html',
Expand Down
4 changes: 3 additions & 1 deletion test/unit/property-effects-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ Polymer({
},

$computeTrickyFunctionFromLiterals: function(num, str) {
return this.computeFromLiterals(num, str);
assert.equal(num, 3);
assert.equal(str, 'foo');
return num + str;
},

computeFromTrickyLiterals: function(a, b) {
Expand Down
102 changes: 80 additions & 22 deletions test/unit/property-effects.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@
<script type="module">
import './property-effects-elements.js';
import { Polymer, html } from '../../polymer-legacy.js';
import { setSanitizeDOMValue, sanitizeDOMValue, setLegacyOptimizations } from '../../lib/utils/settings.js';
import { setSanitizeDOMValue, sanitizeDOMValue, setLegacyOptimizations, legacyUndefined, setLegacyUndefined, legacyNoBatch, setLegacyNoBatch } from '../../lib/utils/settings.js';
import { PropertyEffects } from '../../lib/mixins/property-effects.js';

setLegacyUndefined(Boolean(window.location.search.match('legacyUndefined')));
setLegacyNoBatch(Boolean(window.location.search.match('legacyNoBatch')));


suite('single-element binding effects', function() {

var el;
Expand Down Expand Up @@ -1234,7 +1238,9 @@
el.cpnd3 = {prop: 'cpnd3'};
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3');
el.cpnd4 = 'cpnd4';
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3literalComputedcpnd4');
assert.equal(el.$.boundProps.prop1,
legacyUndefined ?
'cpnd1cpnd2cpnd3' : 'cpnd1cpnd2cpnd3literalComputedcpnd4');
el.cpnd5 = 'cpnd5';
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3literalComputedcpnd5cpnd4');
});
Expand Down Expand Up @@ -1265,7 +1271,9 @@
el.cpnd3 = {prop: 'cpnd3'};
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'), 'cpnd1cpnd2cpnd3');
el.cpnd4 = 'cpnd4';
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'), 'cpnd1cpnd2cpnd3literalComputedcpnd4');
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'),
legacyUndefined ?
'cpnd1cpnd2cpnd3' : 'cpnd1cpnd2cpnd3literalComputedcpnd4');
el.cpnd5 = 'cpnd5';
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'), 'cpnd1cpnd2cpnd3literalComputedcpnd5cpnd4');
});
Expand Down Expand Up @@ -1302,7 +1310,9 @@
el.cpnd3 = {prop: 'cpnd3'};
assert.equal(el.$.compound1.textContent, 'cpnd1cpnd2cpnd3');
el.cpnd4 = 'cpnd4';
assert.equal(el.$.compound1.textContent, 'cpnd1cpnd2cpnd3literalComputedcpnd4');
assert.equal(el.$.compound1.textContent,
legacyUndefined ?
'cpnd1cpnd2cpnd3' : 'cpnd1cpnd2cpnd3literalComputedcpnd4');
el.cpnd5 = 'cpnd5';
assert.equal(el.$.compound1.textContent, 'cpnd1cpnd2cpnd3literalComputedcpnd5cpnd4');
// Once the binding evaluates back to '', it will in fact be ''
Expand Down Expand Up @@ -1770,29 +1780,57 @@
customElements.define('pe-method-observer', TestClass);
let el = document.createElement('pe-method-observer');
document.body.appendChild(el);
assert.equal(el.observer.callCount, 1);
assert.deepEqual(el.observer.getCall(0).args, [undefined, undefined]);
if (legacyUndefined) {
assert.equal(el.observer.callCount, 0);
} else {
assert.equal(el.observer.callCount, 1);
assert.deepEqual(el.observer.getCall(0).args, [undefined, undefined]);
}
assert.equal(el.pcSpy.callCount, 1);
el.a = 'a';
assert.equal(el.observer.callCount, 2);
assert.deepEqual(el.observer.getCall(1).args, ['a', undefined]);
if (legacyUndefined) {
assert.equal(el.observer.callCount, 0);
} else {
assert.equal(el.observer.callCount, 2);
assert.deepEqual(el.observer.getCall(1).args, ['a', undefined]);
}
assert.equal(el.pcSpy.callCount, 2);
el.b = {c: 'c'};
assert.equal(el.observer.callCount, 3);
assert.deepEqual(el.observer.getCall(2).args, ['a', 'c']);
if (legacyUndefined) {
assert.equal(el.observer.callCount, 1);
assert.deepEqual(el.observer.getCall(0).args, ['a', 'c']);
} else {
assert.equal(el.observer.callCount, 3);
assert.deepEqual(el.observer.getCall(2).args, ['a', 'c']);
}
assert.equal(el.pcSpy.callCount, 3);
el.setProperties({
a: 'A',
b: {c: 'C'}
});
assert.equal(el.observer.callCount, 4);
assert.deepEqual(el.observer.getCall(3).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 4);
if (legacyNoBatch && legacyUndefined) {
assert.equal(el.observer.callCount, 3);
assert.deepEqual(el.observer.getCall(1).args, ['A', 'c']);
assert.deepEqual(el.observer.getCall(2).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 5);
} else if (legacyUndefined) {
assert.equal(el.observer.callCount, 2);
assert.deepEqual(el.observer.getCall(1).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 4);
} else {
assert.equal(el.observer.callCount, 4);
assert.deepEqual(el.observer.getCall(3).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 4);
}

el.observer = sinon.spy();
assert.equal(el.observer.callCount, 1);
assert.deepEqual(el.observer.getCall(0).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 5);
if (legacyNoBatch && legacyUndefined) {
assert.equal(el.pcSpy.callCount, 6);
} else {
assert.equal(el.pcSpy.callCount, 5);
}
document.body.removeChild(el);
});

Expand All @@ -1810,23 +1848,43 @@
assert.equal(el.compute.callCount, 0);
assert.equal(el.pcSpy.callCount, 0);
el.a = 'a';
assert.equal(el.compute.callCount, 1);
assert.deepEqual(el.compute.getCall(0).args, ['a', undefined]);
assert.equal(el.prop, 'aundefined');
if (legacyUndefined) {
assert.equal(el.compute.callCount, 0);
} else {
assert.equal(el.compute.callCount, 1);
assert.deepEqual(el.compute.getCall(0).args, ['a', undefined]);
assert.equal(el.prop, 'aundefined');
}
assert.equal(el.pcSpy.callCount, 1);
el.b = {c: 'c'};
assert.equal(el.compute.callCount, 2);
assert.deepEqual(el.compute.getCall(1).args, ['a', 'c']);
if (legacyUndefined) {
assert.equal(el.compute.callCount, 1);
assert.deepEqual(el.compute.getCall(0).args, ['a', 'c']);
} else {
assert.equal(el.compute.callCount, 2);
assert.deepEqual(el.compute.getCall(1).args, ['a', 'c']);
}
assert.equal(el.prop, 'ac');
assert.equal(el.pcSpy.callCount, 2);
el.setProperties({
a: 'A',
b: {c: 'C'}
});
assert.equal(el.compute.callCount, 3);
assert.deepEqual(el.compute.getCall(2).args, ['A', 'C']);
if (legacyNoBatch && legacyUndefined) {
assert.equal(el.compute.callCount, 3);
assert.deepEqual(el.compute.getCall(1).args, ['A', 'c']);
assert.deepEqual(el.compute.getCall(2).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 4);
} else if (legacyUndefined) {
assert.equal(el.compute.callCount, 2);
assert.deepEqual(el.compute.getCall(1).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 3);
} else {
assert.equal(el.compute.callCount, 3);
assert.deepEqual(el.compute.getCall(2).args, ['A', 'C']);
assert.equal(el.pcSpy.callCount, 3);
}
assert.equal(el.prop, 'AC');
assert.equal(el.pcSpy.callCount, 3);
document.body.removeChild(el);
});

Expand Down

0 comments on commit add7784

Please sign in to comment.