diff --git a/lib/mixins/property-accessors.html b/lib/mixins/property-accessors.html
index 7104d229f8..bddf9d4fca 100644
--- a/lib/mixins/property-accessors.html
+++ b/lib/mixins/property-accessors.html
@@ -137,6 +137,7 @@
_initializeProperties() {
this.__serializing = false;
this.__dataCounter = 0;
+ this.__dataEnabled = false;
this.__dataInitialized = false;
this.__dataInvalid = false;
// initialize data with prototype values saved when creating accessors
@@ -475,10 +476,16 @@
}
}
- // TODO(kschaaf): document.
+ /**
+ * Call to enable property accessors. This method must be called
+ * for any side effects of setting properties to occur. For elements,
+ * generally `connectedCallback` is a normal spot to do so.
+ * It is safe to call this method multiple times as it only turns
+ * on property accessors once.
+ */
_enableProperties() {
- if (!this.__dataPropertiesEnabled) {
- this.__dataPropertiesEnabled = true;
+ if (!this.__dataEnabled) {
+ this.__dataEnabled = true;
if (this.__dataInstanceProps) {
this._initializeInstanceProperties(this.__dataInstanceProps);
this.__dataInstanceProps = null;
@@ -490,11 +497,9 @@
/**
* Calls the `_propertiesChanged` callback with the current set of
* pending changes (and old values recorded when pending changes were
- * set), and resets the pending set of changes.
+ * set), and resets the pending set of changes. Generally, this method
+ * should not be called in user code.
*
- * Note that this method must be called once to enable the property
- * accessors system. For elements, generally `connectedCallback`
- * is a normal spot to do so.
*
* @protected
*/
diff --git a/lib/mixins/property-effects.html b/lib/mixins/property-effects.html
index 917f29fa03..0591094250 100644
--- a/lib/mixins/property-effects.html
+++ b/lib/mixins/property-effects.html
@@ -1461,7 +1461,7 @@
this.__dataPendingClients = null;
for (let i=0; i < clients.length; i++) {
let client = clients[i];
- if (!client.__dataPropertiesEnabled) {
+ if (!client.__dataEnabled) {
client._enableProperties();
}
}
@@ -1496,13 +1496,21 @@
}
/**
- * Overrides `PropertyAccessors` to call `_readyClients` callback
- * if it was not called as a result of flushing properties.
+ * Overrides `PropertyAccessors` so that property accessor
+ * side effects are not enabled until after client dom is fully ready.
+ * Also calls `_flushClients` callback to ensure client dom is enabled
+ * that was not enabled as a result of flushing properties.
*
* @override
*/
ready() {
+ // It is important that `super.ready()` is not called here as it
+ // immediately turns on accessors. Instead, we wait until `readyClients`
+ // to enable accessors to provide a guarantee that clients are ready
+ // before processing any accessors side effects.
this._flushProperties();
+ // If no data was pending, `_flushProperties` will not `flushClients`
+ // so ensure this is done.
if (!this.__dataClientsInitialized) {
this._flushClients();
}
@@ -2215,6 +2223,8 @@
* @protected
*/
_stampTemplate(template) {
+ // Ensures that created dom is `_enqueueClient`'d to this element so
+ // that it can be flushed on next call to `_flushProperties`
hostStack.beginHosting(this);
let dom = super._stampTemplate(template);
hostStack.endHosting(this);