Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: appengine/config_service/ui/bower_components/polymer/lib/legacy/class.html

Issue 2923973003: Added base template for config ui. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!--
2 @license
3 Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
7 Code distributed by Google as part of the polymer project is also
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 -->
10 <link rel="import" href="legacy-element-mixin.html">
11 <script>
12
13 (function() {
14
15 'use strict';
16
17 let LegacyElementMixin = Polymer.LegacyElementMixin;
18
19 let metaProps = {
20 attached: true,
21 detached: true,
22 ready: true,
23 created: true,
24 beforeRegister: true,
25 registered: true,
26 attributeChanged: true,
27 // meta objects
28 behaviors: true
29 }
30
31 /**
32 * Applies a "legacy" behavior or array of behaviors to the provided class.
33 *
34 * Note: this method will automatically also apply the `Polymer.LegacyElemen tMixin`
35 * to ensure that any legacy behaviors can rely on legacy Polymer API on
36 * the underlying element.
37 *
38 * @param {Object|Array} behaviors Behavior object or array of behaviors.
39 * @param {HTMLElement} klass Element class.
40 * @return {HTMLElement} Returns a new Element class extended by the
41 * passed in `behaviors` and also by `Polymer.LegacyElementMixin`.
42 * @memberof Polymer
43 */
44 function mixinBehaviors(behaviors, klass) {
45 if (!behaviors) {
46 return klass;
47 }
48 // NOTE: ensure the bahevior is extending a class with
49 // legacy element api. This is necessary since behaviors expect to be able
50 // to access 1.x legacy api.
51 klass = LegacyElementMixin(klass);
52 if (!Array.isArray(behaviors)) {
53 behaviors = [behaviors];
54 }
55 let superBehaviors = klass.prototype.behaviors;
56 // get flattened, deduped list of behaviors *not* already on super class
57 behaviors = flattenBehaviors(behaviors, null, superBehaviors);
58 // mixin new behaviors
59 klass = _mixinBehaviors(behaviors, klass);
60 if (superBehaviors) {
61 behaviors = superBehaviors.concat(behaviors);
62 }
63 // Set behaviors on prototype for BC...
64 klass.prototype.behaviors = behaviors;
65 return klass;
66 }
67
68 // NOTE:
69 // 1.x
70 // Behaviors were mixed in *in reverse order* and de-duped on the fly.
71 // The rule was that behavior properties were copied onto the element
72 // prototype if and only if the property did not already exist.
73 // Given: Polymer{ behaviors: [A, B, C, A, B]}, property copy order was:
74 // (1), B, (2), A, (3) C. This means prototype properties win over
75 // B properties win over A win over C. This mirrors what would happen
76 // with inheritance if element extended B extended A extended C.
77 //
78 // Again given, Polymer{ behaviors: [A, B, C, A, B]}, the resulting
79 // `behaviors` array was [C, A, B].
80 // Behavior lifecycle methods were called in behavior array order
81 // followed by the element, e.g. (1) C.created, (2) A.created,
82 // (3) B.created, (4) element.created. There was no support for
83 // super, and "super-behavior" methods were callable only by name).
84 //
85 // 2.x
86 // Behaviors are made into proper mixins which live in the
87 // element's prototype chain. Behaviors are placed in the element prototype
88 // eldest to youngest and de-duped youngest to oldest:
89 // So, first [A, B, C, A, B] becomes [C, A, B] then,
90 // the element prototype becomes (oldest) (1) Polymer.Element, (2) class(C),
91 // (3) class(A), (4) class(B), (5) class(Polymer({...})).
92 // Result:
93 // This means element properties win over B properties win over A win
94 // over C. (same as 1.x)
95 // If lifecycle is called (super then me), order is
96 // (1) C.created, (2) A.created, (3) B.created, (4) element.created
97 // (again same as 1.x)
98 function _mixinBehaviors(behaviors, klass) {
99 for (let i=0; i<behaviors.length; i++) {
100 let b = behaviors[i];
101 if (b) {
102 klass = Array.isArray(b) ? _mixinBehaviors(b, klass) :
103 GenerateClassFromInfo(b, klass);
104 }
105 }
106 return klass;
107 }
108
109 /**
110 * @param {Array} behaviors List of behaviors to flatten.
111 * @param {Array=} list Target list to flatten behaviors into.
112 * @param {Array=} exclude List of behaviors to exclude from the list.
113 * @return {Array} Returns the list of flattened behaviors.
114 */
115 function flattenBehaviors(behaviors, list, exclude) {
116 list = list || [];
117 for (let i=behaviors.length-1; i >= 0; i--) {
118 let b = behaviors[i];
119 if (b) {
120 if (Array.isArray(b)) {
121 flattenBehaviors(b, list);
122 } else {
123 // dedup
124 if (list.indexOf(b) < 0 && (!exclude || exclude.indexOf(b) < 0)) {
125 list.unshift(b);
126 }
127 }
128 } else {
129 console.warn('behavior is null, check for missing or 404 import');
130 }
131 }
132 return list;
133 }
134
135 function GenerateClassFromInfo(info, Base) {
136
137 class PolymerGenerated extends Base {
138
139 static get properties() {
140 return info.properties;
141 }
142
143 static get observers() {
144 return info.observers;
145 }
146
147 static get template() {
148 // get template first from any imperative set in `info._template`
149 return info._template ||
150 // next look in dom-module associated with this element's is.
151 Polymer.DomModule.import(this.is, 'template') ||
152 // next look for superclass template (note: use superclass symbol
153 // to ensure correct `this.is`)
154 Base.template ||
155 // finally fall back to `_template` in element's protoype.
156 this.prototype._template;
157 }
158
159 created() {
160 super.created();
161 if (info.created) {
162 info.created.call(this);
163 }
164 }
165
166 _registered() {
167 super._registered();
168 /* NOTE: `beforeRegister` is called here for bc, but the behavior
169 is different than in 1.x. In 1.0, the method was called *after*
170 mixing prototypes together but *before* processing of meta-objects.
171 However, dynamic effects can still be set here and can be done either
172 in `beforeRegister` or `registered`. It is no longer possible to set
173 `is` in `beforeRegister` as you could in 1.x.
174 */
175 if (info.beforeRegister) {
176 info.beforeRegister.call(Object.getPrototypeOf(this));
177 }
178 if (info.registered) {
179 info.registered.call(Object.getPrototypeOf(this));
180 }
181 }
182
183 _applyListeners() {
184 super._applyListeners();
185 if (info.listeners) {
186 for (let l in info.listeners) {
187 this._addMethodEventListenerToNode(this, l, info.listeners[l]);
188 }
189 }
190 }
191
192 // note: exception to "super then me" rule;
193 // do work before calling super so that super attributes
194 // only apply if not already set.
195 _ensureAttributes() {
196 if (info.hostAttributes) {
197 for (let a in info.hostAttributes) {
198 this._ensureAttribute(a, info.hostAttributes[a]);
199 }
200 }
201 super._ensureAttributes();
202 }
203
204 ready() {
205 super.ready();
206 if (info.ready) {
207 info.ready.call(this);
208 }
209 }
210
211 attached() {
212 super.attached();
213 if (info.attached) {
214 info.attached.call(this);
215 }
216 }
217
218 detached() {
219 super.detached();
220 if (info.detached) {
221 info.detached.call(this);
222 }
223 }
224
225 attributeChanged(name, old, value) {
226 super.attributeChanged(name, old, value);
227 if (info.attributeChanged) {
228 info.attributeChanged.call(this, name, old, value);
229 }
230 }
231 }
232
233 PolymerGenerated.generatedFrom = info
234
235 for (let p in info) {
236 // NOTE: cannot copy `metaProps` methods onto prototype at least because
237 // `super.ready` must be called and is not included in the user fn.
238 if (!(p in metaProps)) {
239 let pd = Object.getOwnPropertyDescriptor(info, p);
240 if (pd) {
241 Object.defineProperty(PolymerGenerated.prototype, p, pd);
242 }
243 }
244 }
245
246 return PolymerGenerated;
247 }
248
249 /**
250 * Generates a class that extends `Polymer.LegacyElement` based on the
251 * provided info object. Metadata objects on the `info` object
252 * (`properties`, `observers`, `listeners`, `behaviors`, `is`) are used
253 * for Polymer's meta-programming systems, and any functions are copied
254 * to the generated class.
255 *
256 * Valid "metadata" values are as follows:
257 *
258 * `is`: String providing the tag name to register the element under. In
259 * addition, if a `dom-module` with the same id exists, the first template
260 * in that `dom-module` will be stamped into the shadow root of this element ,
261 * with support for declarative event listeners (`on-...`), Polymer data
262 * bindings (`[[...]]` and `{{...}}`), and id-based node finding into
263 * `this.$`.
264 *
265 * `properties`: Object describing property-related metadata used by Polymer
266 * features (key: property names, value: object containing property metadata ).
267 * Valid keys in per-property metadata include:
268 * - `type` (String|Number|Object|Array|...): Used by
269 * `attributeChangedCallback` to determine how string-based attributes
270 * are deserialized to JavaScript property values.
271 * - `notify` (boolean): Causes a change in the property to fire a
272 * non-bubbling event called `<property>-changed`. Elements that have
273 * enabled two-way binding to the property use this event to observe chang es.
274 * - `readOnly` (boolean): Creates a getter for the property, but no setter.
275 * To set a read-only property, use the private setter method
276 * `_setProperty(property, value)`.
277 * - `observer` (string): Observer method name that will be called when
278 * the property changes. The arguments of the method are
279 * `(value, previousValue)`.
280 * - `computed` (string): String describing method and dependent properties
281 * for computing the value of this property (e.g. `'computeFoo(bar, zot)'` ).
282 * Computed properties are read-only by default and can only be changed
283 * via the return value of the computing method.
284 *
285 * `observers`: Array of strings describing multi-property observer methods
286 * and their dependent properties (e.g. `'observeABC(a, b, c)'`).
287 *
288 * `listeners`: Object describing event listeners to be added to each
289 * instance of this element (key: event name, value: method name).
290 *
291 * `behaviors`: Array of additional `info` objects containing metadata
292 * and callbacks in the same format as the `info` object here which are
293 * merged into this element.
294 *
295 * `hostAttributes`: Object listing attributes to be applied to the host
296 * once created (key: attribute name, value: attribute value). Values
297 * are serialized based on the type of the value. Host attributes should
298 * generally be limited to attributes such as `tabIndex` and `aria-...`.
299 * Attributes in `hostAttributes` are only applied if a user-supplied
300 * attribute is not already present (attributes in markup override
301 * `hostAttributes`).
302 *
303 * In addition, the following Polymer-specific callbacks may be provided:
304 * - `registered`: called after first instance of this element,
305 * - `created`: called during `constructor`
306 * - `attached`: called during `connectedCallback`
307 * - `detached`: called during `disconnectedCallback`
308 * - `ready`: called before first `attached`, after all properties of
309 * this element have been propagated to its template and all observers
310 * have run
311 *
312 * @param {Object} info Object containing Polymer metadata and functions
313 * to become class methods.
314 * @return {Polymer.LegacyElement} Generated class
315 * @memberof Polymer
316 */
317 Polymer.Class = function(info) {
318 if (!info) {
319 console.warn('Polymer.Class requires `info` argument');
320 }
321 let klass = GenerateClassFromInfo(info, info.behaviors ?
322 // note: mixinBehaviors ensures `LegacyElementMixin`.
323 mixinBehaviors(info.behaviors, HTMLElement) :
324 LegacyElementMixin(HTMLElement));
325 // decorate klass with registration info
326 klass.is = info.is;
327 return klass;
328 }
329
330 Polymer.mixinBehaviors = mixinBehaviors;
331
332 })();
333
334 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698