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

Side by Side Diff: appengine/config_service/ui/bower_components/polymer/lib/legacy/legacy-element-mixin.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
11 <link rel="import" href="../../../shadycss/apply-shim.html">
12 <link rel="import" href="../mixins/element-mixin.html">
13 <link rel="import" href="../mixins/gesture-event-listeners.html">
14 <link rel="import" href="../utils/mixin.html">
15 <link rel="import" href="../utils/import-href.html">
16 <link rel="import" href="../utils/render-status.html">
17 <link rel="import" href="../utils/unresolved.html">
18 <link rel="import" href="polymer.dom.html">
19
20 <script>
21 (function() {
22
23 'use strict';
24
25 let styleInterface = window.ShadyCSS;
26
27 /**
28 * Element class mixin that provides Polymer's "legacy" API intended to be
29 * backward-compatible to the greatest extent possible with the API
30 * found on the Polymer 1.x `Polymer.Base` prototype applied to all elements
31 * defined using the `Polymer({...})` function.
32 *
33 * @polymerMixin
34 * @mixes Polymer.ElementMixin
35 * @mixes Polymer.GestureEventListeners
36 * @property isAttached {boolean} Set to `true` in this element's
37 * `connectedCallback` and `false` in `disconnectedCallback`
38 * @memberof Polymer
39 * @summary Element class mixin that provides Polymer's "legacy" API
40 */
41 Polymer.LegacyElementMixin = Polymer.dedupingMixin(base => {
42
43 /**
44 * @constructor
45 * @extends {base}
46 * @implements {Polymer_ElementMixin}
47 * @implements {Polymer_GestureEventListeners}
48 */
49 const legacyElementBase = Polymer.GestureEventListeners(Polymer.ElementMixin (base));
50
51 /**
52 * Map of simple names to touch action names
53 * @dict
54 */
55 const DIRECTION_MAP = {
56 'x': 'pan-x',
57 'y': 'pan-y',
58 'none': 'none',
59 'all': 'auto'
60 };
61
62 /**
63 * @polymerMixinClass
64 * @implements {Polymer_LegacyElement}
65 */
66 class LegacyElement extends legacyElementBase {
67
68 constructor() {
69 super();
70 this.root = this;
71 this.created();
72 }
73
74 /**
75 * Legacy callback called during the `constructor`, for overriding
76 * by the user.
77 */
78 created() {}
79
80 connectedCallback() {
81 super.connectedCallback();
82 this.isAttached = true;
83 this.attached();
84 }
85
86 /**
87 * Legacy callback called during `connectedCallback`, for overriding
88 * by the user.
89 */
90 attached() {}
91
92 disconnectedCallback() {
93 super.disconnectedCallback();
94 this.isAttached = false;
95 this.detached();
96 }
97
98 /**
99 * Legacy callback called during `disconnectedCallback`, for overriding
100 * by the user.
101 */
102 detached() {}
103
104 attributeChangedCallback(name, old, value) {
105 if (old !== value) {
106 super.attributeChangedCallback(name, old, value);
107 this.attributeChanged(name, old, value);
108 }
109 }
110
111 /**
112 * Legacy callback called during `attributeChangedChallback`, for overridi ng
113 * by the user.
114 */
115 attributeChanged() {}
116
117 /**
118 * Overrides the default `Polymer.PropertyEffects` implementation to
119 * add support for class initialization via the `_registered` callback.
120 * This is called only when the first instance of the element is created.
121 *
122 * @override
123 */
124 _initializeProperties() {
125 let proto = Object.getPrototypeOf(this);
126 if (!proto.hasOwnProperty('__hasRegisterFinished')) {
127 proto.__hasRegisterFinished = true;
128 this._registered();
129 }
130 super._initializeProperties();
131 }
132
133 /**
134 * Called automatically when an element is initializing.
135 * Users may override this method to perform class registration time
136 * work. The implementation should ensure the work is performed
137 * only once for the class.
138 * @protected
139 */
140 _registered() {}
141
142 /**
143 * Overrides the default `Polymer.PropertyEffects` implementation to
144 * add support for installing `hostAttributes` and `listeners`.
145 *
146 * @override
147 */
148 ready() {
149 this._ensureAttributes();
150 this._applyListeners();
151 super.ready();
152 }
153
154 /**
155 * Ensures an element has required attributes. Called when the element
156 * is being readied via `ready`. Users should override to set the
157 * element's required attributes. The implementation should be sure
158 * to check and not override existing attributes added by
159 * the user of the element. Typically, setting attributes should be left
160 * to the element user and not done here; reasonable exceptions include
161 * setting aria roles and focusability.
162 * @protected
163 */
164 _ensureAttributes() {}
165
166 /**
167 * Adds element event listeners. Called when the element
168 * is being readied via `ready`. Users should override to
169 * add any required element event listeners.
170 * In performance critical elements, the work done here should be kept
171 * to a minimum since it is done before the element is rendered. In
172 * these elements, consider adding listeners asychronously so as not to
173 * block render.
174 * @protected
175 */
176 _applyListeners() {}
177
178 /**
179 * Converts a typed JavaScript value to a string.
180 *
181 * Note this method is provided as backward-compatible legacy API
182 * only. It is not directly called by any Polymer features. To customize
183 * how properties are serialized to attributes for attribute bindings and
184 * `reflectToAttribute: true` properties as well as this method, override
185 * the `_serializeValue` method provided by `Polymer.PropertyAccessors`.
186 *
187 * @param {*} value Value to deserialize
188 * @return {string} Serialized value
189 */
190 serialize(value) {
191 return this._serializeValue(value);
192 }
193
194 /**
195 * Converts a string to a typed JavaScript value.
196 *
197 * Note this method is provided as backward-compatible legacy API
198 * only. It is not directly called by any Polymer features. To customize
199 * how attributes are deserialized to properties for in
200 * `attributeChangedCallback`, override `_deserializeValue` method
201 * provided by `Polymer.PropertyAccessors`.
202 *
203 * @param {string} value String to deserialize
204 * @param {*} type Type to deserialize the string to
205 * @return {*} Returns the deserialized value in the `type` given.
206 */
207 deserialize(value, type) {
208 return this._deserializeValue(value, type);
209 }
210
211 /**
212 * Serializes a property to its associated attribute.
213 *
214 * Note this method is provided as backward-compatible legacy API
215 * only. It is not directly called by any Polymer features.
216 *
217 * @param {string} property Property name to reflect.
218 * @param {string=} attribute Attribute name to reflect.
219 * @param {*=} value Property value to refect.
220 */
221 reflectPropertyToAttribute(property, attribute, value) {
222 this._propertyToAttribute(property, attribute, value);
223 }
224
225 /**
226 * Sets a typed value to an HTML attribute on a node.
227 *
228 * Note this method is provided as backward-compatible legacy API
229 * only. It is not directly called by any Polymer features.
230 *
231 * @param {*} value Value to serialize.
232 * @param {string} attribute Attribute name to serialize to.
233 * @param {Element} node Element to set attribute to.
234 */
235 serializeValueToAttribute(value, attribute, node) {
236 this._valueToNodeAttribute(node || this, value, attribute);
237 }
238
239 /**
240 * Copies own properties (including accessor descriptors) from a source
241 * object to a target object.
242 *
243 * @param {Object} prototype Target object to copy properties to.
244 * @param {Object} api Source object to copy properties from.
245 * @return {Object} prototype object that was passed as first argument.
246 */
247 extend(prototype, api) {
248 if (!(prototype && api)) {
249 return prototype || api;
250 }
251 let n$ = Object.getOwnPropertyNames(api);
252 for (let i=0, n; (i<n$.length) && (n=n$[i]); i++) {
253 let pd = Object.getOwnPropertyDescriptor(api, n);
254 if (pd) {
255 Object.defineProperty(prototype, n, pd);
256 }
257 }
258 return prototype;
259 }
260
261 /**
262 * Copies props from a source object to a target object.
263 *
264 * Note, this method uses a simple `for...in` strategy for enumerating
265 * properties. To ensure only `ownProperties` are copied from source
266 * to target and that accessor implementations are copied, use `extend`.
267 *
268 * @param {Object} target Target object to copy properties to.
269 * @param {Object} source Source object to copy properties from.
270 * @return {Object} Target object that was passed as first argument.
271 */
272 mixin(target, source) {
273 for (let i in source) {
274 target[i] = source[i];
275 }
276 return target;
277 }
278
279 /**
280 * Sets the prototype of an object.
281 *
282 * Note this method is provided as backward-compatible legacy API
283 * only. It is not directly called by any Polymer features.
284 * @param {Object} object The object on which to set the prototype.
285 * @param {Object} prototype The prototype that will be set on the given
286 * `object`.
287 * @return {Object} Returns the given `object` with its prototype set
288 * to the given `prototype` object.
289 */
290 chainObject(object, prototype) {
291 if (object && prototype && object !== prototype) {
292 object.__proto__ = prototype;
293 }
294 return object;
295 }
296
297 /* **** Begin Template **** */
298
299 /**
300 * Calls `importNode` on the `content` of the `template` specified and
301 * returns a document fragment containing the imported content.
302 *
303 * @param {HTMLTemplateElement} template HTML template element to instance .
304 * @return {DocumentFragment} Document fragment containing the imported
305 * template content.
306 */
307 instanceTemplate(template) {
308 let content = this.constructor._contentForTemplate(template);
309 let dom = /** @type {DocumentFragment} */
310 (document.importNode(content, true));
311 return dom;
312 }
313
314 /* **** Begin Events **** */
315
316 /**
317 * Dispatches a custom event with an optional detail value.
318 *
319 * @param {string} type Name of event type.
320 * @param {*=} detail Detail value containing event-specific
321 * payload.
322 * @param {Object=} options Object specifying options. These may include:
323 * `bubbles` (boolean, defaults to `true`),
324 * `cancelable` (boolean, defaults to false), and
325 * `node` on which to fire the event (HTMLElement, defaults to `this`).
326 * @return {Event} The new event that was fired.
327 */
328 fire(type, detail, options) {
329 options = options || {};
330 detail = (detail === null || detail === undefined) ? {} : detail;
331 let event = new Event(type, {
332 bubbles: options.bubbles === undefined ? true : options.bubbles,
333 cancelable: Boolean(options.cancelable),
334 composed: options.composed === undefined ? true: options.composed
335 });
336 event.detail = detail;
337 let node = options.node || this;
338 node.dispatchEvent(event)
339 return event;
340 }
341
342 /**
343 * Convenience method to add an event listener on a given element,
344 * late bound to a named method on this element.
345 *
346 * @param {Element} node Element to add event listener to.
347 * @param {string} eventName Name of event to listen for.
348 * @param {string} methodName Name of handler method on `this` to call.
349 */
350 listen(node, eventName, methodName) {
351 node = node || this;
352 let hbl = this.__boundListeners ||
353 (this.__boundListeners = new WeakMap());
354 let bl = hbl.get(node);
355 if (!bl) {
356 bl = {};
357 hbl.set(node, bl);
358 }
359 let key = eventName + methodName;
360 if (!bl[key]) {
361 bl[key] = this._addMethodEventListenerToNode(
362 node, eventName, methodName, this);
363 }
364 }
365
366 /**
367 * Convenience method to remove an event listener from a given element,
368 * late bound to a named method on this element.
369 *
370 * @param {Element} node Element to remove event listener from.
371 * @param {string} eventName Name of event to stop listening to.
372 * @param {string} methodName Name of handler method on `this` to not call
373 anymore.
374 */
375 unlisten(node, eventName, methodName) {
376 node = node || this;
377 let bl = this.__boundListeners && this.__boundListeners.get(node);
378 let key = eventName + methodName;
379 let handler = bl && bl[key];
380 if (handler) {
381 this._removeEventListenerFromNode(node, eventName, handler);
382 bl[key] = null;
383 }
384 }
385
386 /**
387 * Override scrolling behavior to all direction, one direction, or none.
388 *
389 * Valid scroll directions:
390 * - 'all': scroll in any direction
391 * - 'x': scroll only in the 'x' direction
392 * - 'y': scroll only in the 'y' direction
393 * - 'none': disable scrolling for this node
394 *
395 * @param {string=} direction Direction to allow scrolling
396 * Defaults to `all`.
397 * @param {HTMLElement=} node Element to apply scroll direction setting.
398 * Defaults to `this`.
399 */
400 setScrollDirection(direction, node) {
401 Polymer.Gestures.setTouchAction(node || this, DIRECTION_MAP[direction] | | 'auto');
402 }
403 /* **** End Events **** */
404
405 /**
406 * Convenience method to run `querySelector` on this local DOM scope.
407 *
408 * This function calls `Polymer.dom(this.root).querySelector(slctr)`.
409 *
410 * @param {string} slctr Selector to run on this local DOM scope
411 * @return {Element} Element found by the selector, or null if not found.
412 */
413 $$(slctr) {
414 return this.root.querySelector(slctr);
415 }
416
417 /**
418 * Return the element whose local dom within which this element
419 * is contained. This is a shorthand for
420 * `this.getRootNode().host`.
421 */
422 get domHost() {
423 let root = this.getRootNode();
424 return (root instanceof DocumentFragment) ? root.host : root;
425 }
426
427 /**
428 * Force this element to distribute its children to its local dom.
429 * This is necessary only when ShadyDOM is used and only in cases that
430 * are not automatically handled. For example,
431 * a user should call `distributeContent` if distribution has been
432 * invalidated due to an element being added or removed from the shadowRoo t
433 * that contains an insertion point (`<slot>`) inside its subtree.
434 */
435 distributeContent() {
436 if (window.ShadyDOM && this.shadowRoot) {
437 this.shadowRoot.forceRender();
438 }
439 }
440
441 /**
442 * Returns a list of nodes that are the effective childNodes. The effectiv e
443 * childNodes list is the same as the element's childNodes except that
444 * any `<content>` elements are replaced with the list of nodes distribute d
445 * to the `<content>`, the result of its `getDistributedNodes` method.
446 *
447 * @return {Array<Node>} List of effctive child nodes.
448 */
449 getEffectiveChildNodes() {
450 return Polymer.dom(this).getEffectiveChildNodes();
451 }
452
453 /**
454 * Returns a list of nodes distributed within this element that match
455 * `selector`. These can be dom children or elements distributed to
456 * children that are insertion points.
457 * @param {string} selector Selector to run.
458 * @return {Array<Node>} List of distributed elements that match selector.
459 */
460 queryDistributedElements(selector) {
461 return Polymer.dom(this).queryDistributedElements(selector);
462 }
463
464 /**
465 * Returns a list of elements that are the effective children. The effecti ve
466 * children list is the same as the element's children except that
467 * any `<content>` elements are replaced with the list of elements
468 * distributed to the `<content>`.
469 *
470 * @return {Array<Node>} List of effctive children.
471 */
472 getEffectiveChildren() {
473 let list = this.getEffectiveChildNodes();
474 return list.filter(function(n) {
475 return (n.nodeType === Node.ELEMENT_NODE);
476 });
477 }
478
479 /**
480 * Returns a string of text content that is the concatenation of the
481 * text content's of the element's effective childNodes (the elements
482 * returned by <a href="#getEffectiveChildNodes>getEffectiveChildNodes</a> .
483 *
484 * @return {string} List of effctive children.
485 */
486 getEffectiveTextContent() {
487 let cn = this.getEffectiveChildNodes();
488 let tc = [];
489 for (let i=0, c; (c = cn[i]); i++) {
490 if (c.nodeType !== Node.COMMENT_NODE) {
491 tc.push(c.textContent);
492 }
493 }
494 return tc.join('');
495 }
496
497 /**
498 * Returns the first effective childNode within this element that
499 * match `selector`. These can be dom child nodes or elements distributed
500 * to children that are insertion points.
501 * @param {string} selector Selector to run.
502 * @return {Object<Node>} First effective child node that matches selector .
503 */
504 queryEffectiveChildren(selector) {
505 let e$ = this.queryDistributedElements(selector);
506 return e$ && e$[0];
507 }
508
509 /**
510 * Returns a list of effective childNodes within this element that
511 * match `selector`. These can be dom child nodes or elements distributed
512 * to children that are insertion points.
513 * @param {string} selector Selector to run.
514 * @return {Array<Node>} List of effective child nodes that match selector .
515 */
516 queryAllEffectiveChildren(selector) {
517 return this.queryDistributedElements(selector);
518 }
519
520 /**
521 * Returns a list of nodes distributed to this element's `<slot>`.
522 *
523 * If this element contains more than one `<slot>` in its local DOM,
524 * an optional selector may be passed to choose the desired content.
525 *
526 * @param {string=} slctr CSS selector to choose the desired
527 * `<slot>`. Defaults to `content`.
528 * @return {Array<Node>} List of distributed nodes for the `<slot>`.
529 */
530 getContentChildNodes(slctr) {
531 let content = this.root.querySelector(slctr || 'slot');
532 return content ? Polymer.dom(content).getDistributedNodes() : [];
533 }
534
535 /**
536 * Returns a list of element children distributed to this element's
537 * `<slot>`.
538 *
539 * If this element contains more than one `<slot>` in its
540 * local DOM, an optional selector may be passed to choose the desired
541 * content. This method differs from `getContentChildNodes` in that only
542 * elements are returned.
543 *
544 * @param {string=} slctr CSS selector to choose the desired
545 * `<content>`. Defaults to `content`.
546 * @return {Array<HTMLElement>} List of distributed nodes for the
547 * `<slot>`.
548 */
549 getContentChildren(slctr) {
550 return this.getContentChildNodes(slctr).filter(function(n) {
551 return (n.nodeType === Node.ELEMENT_NODE);
552 });
553 }
554
555 /**
556 * Checks whether an element is in this element's light DOM tree.
557 *
558 * @param {?Node} node The element to be checked.
559 * @return {boolean} true if node is in this element's light DOM tree.
560 */
561 isLightDescendant(node) {
562 return this !== node && this.contains(node) &&
563 this.getRootNode() === node.getRootNode();
564 }
565
566 /**
567 * Checks whether an element is in this element's local DOM tree.
568 *
569 * @param {HTMLElement=} node The element to be checked.
570 * @return {boolean} true if node is in this element's local DOM tree.
571 */
572 isLocalDescendant(node) {
573 return this.root === node.getRootNode();
574 }
575
576 // NOTE: should now be handled by ShadyCss library.
577 scopeSubtree(container, shouldObserve) { // eslint-disable-line no-unused- vars
578 }
579
580 /**
581 * Returns the computed style value for the given property.
582 * @param {string} property The css property name.
583 * @return {string} Returns the computed css property value for the given
584 * `property`.
585 */
586 getComputedStyleValue(property) {
587 return styleInterface.getComputedStyleValue(this, property);
588 }
589
590 // debounce
591
592 /**
593 * Call `debounce` to collapse multiple requests for a named task into
594 * one invocation which is made after the wait time has elapsed with
595 * no new request. If no wait time is given, the callback will be called
596 * at microtask timing (guaranteed before paint).
597 *
598 * debouncedClickAction(e) {
599 * // will not call `processClick` more than once per 100ms
600 * this.debounce('click', function() {
601 * this.processClick();
602 * } 100);
603 * }
604 *
605 * @param {string} jobName String to indentify the debounce job.
606 * @param {function()} callback Function that is called (with `this`
607 * context) when the wait time elapses.
608 * @param {number} wait Optional wait time in milliseconds (ms) after the
609 * last signal that must elapse before invoking `callback`
610 * @return {Object} Returns a debouncer object on which exists the
611 * following methods: `isActive()` returns true if the debouncer is
612 * active; `cancel()` cancels the debouncer if it is active;
613 * `flush()` immediately invokes the debounced callback if the debouncer
614 * is active.
615 */
616 debounce(jobName, callback, wait) {
617 this._debouncers = this._debouncers || {};
618 return this._debouncers[jobName] = Polymer.Debouncer.debounce(
619 this._debouncers[jobName]
620 , wait > 0 ? Polymer.Async.timeOut.after(wait) : Polymer.Async.micro Task
621 , callback.bind(this));
622 }
623
624 /**
625 * Returns whether a named debouncer is active.
626 *
627 * @param {string} jobName The name of the debouncer started with `debounc e`
628 * @return {boolean} Whether the debouncer is active (has not yet fired).
629 */
630 isDebouncerActive(jobName) {
631 this._debouncers = this._debouncers || {};
632 let debouncer = this._debouncers[jobName];
633 return !!(debouncer && debouncer.isActive());
634 }
635
636 /**
637 * Immediately calls the debouncer `callback` and inactivates it.
638 *
639 * @param {string} jobName The name of the debouncer started with `debounc e`
640 */
641 flushDebouncer(jobName) {
642 this._debouncers = this._debouncers || {};
643 let debouncer = this._debouncers[jobName];
644 if (debouncer) {
645 debouncer.flush();
646 }
647 }
648
649 /**
650 * Cancels an active debouncer. The `callback` will not be called.
651 *
652 * @param {string} jobName The name of the debouncer started with `debounc e`
653 */
654 cancelDebouncer(jobName) {
655 this._debouncers = this._debouncers || {}
656 let debouncer = this._debouncers[jobName];
657 if (debouncer) {
658 debouncer.cancel();
659 }
660 }
661
662 /**
663 * Runs a callback function asyncronously.
664 *
665 * By default (if no waitTime is specified), async callbacks are run at
666 * microtask timing, which will occur before paint.
667 *
668 * @param {Function} callback The callback function to run, bound to `this `.
669 * @param {number=} waitTime Time to wait before calling the
670 * `callback`. If unspecified or 0, the callback will be run at microta sk
671 * timing (before paint).
672 * @return {number} Handle that may be used to cancel the async job.
673 */
674 async(callback, waitTime) {
675 return waitTime > 0 ? Polymer.Async.timeOut.run(callback.bind(this), wai tTime) :
676 ~Polymer.Async.microTask.run(callback.bind(this));
677 }
678
679 /**
680 * Cancels an async operation started with `async`.
681 *
682 * @param {number} handle Handle returned from original `async` call to
683 * cancel.
684 */
685 cancelAsync(handle) {
686 handle < 0 ? Polymer.Async.microTask.cancel(~handle) :
687 Polymer.Async.timeOut.cancel(handle);
688 }
689
690 // other
691
692 /**
693 * Convenience method for creating an element and configuring it.
694 *
695 * @param {string} tag HTML element tag to create.
696 * @param {Object} props Object of properties to configure on the
697 * instance.
698 * @return {Element} Newly created and configured element.
699 */
700 create(tag, props) {
701 let elt = document.createElement(tag);
702 if (props) {
703 if (elt.setProperties) {
704 elt.setProperties(props);
705 } else {
706 for (let n in props) {
707 elt[n] = props[n];
708 }
709 }
710 }
711 return elt;
712 }
713
714 /**
715 * Convenience method for importing an HTML document imperatively.
716 *
717 * This method creates a new `<link rel="import">` element with
718 * the provided URL and appends it to the document to start loading.
719 * In the `onload` callback, the `import` property of the `link`
720 * element will contain the imported document contents.
721 *
722 * @param {string} href URL to document to load.
723 * @param {Function} onload Callback to notify when an import successfully
724 * loaded.
725 * @param {Function} onerror Callback to notify when an import
726 * unsuccessfully loaded.
727 * @param {boolean} optAsync True if the import should be loaded `async`.
728 * Defaults to `false`.
729 * @return {HTMLLinkElement} The link element for the URL to be loaded.
730 */
731 importHref(href, onload, onerror, optAsync) { // eslint-disable-line no-un used-vars
732 let loadFn = onload ? onload.bind(this) : null;
733 let errorFn = onerror ? onerror.bind(this) : null;
734 return Polymer.importHref(href, loadFn, errorFn, optAsync);
735 }
736
737 /**
738 * Polyfill for Element.prototype.matches, which is sometimes still
739 * prefixed.
740 *
741 * @param {string} selector Selector to test.
742 * @param {Element=} node Element to test the selector against.
743 * @return {boolean} Whether the element matches the selector.
744 */
745 elementMatches(selector, node) {
746 return Polymer.dom.matchesSelector(node || this, selector);
747 }
748
749 /**
750 * Toggles an HTML attribute on or off.
751 *
752 * @param {string} name HTML attribute name
753 * @param {boolean=} bool Boolean to force the attribute on or off.
754 * When unspecified, the state of the attribute will be reversed.
755 * @param {HTMLElement=} node Node to target. Defaults to `this`.
756 */
757 toggleAttribute(name, bool, node) {
758 node = node || this;
759 if (arguments.length == 1) {
760 bool = !node.hasAttribute(name);
761 }
762 if (bool) {
763 node.setAttribute(name, '');
764 } else {
765 node.removeAttribute(name);
766 }
767 }
768
769
770 /**
771 * Toggles a CSS class on or off.
772 *
773 * @param {string} name CSS class name
774 * @param {boolean=} bool Boolean to force the class on or off.
775 * When unspecified, the state of the class will be reversed.
776 * @param {HTMLElement=} node Node to target. Defaults to `this`.
777 */
778 toggleClass(name, bool, node) {
779 node = node || this;
780 if (arguments.length == 1) {
781 bool = !node.classList.contains(name);
782 }
783 if (bool) {
784 node.classList.add(name);
785 } else {
786 node.classList.remove(name);
787 }
788 }
789
790 /**
791 * Cross-platform helper for setting an element's CSS `transform` property .
792 *
793 * @param {string} transformText Transform setting.
794 * @param {HTMLElement=} node Element to apply the transform to.
795 * Defaults to `this`
796 */
797 transform(transformText, node) {
798 node = node || this;
799 node.style.webkitTransform = transformText;
800 node.style.transform = transformText;
801 }
802
803 /**
804 * Cross-platform helper for setting an element's CSS `translate3d`
805 * property.
806 *
807 * @param {number} x X offset.
808 * @param {number} y Y offset.
809 * @param {number} z Z offset.
810 * @param {HTMLElement=} node Element to apply the transform to.
811 * Defaults to `this`.
812 */
813 translate3d(x, y, z, node) {
814 node = node || this;
815 this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
816 }
817
818 /**
819 * Removes an item from an array, if it exists.
820 *
821 * If the array is specified by path, a change notification is
822 * generated, so that observers, data bindings and computed
823 * properties watching that path can update.
824 *
825 * If the array is passed directly, **no change
826 * notification is generated**.
827 *
828 * @param {string | !Array<number|string>} arrayOrPath Path to array from which to remove the item
829 * (or the array itself).
830 * @param {*} item Item to remove.
831 * @return {Array} Array containing item removed.
832 */
833 arrayDelete(arrayOrPath, item) {
834 let index;
835 if (Array.isArray(arrayOrPath)) {
836 index = arrayOrPath.indexOf(item);
837 if (index >= 0) {
838 return arrayOrPath.splice(index, 1);
839 }
840 } else {
841 let arr = Polymer.Path.get(this, arrayOrPath);
842 index = arr.indexOf(item);
843 if (index >= 0) {
844 return this.splice(arrayOrPath, index, 1);
845 }
846 }
847 return null;
848 }
849
850 // logging
851
852 /**
853 * Facades `console.log`/`warn`/`error` as override point.
854 *
855 * @param {string} level One of 'log', 'warn', 'error'
856 * @param {Array} args Array of strings or objects to log
857 */
858 _logger(level, args) {
859 // accept ['foo', 'bar'] and [['foo', 'bar']]
860 if (Array.isArray(args) && args.length === 1) {
861 args = args[0];
862 }
863 switch(level) {
864 case 'log':
865 case 'warn':
866 case 'error':
867 console[level](...args);
868 }
869 }
870
871 /**
872 * Facades `console.log` as an override point.
873 *
874 * @param {...*} var_args Array of strings or objects to log
875 */
876 _log(...args) {
877 this._logger('log', args);
878 }
879
880 /**
881 * Facades `console.warn` as an override point.
882 *
883 * @param {...*} var_args Array of strings or objects to log
884 */
885 _warn(...args) {
886 this._logger('warn', args);
887 }
888
889 /**
890 * Facades `console.error` as an override point.
891 *
892 * @param {...*} var_args Array of strings or objects to log
893 */
894 _error(...args) {
895 this._logger('error', args)
896 }
897
898 /**
899 * Formats a message using the element type an a method name.
900 *
901 * @param {string} methodName Method name to associate with message
902 * @param {...*} var_args Array of strings or objects to log
903 * @return {string} String with formatting information for `console`
904 * logging.
905 */
906 _logf(...args) {
907 return ['[%s::%s]', this.is, ...args];
908 }
909
910 }
911
912 return LegacyElement;
913
914 });
915
916 })();
917 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698