UNPKG

five-bells-visualization

Version:
153 lines (133 loc) 5.2 kB
<!-- @license 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>