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

Side by Side Diff: pkg/polymer/lib/src/js/polymer/polymer.concat.js

Issue 182193002: [polymer] interop with polymer-element and polymer.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 The Polymer Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file.
5 */
6 Polymer = {};
7
8 /*
9 * Copyright 2013 The Polymer Authors. All rights reserved.
10 * Use of this source code is governed by a BSD-style
11 * license that can be found in the LICENSE file.
12 */
13
14 // TODO(sorvell): this ensures Polymer is an object and not a function
15 // Platform is currently defining it as a function to allow for async loading
16 // of polymer; once we refine the loading process this likely goes away.
17 if (typeof window.Polymer === 'function') {
18 Polymer = {};
19 }
20
21
22 /*
23 * Copyright 2013 The Polymer Authors. All rights reserved.
24 * Use of this source code is governed by a BSD-style
25 * license that can be found in the LICENSE file.
26 */
27 (function(scope) {
28
29 // copy own properties from 'api' to 'prototype, with name hinting for 'super'
30 function extend(prototype, api) {
31 if (prototype && api) {
32 // use only own properties of 'api'
33 Object.getOwnPropertyNames(api).forEach(function(n) {
34 // acquire property descriptor
35 var pd = Object.getOwnPropertyDescriptor(api, n);
36 if (pd) {
37 // clone property via descriptor
38 Object.defineProperty(prototype, n, pd);
39 // cache name-of-method for 'super' engine
40 if (typeof pd.value == 'function') {
41 // hint the 'super' engine
42 pd.value.nom = n;
43 }
44 }
45 });
46 }
47 return prototype;
48 }
49
50 // exports
51
52 scope.extend = extend;
53
54 })(Polymer);
55
56 /*
57 * Copyright 2013 The Polymer Authors. All rights reserved.
58 * Use of this source code is governed by a BSD-style
59 * license that can be found in the LICENSE file.
60 */
61
62 (function(scope) {
63
64 // usage
65
66 // invoke cb.call(this) in 100ms, unless the job is re-registered,
67 // which resets the timer
68 //
69 // this.myJob = this.job(this.myJob, cb, 100)
70 //
71 // returns a job handle which can be used to re-register a job
72
73 var Job = function(inContext) {
74 this.context = inContext;
75 this.boundComplete = this.complete.bind(this)
76 };
77 Job.prototype = {
78 go: function(callback, wait) {
79 this.callback = callback;
80 var h;
81 if (!wait) {
82 h = requestAnimationFrame(this.boundComplete);
83 this.handle = function() {
84 cancelAnimationFrame(h);
85 }
86 } else {
87 h = setTimeout(this.boundComplete, wait);
88 this.handle = function() {
89 clearTimeout(h);
90 }
91 }
92 },
93 stop: function() {
94 if (this.handle) {
95 this.handle();
96 this.handle = null;
97 }
98 },
99 complete: function() {
100 if (this.handle) {
101 this.stop();
102 this.callback.call(this.context);
103 }
104 }
105 };
106
107 function job(job, callback, wait) {
108 if (job) {
109 job.stop();
110 } else {
111 job = new Job(this);
112 }
113 job.go(callback, wait);
114 return job;
115 }
116
117 // exports
118
119 scope.job = job;
120
121 })(Polymer);
122
123 /*
124 * Copyright 2013 The Polymer Authors. All rights reserved.
125 * Use of this source code is governed by a BSD-style
126 * license that can be found in the LICENSE file.
127 */
128 (function(scope) {
129
130 var registry = {};
131
132 HTMLElement.register = function(tag, prototype) {
133 registry[tag] = prototype;
134 }
135
136 // get prototype mapped to node <tag>
137 HTMLElement.getPrototypeForTag = function(tag) {
138 var prototype = !tag ? HTMLElement.prototype : registry[tag];
139 // TODO(sjmiles): creating <tag> is likely to have wasteful side-effects
140 return prototype || Object.getPrototypeOf(document.createElement(tag));
141 };
142
143 // we have to flag propagation stoppage for the event dispatcher
144 var originalStopPropagation = Event.prototype.stopPropagation;
145 Event.prototype.stopPropagation = function() {
146 this.cancelBubble = true;
147 originalStopPropagation.apply(this, arguments);
148 };
149
150 // TODO(sorvell): remove when we're sure imports does not need
151 // to load stylesheets
152 /*
153 HTMLImports.importer.preloadSelectors +=
154 ', polymer-element link[rel=stylesheet]';
155 */
156 })(Polymer);
157
158 /*
159 * Copyright 2013 The Polymer Authors. All rights reserved.
160 * Use of this source code is governed by a BSD-style
161 * license that can be found in the LICENSE file.
162 */
163 (function(scope) {
164 // super
165
166 // `arrayOfArgs` is an optional array of args like one might pass
167 // to `Function.apply`
168
169 // TODO(sjmiles):
170 // $super must be installed on an instance or prototype chain
171 // as `super`, and invoked via `this`, e.g.
172 // `this.super();`
173
174 // will not work if function objects are not unique, for example,
175 // when using mixins.
176 // The memoization strategy assumes each function exists on only one
177 // prototype chain i.e. we use the function object for memoizing)
178 // perhaps we can bookkeep on the prototype itself instead
179 function $super(arrayOfArgs) {
180 // since we are thunking a method call, performance is important here:
181 // memoize all lookups, once memoized the fast path calls no other
182 // functions
183 //
184 // find the caller (cannot be `strict` because of 'caller')
185 var caller = $super.caller;
186 // memoized 'name of method'
187 var nom = caller.nom;
188 // memoized next implementation prototype
189 var _super = caller._super;
190 if (!_super) {
191 if (!nom) {
192 nom = caller.nom = nameInThis.call(this, caller);
193 }
194 if (!nom) {
195 console.warn('called super() on a method not installed declaratively ( has no .nom property)');
196 }
197 // super prototype is either cached or we have to find it
198 // by searching __proto__ (at the 'top')
199 _super = memoizeSuper(caller, nom, getPrototypeOf(this));
200 }
201 if (!_super) {
202 // if _super is falsey, there is no super implementation
203 //console.warn('called $super(' + nom + ') where there is no super imple mentation');
204 } else {
205 // our super function
206 var fn = _super[nom];
207 // memoize information so 'fn' can call 'super'
208 if (!fn._super) {
209 memoizeSuper(fn, nom, _super);
210 }
211 // invoke the inherited method
212 // if 'fn' is not function valued, this will throw
213 return fn.apply(this, arrayOfArgs || []);
214 }
215 }
216
217 function nextSuper(proto, name, caller) {
218 // look for an inherited prototype that implements name
219 while (proto) {
220 if ((proto[name] !== caller) && proto[name]) {
221 return proto;
222 }
223 proto = getPrototypeOf(proto);
224 }
225 }
226
227 function memoizeSuper(method, name, proto) {
228 // find and cache next prototype containing `name`
229 // we need the prototype so we can do another lookup
230 // from here
231 method._super = nextSuper(proto, name, method);
232 if (method._super) {
233 // _super is a prototype, the actual method is _super[name]
234 // tag super method with it's name for further lookups
235 method._super[name].nom = name;
236 }
237 return method._super;
238 }
239
240 function nameInThis(value) {
241 var p = this.__proto__;
242 while (p && p !== HTMLElement.prototype) {
243 // TODO(sjmiles): getOwnPropertyNames is absurdly expensive
244 var n$ = Object.getOwnPropertyNames(p);
245 for (var i=0, l=n$.length, n; i<l && (n=n$[i]); i++) {
246 var d = Object.getOwnPropertyDescriptor(p, n);
247 if (typeof d.value === 'function' && d.value === value) {
248 return n;
249 }
250 }
251 p = p.__proto__;
252 }
253 }
254
255 // NOTE: In some platforms (IE10) the prototype chain is faked via
256 // __proto__. Therefore, always get prototype via __proto__ instead of
257 // the more standard Object.getPrototypeOf.
258 function getPrototypeOf(prototype) {
259 return prototype.__proto__;
260 }
261
262 // utility function to precompute name tags for functions
263 // in a (unchained) prototype
264 function hintSuper(prototype) {
265 // tag functions with their prototype name to optimize
266 // super call invocations
267 for (var n in prototype) {
268 var pd = Object.getOwnPropertyDescriptor(prototype, n);
269 if (pd && typeof pd.value === 'function') {
270 pd.value.nom = n;
271 }
272 }
273 }
274
275 // exports
276
277 scope.super = $super;
278
279 })(Polymer);
280
281 /*
282 * Copyright 2013 The Polymer Authors. All rights reserved.
283 * Use of this source code is governed by a BSD-style
284 * license that can be found in the LICENSE file.
285 */
286
287 (function(scope) {
288
289 var typeHandlers = {
290 string: function(value) {
291 return value;
292 },
293 date: function(value) {
294 return new Date(Date.parse(value) || Date.now());
295 },
296 boolean: function(value) {
297 if (value === '') {
298 return true;
299 }
300 return value === 'false' ? false : !!value;
301 },
302 number: function(value) {
303 var n = parseFloat(value);
304 // hex values like "0xFFFF" parseFloat as 0
305 if (n === 0) {
306 n = parseInt(value);
307 }
308 return isNaN(n) ? value : n;
309 // this code disabled because encoded values (like "0xFFFF")
310 // do not round trip to their original format
311 //return (String(floatVal) === value) ? floatVal : value;
312 },
313 object: function(value, currentValue) {
314 if (currentValue === null) {
315 return value;
316 }
317 try {
318 // If the string is an object, we can parse is with the JSON library.
319 // include convenience replace for single-quotes. If the author omits
320 // quotes altogether, parse will fail.
321 return JSON.parse(value.replace(/'/g, '"'));
322 } catch(e) {
323 // The object isn't valid JSON, return the raw value
324 return value;
325 }
326 },
327 // avoid deserialization of functions
328 'function': function(value, currentValue) {
329 return currentValue;
330 }
331 };
332
333 function deserializeValue(value, currentValue) {
334 // attempt to infer type from default value
335 var inferredType = typeof currentValue;
336 // invent 'date' type value for Date
337 if (currentValue instanceof Date) {
338 inferredType = 'date';
339 }
340 // delegate deserialization via type string
341 return typeHandlers[inferredType](value, currentValue);
342 }
343
344 // exports
345
346 scope.deserializeValue = deserializeValue;
347
348 })(Polymer);
349
350 /*
351 * Copyright 2013 The Polymer Authors. All rights reserved.
352 * Use of this source code is governed by a BSD-style
353 * license that can be found in the LICENSE file.
354 */
355 (function(scope) {
356
357 // imports
358
359 var extend = scope.extend;
360
361 // module
362
363 var api = {};
364
365 api.declaration = {};
366 api.instance = {};
367
368 api.publish = function(apis, prototype) {
369 for (var n in apis) {
370 extend(prototype, apis[n]);
371 }
372 }
373
374 // exports
375
376 scope.api = api;
377
378 })(Polymer);
379
380 /*
381 * Copyright 2013 The Polymer Authors. All rights reserved.
382 * Use of this source code is governed by a BSD-style
383 * license that can be found in the LICENSE file.
384 */
385 (function(scope) {
386
387 var utils = {
388 /**
389 * Invokes a function asynchronously. The context of the callback
390 * function is bound to 'this' automatically.
391 * @method async
392 * @param {Function|String} method
393 * @param {any|Array} args
394 * @param {number} timeout
395 */
396 async: function(method, args, timeout) {
397 // when polyfilling Object.observe, ensure changes
398 // propagate before executing the async method
399 Platform.flush();
400 // second argument to `apply` must be an array
401 args = (args && args.length) ? args : [args];
402 // function to invoke
403 var fn = function() {
404 (this[method] || method).apply(this, args);
405 }.bind(this);
406 // execute `fn` sooner or later
407 var handle = timeout ? setTimeout(fn, timeout) :
408 requestAnimationFrame(fn);
409 // NOTE: switch on inverting handle to determine which time is used.
410 return timeout ? handle : 1 / handle;
411 },
412 cancelAsync: function(handle) {
413 if (handle < 1) {
414 cancelAnimationFrame(Math.round(1 / handle));
415 } else {
416 clearTimeout(handle);
417 }
418 },
419 /**
420 * Fire an event.
421 * @method fire
422 * @returns {Object} event
423 * @param {string} type An event name.
424 * @param {any} detail
425 * @param {Node} onNode Target node.
426 */
427 fire: function(type, detail, onNode, bubbles, cancelable) {
428 var node = onNode || this;
429 var detail = detail || {};
430 var event = new CustomEvent(type, {
431 bubbles: (bubbles !== undefined ? bubbles : true),
432 cancelable: (cancelable !== undefined ? cancelable : true),
433 detail: detail
434 });
435 node.dispatchEvent(event);
436 return event;
437 },
438 /**
439 * Fire an event asynchronously.
440 * @method asyncFire
441 * @param {string} type An event name.
442 * @param detail
443 * @param {Node} toNode Target node.
444 */
445 asyncFire: function(/*inType, inDetail*/) {
446 this.async("fire", arguments);
447 },
448 /**
449 * Remove class from old, add class to anew, if they exist
450 * @param classFollows
451 * @param anew A node.
452 * @param old A node
453 * @param className
454 */
455 classFollows: function(anew, old, className) {
456 if (old) {
457 old.classList.remove(className);
458 }
459 if (anew) {
460 anew.classList.add(className);
461 }
462 }
463 };
464
465 // no-operation function for handy stubs
466 var nop = function() {};
467
468 // null-object for handy stubs
469 var nob = {};
470
471 // deprecated
472
473 utils.asyncMethod = utils.async;
474
475 // exports
476
477 scope.api.instance.utils = utils;
478 scope.nop = nop;
479 scope.nob = nob;
480
481 })(Polymer);
482
483 /*
484 * Copyright 2013 The Polymer Authors. All rights reserved.
485 * Use of this source code is governed by a BSD-style
486 * license that can be found in the LICENSE file.
487 */
488
489 (function(scope) {
490
491 // imports
492
493 var log = window.logFlags || {};
494 var EVENT_PREFIX = 'on-';
495
496 // instance events api
497 var events = {
498 // read-only
499 EVENT_PREFIX: EVENT_PREFIX,
500 // event listeners on host
501 addHostListeners: function() {
502 var events = this.eventDelegates;
503 log.events && (Object.keys(events).length > 0) && console.log('[%s] addHos tListeners:', this.localName, events);
504 // NOTE: host events look like bindings but really are not;
505 // (1) we don't want the attribute to be set and (2) we want to support
506 // multiple event listeners ('host' and 'instance') and Node.bind
507 // by default supports 1 thing being bound.
508 // We do, however, leverage the event hookup code in PolymerExpressions
509 // so that we have a common code path for handling declarative events.
510 var self = this, bindable, eventName;
511 for (var n in events) {
512 eventName = EVENT_PREFIX + n;
513 bindable = PolymerExpressions.prepareEventBinding(
514 Path.get(events[n]),
515 eventName,
516 {
517 resolveEventHandler: function(model, path, node) {
518 var fn = path.getValueFrom(self);
519 if (fn) {
520 return fn.bind(self);
521 }
522 }
523 }
524 );
525 bindable(this, this, false);
526 }
527 },
528 // call 'method' or function method on 'obj' with 'args', if the method exis ts
529 dispatchMethod: function(obj, method, args) {
530 if (obj) {
531 log.events && console.group('[%s] dispatch [%s]', obj.localName, method) ;
532 var fn = typeof method === 'function' ? method : obj[method];
533 if (fn) {
534 fn[args ? 'apply' : 'call'](obj, args);
535 }
536 log.events && console.groupEnd();
537 Platform.flush();
538 }
539 }
540 };
541
542 // exports
543
544 scope.api.instance.events = events;
545
546 })(Polymer);
547
548 /*
549 * Copyright 2013 The Polymer Authors. All rights reserved.
550 * Use of this source code is governed by a BSD-style
551 * license that can be found in the LICENSE file.
552 */
553 (function(scope) {
554
555 // instance api for attributes
556
557 var attributes = {
558 copyInstanceAttributes: function () {
559 var a$ = this._instanceAttributes;
560 for (var k in a$) {
561 if (!this.hasAttribute(k)) {
562 this.setAttribute(k, a$[k]);
563 }
564 }
565 },
566 // for each attribute on this, deserialize value to property as needed
567 takeAttributes: function() {
568 // if we have no publish lookup table, we have no attributes to take
569 // TODO(sjmiles): ad hoc
570 if (this._publishLC) {
571 for (var i=0, a$=this.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {
572 this.attributeToProperty(a.name, a.value);
573 }
574 }
575 },
576 // if attribute 'name' is mapped to a property, deserialize
577 // 'value' into that property
578 attributeToProperty: function(name, value) {
579 // try to match this attribute to a property (attributes are
580 // all lower-case, so this is case-insensitive search)
581 var name = this.propertyForAttribute(name);
582 if (name) {
583 // filter out 'mustached' values, these are to be
584 // replaced with bound-data and are not yet values
585 // themselves
586 if (value && value.search(scope.bindPattern) >= 0) {
587 return;
588 }
589 // get original value
590 var currentValue = this[name];
591 // deserialize Boolean or Number values from attribute
592 var value = this.deserializeValue(value, currentValue);
593 // only act if the value has changed
594 if (value !== currentValue) {
595 // install new value (has side-effects)
596 this[name] = value;
597 }
598 }
599 },
600 // return the published property matching name, or undefined
601 propertyForAttribute: function(name) {
602 var match = this._publishLC && this._publishLC[name];
603 //console.log('propertyForAttribute:', name, 'matches', match);
604 return match;
605 },
606 // convert representation of 'stringValue' based on type of 'currentValue'
607 deserializeValue: function(stringValue, currentValue) {
608 return scope.deserializeValue(stringValue, currentValue);
609 },
610 serializeValue: function(value, inferredType) {
611 if (inferredType === 'boolean') {
612 return value ? '' : undefined;
613 } else if (inferredType !== 'object' && inferredType !== 'function'
614 && value !== undefined) {
615 return value;
616 }
617 },
618 reflectPropertyToAttribute: function(name) {
619 var inferredType = typeof this[name];
620 // try to intelligently serialize property value
621 var serializedValue = this.serializeValue(this[name], inferredType);
622 // boolean properties must reflect as boolean attributes
623 if (serializedValue !== undefined) {
624 this.setAttribute(name, serializedValue);
625 // TODO(sorvell): we should remove attr for all properties
626 // that have undefined serialization; however, we will need to
627 // refine the attr reflection system to achieve this; pica, for example,
628 // relies on having inferredType object properties not removed as
629 // attrs.
630 } else if (inferredType === 'boolean') {
631 this.removeAttribute(name);
632 }
633 }
634 };
635
636 // exports
637
638 scope.api.instance.attributes = attributes;
639
640 })(Polymer);
641
642 /*
643 * Copyright 2013 The Polymer Authors. All rights reserved.
644 * Use of this source code is governed by a BSD-style
645 * license that can be found in the LICENSE file.
646 */
647 (function(scope) {
648
649 // imports
650
651 var log = window.logFlags || {};
652
653 // magic words
654
655 var OBSERVE_SUFFIX = 'Changed';
656
657 // element api
658
659 var empty = [];
660
661 var properties = {
662 observeProperties: function() {
663 var n$ = this._observeNames, pn$ = this._publishNames;
664 if ((n$ && n$.length) || (pn$ && pn$.length)) {
665 var self = this;
666 var o = this._propertyObserver = new CompoundObserver();
667 for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
668 o.addPath(this, n);
669 // observer array properties
670 var pd = Object.getOwnPropertyDescriptor(this.__proto__, n);
671 if (pd && pd.value) {
672 this.observeArrayValue(n, pd.value, null);
673 }
674 }
675 for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) {
676 if (!this.observe || (this.observe[n] === undefined)) {
677 o.addPath(this, n);
678 }
679 }
680 o.open(this.notifyPropertyChanges, this);
681 }
682 },
683 notifyPropertyChanges: function(newValues, oldValues, paths) {
684 var name, method, called = {};
685 for (var i in oldValues) {
686 // note: paths is of form [object, path, object, path]
687 name = paths[2 * i + 1];
688 if (this.publish[name] !== undefined) {
689 this.reflectPropertyToAttribute(name);
690 }
691 method = this.observe[name];
692 if (method) {
693 this.observeArrayValue(name, newValues[i], oldValues[i]);
694 if (!called[method]) {
695 called[method] = true;
696 // observes the value if it is an array
697 this.invokeMethod(method, [oldValues[i], newValues[i], arguments]);
698 }
699 }
700 }
701 },
702 observeArrayValue: function(name, value, old) {
703 // we only care if there are registered side-effects
704 var callbackName = this.observe[name];
705 if (callbackName) {
706 // if we are observing the previous value, stop
707 if (Array.isArray(old)) {
708 log.observe && console.log('[%s] observeArrayValue: unregister observe r [%s]', this.localName, name);
709 this.unregisterObserver(name + '__array');
710 }
711 // if the new value is an array, being observing it
712 if (Array.isArray(value)) {
713 log.observe && console.log('[%s] observeArrayValue: register observer [%s]', this.localName, name, value);
714 var observer = new ArrayObserver(value);
715 observer.open(function(value, old) {
716 this.invokeMethod(callbackName, [old]);
717 }, this);
718 this.registerObserver(name + '__array', observer);
719 }
720 }
721 },
722 bindProperty: function(property, observable) {
723 // apply Polymer two-way reference binding
724 return bindProperties(this, property, observable);
725 },
726 unbindAllProperties: function() {
727 if (this._propertyObserver) {
728 this._propertyObserver.close();
729 }
730 this.unregisterObservers();
731 },
732 unbindProperty: function(name) {
733 return this.unregisterObserver(name);
734 },
735 invokeMethod: function(method, args) {
736 var fn = this[method] || method;
737 if (typeof fn === 'function') {
738 fn.apply(this, args);
739 }
740 },
741 // bookkeeping observers for memory management
742 registerObserver: function(name, observer) {
743 var o$ = this._observers || (this._observers = {});
744 o$[name] = observer;
745 },
746 unregisterObserver: function(name) {
747 var o$ = this._observers;
748 if (o$ && o$[name]) {
749 o$[name].close();
750 o$[name] = null;
751 return true;
752 }
753 },
754 unregisterObservers: function() {
755 if (this._observers) {
756 var keys=Object.keys(this._observers);
757 for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) {
758 o = this._observers[k];
759 o.close();
760 }
761 this._observers = {};
762 }
763 }
764 };
765
766 // property binding
767 // bind a property in A to a path in B by converting A[property] to a
768 // getter/setter pair that accesses B[...path...]
769 function bindProperties(inA, inProperty, observable) {
770 log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, i nA.localName, inProperty);
771 // capture A's value if B's value is null or undefined,
772 // otherwise use B's value
773 // TODO(sorvell): need to review, can do with ObserverTransform
774 var v = observable.discardChanges();
775 if (v === null || v === undefined) {
776 observable.setValue(inA[inProperty]);
777 }
778 return Observer.defineComputedProperty(inA, inProperty, observable);
779 }
780
781 // logging
782 var LOG_OBSERVE = '[%s] watching [%s]';
783 var LOG_OBSERVED = '[%s#%s] watch: [%s] now [%s] was [%s]';
784 var LOG_CHANGED = '[%s#%s] propertyChanged: [%s] now [%s] was [%s]';
785 var LOG_BIND_PROPS = "[%s]: bindProperties: [%s] to [%s].[%s]";
786
787 // exports
788
789 scope.api.instance.properties = properties;
790
791 })(Polymer);
792
793 /*
794 * Copyright 2013 The Polymer Authors. All rights reserved.
795 * Use of this source code is governed by a BSD-style
796 * license that can be found in the LICENSE file.
797 */
798 (function(scope) {
799
800 // imports
801
802 var log = window.logFlags || 0;
803 var events = scope.api.instance.events;
804
805 var syntax = new PolymerExpressions();
806 syntax.resolveEventHandler = function(model, path, node) {
807 var ctlr = findEventController(node);
808 if (ctlr) {
809 var fn = path.getValueFrom(ctlr);
810 if (fn) {
811 return fn.bind(ctlr);
812 }
813 }
814 }
815
816 // An event controller is the host element for the shadowRoot in which
817 // the node exists, or the first ancestor with a 'lightDomController'
818 // property.
819 function findEventController(node) {
820 while (node.parentNode) {
821 if (node.lightDomController) {
822 return node;
823 }
824 node = node.parentNode;
825 }
826 return node.host;
827 };
828
829 // element api supporting mdv
830
831 var mdv = {
832 syntax: syntax,
833 instanceTemplate: function(template) {
834 return template.createInstance(this, this.syntax);
835 },
836 bind: function(name, observable, oneTime) {
837 // note: binding is a prepare signal. This allows us to be sure that any
838 // property changes that occur as a result of binding will be observed.
839 if (!this._elementPrepared) {
840 this.prepareElement();
841 }
842 var property = this.propertyForAttribute(name);
843 if (!property) {
844 // TODO(sjmiles): this mixin method must use the special form
845 // of `super` installed by `mixinMethod` in declaration/prototype.js
846 return this.mixinSuper(arguments);
847 } else {
848 // clean out the closets
849 this.unbind(name);
850 // use n-way Polymer binding
851 var observer = this.bindProperty(property, observable);
852 // stick path on observer so it's available via this.bindings
853 observer.path = observable.path_;
854 // reflect bound property to attribute when binding
855 // to ensure binding is not left on attribute if property
856 // does not update due to not changing.
857 this.reflectPropertyToAttribute(property);
858 return this.bindings[name] = observer;
859 }
860 },
861 asyncUnbindAll: function() {
862 if (!this._unbound) {
863 log.unbind && console.log('[%s] asyncUnbindAll', this.localName);
864 this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);
865 }
866 },
867 unbindAll: function() {
868 if (!this._unbound) {
869 this.unbindAllProperties();
870 this.super();
871 // unbind shadowRoot
872 var root = this.shadowRoot;
873 while (root) {
874 unbindNodeTree(root);
875 root = root.olderShadowRoot;
876 }
877 this._unbound = true;
878 }
879 },
880 cancelUnbindAll: function(preventCascade) {
881 if (this._unbound) {
882 log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAl l', this.localName);
883 return;
884 }
885 log.unbind && console.log('[%s] cancelUnbindAll', this.localName);
886 if (this._unbindAllJob) {
887 this._unbindAllJob = this._unbindAllJob.stop();
888 }
889 // cancel unbinding our shadow tree iff we're not in the process of
890 // cascading our tree (as we do, for example, when the element is inserted ).
891 if (!preventCascade) {
892 forNodeTree(this.shadowRoot, function(n) {
893 if (n.cancelUnbindAll) {
894 n.cancelUnbindAll();
895 }
896 });
897 }
898 }
899 };
900
901 function unbindNodeTree(node) {
902 forNodeTree(node, _nodeUnbindAll);
903 }
904
905 function _nodeUnbindAll(node) {
906 node.unbindAll();
907 }
908
909 function forNodeTree(node, callback) {
910 if (node) {
911 callback(node);
912 for (var child = node.firstChild; child; child = child.nextSibling) {
913 forNodeTree(child, callback);
914 }
915 }
916 }
917
918 var mustachePattern = /\{\{([^{}]*)}}/;
919
920 // exports
921
922 scope.bindPattern = mustachePattern;
923 scope.api.instance.mdv = mdv;
924
925 })(Polymer);
926
927 /*
928 * Copyright 2013 The Polymer Authors. All rights reserved.
929 * Use of this source code is governed by a BSD-style
930 * license that can be found in the LICENSE file.
931 */
932 (function(scope) {
933 var preparingElements = 0;
934
935 var base = {
936 PolymerBase: true,
937 job: Polymer.job,
938 super: Polymer.super,
939 // user entry point for element has had its createdCallback called
940 created: function() {
941 },
942 // user entry point for element has shadowRoot and is ready for
943 // api interaction
944 ready: function() {
945 },
946 createdCallback: function() {
947 this.created();
948 if (this.ownerDocument.defaultView || this.alwaysPrepare ||
949 preparingElements > 0) {
950 this.prepareElement();
951 }
952 },
953 // system entry point, do not override
954 prepareElement: function() {
955 this._elementPrepared = true;
956 // install shadowRoots storage
957 this.shadowRoots = {};
958 // install property observers
959 this.observeProperties();
960 // install boilerplate attributes
961 this.copyInstanceAttributes();
962 // process input attributes
963 this.takeAttributes();
964 // add event listeners
965 this.addHostListeners();
966 // guarantees that while preparing, any
967 // sub-elements are also prepared
968 preparingElements++;
969 // process declarative resources
970 this.parseDeclarations(this.__proto__);
971 // decrement semaphore
972 preparingElements--;
973 // TODO(sorvell): CE polyfill uses unresolved attribute to simulate
974 // :unresolved; remove this attribute to be compatible with native
975 // CE.
976 this.removeAttribute('unresolved');
977 // user entry point
978 this.ready();
979 },
980 attachedCallback: function() {
981 if (!this._elementPrepared) {
982 this.prepareElement();
983 }
984 this.cancelUnbindAll(true);
985 // invoke user action
986 if (this.attached) {
987 this.attached();
988 }
989 // TODO(sorvell): bc
990 if (this.enteredView) {
991 this.enteredView();
992 }
993 // NOTE: domReady can be used to access elements in dom (descendants,
994 // ancestors, siblings) such that the developer is enured to upgrade
995 // ordering. If the element definitions have loaded, domReady
996 // can be used to access upgraded elements.
997 if (!this.hasBeenAttached) {
998 this.hasBeenAttached = true;
999 if (this.domReady) {
1000 this.async('domReady');
1001 }
1002 }
1003 },
1004 detachedCallback: function() {
1005 if (!this.preventDispose) {
1006 this.asyncUnbindAll();
1007 }
1008 // invoke user action
1009 if (this.detached) {
1010 this.detached();
1011 }
1012 // TODO(sorvell): bc
1013 if (this.leftView) {
1014 this.leftView();
1015 }
1016 },
1017 // TODO(sorvell): bc
1018 enteredViewCallback: function() {
1019 this.attachedCallback();
1020 },
1021 // TODO(sorvell): bc
1022 leftViewCallback: function() {
1023 this.detachedCallback();
1024 },
1025 // TODO(sorvell): bc
1026 enteredDocumentCallback: function() {
1027 this.attachedCallback();
1028 },
1029 // TODO(sorvell): bc
1030 leftDocumentCallback: function() {
1031 this.detachedCallback();
1032 },
1033 // recursive ancestral <element> initialization, oldest first
1034 parseDeclarations: function(p) {
1035 if (p && p.element) {
1036 this.parseDeclarations(p.__proto__);
1037 p.parseDeclaration.call(this, p.element);
1038 }
1039 },
1040 // parse input <element> as needed, override for custom behavior
1041 parseDeclaration: function(elementElement) {
1042 var template = this.fetchTemplate(elementElement);
1043 if (template) {
1044 var root = this.shadowFromTemplate(template);
1045 this.shadowRoots[elementElement.name] = root;
1046 }
1047 },
1048 // return a shadow-root template (if desired), override for custom behavior
1049 fetchTemplate: function(elementElement) {
1050 return elementElement.querySelector('template');
1051 },
1052 // utility function that creates a shadow root from a <template>
1053 shadowFromTemplate: function(template) {
1054 if (template) {
1055 // make a shadow root
1056 var root = this.createShadowRoot();
1057 // migrate flag(s)
1058 root.resetStyleInheritance = this.resetStyleInheritance;
1059 // stamp template
1060 // which includes parsing and applying MDV bindings before being
1061 // inserted (to avoid {{}} in attribute values)
1062 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
1063 var dom = this.instanceTemplate(template);
1064 // append to shadow dom
1065 root.appendChild(dom);
1066 // perform post-construction initialization tasks on shadow root
1067 this.shadowRootReady(root, template);
1068 // return the created shadow root
1069 return root;
1070 }
1071 },
1072 // utility function that stamps a <template> into light-dom
1073 lightFromTemplate: function(template) {
1074 if (template) {
1075 // TODO(sorvell): mark this element as a lightDOMController so that
1076 // event listeners on bound nodes inside it will be called on it.
1077 // Note, the expectation here is that events on all descendants
1078 // should be handled by this element.
1079 this.lightDomController = true;
1080 // stamp template
1081 // which includes parsing and applying MDV bindings before being
1082 // inserted (to avoid {{}} in attribute values)
1083 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
1084 var dom = this.instanceTemplate(template);
1085 // append to shadow dom
1086 this.appendChild(dom);
1087 // perform post-construction initialization tasks on ahem, light root
1088 this.shadowRootReady(this, template);
1089 // return the created shadow root
1090 return dom;
1091 }
1092 },
1093 shadowRootReady: function(root, template) {
1094 // locate nodes with id and store references to them in this.$ hash
1095 this.marshalNodeReferences(root);
1096 // set up pointer gestures
1097 PointerGestures.register(root);
1098 },
1099 // locate nodes with id and store references to them in this.$ hash
1100 marshalNodeReferences: function(root) {
1101 // establish $ instance variable
1102 var $ = this.$ = this.$ || {};
1103 // populate $ from nodes with ID from the LOCAL tree
1104 if (root) {
1105 var n$ = root.querySelectorAll("[id]");
1106 for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
1107 $[n.id] = n;
1108 };
1109 }
1110 },
1111 attributeChangedCallback: function(name, oldValue) {
1112 // TODO(sjmiles): adhoc filter
1113 if (name !== 'class' && name !== 'style') {
1114 this.attributeToProperty(name, this.getAttribute(name));
1115 }
1116 if (this.attributeChanged) {
1117 this.attributeChanged.apply(this, arguments);
1118 }
1119 },
1120 onMutation: function(node, listener) {
1121 var observer = new MutationObserver(function(mutations) {
1122 listener.call(this, observer, mutations);
1123 observer.disconnect();
1124 }.bind(this));
1125 observer.observe(node, {childList: true, subtree: true});
1126 }
1127 };
1128
1129 // true if object has own PolymerBase api
1130 function isBase(object) {
1131 return object.hasOwnProperty('PolymerBase')
1132 }
1133
1134 // name a base constructor for dev tools
1135
1136 function PolymerBase() {};
1137 PolymerBase.prototype = base;
1138 base.constructor = PolymerBase;
1139
1140 // exports
1141
1142 scope.Base = PolymerBase;
1143 scope.isBase = isBase;
1144 scope.api.instance.base = base;
1145
1146 })(Polymer);
1147
1148 /*
1149 * Copyright 2013 The Polymer Authors. All rights reserved.
1150 * Use of this source code is governed by a BSD-style
1151 * license that can be found in the LICENSE file.
1152 */
1153 (function(scope) {
1154
1155 // imports
1156
1157 var log = window.logFlags || {};
1158
1159 // magic words
1160
1161 var STYLE_SCOPE_ATTRIBUTE = 'element';
1162 var STYLE_CONTROLLER_SCOPE = 'controller';
1163
1164 var styles = {
1165 STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE,
1166 /**
1167 * Installs external stylesheets and <style> elements with the attribute
1168 * polymer-scope='controller' into the scope of element. This is intended
1169 * to be a called during custom element construction. Note, this incurs a
1170 * per instance cost and should be used sparingly.
1171 *
1172 * The need for this type of styling should go away when the shadowDOM spec
1173 * addresses these issues:
1174 *
1175 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391
1176 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390
1177 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389
1178 *
1179 * @param element The custom element instance into whose controller (parent)
1180 * scope styles will be installed.
1181 * @param elementElement The <element> containing controller styles.
1182 */
1183 // TODO(sorvell): remove when spec issues are addressed
1184 installControllerStyles: function() {
1185 // apply controller styles, but only if they are not yet applied
1186 var scope = this.findStyleController();
1187 if (scope && !this.scopeHasElementStyle(scope, STYLE_CONTROLLER_SCOPE)) {
1188 // allow inherited controller styles
1189 var proto = getPrototypeOf(this), cssText = '';
1190 while (proto && proto.element) {
1191 cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE);
1192 proto = getPrototypeOf(proto);
1193 }
1194 if (cssText) {
1195 var style = this.element.cssTextToScopeStyle(cssText,
1196 STYLE_CONTROLLER_SCOPE);
1197 // TODO(sorvell): for now these styles are not shimmed
1198 // but we may need to shim them
1199 Polymer.applyStyleToScope(style, scope);
1200 }
1201 }
1202 },
1203 findStyleController: function() {
1204 if (window.ShadowDOMPolyfill) {
1205 return wrap(document.head);
1206 } else {
1207 // find the shadow root that contains this element
1208 var n = this;
1209 while (n.parentNode) {
1210 n = n.parentNode;
1211 }
1212 return n === document ? document.head : n;
1213 }
1214 },
1215 scopeHasElementStyle: function(scope, descriptor) {
1216 var rule = STYLE_SCOPE_ATTRIBUTE + '=' + this.localName + '-' + descriptor ;
1217 return scope.querySelector('style[' + rule + ']');
1218 }
1219 };
1220
1221 // NOTE: use raw prototype traversal so that we ensure correct traversal
1222 // on platforms where the protoype chain is simulated via __proto__ (IE10)
1223 function getPrototypeOf(prototype) {
1224 return prototype.__proto__;
1225 }
1226
1227 // exports
1228
1229 scope.api.instance.styles = styles;
1230
1231 })(Polymer);
1232
1233 /*
1234 * Copyright 2013 The Polymer Authors. All rights reserved.
1235 * Use of this source code is governed by a BSD-style
1236 * license that can be found in the LICENSE file.
1237 */
1238 (function(scope) {
1239
1240 // imports
1241
1242 var extend = scope.extend;
1243 var api = scope.api;
1244
1245 // imperative implementation: Polymer()
1246
1247 // specify an 'own' prototype for tag `name`
1248 function element(name, prototype) {
1249 if (getRegisteredPrototype[name]) {
1250 throw 'Already registered (Polymer) prototype for element ' + name;
1251 }
1252 // cache the prototype
1253 registerPrototype(name, prototype);
1254 // notify the registrar waiting for 'name', if any
1255 notifyPrototype(name);
1256 }
1257
1258 // async prototype source
1259
1260 function waitingForPrototype(name, client) {
1261 waitPrototype[name] = client;
1262 }
1263
1264 var waitPrototype = {};
1265
1266 function notifyPrototype(name) {
1267 if (waitPrototype[name]) {
1268 waitPrototype[name].registerWhenReady();
1269 delete waitPrototype[name];
1270 }
1271 }
1272
1273 // utility and bookkeeping
1274
1275 // maps tag names to prototypes, as registered with
1276 // Polymer. Prototypes associated with a tag name
1277 // using document.registerElement are available from
1278 // HTMLElement.getPrototypeForTag().
1279 // If an element was fully registered by Polymer, then
1280 // Polymer.getRegisteredPrototype(name) ===
1281 // HTMLElement.getPrototypeForTag(name)
1282
1283 var prototypesByName = {};
1284
1285 function registerPrototype(name, prototype) {
1286 return prototypesByName[name] = prototype || {};
1287 }
1288
1289 function getRegisteredPrototype(name) {
1290 return prototypesByName[name];
1291 }
1292
1293 // exports
1294
1295 scope.getRegisteredPrototype = getRegisteredPrototype;
1296 scope.waitingForPrototype = waitingForPrototype;
1297
1298 // namespace shenanigans so we can expose our scope on the registration
1299 // function
1300
1301 // make window.Polymer reference `element()`
1302
1303 window.Polymer = element;
1304
1305 // TODO(sjmiles): find a way to do this that is less terrible
1306 // copy window.Polymer properties onto `element()`
1307
1308 extend(Polymer, scope);
1309
1310 // Under the HTMLImports polyfill, scripts in the main document
1311 // do not block on imports; we want to allow calls to Polymer in the main
1312 // document. Platform collects those calls until we can process them, which
1313 // we do here.
1314
1315 var declarations = Platform.deliverDeclarations();
1316 if (declarations) {
1317 for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {
1318 element.apply(null, d);
1319 }
1320 }
1321
1322 })(Polymer);
1323
1324 /*
1325 * Copyright 2013 The Polymer Authors. All rights reserved.
1326 * Use of this source code is governed by a BSD-style
1327 * license that can be found in the LICENSE file.
1328 */
1329
1330 (function(scope) {
1331
1332 var path = {
1333 resolveElementPaths: function(node) {
1334 Platform.urlResolver.resolveDom(node);
1335 },
1336 addResolvePathApi: function() {
1337 // let assetpath attribute modify the resolve path
1338 var assetPath = this.getAttribute('assetpath') || '';
1339 var root = new URL(assetPath, this.ownerDocument.baseURI);
1340 this.prototype.resolvePath = function(urlPath, base) {
1341 var u = new URL(urlPath, base || root);
1342 return u.href;
1343 };
1344 }
1345 };
1346
1347 // exports
1348 scope.api.declaration.path = path;
1349
1350 })(Polymer);
1351
1352 /*
1353 * Copyright 2013 The Polymer Authors. All rights reserved.
1354 * Use of this source code is governed by a BSD-style
1355 * license that can be found in the LICENSE file.
1356 */
1357 (function(scope) {
1358
1359 // imports
1360
1361 var log = window.logFlags || {};
1362 var api = scope.api.instance.styles;
1363 var STYLE_SCOPE_ATTRIBUTE = api.STYLE_SCOPE_ATTRIBUTE;
1364
1365 // magic words
1366
1367 var STYLE_SELECTOR = 'style';
1368 var STYLE_LOADABLE_MATCH = '@import';
1369 var SHEET_SELECTOR = 'link[rel=stylesheet]';
1370 var STYLE_GLOBAL_SCOPE = 'global';
1371 var SCOPE_ATTR = 'polymer-scope';
1372
1373 var styles = {
1374 // returns true if resources are loading
1375 loadStyles: function(callback) {
1376 var content = this.templateContent();
1377 if (content) {
1378 this.convertSheetsToStyles(content);
1379 }
1380 var styles = this.findLoadableStyles(content);
1381 if (styles.length) {
1382 Platform.styleResolver.loadStyles(styles, callback);
1383 } else if (callback) {
1384 callback();
1385 }
1386 },
1387 convertSheetsToStyles: function(root) {
1388 var s$ = root.querySelectorAll(SHEET_SELECTOR);
1389 for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) {
1390 c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI) ,
1391 this.ownerDocument);
1392 this.copySheetAttributes(c, s);
1393 s.parentNode.replaceChild(c, s);
1394 }
1395 },
1396 copySheetAttributes: function(style, link) {
1397 for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {
1398 if (a.name !== 'rel' && a.name !== 'src') {
1399 style.setAttribute(a.name, a.value);
1400 }
1401 }
1402 },
1403 findLoadableStyles: function(root) {
1404 var loadables = [];
1405 if (root) {
1406 var s$ = root.querySelectorAll(STYLE_SELECTOR);
1407 for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {
1408 if (s.textContent.match(STYLE_LOADABLE_MATCH)) {
1409 loadables.push(s);
1410 }
1411 }
1412 }
1413 return loadables;
1414 },
1415 /**
1416 * Install external stylesheets loaded in <polymer-element> elements into th e
1417 * element's template.
1418 * @param elementElement The <element> element to style.
1419 */
1420 // TODO(sorvell): wip... caching and styles handling can probably be removed
1421 // We need a scheme to ensure stylesheets are eagerly loaded without
1422 // the creation of an element instance. Here are 2 options for handling this :
1423 // 1. create a dummy element with ShadowDOM in dom that includes ALL styles
1424 // processed here.
1425 // 2. place stylesheets outside the element template. This will allow
1426 // imports to naturally load the sheets. Then at load time, we can remove
1427 // the stylesheet from dom.
1428 installSheets: function() {
1429 this.cacheSheets();
1430 this.cacheStyles();
1431 this.installLocalSheets();
1432 this.installGlobalStyles();
1433 },
1434 /**
1435 * Remove all sheets from element and store for later use.
1436 */
1437 cacheSheets: function() {
1438 this.sheets = this.findNodes(SHEET_SELECTOR);
1439 this.sheets.forEach(function(s) {
1440 if (s.parentNode) {
1441 s.parentNode.removeChild(s);
1442 }
1443 });
1444 },
1445 cacheStyles: function() {
1446 this.styles = this.findNodes(STYLE_SELECTOR + '[' + SCOPE_ATTR + ']');
1447 this.styles.forEach(function(s) {
1448 if (s.parentNode) {
1449 s.parentNode.removeChild(s);
1450 }
1451 });
1452 },
1453 /**
1454 * Takes external stylesheets loaded in an <element> element and moves
1455 * their content into a <style> element inside the <element>'s template.
1456 * The sheet is then removed from the <element>. This is done only so
1457 * that if the element is loaded in the main document, the sheet does
1458 * not become active.
1459 * Note, ignores sheets with the attribute 'polymer-scope'.
1460 * @param elementElement The <element> element to style.
1461 */
1462 installLocalSheets: function () {
1463 var sheets = this.sheets.filter(function(s) {
1464 return !s.hasAttribute(SCOPE_ATTR);
1465 });
1466 var content = this.templateContent();
1467 if (content) {
1468 var cssText = '';
1469 sheets.forEach(function(sheet) {
1470 cssText += cssTextFromSheet(sheet) + '\n';
1471 });
1472 if (cssText) {
1473 var style = createStyleElement(cssText, this.ownerDocument);
1474 content.insertBefore(style, content.firstChild);
1475 }
1476 }
1477 },
1478 findNodes: function(selector, matcher) {
1479 var nodes = this.querySelectorAll(selector).array();
1480 var content = this.templateContent();
1481 if (content) {
1482 var templateNodes = content.querySelectorAll(selector).array();
1483 nodes = nodes.concat(templateNodes);
1484 }
1485 return matcher ? nodes.filter(matcher) : nodes;
1486 },
1487 templateContent: function() {
1488 var template = this.querySelector('template');
1489 return template && templateContent(template);
1490 },
1491 /**
1492 * Promotes external stylesheets and <style> elements with the attribute
1493 * polymer-scope='global' into global scope.
1494 * This is particularly useful for defining @keyframe rules which
1495 * currently do not function in scoped or shadow style elements.
1496 * (See wkb.ug/72462)
1497 * @param elementElement The <element> element to style.
1498 */
1499 // TODO(sorvell): remove when wkb.ug/72462 is addressed.
1500 installGlobalStyles: function() {
1501 var style = this.styleForScope(STYLE_GLOBAL_SCOPE);
1502 applyStyleToScope(style, document.head);
1503 },
1504 cssTextForScope: function(scopeDescriptor) {
1505 var cssText = '';
1506 // handle stylesheets
1507 var selector = '[' + SCOPE_ATTR + '=' + scopeDescriptor + ']';
1508 var matcher = function(s) {
1509 return matchesSelector(s, selector);
1510 };
1511 var sheets = this.sheets.filter(matcher);
1512 sheets.forEach(function(sheet) {
1513 cssText += cssTextFromSheet(sheet) + '\n\n';
1514 });
1515 // handle cached style elements
1516 var styles = this.styles.filter(matcher);
1517 styles.forEach(function(style) {
1518 cssText += style.textContent + '\n\n';
1519 });
1520 return cssText;
1521 },
1522 styleForScope: function(scopeDescriptor) {
1523 var cssText = this.cssTextForScope(scopeDescriptor);
1524 return this.cssTextToScopeStyle(cssText, scopeDescriptor);
1525 },
1526 cssTextToScopeStyle: function(cssText, scopeDescriptor) {
1527 if (cssText) {
1528 var style = createStyleElement(cssText);
1529 style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') +
1530 '-' + scopeDescriptor);
1531 return style;
1532 }
1533 }
1534 };
1535
1536 function importRuleForSheet(sheet, baseUrl) {
1537 var href = new URL(sheet.getAttribute('href'), baseUrl).href;
1538 return '@import \'' + href + '\';'
1539 }
1540
1541 function applyStyleToScope(style, scope) {
1542 if (style) {
1543 // TODO(sorvell): necessary for IE
1544 // see https://connect.microsoft.com/IE/feedback/details/790212/
1545 // cloning-a-style-element-and-adding-to-document-produces
1546 // -unexpected-result#details
1547 // var clone = style.cloneNode(true);
1548 var clone = createStyleElement(style.textContent);
1549 var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE);
1550 if (attr) {
1551 clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr);
1552 }
1553 scope.appendChild(clone);
1554 }
1555 }
1556
1557 function createStyleElement(cssText, scope) {
1558 scope = scope || document;
1559 scope = scope.createElement ? scope : scope.ownerDocument;
1560 var style = scope.createElement('style');
1561 style.textContent = cssText;
1562 return style;
1563 }
1564
1565 function cssTextFromSheet(sheet) {
1566 return (sheet && sheet.__resource) || '';
1567 }
1568
1569 function matchesSelector(node, inSelector) {
1570 if (matches) {
1571 return matches.call(node, inSelector);
1572 }
1573 }
1574 var p = HTMLElement.prototype;
1575 var matches = p.matches || p.matchesSelector || p.webkitMatchesSelector
1576 || p.mozMatchesSelector;
1577
1578 // exports
1579
1580 scope.api.declaration.styles = styles;
1581 scope.applyStyleToScope = applyStyleToScope;
1582
1583 })(Polymer);
1584
1585 /*
1586 * Copyright 2013 The Polymer Authors. All rights reserved.
1587 * Use of this source code is governed by a BSD-style
1588 * license that can be found in the LICENSE file.
1589 */
1590
1591 (function(scope) {
1592
1593 // imports
1594
1595 var log = window.logFlags || {};
1596 var api = scope.api.instance.events;
1597 var EVENT_PREFIX = api.EVENT_PREFIX;
1598 // polymer-element declarative api: events feature
1599
1600 var events = {
1601 parseHostEvents: function() {
1602 // our delegates map
1603 var delegates = this.prototype.eventDelegates;
1604 // extract data from attributes into delegates
1605 this.addAttributeDelegates(delegates);
1606 },
1607 addAttributeDelegates: function(delegates) {
1608 // for each attribute
1609 for (var i=0, a; a=this.attributes[i]; i++) {
1610 // does it have magic marker identifying it as an event delegate?
1611 if (this.hasEventPrefix(a.name)) {
1612 // if so, add the info to delegates
1613 delegates[this.removeEventPrefix(a.name)] = a.value.replace('{{', '')
1614 .replace('}}', '').trim();
1615 }
1616 }
1617 },
1618 // starts with 'on-'
1619 hasEventPrefix: function (n) {
1620 return n && (n[0] === 'o') && (n[1] === 'n') && (n[2] === '-');
1621 },
1622 removeEventPrefix: function(n) {
1623 return n.slice(prefixLength);
1624 }
1625 };
1626
1627 var prefixLength = EVENT_PREFIX.length;
1628
1629 // exports
1630 scope.api.declaration.events = events;
1631
1632 })(Polymer);
1633 /*
1634 * Copyright 2013 The Polymer Authors. All rights reserved.
1635 * Use of this source code is governed by a BSD-style
1636 * license that can be found in the LICENSE file.
1637 */
1638 (function(scope) {
1639
1640 // element api
1641
1642 var properties = {
1643 inferObservers: function(prototype) {
1644 // called before prototype.observe is chained to inherited object
1645 var observe = prototype.observe, property;
1646 for (var n in prototype) {
1647 if (n.slice(-7) === 'Changed') {
1648 if (!observe) {
1649 observe = (prototype.observe = {});
1650 }
1651 property = n.slice(0, -7)
1652 observe[property] = observe[property] || n;
1653 }
1654 }
1655 },
1656 explodeObservers: function(prototype) {
1657 // called before prototype.observe is chained to inherited object
1658 var o = prototype.observe;
1659 if (o) {
1660 var exploded = {};
1661 for (var n in o) {
1662 var names = n.split(' ');
1663 for (var i=0, ni; ni=names[i]; i++) {
1664 exploded[ni] = o[n];
1665 }
1666 }
1667 prototype.observe = exploded;
1668 }
1669 },
1670 optimizePropertyMaps: function(prototype) {
1671 if (prototype.observe) {
1672 // construct name list
1673 var a = prototype._observeNames = [];
1674 for (var n in prototype.observe) {
1675 var names = n.split(' ');
1676 for (var i=0, ni; ni=names[i]; i++) {
1677 a.push(ni);
1678 }
1679 //a.push(n);
1680 }
1681 }
1682 if (prototype.publish) {
1683 // construct name list
1684 var a = prototype._publishNames = [];
1685 for (var n in prototype.publish) {
1686 a.push(n);
1687 }
1688 }
1689 },
1690 publishProperties: function(prototype, base) {
1691 // if we have any properties to publish
1692 var publish = prototype.publish;
1693 if (publish) {
1694 // transcribe `publish` entries onto own prototype
1695 this.requireProperties(publish, prototype, base);
1696 // construct map of lower-cased property names
1697 prototype._publishLC = this.lowerCaseMap(publish);
1698 }
1699 },
1700 requireProperties: function(properties, prototype, base) {
1701 // ensure a prototype value for each property
1702 for (var n in properties) {
1703 if (prototype[n] === undefined && base[n] === undefined) {
1704 prototype[n] = properties[n];
1705 }
1706 }
1707 },
1708 lowerCaseMap: function(properties) {
1709 var map = {};
1710 for (var n in properties) {
1711 map[n.toLowerCase()] = n;
1712 }
1713 return map;
1714 }
1715 };
1716
1717 // exports
1718
1719 scope.api.declaration.properties = properties;
1720
1721 })(Polymer);
1722
1723 /*
1724 * Copyright 2013 The Polymer Authors. All rights reserved.
1725 * Use of this source code is governed by a BSD-style
1726 * license that can be found in the LICENSE file.
1727 */
1728 (function(scope) {
1729
1730 // magic words
1731
1732 var ATTRIBUTES_ATTRIBUTE = 'attributes';
1733 var ATTRIBUTES_REGEX = /\s|,/;
1734
1735 // attributes api
1736
1737 var attributes = {
1738 inheritAttributesObjects: function(prototype) {
1739 // chain our lower-cased publish map to the inherited version
1740 this.inheritObject(prototype, 'publishLC');
1741 // chain our instance attributes map to the inherited version
1742 this.inheritObject(prototype, '_instanceAttributes');
1743 },
1744 publishAttributes: function(prototype, base) {
1745 // merge names from 'attributes' attribute
1746 var attributes = this.getAttribute(ATTRIBUTES_ATTRIBUTE);
1747 if (attributes) {
1748 // get properties to publish
1749 var publish = prototype.publish || (prototype.publish = {});
1750 // names='a b c' or names='a,b,c'
1751 var names = attributes.split(ATTRIBUTES_REGEX);
1752 // record each name for publishing
1753 for (var i=0, l=names.length, n; i<l; i++) {
1754 // remove excess ws
1755 n = names[i].trim();
1756 // do not override explicit entries
1757 if (n && publish[n] === undefined && base[n] === undefined) {
1758 publish[n] = null;
1759 }
1760 }
1761 }
1762 },
1763 // record clonable attributes from <element>
1764 accumulateInstanceAttributes: function() {
1765 // inherit instance attributes
1766 var clonable = this.prototype._instanceAttributes;
1767 // merge attributes from element
1768 var a$ = this.attributes;
1769 for (var i=0, l=a$.length, a; (i<l) && (a=a$[i]); i++) {
1770 if (this.isInstanceAttribute(a.name)) {
1771 clonable[a.name] = a.value;
1772 }
1773 }
1774 },
1775 isInstanceAttribute: function(name) {
1776 return !this.blackList[name] && name.slice(0,3) !== 'on-';
1777 },
1778 // do not clone these attributes onto instances
1779 blackList: {
1780 name: 1,
1781 'extends': 1,
1782 constructor: 1,
1783 noscript: 1,
1784 assetpath: 1,
1785 'cache-csstext': 1
1786 }
1787 };
1788
1789 // add ATTRIBUTES_ATTRIBUTE to the blacklist
1790 attributes.blackList[ATTRIBUTES_ATTRIBUTE] = 1;
1791
1792 // exports
1793
1794 scope.api.declaration.attributes = attributes;
1795
1796 })(Polymer);
1797
1798 /*
1799 * Copyright 2013 The Polymer Authors. All rights reserved.
1800 * Use of this source code is governed by a BSD-style
1801 * license that can be found in the LICENSE file.
1802 */
1803 (function(scope) {
1804
1805 // imports
1806
1807 var api = scope.api;
1808 var isBase = scope.isBase;
1809 var extend = scope.extend;
1810
1811 // prototype api
1812
1813 var prototype = {
1814
1815 register: function(name, extendeeName) {
1816 // build prototype combining extendee, Polymer base, and named api
1817 this.buildPrototype(name, extendeeName);
1818 // register our custom element with the platform
1819 this.registerPrototype(name, extendeeName);
1820 // reference constructor in a global named by 'constructor' attribute
1821 this.publishConstructor();
1822 },
1823
1824 buildPrototype: function(name, extendeeName) {
1825 // get our custom prototype (before chaining)
1826 var extension = scope.getRegisteredPrototype(name);
1827 // get basal prototype
1828 var base = this.generateBasePrototype(extendeeName);
1829 // implement declarative features
1830 this.desugarBeforeChaining(extension, base);
1831 // join prototypes
1832 this.prototype = this.chainPrototypes(extension, base);
1833 // more declarative features
1834 this.desugarAfterChaining(name, extendeeName);
1835 },
1836
1837 desugarBeforeChaining: function(prototype, base) {
1838 // back reference declaration element
1839 // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
1840 prototype.element = this;
1841 // transcribe `attributes` declarations onto own prototype's `publish`
1842 this.publishAttributes(prototype, base);
1843 // `publish` properties to the prototype and to attribute watch
1844 this.publishProperties(prototype, base);
1845 // infer observers for `observe` list based on method names
1846 this.inferObservers(prototype);
1847 // desugar compound observer syntax, e.g. 'a b c'
1848 this.explodeObservers(prototype);
1849 },
1850
1851 chainPrototypes: function(prototype, base) {
1852 // chain various meta-data objects to inherited versions
1853 this.inheritMetaData(prototype, base);
1854 // chain custom api to inherited
1855 var chained = this.chainObject(prototype, base);
1856 // x-platform fixup
1857 ensurePrototypeTraversal(chained);
1858 return chained;
1859 },
1860
1861 inheritMetaData: function(prototype, base) {
1862 // chain observe object to inherited
1863 this.inheritObject('observe', prototype, base);
1864 // chain publish object to inherited
1865 this.inheritObject('publish', prototype, base);
1866 // chain our lower-cased publish map to the inherited version
1867 this.inheritObject('_publishLC', prototype, base);
1868 // chain our instance attributes map to the inherited version
1869 this.inheritObject('_instanceAttributes', prototype, base);
1870 // chain our event delegates map to the inherited version
1871 this.inheritObject('eventDelegates', prototype, base);
1872 },
1873
1874 // implement various declarative features
1875 desugarAfterChaining: function(name, extendee) {
1876 // build side-chained lists to optimize iterations
1877 this.optimizePropertyMaps(this.prototype);
1878 // install external stylesheets as if they are inline
1879 this.installSheets();
1880 // adjust any paths in dom from imports
1881 this.resolveElementPaths(this);
1882 // compile list of attributes to copy to instances
1883 this.accumulateInstanceAttributes();
1884 // parse on-* delegates declared on `this` element
1885 this.parseHostEvents();
1886 //
1887 // install a helper method this.resolvePath to aid in
1888 // setting resource urls. e.g.
1889 // this.$.image.src = this.resolvePath('images/foo.png')
1890 this.addResolvePathApi();
1891 // under ShadowDOMPolyfill, transforms to approximate missing CSS features
1892 if (window.ShadowDOMPolyfill) {
1893 Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
1894 }
1895 // allow custom element access to the declarative context
1896 if (this.prototype.registerCallback) {
1897 this.prototype.registerCallback(this);
1898 }
1899 },
1900
1901 // if a named constructor is requested in element, map a reference
1902 // to the constructor to the given symbol
1903 publishConstructor: function() {
1904 var symbol = this.getAttribute('constructor');
1905 if (symbol) {
1906 window[symbol] = this.ctor;
1907 }
1908 },
1909
1910 // build prototype combining extendee, Polymer base, and named api
1911 generateBasePrototype: function(extnds) {
1912 var prototype = this.findBasePrototype(extnds);
1913 if (!prototype) {
1914 // create a prototype based on tag-name extension
1915 var prototype = HTMLElement.getPrototypeForTag(extnds);
1916 // insert base api in inheritance chain (if needed)
1917 prototype = this.ensureBaseApi(prototype);
1918 // memoize this base
1919 memoizedBases[extnds] = prototype;
1920 }
1921 return prototype;
1922 },
1923
1924 findBasePrototype: function(name) {
1925 return memoizedBases[name];
1926 },
1927
1928 // install Polymer instance api into prototype chain, as needed
1929 ensureBaseApi: function(prototype) {
1930 if (prototype.PolymerBase) {
1931 return prototype;
1932 }
1933 var extended = Object.create(prototype);
1934 // we need a unique copy of base api for each base prototype
1935 // therefore we 'extend' here instead of simply chaining
1936 api.publish(api.instance, extended);
1937 // TODO(sjmiles): sharing methods across prototype chains is
1938 // not supported by 'super' implementation which optimizes
1939 // by memoizing prototype relationships.
1940 // Probably we should have a version of 'extend' that is
1941 // share-aware: it could study the text of each function,
1942 // look for usage of 'super', and wrap those functions in
1943 // closures.
1944 // As of now, there is only one problematic method, so
1945 // we just patch it manually.
1946 // To avoid re-entrancy problems, the special super method
1947 // installed is called `mixinSuper` and the mixin method
1948 // must use this method instead of the default `super`.
1949 this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');
1950 // return buffed-up prototype
1951 return extended;
1952 },
1953
1954 mixinMethod: function(extended, prototype, api, name) {
1955 var $super = function(args) {
1956 return prototype[name].apply(this, args);
1957 };
1958 extended[name] = function() {
1959 this.mixinSuper = $super;
1960 return api[name].apply(this, arguments);
1961 }
1962 },
1963
1964 // ensure prototype[name] inherits from a prototype.prototype[name]
1965 inheritObject: function(name, prototype, base) {
1966 // require an object
1967 var source = prototype[name] || {};
1968 // chain inherited properties onto a new object
1969 prototype[name] = this.chainObject(source, base[name]);
1970 },
1971
1972 // register 'prototype' to custom element 'name', store constructor
1973 registerPrototype: function(name, extendee) {
1974 var info = {
1975 prototype: this.prototype
1976 }
1977 // native element must be specified in extends
1978 var typeExtension = this.findTypeExtension(extendee);
1979 if (typeExtension) {
1980 info.extends = typeExtension;
1981 }
1982 // register the prototype with HTMLElement for name lookup
1983 HTMLElement.register(name, this.prototype);
1984 // register the custom type
1985 this.ctor = document.registerElement(name, info);
1986 },
1987
1988 findTypeExtension: function(name) {
1989 if (name && name.indexOf('-') < 0) {
1990 return name;
1991 } else {
1992 var p = this.findBasePrototype(name);
1993 if (p.element) {
1994 return this.findTypeExtension(p.element.extends);
1995 }
1996 }
1997 }
1998
1999 };
2000
2001 // memoize base prototypes
2002 var memoizedBases = {};
2003
2004 // implementation of 'chainObject' depends on support for __proto__
2005 if (Object.__proto__) {
2006 prototype.chainObject = function(object, inherited) {
2007 if (object && inherited && object !== inherited) {
2008 object.__proto__ = inherited;
2009 }
2010 return object;
2011 }
2012 } else {
2013 prototype.chainObject = function(object, inherited) {
2014 if (object && inherited && object !== inherited) {
2015 var chained = Object.create(inherited);
2016 object = extend(chained, object);
2017 }
2018 return object;
2019 }
2020 }
2021
2022 // On platforms that do not support __proto__ (versions of IE), the prototype
2023 // chain of a custom element is simulated via installation of __proto__.
2024 // Although custom elements manages this, we install it here so it's
2025 // available during desugaring.
2026 function ensurePrototypeTraversal(prototype) {
2027 if (!Object.__proto__) {
2028 var ancestor = Object.getPrototypeOf(prototype);
2029 prototype.__proto__ = ancestor;
2030 if (isBase(ancestor)) {
2031 ancestor.__proto__ = Object.getPrototypeOf(ancestor);
2032 }
2033 }
2034 }
2035
2036 // exports
2037
2038 api.declaration.prototype = prototype;
2039
2040 })(Polymer);
2041
2042 /*
2043 * Copyright 2013 The Polymer Authors. All rights reserved.
2044 * Use of this source code is governed by a BSD-style
2045 * license that can be found in the LICENSE file.
2046 */
2047 (function(scope) {
2048
2049 var queue = {
2050 // tell the queue to wait for an element to be ready
2051 wait: function(element, check, go) {
2052 if (this.indexOf(element) === -1) {
2053 this.add(element);
2054 element.__check = check;
2055 element.__go = go;
2056 }
2057 return (this.indexOf(element) !== 0);
2058 },
2059 add: function(element) {
2060 //console.log('queueing', element.name);
2061 queueForElement(element).push(element);
2062 },
2063 indexOf: function(element) {
2064 var i = queueForElement(element).indexOf(element);
2065 if (i >= 0 && document.contains(element)) {
2066 i += (HTMLImports.useNative || HTMLImports.ready) ? importQueue.length :
2067 1e9;
2068 }
2069 return i;
2070 },
2071 // tell the queue an element is ready to be registered
2072 go: function(element) {
2073 var readied = this.remove(element);
2074 if (readied) {
2075 readied.__go.call(readied);
2076 readied.__check = readied.__go = null;
2077 this.check();
2078 }
2079 },
2080 remove: function(element) {
2081 var i = this.indexOf(element);
2082 if (i !== 0) {
2083 //console.warn('queue order wrong', i);
2084 return;
2085 }
2086 return queueForElement(element).shift();
2087 },
2088 check: function() {
2089 // next
2090 var element = this.nextElement();
2091 if (element) {
2092 element.__check.call(element);
2093 }
2094 if (this.canReady()) {
2095 this.ready();
2096 return true;
2097 }
2098 },
2099 nextElement: function() {
2100 return nextQueued();
2101 },
2102 canReady: function() {
2103 return !this.waitToReady && this.isEmpty();
2104 },
2105 isEmpty: function() {
2106 return !importQueue.length && !mainQueue.length;
2107 },
2108 ready: function() {
2109 // TODO(sorvell): As an optimization, turn off CE polyfill upgrading
2110 // while registering. This way we avoid having to upgrade each document
2111 // piecemeal per registration and can instead register all elements
2112 // and upgrade once in a batch. Without this optimization, upgrade time
2113 // degrades significantly when SD polyfill is used. This is mainly because
2114 // querying the document tree for elements is slow under the SD polyfill.
2115 if (CustomElements.ready === false) {
2116 CustomElements.upgradeDocumentTree(document);
2117 CustomElements.ready = true;
2118 }
2119 if (readyCallbacks) {
2120 var fn;
2121 while (readyCallbacks.length) {
2122 fn = readyCallbacks.shift();
2123 fn();
2124 }
2125 }
2126 },
2127 addReadyCallback: function(callback) {
2128 if (callback) {
2129 readyCallbacks.push(callback);
2130 }
2131 },
2132 waitToReady: true
2133 };
2134
2135 var importQueue = [];
2136 var mainQueue = [];
2137 var readyCallbacks = [];
2138
2139 function queueForElement(element) {
2140 return document.contains(element) ? mainQueue : importQueue;
2141 }
2142
2143 function nextQueued() {
2144 return importQueue.length ? importQueue[0] : mainQueue[0];
2145 }
2146
2147 var polymerReadied = false;
2148
2149 document.addEventListener('WebComponentsReady', function() {
2150 CustomElements.ready = false;
2151 });
2152
2153 function whenPolymerReady(callback) {
2154 queue.waitToReady = true;
2155 CustomElements.ready = false;
2156 HTMLImports.whenImportsReady(function() {
2157 queue.addReadyCallback(callback);
2158 queue.waitToReady = false;
2159 queue.check();
2160 });
2161 }
2162
2163 // exports
2164 scope.queue = queue;
2165 scope.whenPolymerReady = whenPolymerReady;
2166 })(Polymer);
2167
2168 /*
2169 * Copyright 2013 The Polymer Authors. All rights reserved.
2170 * Use of this source code is governed by a BSD-style
2171 * license that can be found in the LICENSE file.
2172 */
2173 (function(scope) {
2174
2175 var whenPolymerReady = scope.whenPolymerReady;
2176
2177 function importElements(elementOrFragment, callback) {
2178 if (elementOrFragment) {
2179 document.head.appendChild(elementOrFragment);
2180 whenPolymerReady(callback);
2181 } else if (callback) {
2182 callback();
2183 }
2184 }
2185
2186 function importUrls(urls, callback) {
2187 if (urls && urls.length) {
2188 var frag = document.createDocumentFragment();
2189 for (var i=0, l=urls.length, url, link; (i<l) && (url=urls[i]); i++) {
2190 link = document.createElement('link');
2191 link.rel = 'import';
2192 link.href = url;
2193 frag.appendChild(link);
2194 }
2195 importElements(frag, callback);
2196 } else if (callback) {
2197 callback();
2198 }
2199 }
2200
2201 // exports
2202 scope.import = importUrls;
2203 scope.importElements = importElements;
2204
2205 })(Polymer);
2206
2207 /*
2208 * Copyright 2013 The Polymer Authors. All rights reserved.
2209 * Use of this source code is governed by a BSD-style
2210 * license that can be found in the LICENSE file.
2211 */
2212 (function(scope) {
2213
2214 // imports
2215
2216 var extend = scope.extend;
2217 var api = scope.api;
2218 var queue = scope.queue;
2219 var whenPolymerReady = scope.whenPolymerReady;
2220 var getRegisteredPrototype = scope.getRegisteredPrototype;
2221 var waitingForPrototype = scope.waitingForPrototype;
2222
2223 // declarative implementation: <polymer-element>
2224
2225 var prototype = extend(Object.create(HTMLElement.prototype), {
2226
2227 createdCallback: function() {
2228 if (this.getAttribute('name')) {
2229 this.init();
2230 }
2231 },
2232
2233 init: function() {
2234 // fetch declared values
2235 this.name = this.getAttribute('name');
2236 this.extends = this.getAttribute('extends');
2237 // initiate any async resource fetches
2238 this.loadResources();
2239 // register when all constraints are met
2240 this.registerWhenReady();
2241 },
2242
2243 registerWhenReady: function() {
2244 if (this.registered
2245 || this.waitingForPrototype(this.name)
2246 || this.waitingForQueue()
2247 || this.waitingForResources()) {
2248 return;
2249 }
2250 queue.go(this);
2251 },
2252
2253
2254 // TODO(sorvell): refactor, this method is private-ish, but it's being
2255 // called by the queue object.
2256 _register: function() {
2257 //console.log('registering', this.name);
2258 //console.group('registering', this.name);
2259 // warn if extending from a custom element not registered via Polymer
2260 if (isCustomTag(this.extends) && !isRegistered(this.extends)) {
2261 console.warn('%s is attempting to extend %s, an unregistered element ' +
2262 'or one that was not registered with Polymer.', this.name,
2263 this.extends);
2264 }
2265 this.register(this.name, this.extends);
2266 this.registered = true;
2267 //console.groupEnd();
2268 },
2269
2270 waitingForPrototype: function(name) {
2271 if (!getRegisteredPrototype(name)) {
2272 // then wait for a prototype
2273 waitingForPrototype(name, this);
2274 // emulate script if user is not supplying one
2275 this.handleNoScript(name);
2276 // prototype not ready yet
2277 return true;
2278 }
2279 },
2280
2281 handleNoScript: function(name) {
2282 // if explicitly marked as 'noscript'
2283 if (this.hasAttribute('noscript') && !this.noscript) {
2284 this.noscript = true;
2285 // TODO(sorvell): CustomElements polyfill awareness:
2286 // noscript elements should upgrade in logical order
2287 // script injection ensures this under native custom elements;
2288 // under imports + ce polyfills, scripts run before upgrades.
2289 // dependencies should be ready at upgrade time so register
2290 // prototype at this time.
2291 if (window.CustomElements && !CustomElements.useNative) {
2292 Polymer(name);
2293 } else {
2294 var script = document.createElement('script');
2295 script.textContent = 'Polymer(\'' + name + '\');';
2296 this.appendChild(script);
2297 }
2298 }
2299 },
2300
2301 waitingForResources: function() {
2302 return this._needsResources;
2303 },
2304
2305 // NOTE: Elements must be queued in proper order for inheritance/composition
2306 // dependency resolution. Previously this was enforced for inheritance,
2307 // and by rule for composition. It's now entirely by rule.
2308 waitingForQueue: function() {
2309 return queue.wait(this, this.registerWhenReady, this._register);
2310 },
2311
2312 loadResources: function() {
2313 this._needsResources = true;
2314 this.loadStyles(function() {
2315 this._needsResources = false;
2316 this.registerWhenReady();
2317 }.bind(this));
2318 }
2319
2320 });
2321
2322 // semi-pluggable APIs
2323
2324 // TODO(sjmiles): should be fully pluggable (aka decoupled, currently
2325 // the various plugins are allowed to depend on each other directly)
2326 api.publish(api.declaration, prototype);
2327
2328 // utility and bookkeeping
2329
2330 function isRegistered(name) {
2331 return Boolean(HTMLElement.getPrototypeForTag(name));
2332 }
2333
2334 function isCustomTag(name) {
2335 return (name && name.indexOf('-') >= 0);
2336 }
2337
2338 // exports
2339
2340 scope.getRegisteredPrototype = getRegisteredPrototype;
2341
2342 // boot tasks
2343
2344 whenPolymerReady(function() {
2345 document.body.removeAttribute('unresolved');
2346 document.dispatchEvent(
2347 new CustomEvent('polymer-ready', {bubbles: true})
2348 );
2349 });
2350
2351 // register polymer-element with document
2352
2353 document.registerElement('polymer-element', {prototype: prototype});
2354
2355 })(Polymer);
2356
2357 //# sourceMappingURL=polymer.concat.js.map
OLDNEW
« no previous file with comments | « pkg/polymer/lib/src/js/polymer/polymer-body.html ('k') | pkg/polymer/lib/src/js/polymer/polymer.concat.js.map » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698