Index: third_party/polymer/v0_8/components/polymer/src/standard/configure.html |
diff --git a/third_party/polymer/v0_8/components/polymer/src/standard/configure.html b/third_party/polymer/v0_8/components/polymer/src/standard/configure.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..27af16d2314655bcc0ff5287f8bd7529c0e328e9 |
--- /dev/null |
+++ b/third_party/polymer/v0_8/components/polymer/src/standard/configure.html |
@@ -0,0 +1,184 @@ |
+<!-- |
+@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> |
+ |
+ /* |
+ Process inputs efficiently via a configure lifecycle callback. |
+ Configure is called top-down, host before local dom. Users should |
+ implement configure to supply a set of default values for the element by |
+ returning an object containing the properties and values to set. |
+ |
+ Configured values are not immediately set, instead they are set when |
+ an element becomes ready, after its local dom is ready. This ensures |
+ that any user change handlers are not called before ready time. |
+ |
+ */ |
+ |
+ /* |
+ Implementation notes: |
+ |
+ Configured values are collected into _config. At ready time, properties |
+ are set to the values in _config. This ensures properties are set child |
+ before host and change handlers are called only at ready time. The host |
+ will reset a value already propagated to a child, but this is not |
+ inefficient because of dirty checking at the set point. |
+ |
+ Bind notification events are sent when properties are set at ready time |
+ and thus received by the host before it is ready. Since notifications result |
+ in property updates and this triggers side effects, handling notifications |
+ is deferred until ready time. |
+ |
+ In general, events can be heard before an element is ready. This may occur |
+ when a user sends an event in a change handler or listens to a data event |
+ directly (on-foo-changed). |
+ */ |
+ |
+ Polymer.Base._addFeature({ |
+ |
+ // storage for configuration |
+ _setupConfigure: function(initialConfig) { |
+ this._config = initialConfig || {}; |
+ this._handlers = []; |
+ }, |
+ |
+ // static attributes are deserialized into _config |
+ _takeAttributes: function() { |
+ this._takeAttributesToModel(this._config); |
+ }, |
+ |
+ // at configure time values are stored in _config |
+ _configValue: function(name, value) { |
+ this._config[name] = value; |
+ }, |
+ |
+ // Override polymer-mini thunk |
+ _beforeClientsReady: function() { |
+ this._configure(); |
+ }, |
+ |
+ // configure: returns user supplied default property values |
+ // combines with _config to create final property values |
+ _configure: function() { |
+ this._configureAnnotationReferences(); |
+ // get individual default values from property configs |
+ var config = {}; |
+ this._configureProperties(this.properties, config); |
+ // behave! |
+ this.behaviors.forEach(function(b) { |
+ this._configureProperties(b.properties, config); |
+ }, this); |
+ // get add'l default values from central configure |
+ // combine defaults returned from configure with inputs in _config |
+ this._mixinConfigure(config, this._config); |
+ // this is the new _config, which are the final values to be applied |
+ this._config = config; |
+ // pass configuration data to bindings |
+ this._distributeConfig(this._config); |
+ }, |
+ |
+ _configureProperties: function(properties, config) { |
+ for (i in properties) { |
+ var c = properties[i]; |
+ if (c.value !== undefined) { |
+ var value = c.value; |
+ if (typeof value == 'function') { |
+ // pass existing config values (this._config) to value function |
+ value = value.call(this, this._config); |
+ } |
+ config[i] = value; |
+ } |
+ } |
+ }, |
+ |
+ _mixinConfigure: function(a, b) { |
+ for (var prop in b) { |
+ if (!this.isReadOnlyProperty(prop)) { |
+ a[prop] = b[prop]; |
+ } |
+ } |
+ }, |
+ |
+ // distribute config values to bound nodes. |
+ _distributeConfig: function(config) { |
+ var fx$ = this._propertyEffects; |
+ if (fx$) { |
+ for (var p in config) { |
+ var fx = fx$[p]; |
+ if (fx) { |
+ for (var i=0, l=fx.length, x; (i<l) && (x=fx[i]); i++) { |
+ if (x.kind === 'annotation') { |
+ var node = this._nodes[x.effect.index]; |
+ // seeding configuration only |
+ if (node._configValue) { |
+ var value = (p === x.effect.value) ? config[p] : |
+ this.getPathValue(x.effect.value, config); |
+ node._configValue(x.effect.name, value); |
+ } |
+ } |
+ } |
+ } |
+ } |
+ } |
+ }, |
+ |
+ // Override polymer-mini thunk |
+ _afterClientsReady: function() { |
+ this._applyConfig(this._config); |
+ this._flushHandlers(); |
+ }, |
+ |
+ // NOTE: values are already propagated to children via |
+ // _distributeConfig so propagation triggered by effects here is |
+ // redundant, but safe due to dirty checking |
+ _applyConfig: function(config) { |
+ for (var n in config) { |
+ // Don't stomp on values that may have been set by other side effects |
+ if (this[n] === undefined) { |
+ // Call _propertySet for any properties with accessors, which will |
+ // initialize read-only properties also |
+ // TODO(kschaaf): consider passing fromAbove here to prevent |
+ // unnecessary notify for: 1) possible perf, 2) debuggability |
+ var effects = this._propertyEffects[n]; |
+ if (effects) { |
+ this._propertySet(n, config[n], effects); |
+ } else { |
+ this[n] = config[n]; |
+ } |
+ } |
+ } |
+ }, |
+ |
+ // NOTE: Notifications can be processed before ready since |
+ // they are sent at *child* ready time. Since notifications cause side |
+ // effects and side effects must not be processed before ready time, |
+ // handling is queue/defered until then. |
+ _notifyListener: function(fn, e) { |
+ if (!this._clientsReadied) { |
+ this._queueHandler([fn, e, e.target]); |
+ } else { |
+ return fn.call(this, e, e.target); |
+ } |
+ }, |
+ |
+ _queueHandler: function(args) { |
+ this._handlers.push(args); |
+ }, |
+ |
+ _flushHandlers: function() { |
+ var h$ = this._handlers; |
+ for (var i=0, l=h$.length, h; (i<l) && (h=h$[i]); i++) { |
+ h[0].call(this, h[1], h[2]); |
+ } |
+ } |
+ |
+ }); |
+ |
+</script> |