diff --git a/lib/mixins/element-mixin.html b/lib/mixins/element-mixin.html
index 41d7551767..9f2733d234 100644
--- a/lib/mixins/element-mixin.html
+++ b/lib/mixins/element-mixin.html
@@ -576,7 +576,6 @@
*/
_initializeProperties() {
Polymer.telemetry.instanceCount++;
- hostStack.registerHost(this);
this.constructor.finalize();
const importPath = this.constructor.importPath;
// note: finalize template when we have access to `localName` to
@@ -649,9 +648,7 @@
*/
ready() {
if (this._template) {
- hostStack.beginHosting(this);
this.root = this._stampTemplate(this._template);
- hostStack.endHosting(this);
this.$ = this.root.$;
}
super.ready();
@@ -785,53 +782,6 @@
return PolymerElement;
});
- /**
- * Helper api for enqueing client dom created by a host element.
- *
- * By default elements are flushed via `_flushProperties` when
- * `connectedCallback` is called. Elements attach their client dom to
- * themselves at `ready` time which results from this first flush.
- * This provides an ordering guarantee that the client dom an element
- * creates is flushed before the element itself (i.e. client `ready`
- * fires before host `ready`).
- *
- * However, if `_flushProperties` is called *before* an element is connected,
- * as for example `Templatize` does, this ordering guarantee cannot be
- * satisfied because no elements are connected. (Note: Bound elements that
- * receive data do become enqueued clients and are properly ordered but
- * unbound elements are not.)
- *
- * To maintain the desired "client before host" ordering guarantee for this
- * case we rely on the "host stack. Client nodes registers themselves with
- * the creating host element when created. This ensures that all client dom
- * is readied in the proper order, maintaining the desired guarantee.
- *
- * @private
- */
- let hostStack = {
-
- stack: [],
-
- registerHost(inst) {
- if (this.stack.length) {
- let host = this.stack[this.stack.length-1];
- host._enqueueClient(inst);
- }
- },
-
- beginHosting(inst) {
- this.stack.push(inst);
- },
-
- endHosting(inst) {
- let stackLen = this.stack.length;
- if (stackLen && this.stack[stackLen-1] == inst) {
- this.stack.pop();
- }
- }
-
- }
-
/**
* Provides basic tracking of element definitions (registrations) and
* instance counts.
diff --git a/lib/mixins/property-effects.html b/lib/mixins/property-effects.html
index adfe6e26fc..917f29fa03 100644
--- a/lib/mixins/property-effects.html
+++ b/lib/mixins/property-effects.html
@@ -1086,6 +1086,7 @@
*/
_initializeProperties() {
super._initializeProperties();
+ hostStack.registerHost(this);
this.__dataClientsInitialized = false;
this.__dataPendingClients = null;
this.__dataToNotify = null;
@@ -1431,22 +1432,40 @@
if (!this.__dataClientsInitialized) {
this.__dataClientsInitialized = true;
this._readyClients();
+ this.__dataInitialized = true;
+ } else {
+ // Flush all clients
+ let clients = this.__dataPendingClients;
+ if (clients) {
+ this.__dataPendingClients = null;
+ for (let i=0; i < clients.length; i++) {
+ let client = clients[i];
+ if (client.__dataPending) {
+ client._flushProperties();
+ }
+ }
+ }
}
- // Flush all clients
+ }
+
+ /**
+ * Perform any initial setup on client dom. Called before the first
+ * `_flushProperties` call on client dom and before any element
+ * observers are called.
+ *
+ * @protected
+ */
+ _readyClients() {
let clients = this.__dataPendingClients;
if (clients) {
this.__dataPendingClients = null;
for (let i=0; i < clients.length; i++) {
let client = clients[i];
- // boot up client if necessary, otherwise flush properties
if (!client.__dataPropertiesEnabled) {
client._enableProperties();
- } else if (client.__dataPending) {
- client._flushProperties();
}
}
}
- this.__dataInitialized = true;
}
/**
@@ -1494,15 +1513,6 @@
}
}
- /**
- * Perform any initial setup on client dom. Called before the first
- * `_flushProperties` call on client dom and before any element
- * observers are called.
- *
- * @protected
- */
- _readyClients() {}
-
/**
* Implements `PropertyAccessors`'s properties changed callback.
*
@@ -2205,7 +2215,9 @@
* @protected
*/
_stampTemplate(template) {
+ hostStack.beginHosting(this);
let dom = super._stampTemplate(template);
+ hostStack.endHosting(this);
let templateInfo = this._bindTemplate(template, true);
// Add template-instance-specific data to instanced templateInfo
templateInfo.nodeList = dom.nodeList;
@@ -2505,5 +2517,52 @@
return PropertyEffects;
});
+ /**
+ * Helper api for enqueing client dom created by a host element.
+ *
+ * By default elements are flushed via `_flushProperties` when
+ * `connectedCallback` is called. Elements attach their client dom to
+ * themselves at `ready` time which results from this first flush.
+ * This provides an ordering guarantee that the client dom an element
+ * creates is flushed before the element itself (i.e. client `ready`
+ * fires before host `ready`).
+ *
+ * However, if `_flushProperties` is called *before* an element is connected,
+ * as for example `Templatize` does, this ordering guarantee cannot be
+ * satisfied because no elements are connected. (Note: Bound elements that
+ * receive data do become enqueued clients and are properly ordered but
+ * unbound elements are not.)
+ *
+ * To maintain the desired "client before host" ordering guarantee for this
+ * case we rely on the "host stack. Client nodes registers themselves with
+ * the creating host element when created. This ensures that all client dom
+ * is readied in the proper order, maintaining the desired guarantee.
+ *
+ * @private
+ */
+ let hostStack = {
+
+ stack: [],
+
+ registerHost(inst) {
+ if (this.stack.length) {
+ let host = this.stack[this.stack.length-1];
+ host._enqueueClient(inst);
+ }
+ },
+
+ beginHosting(inst) {
+ this.stack.push(inst);
+ },
+
+ endHosting(inst) {
+ let stackLen = this.stack.length;
+ if (stackLen && this.stack[stackLen-1] == inst) {
+ this.stack.pop();
+ }
+ }
+
+ }
+
})();