five-bells-visualization
Version:
Tool to visualize Five Bells payments
153 lines (133 loc) • 5.2 kB
HTML
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<script>
/**
* Provides `ready` lifecycle callback which is called parent to child.
*
* This can be useful in a number of cases. Here are some examples:
*
* Setting a default property value that should have a side effect: To ensure
* the side effect, an element must set a default value no sooner than
* `created`; however, since `created` flows child to host, this is before the
* host has had a chance to set a property value on the child. The `ready`
* method solves this problem since it's called host to child.
*
* Dom distribution: To support reprojection efficiently, it's important to
* distribute from host to child in one shot. The `attachedCallback` mostly
* goes in the desired order except for elements that are in dom to start; in
* this case, all children are attached before the host element. Ready also
* addresses this case since it's guaranteed to be called host to child.
*
* @class standard feature: ready
*/
(function() {
var baseAttachedCallback = Polymer.Base.attachedCallback;
Polymer.Base._addFeature({
hostStack: [],
// for overriding
ready: function() {
},
// NOTE: The concept of 'host' is overloaded. There are two different
// notions:
// 1. an element hosts the elements in its local dom root.
// 2. an element hosts the elements on which it configures data.
// Practially, these notions are almost always coincident.
// Some special elements like templates may separate them.
// In order not to over-emphaisize this technical difference, we expose
// one concept to the user and it maps to the dom-related meaning of host.
//
// 1. set this element's `host` and push this element onto the `host`'s
// list of `client` elements
// 2. establish this element as the current hosting element (allows
// any elements we stamp to easily set host to us).
_pushHost: function(host) {
// NOTE: The `dataHost` of an element never changes.
this.dataHost = host = host ||
Polymer.Base.hostStack[Polymer.Base.hostStack.length-1];
// this.dataHost reflects the parent element who manages
// any bindings for the element. Only elements originally
// stamped from Polymer templates have a dataHost, and this
// never changes
if (host && host._clients) {
host._clients.push(this);
}
this._beginHost();
},
_beginHost: function() {
Polymer.Base.hostStack.push(this);
if (!this._clients) {
this._clients = [];
}
},
_popHost: function() {
// this element is no longer the current hosting element
Polymer.Base.hostStack.pop();
},
_tryReady: function() {
if (this._canReady()) {
this._ready();
}
},
_canReady: function() {
return !this.dataHost || this.dataHost._clientsReadied;
},
_ready: function() {
// extension point
this._beforeClientsReady();
this._readyClients();
// extension point
this._afterClientsReady();
this._readySelf();
},
_readyClients: function() {
// prepare root
this._setupRoot();
// logically distribute self
this._beginDistribute();
// now fully prepare localChildren
var c$ = this._clients;
for (var i=0, l= c$.length, c; (i<l) && (c=c$[i]); i++) {
c._ready();
}
// perform actual dom composition
this._finishDistribute();
// ensure elements are attached if they are in the dom at ready time
// helps normalize attached ordering between native and polyfill ce.
// TODO(sorvell): worth perf cost? ~6%
// if (!Polymer.Settings.useNativeCustomElements) {
// CustomElements.takeRecords();
// }
this._clientsReadied = true;
this._clients = null;
},
// mark readied and call `ready`
// note: called localChildren -> host
_readySelf: function() {
this._doBehavior('ready');
this._readied = true;
if (this._attachedPending) {
this._attachedPending = false;
this.attachedCallback();
}
},
// for system overriding
_beforeClientsReady: function() {},
_afterClientsReady: function() {},
// normalize lifecycle: ensure attached occurs only after ready.
attachedCallback: function() {
if (this._readied) {
baseAttachedCallback.call(this);
} else {
this._attachedPending = true;
}
}
});
})();
</script>