Skip to content

Commit

Permalink
Move hostStack to property-effects and make readyClients explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpschaaf committed May 12, 2017
1 parent 2f1e964 commit c7a81ea
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 64 deletions.
50 changes: 0 additions & 50 deletions lib/mixins/element-mixin.html
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down
87 changes: 73 additions & 14 deletions lib/mixins/property-effects.html
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,7 @@
*/
_initializeProperties() {
super._initializeProperties();
hostStack.registerHost(this);
this.__dataClientsInitialized = false;
this.__dataPendingClients = null;
this.__dataToNotify = null;
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
}

}

})();
</script>

0 comments on commit c7a81ea

Please sign in to comment.