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

Side by Side Diff: polymer_1.0.4/bower_components/polymer/polymer.html

Issue 1205703007: Add polymer 1.0 to npm_modules (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Renamed folder to 1.0.4 Created 5 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) 2015 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 @license
11 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
12 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
13 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
14 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
15 Code distributed by Google as part of the polymer project is also
16 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
17 --><link rel="import" href="polymer-mini.html">
18
19 <script>Polymer.nar = [];
20 Polymer.Annotations = {
21 parseAnnotations: function (template) {
22 var list = [];
23 var content = template._content || template.content;
24 this._parseNodeAnnotations(content, list);
25 return list;
26 },
27 _parseNodeAnnotations: function (node, list) {
28 return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, li st) : this._parseElementAnnotations(node, list);
29 },
30 _testEscape: function (value) {
31 var escape = value.slice(0, 2);
32 if (escape === '{{' || escape === '[[') {
33 return escape;
34 }
35 },
36 _parseTextNodeAnnotation: function (node, list) {
37 var v = node.textContent;
38 var escape = this._testEscape(v);
39 if (escape) {
40 node.textContent = ' ';
41 var annote = {
42 bindings: [{
43 kind: 'text',
44 mode: escape[0],
45 value: v.slice(2, -2).trim()
46 }]
47 };
48 list.push(annote);
49 return annote;
50 }
51 },
52 _parseElementAnnotations: function (element, list) {
53 var annote = {
54 bindings: [],
55 events: []
56 };
57 this._parseChildNodesAnnotations(element, annote, list);
58 if (element.attributes) {
59 this._parseNodeAttributeAnnotations(element, annote, list);
60 if (this.prepElement) {
61 this.prepElement(element);
62 }
63 }
64 if (annote.bindings.length || annote.events.length || annote.id) {
65 list.push(annote);
66 }
67 return annote;
68 },
69 _parseChildNodesAnnotations: function (root, annote, list, callback) {
70 if (root.firstChild) {
71 for (var i = 0, node = root.firstChild; node; node = node.nextSibling, i++) {
72 if (node.localName === 'template' && !node.hasAttribute('preserve-content')) {
73 this._parseTemplate(node, i, list, annote);
74 }
75 var childAnnotation = this._parseNodeAnnotations(node, list, callback);
76 if (childAnnotation) {
77 childAnnotation.parent = annote;
78 childAnnotation.index = i;
79 }
80 }
81 }
82 },
83 _parseTemplate: function (node, index, list, parent) {
84 var content = document.createDocumentFragment();
85 content._notes = this.parseAnnotations(node);
86 content.appendChild(node.content);
87 list.push({
88 bindings: Polymer.nar,
89 events: Polymer.nar,
90 templateContent: content,
91 parent: parent,
92 index: index
93 });
94 },
95 _parseNodeAttributeAnnotations: function (node, annotation) {
96 for (var i = node.attributes.length - 1, a; a = node.attributes[i]; i--) {
97 var n = a.name, v = a.value;
98 if (n === 'id' && !this._testEscape(v)) {
99 annotation.id = v;
100 } else if (n.slice(0, 3) === 'on-') {
101 node.removeAttribute(n);
102 annotation.events.push({
103 name: n.slice(3),
104 value: v
105 });
106 } else {
107 var b = this._parseNodeAttributeAnnotation(node, n, v);
108 if (b) {
109 annotation.bindings.push(b);
110 }
111 }
112 }
113 },
114 _parseNodeAttributeAnnotation: function (node, n, v) {
115 var escape = this._testEscape(v);
116 if (escape) {
117 var customEvent;
118 var name = n;
119 var mode = escape[0];
120 v = v.slice(2, -2).trim();
121 var not = false;
122 if (v[0] == '!') {
123 v = v.substring(1);
124 not = true;
125 }
126 var kind = 'property';
127 if (n[n.length - 1] == '$') {
128 name = n.slice(0, -1);
129 kind = 'attribute';
130 }
131 var notifyEvent, colon;
132 if (mode == '{' && (colon = v.indexOf('::')) > 0) {
133 notifyEvent = v.substring(colon + 2);
134 v = v.substring(0, colon);
135 customEvent = true;
136 }
137 if (node.localName == 'input' && n == 'value') {
138 node.setAttribute(n, '');
139 }
140 node.removeAttribute(n);
141 if (kind === 'property') {
142 name = Polymer.CaseMap.dashToCamelCase(name);
143 }
144 return {
145 kind: kind,
146 mode: mode,
147 name: name,
148 value: v,
149 negate: not,
150 event: notifyEvent,
151 customEvent: customEvent
152 };
153 }
154 },
155 _localSubTree: function (node, host) {
156 return node === host ? node.childNodes : node._lightChildren || node.childNodes;
157 },
158 findAnnotatedNode: function (root, annote) {
159 var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote .parent);
160 return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.i ndex];
161 }
162 };
163 (function () {
164 function resolveCss(cssText, ownerDocument) {
165 return cssText.replace(CSS_URL_RX, function (m, pre, url, post) {
166 return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + po st;
167 });
168 }
169 function resolveAttrs(element, ownerDocument) {
170 for (var name in URL_ATTRS) {
171 var a$ = URL_ATTRS[name];
172 for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {
173 if (name === '*' || element.localName === name) {
174 at = element.attributes[a];
175 v = at && at.value;
176 if (v && v.search(BINDING_RX) < 0) {
177 at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocume nt);
178 }
179 }
180 }
181 }
182 }
183 function resolve(url, ownerDocument) {
184 if (url && url[0] === '#') {
185 return url;
186 }
187 var resolver = getUrlResolver(ownerDocument);
188 resolver.href = url;
189 return resolver.href || url;
190 }
191 var tempDoc;
192 var tempDocBase;
193 function resolveUrl(url, baseUri) {
194 if (!tempDoc) {
195 tempDoc = document.implementation.createHTMLDocument('temp');
196 tempDocBase = tempDoc.createElement('base');
197 tempDoc.head.appendChild(tempDocBase);
198 }
199 tempDocBase.href = baseUri;
200 return resolve(url, tempDoc);
201 }
202 function getUrlResolver(ownerDocument) {
203 return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocume nt.createElement('a'));
204 }
205 var CSS_URL_RX = /(url\()([^)]*)(\))/g;
206 var URL_ATTRS = {
207 '*': [
208 'href',
209 'src',
210 'style',
211 'url'
212 ],
213 form: ['action']
214 };
215 var BINDING_RX = /\{\{|\[\[/;
216 Polymer.ResolveUrl = {
217 resolveCss: resolveCss,
218 resolveAttrs: resolveAttrs,
219 resolveUrl: resolveUrl
220 };
221 }());
222 Polymer.Base._addFeature({
223 _prepAnnotations: function () {
224 if (!this._template) {
225 this._notes = [];
226 } else {
227 Polymer.Annotations.prepElement = this._prepElement.bind(this);
228 this._notes = Polymer.Annotations.parseAnnotations(this._template);
229 this._processAnnotations(this._notes);
230 Polymer.Annotations.prepElement = null;
231 }
232 },
233 _processAnnotations: function (notes) {
234 for (var i = 0; i < notes.length; i++) {
235 var note = notes[i];
236 for (var j = 0; j < note.bindings.length; j++) {
237 var b = note.bindings[j];
238 b.signature = this._parseMethod(b.value);
239 if (!b.signature) {
240 b.model = this._modelForPath(b.value);
241 }
242 }
243 if (note.templateContent) {
244 this._processAnnotations(note.templateContent._notes);
245 var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(n ote.templateContent._notes);
246 var bindings = [];
247 for (var prop in pp) {
248 bindings.push({
249 index: note.index,
250 kind: 'property',
251 mode: '{',
252 name: '_parent_' + prop,
253 model: prop,
254 value: prop
255 });
256 }
257 note.bindings = note.bindings.concat(bindings);
258 }
259 }
260 },
261 _discoverTemplateParentProps: function (notes) {
262 var pp = {};
263 notes.forEach(function (n) {
264 n.bindings.forEach(function (b) {
265 if (b.signature) {
266 var args = b.signature.args;
267 for (var k = 0; k < args.length; k++) {
268 pp[args[k].model] = true;
269 }
270 } else {
271 pp[b.model] = true;
272 }
273 });
274 if (n.templateContent) {
275 var tpp = n.templateContent._parentProps;
276 Polymer.Base.mixin(pp, tpp);
277 }
278 });
279 return pp;
280 },
281 _prepElement: function (element) {
282 Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
283 },
284 _findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
285 _marshalAnnotationReferences: function () {
286 if (this._template) {
287 this._marshalIdNodes();
288 this._marshalAnnotatedNodes();
289 this._marshalAnnotatedListeners();
290 }
291 },
292 _configureAnnotationReferences: function () {
293 this._configureTemplateContent();
294 },
295 _configureTemplateContent: function () {
296 this._notes.forEach(function (note, i) {
297 if (note.templateContent) {
298 this._nodes[i]._content = note.templateContent;
299 }
300 }, this);
301 },
302 _marshalIdNodes: function () {
303 this.$ = {};
304 this._notes.forEach(function (a) {
305 if (a.id) {
306 this.$[a.id] = this._findAnnotatedNode(this.root, a);
307 }
308 }, this);
309 },
310 _marshalAnnotatedNodes: function () {
311 if (this._nodes) {
312 this._nodes = this._nodes.map(function (a) {
313 return this._findAnnotatedNode(this.root, a);
314 }, this);
315 }
316 },
317 _marshalAnnotatedListeners: function () {
318 this._notes.forEach(function (a) {
319 if (a.events && a.events.length) {
320 var node = this._findAnnotatedNode(this.root, a);
321 a.events.forEach(function (e) {
322 this.listen(node, e.name, e.value);
323 }, this);
324 }
325 }, this);
326 }
327 });
328 Polymer.Base._addFeature({
329 listeners: {},
330 _listenListeners: function (listeners) {
331 var node, name, key;
332 for (key in listeners) {
333 if (key.indexOf('.') < 0) {
334 node = this;
335 name = key;
336 } else {
337 name = key.split('.');
338 node = this.$[name[0]];
339 name = name[1];
340 }
341 this.listen(node, name, listeners[key]);
342 }
343 },
344 listen: function (node, eventName, methodName) {
345 this._listen(node, eventName, this._createEventHandler(node, eventName, methodNa me));
346 },
347 _boundListenerKey: function (eventName, methodName) {
348 return eventName + ':' + methodName;
349 },
350 _recordEventHandler: function (host, eventName, target, methodName, handler) {
351 var hbl = host.__boundListeners;
352 if (!hbl) {
353 hbl = host.__boundListeners = new WeakMap();
354 }
355 var bl = hbl.get(target);
356 if (!bl) {
357 bl = {};
358 hbl.set(target, bl);
359 }
360 var key = this._boundListenerKey(eventName, methodName);
361 bl[key] = handler;
362 },
363 _recallEventHandler: function (host, eventName, target, methodName) {
364 var hbl = host.__boundListeners;
365 if (!hbl) {
366 return;
367 }
368 var bl = hbl.get(target);
369 if (!bl) {
370 return;
371 }
372 var key = this._boundListenerKey(eventName, methodName);
373 return bl[key];
374 },
375 _createEventHandler: function (node, eventName, methodName) {
376 var host = this;
377 var handler = function (e) {
378 if (host[methodName]) {
379 host[methodName](e, e.detail);
380 } else {
381 host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));
382 }
383 };
384 this._recordEventHandler(host, eventName, node, methodName, handler);
385 return handler;
386 },
387 unlisten: function (node, eventName, methodName) {
388 var handler = this._recallEventHandler(this, eventName, node, methodName);
389 if (handler) {
390 this._unlisten(node, eventName, handler);
391 }
392 },
393 _listen: function (node, eventName, handler) {
394 node.addEventListener(eventName, handler);
395 },
396 _unlisten: function (node, eventName, handler) {
397 node.removeEventListener(eventName, handler);
398 }
399 });
400 (function () {
401 'use strict';
402 var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
403 var GESTURE_KEY = '__polymerGestures';
404 var HANDLED_OBJ = '__polymerGesturesHandled';
405 var TOUCH_ACTION = '__polymerGesturesTouchAction';
406 var TAP_DISTANCE = 25;
407 var TRACK_DISTANCE = 5;
408 var TRACK_LENGTH = 2;
409 var MOUSE_TIMEOUT = 2500;
410 var MOUSE_EVENTS = [
411 'mousedown',
412 'mousemove',
413 'mouseup',
414 'click'
415 ];
416 var mouseCanceller = function (mouseEvent) {
417 mouseEvent[HANDLED_OBJ] = { skip: true };
418 if (mouseEvent.type === 'click') {
419 var path = Polymer.dom(mouseEvent).path;
420 for (var i = 0; i < path.length; i++) {
421 if (path[i] === POINTERSTATE.mouse.target) {
422 return;
423 }
424 }
425 mouseEvent.preventDefault();
426 mouseEvent.stopPropagation();
427 }
428 };
429 function setupTeardownMouseCanceller(setup) {
430 for (var i = 0, en; i < MOUSE_EVENTS.length; i++) {
431 en = MOUSE_EVENTS[i];
432 if (setup) {
433 document.addEventListener(en, mouseCanceller, true);
434 } else {
435 document.removeEventListener(en, mouseCanceller, true);
436 }
437 }
438 }
439 function ignoreMouse() {
440 if (!POINTERSTATE.mouse.mouseIgnoreJob) {
441 setupTeardownMouseCanceller(true);
442 }
443 var unset = function () {
444 setupTeardownMouseCanceller();
445 POINTERSTATE.mouse.target = null;
446 POINTERSTATE.mouse.mouseIgnoreJob = null;
447 };
448 POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgn oreJob, unset, MOUSE_TIMEOUT);
449 }
450 var POINTERSTATE = {
451 mouse: {
452 target: null,
453 mouseIgnoreJob: null
454 },
455 touch: {
456 x: 0,
457 y: 0,
458 id: -1,
459 scrollDecided: false
460 }
461 };
462 function firstTouchAction(ev) {
463 var path = Polymer.dom(ev).path;
464 var ta = 'auto';
465 for (var i = 0, n; i < path.length; i++) {
466 n = path[i];
467 if (n[TOUCH_ACTION]) {
468 ta = n[TOUCH_ACTION];
469 break;
470 }
471 }
472 return ta;
473 }
474 var Gestures = {
475 gestures: {},
476 recognizers: [],
477 deepTargetFind: function (x, y) {
478 var node = document.elementFromPoint(x, y);
479 var next = node;
480 while (next && next.shadowRoot) {
481 next = next.shadowRoot.elementFromPoint(x, y);
482 if (next) {
483 node = next;
484 }
485 }
486 return node;
487 },
488 handleNative: function (ev) {
489 var handled;
490 var type = ev.type;
491 var node = ev.currentTarget;
492 var gobj = node[GESTURE_KEY];
493 var gs = gobj[type];
494 if (!gs) {
495 return;
496 }
497 if (!ev[HANDLED_OBJ]) {
498 ev[HANDLED_OBJ] = {};
499 if (type.slice(0, 5) === 'touch') {
500 var t = ev.changedTouches[0];
501 if (type === 'touchstart') {
502 if (ev.touches.length === 1) {
503 POINTERSTATE.touch.id = t.identifier;
504 }
505 }
506 if (POINTERSTATE.touch.id !== t.identifier) {
507 return;
508 }
509 if (!HAS_NATIVE_TA) {
510 if (type === 'touchstart' || type === 'touchmove') {
511 Gestures.handleTouchAction(ev);
512 }
513 }
514 if (type === 'touchend') {
515 POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
516 ignoreMouse(true);
517 }
518 }
519 }
520 handled = ev[HANDLED_OBJ];
521 if (handled.skip) {
522 return;
523 }
524 var recognizers = Gestures.recognizers;
525 for (var i = 0, r; i < recognizers.length; i++) {
526 r = recognizers[i];
527 if (gs[r.name] && !handled[r.name]) {
528 handled[r.name] = true;
529 r[type](ev);
530 }
531 }
532 },
533 handleTouchAction: function (ev) {
534 var t = ev.changedTouches[0];
535 var type = ev.type;
536 if (type === 'touchstart') {
537 POINTERSTATE.touch.x = t.clientX;
538 POINTERSTATE.touch.y = t.clientY;
539 POINTERSTATE.touch.scrollDecided = false;
540 } else if (type === 'touchmove') {
541 if (POINTERSTATE.touch.scrollDecided) {
542 return;
543 }
544 POINTERSTATE.touch.scrollDecided = true;
545 var ta = firstTouchAction(ev);
546 var prevent = false;
547 var dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
548 var dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
549 if (!ev.cancelable) {
550 } else if (ta === 'none') {
551 prevent = true;
552 } else if (ta === 'pan-x') {
553 prevent = dy > dx;
554 } else if (ta === 'pan-y') {
555 prevent = dx > dy;
556 }
557 if (prevent) {
558 ev.preventDefault();
559 }
560 }
561 },
562 add: function (node, evType, handler) {
563 var recognizer = this.gestures[evType];
564 var deps = recognizer.deps;
565 var name = recognizer.name;
566 var gobj = node[GESTURE_KEY];
567 if (!gobj) {
568 node[GESTURE_KEY] = gobj = {};
569 }
570 for (var i = 0, dep, gd; i < deps.length; i++) {
571 dep = deps[i];
572 gd = gobj[dep];
573 if (!gd) {
574 gobj[dep] = gd = {};
575 node.addEventListener(dep, this.handleNative);
576 }
577 gd[name] = (gd[name] || 0) + 1;
578 }
579 node.addEventListener(evType, handler);
580 if (recognizer.touchAction) {
581 this.setTouchAction(node, recognizer.touchAction);
582 }
583 },
584 remove: function (node, evType, handler) {
585 var recognizer = this.gestures[evType];
586 var deps = recognizer.deps;
587 var name = recognizer.name;
588 var gobj = node[GESTURE_KEY];
589 if (gobj) {
590 for (var i = 0, dep, gd; i < deps.length; i++) {
591 dep = deps[i];
592 gd = gobj[dep];
593 if (gd && gd[name]) {
594 gd[name] = (gd[name] || 1) - 1;
595 if (gd[name] === 0) {
596 node.removeEventListener(dep, this.handleNative);
597 }
598 }
599 }
600 }
601 node.removeEventListener(evType, handler);
602 },
603 register: function (recog) {
604 this.recognizers.push(recog);
605 for (var i = 0; i < recog.emits.length; i++) {
606 this.gestures[recog.emits[i]] = recog;
607 }
608 },
609 findRecognizerByEvent: function (evName) {
610 for (var i = 0, r; i < this.recognizers.length; i++) {
611 r = this.recognizers[i];
612 for (var j = 0, n; j < r.emits.length; j++) {
613 n = r.emits[j];
614 if (n === evName) {
615 return r;
616 }
617 }
618 }
619 return null;
620 },
621 setTouchAction: function (node, value) {
622 if (HAS_NATIVE_TA) {
623 node.style.touchAction = value;
624 }
625 node[TOUCH_ACTION] = value;
626 },
627 fire: function (target, type, detail) {
628 var ev = Polymer.Base.fire(type, detail, {
629 node: target,
630 bubbles: true,
631 cancelable: true
632 });
633 if (ev.defaultPrevented) {
634 var se = detail.sourceEvent;
635 if (se && se.preventDefault) {
636 se.preventDefault();
637 }
638 }
639 },
640 prevent: function (evName) {
641 var recognizer = this.findRecognizerByEvent(evName);
642 if (recognizer.info) {
643 recognizer.info.prevent = true;
644 }
645 }
646 };
647 Gestures.register({
648 name: 'downup',
649 deps: [
650 'mousedown',
651 'touchstart',
652 'touchend'
653 ],
654 emits: [
655 'down',
656 'up'
657 ],
658 mousedown: function (e) {
659 var t = e.currentTarget;
660 var self = this;
661 var upfn = function upfn(e) {
662 self.fire('up', t, e);
663 document.removeEventListener('mouseup', upfn);
664 };
665 document.addEventListener('mouseup', upfn);
666 this.fire('down', t, e);
667 },
668 touchstart: function (e) {
669 this.fire('down', e.currentTarget, e.changedTouches[0]);
670 },
671 touchend: function (e) {
672 this.fire('up', e.currentTarget, e.changedTouches[0]);
673 },
674 fire: function (type, target, event) {
675 var self = this;
676 Gestures.fire(target, type, {
677 x: event.clientX,
678 y: event.clientY,
679 sourceEvent: event,
680 prevent: Gestures.prevent.bind(Gestures)
681 });
682 }
683 });
684 Gestures.register({
685 name: 'track',
686 touchAction: 'none',
687 deps: [
688 'mousedown',
689 'touchstart',
690 'touchmove',
691 'touchend'
692 ],
693 emits: ['track'],
694 info: {
695 x: 0,
696 y: 0,
697 state: 'start',
698 started: false,
699 moves: [],
700 addMove: function (move) {
701 if (this.moves.length > TRACK_LENGTH) {
702 this.moves.shift();
703 }
704 this.moves.push(move);
705 },
706 prevent: false
707 },
708 clearInfo: function () {
709 this.info.state = 'start';
710 this.info.started = false;
711 this.info.moves = [];
712 this.info.x = 0;
713 this.info.y = 0;
714 this.info.prevent = false;
715 },
716 hasMovedEnough: function (x, y) {
717 if (this.info.prevent) {
718 return false;
719 }
720 if (this.info.started) {
721 return true;
722 }
723 var dx = Math.abs(this.info.x - x);
724 var dy = Math.abs(this.info.y - y);
725 return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
726 },
727 mousedown: function (e) {
728 var t = e.currentTarget;
729 var self = this;
730 var movefn = function movefn(e) {
731 var x = e.clientX, y = e.clientY;
732 if (self.hasMovedEnough(x, y)) {
733 self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : ' start';
734 self.info.addMove({
735 x: x,
736 y: y
737 });
738 self.fire(t, e);
739 self.info.started = true;
740 }
741 };
742 var upfn = function upfn(e) {
743 if (self.info.started) {
744 Gestures.prevent('tap');
745 movefn(e);
746 }
747 self.clearInfo();
748 document.removeEventListener('mousemove', movefn);
749 document.removeEventListener('mouseup', upfn);
750 };
751 document.addEventListener('mousemove', movefn);
752 document.addEventListener('mouseup', upfn);
753 this.info.x = e.clientX;
754 this.info.y = e.clientY;
755 },
756 touchstart: function (e) {
757 var ct = e.changedTouches[0];
758 this.info.x = ct.clientX;
759 this.info.y = ct.clientY;
760 },
761 touchmove: function (e) {
762 var t = e.currentTarget;
763 var ct = e.changedTouches[0];
764 var x = ct.clientX, y = ct.clientY;
765 if (this.hasMovedEnough(x, y)) {
766 this.info.addMove({
767 x: x,
768 y: y
769 });
770 this.fire(t, ct);
771 this.info.state = 'track';
772 this.info.started = true;
773 }
774 },
775 touchend: function (e) {
776 var t = e.currentTarget;
777 var ct = e.changedTouches[0];
778 if (this.info.started) {
779 Gestures.prevent('tap');
780 this.info.state = 'end';
781 this.info.addMove({
782 x: ct.clientX,
783 y: ct.clientY
784 });
785 this.fire(t, ct);
786 }
787 this.clearInfo();
788 },
789 fire: function (target, touch) {
790 var secondlast = this.info.moves[this.info.moves.length - 2];
791 var lastmove = this.info.moves[this.info.moves.length - 1];
792 var dx = lastmove.x - this.info.x;
793 var dy = lastmove.y - this.info.y;
794 var ddx, ddy = 0;
795 if (secondlast) {
796 ddx = lastmove.x - secondlast.x;
797 ddy = lastmove.y - secondlast.y;
798 }
799 return Gestures.fire(target, 'track', {
800 state: this.info.state,
801 x: touch.clientX,
802 y: touch.clientY,
803 dx: dx,
804 dy: dy,
805 ddx: ddx,
806 ddy: ddy,
807 sourceEvent: touch,
808 hover: function () {
809 return Gestures.deepTargetFind(touch.clientX, touch.clientY);
810 }
811 });
812 }
813 });
814 Gestures.register({
815 name: 'tap',
816 deps: [
817 'mousedown',
818 'click',
819 'touchstart',
820 'touchend'
821 ],
822 emits: ['tap'],
823 info: {
824 x: NaN,
825 y: NaN,
826 prevent: false
827 },
828 reset: function () {
829 this.info.x = NaN;
830 this.info.y = NaN;
831 this.info.prevent = false;
832 },
833 save: function (e) {
834 this.info.x = e.clientX;
835 this.info.y = e.clientY;
836 },
837 mousedown: function (e) {
838 this.save(e);
839 },
840 click: function (e) {
841 this.forward(e);
842 },
843 touchstart: function (e) {
844 this.save(e.changedTouches[0]);
845 },
846 touchend: function (e) {
847 this.forward(e.changedTouches[0]);
848 },
849 forward: function (e) {
850 var dx = Math.abs(e.clientX - this.info.x);
851 var dy = Math.abs(e.clientY - this.info.y);
852 if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) {
853 if (!this.info.prevent) {
854 Gestures.fire(e.target, 'tap', {
855 x: e.clientX,
856 y: e.clientY,
857 sourceEvent: e
858 });
859 }
860 }
861 this.reset();
862 }
863 });
864 var DIRECTION_MAP = {
865 x: 'pan-x',
866 y: 'pan-y',
867 none: 'none',
868 all: 'auto'
869 };
870 Polymer.Base._addFeature({
871 _listen: function (node, eventName, handler) {
872 if (Gestures.gestures[eventName]) {
873 Gestures.add(node, eventName, handler);
874 } else {
875 node.addEventListener(eventName, handler);
876 }
877 },
878 _unlisten: function (node, eventName, handler) {
879 if (Gestures.gestures[eventName]) {
880 Gestures.remove(node, eventName, handler);
881 } else {
882 node.removeEventListener(eventName, handler);
883 }
884 },
885 setScrollDirection: function (direction, node) {
886 node = node || this;
887 Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');
888 }
889 });
890 Polymer.Gestures = Gestures;
891 }());
892 Polymer.Async = function () {
893 var currVal = 0;
894 var lastVal = 0;
895 var callbacks = [];
896 var twiddle = document.createTextNode('');
897 function runAsync(callback, waitTime) {
898 if (waitTime > 0) {
899 return ~setTimeout(callback, waitTime);
900 } else {
901 twiddle.textContent = currVal++;
902 callbacks.push(callback);
903 return currVal - 1;
904 }
905 }
906 function cancelAsync(handle) {
907 if (handle < 0) {
908 clearTimeout(~handle);
909 } else {
910 var idx = handle - lastVal;
911 if (idx >= 0) {
912 if (!callbacks[idx]) {
913 throw 'invalid async handle: ' + handle;
914 }
915 callbacks[idx] = null;
916 }
917 }
918 }
919 function atEndOfMicrotask() {
920 var len = callbacks.length;
921 for (var i = 0; i < len; i++) {
922 var cb = callbacks[i];
923 if (cb) {
924 cb();
925 }
926 }
927 callbacks.splice(0, len);
928 lastVal += len;
929 }
930 new (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask).observe(tw iddle, { characterData: true });
931 return {
932 run: runAsync,
933 cancel: cancelAsync
934 };
935 }();
936 Polymer.Debounce = function () {
937 var Async = Polymer.Async;
938 var Debouncer = function (context) {
939 this.context = context;
940 this.boundComplete = this.complete.bind(this);
941 };
942 Debouncer.prototype = {
943 go: function (callback, wait) {
944 var h;
945 this.finish = function () {
946 Async.cancel(h);
947 };
948 h = Async.run(this.boundComplete, wait);
949 this.callback = callback;
950 },
951 stop: function () {
952 if (this.finish) {
953 this.finish();
954 this.finish = null;
955 }
956 },
957 complete: function () {
958 if (this.finish) {
959 this.stop();
960 this.callback.call(this.context);
961 }
962 }
963 };
964 function debounce(debouncer, callback, wait) {
965 if (debouncer) {
966 debouncer.stop();
967 } else {
968 debouncer = new Debouncer(this);
969 }
970 debouncer.go(callback, wait);
971 return debouncer;
972 }
973 return debounce;
974 }();
975 Polymer.Base._addFeature({
976 $$: function (slctr) {
977 return Polymer.dom(this.root).querySelector(slctr);
978 },
979 toggleClass: function (name, bool, node) {
980 node = node || this;
981 if (arguments.length == 1) {
982 bool = !node.classList.contains(name);
983 }
984 if (bool) {
985 Polymer.dom(node).classList.add(name);
986 } else {
987 Polymer.dom(node).classList.remove(name);
988 }
989 },
990 toggleAttribute: function (name, bool, node) {
991 node = node || this;
992 if (arguments.length == 1) {
993 bool = !node.hasAttribute(name);
994 }
995 if (bool) {
996 Polymer.dom(node).setAttribute(name, '');
997 } else {
998 Polymer.dom(node).removeAttribute(name);
999 }
1000 },
1001 classFollows: function (name, toElement, fromElement) {
1002 if (fromElement) {
1003 Polymer.dom(fromElement).classList.remove(name);
1004 }
1005 if (toElement) {
1006 Polymer.dom(toElement).classList.add(name);
1007 }
1008 },
1009 attributeFollows: function (name, toElement, fromElement) {
1010 if (fromElement) {
1011 Polymer.dom(fromElement).removeAttribute(name);
1012 }
1013 if (toElement) {
1014 Polymer.dom(toElement).setAttribute(name, '');
1015 }
1016 },
1017 getContentChildNodes: function (slctr) {
1018 return Polymer.dom(Polymer.dom(this.root).querySelector(slctr || 'content')).get DistributedNodes();
1019 },
1020 getContentChildren: function (slctr) {
1021 return this.getContentChildNodes(slctr).filter(function (n) {
1022 return n.nodeType === Node.ELEMENT_NODE;
1023 });
1024 },
1025 fire: function (type, detail, options) {
1026 options = options || Polymer.nob;
1027 var node = options.node || this;
1028 var detail = detail === null || detail === undefined ? Polymer.nob : detail;
1029 var bubbles = options.bubbles === undefined ? true : options.bubbles;
1030 var cancelable = Boolean(options.cancelable);
1031 var event = new CustomEvent(type, {
1032 bubbles: Boolean(bubbles),
1033 cancelable: cancelable,
1034 detail: detail
1035 });
1036 node.dispatchEvent(event);
1037 return event;
1038 },
1039 async: function (callback, waitTime) {
1040 return Polymer.Async.run(callback.bind(this), waitTime);
1041 },
1042 cancelAsync: function (handle) {
1043 Polymer.Async.cancel(handle);
1044 },
1045 arrayDelete: function (path, item) {
1046 var index;
1047 if (Array.isArray(path)) {
1048 index = path.indexOf(item);
1049 if (index >= 0) {
1050 return path.splice(index, 1);
1051 }
1052 } else {
1053 var arr = this.get(path);
1054 index = arr.indexOf(item);
1055 if (index >= 0) {
1056 return this.splice(path, index, 1);
1057 }
1058 }
1059 },
1060 transform: function (transform, node) {
1061 node = node || this;
1062 node.style.webkitTransform = transform;
1063 node.style.transform = transform;
1064 },
1065 translate3d: function (x, y, z, node) {
1066 node = node || this;
1067 this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
1068 },
1069 importHref: function (href, onload, onerror) {
1070 var l = document.createElement('link');
1071 l.rel = 'import';
1072 l.href = href;
1073 if (onload) {
1074 l.onload = onload.bind(this);
1075 }
1076 if (onerror) {
1077 l.onerror = onerror.bind(this);
1078 }
1079 document.head.appendChild(l);
1080 return l;
1081 },
1082 create: function (tag, props) {
1083 var elt = document.createElement(tag);
1084 if (props) {
1085 for (var n in props) {
1086 elt[n] = props[n];
1087 }
1088 }
1089 return elt;
1090 },
1091 mixin: function (target, source) {
1092 for (var i in source) {
1093 target[i] = source[i];
1094 }
1095 }
1096 });
1097 Polymer.Bind = {
1098 prepareModel: function (model) {
1099 model._propertyEffects = {};
1100 model._bindListeners = [];
1101 var api = this._modelApi;
1102 for (var n in api) {
1103 model[n] = api[n];
1104 }
1105 },
1106 _modelApi: {
1107 _notifyChange: function (property) {
1108 var eventName = Polymer.CaseMap.camelToDashCase(property) + '-changed';
1109 this.fire(eventName, { value: this[property] }, { bubbles: false });
1110 },
1111 _propertySet: function (property, value, effects) {
1112 var old = this.__data__[property];
1113 if (old !== value && (old === old || value === value)) {
1114 this.__data__[property] = value;
1115 if (typeof value == 'object') {
1116 this._clearPath(property);
1117 }
1118 if (this._propertyChanged) {
1119 this._propertyChanged(property, value, old);
1120 }
1121 if (effects) {
1122 this._effectEffects(property, value, effects, old);
1123 }
1124 }
1125 return old;
1126 },
1127 _effectEffects: function (property, value, effects, old) {
1128 effects.forEach(function (fx) {
1129 var fn = Polymer.Bind['_' + fx.kind + 'Effect'];
1130 if (fn) {
1131 fn.call(this, property, value, fx.effect, old);
1132 }
1133 }, this);
1134 },
1135 _clearPath: function (path) {
1136 for (var prop in this.__data__) {
1137 if (prop.indexOf(path + '.') === 0) {
1138 this.__data__[prop] = undefined;
1139 }
1140 }
1141 }
1142 },
1143 ensurePropertyEffects: function (model, property) {
1144 var fx = model._propertyEffects[property];
1145 if (!fx) {
1146 fx = model._propertyEffects[property] = [];
1147 }
1148 return fx;
1149 },
1150 addPropertyEffect: function (model, property, kind, effect) {
1151 var fx = this.ensurePropertyEffects(model, property);
1152 fx.push({
1153 kind: kind,
1154 effect: effect
1155 });
1156 },
1157 createBindings: function (model) {
1158 var fx$ = model._propertyEffects;
1159 if (fx$) {
1160 for (var n in fx$) {
1161 var fx = fx$[n];
1162 fx.sort(this._sortPropertyEffects);
1163 this._createAccessors(model, n, fx);
1164 }
1165 }
1166 },
1167 _sortPropertyEffects: function () {
1168 var EFFECT_ORDER = {
1169 'compute': 0,
1170 'annotation': 1,
1171 'computedAnnotation': 2,
1172 'reflect': 3,
1173 'notify': 4,
1174 'observer': 5,
1175 'complexObserver': 6,
1176 'function': 7
1177 };
1178 return function (a, b) {
1179 return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];
1180 };
1181 }(),
1182 _createAccessors: function (model, property, effects) {
1183 var defun = {
1184 get: function () {
1185 return this.__data__[property];
1186 }
1187 };
1188 var setter = function (value) {
1189 this._propertySet(property, value, effects);
1190 };
1191 if (model.getPropertyInfo && model.getPropertyInfo(property).readOnly) {
1192 model['_set' + this.upper(property)] = setter;
1193 } else {
1194 defun.set = setter;
1195 }
1196 Object.defineProperty(model, property, defun);
1197 },
1198 upper: function (name) {
1199 return name[0].toUpperCase() + name.substring(1);
1200 },
1201 _addAnnotatedListener: function (model, index, property, path, event) {
1202 var fn = this._notedListenerFactory(property, path, this._isStructured(path), th is._isEventBogus);
1203 var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';
1204 model._bindListeners.push({
1205 index: index,
1206 property: property,
1207 path: path,
1208 changedFn: fn,
1209 event: eventName
1210 });
1211 },
1212 _isStructured: function (path) {
1213 return path.indexOf('.') > 0;
1214 },
1215 _isEventBogus: function (e, target) {
1216 return e.path && e.path[0] !== target;
1217 },
1218 _notedListenerFactory: function (property, path, isStructured, bogusTest) {
1219 return function (e, target) {
1220 if (!bogusTest(e, target)) {
1221 if (e.detail && e.detail.path) {
1222 this.notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);
1223 } else {
1224 var value = target[property];
1225 if (!isStructured) {
1226 this[path] = target[property];
1227 } else {
1228 if (this.__data__[path] != value) {
1229 this.set(path, value);
1230 }
1231 }
1232 }
1233 }
1234 };
1235 },
1236 prepareInstance: function (inst) {
1237 inst.__data__ = Object.create(null);
1238 },
1239 setupBindListeners: function (inst) {
1240 inst._bindListeners.forEach(function (info) {
1241 var node = inst._nodes[info.index];
1242 node.addEventListener(info.event, inst._notifyListener.bind(inst, info.changedFn ));
1243 });
1244 }
1245 };
1246 Polymer.Base.extend(Polymer.Bind, {
1247 _shouldAddListener: function (effect) {
1248 return effect.name && effect.mode === '{' && !effect.negate && effect.kind != 'a ttribute';
1249 },
1250 _annotationEffect: function (source, value, effect) {
1251 if (source != effect.value) {
1252 value = this.get(effect.value);
1253 this.__data__[effect.value] = value;
1254 }
1255 var calc = effect.negate ? !value : value;
1256 if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
1257 return this._applyEffectValue(calc, effect);
1258 }
1259 },
1260 _reflectEffect: function (source) {
1261 this.reflectPropertyToAttribute(source);
1262 },
1263 _notifyEffect: function (source) {
1264 this._notifyChange(source);
1265 },
1266 _functionEffect: function (source, value, fn, old) {
1267 fn.call(this, source, value, old);
1268 },
1269 _observerEffect: function (source, value, effect, old) {
1270 var fn = this[effect.method];
1271 if (fn) {
1272 fn.call(this, value, old);
1273 } else {
1274 this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + ' ` not defined'));
1275 }
1276 },
1277 _complexObserverEffect: function (source, value, effect) {
1278 var fn = this[effect.method];
1279 if (fn) {
1280 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
1281 if (args) {
1282 fn.apply(this, args);
1283 }
1284 } else {
1285 this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.met hod + '` not defined'));
1286 }
1287 },
1288 _computeEffect: function (source, value, effect) {
1289 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
1290 if (args) {
1291 var fn = this[effect.method];
1292 if (fn) {
1293 this[effect.property] = fn.apply(this, args);
1294 } else {
1295 this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
1296 }
1297 }
1298 },
1299 _annotatedComputationEffect: function (source, value, effect) {
1300 var computedHost = this._rootDataHost || this;
1301 var fn = computedHost[effect.method];
1302 if (fn) {
1303 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
1304 if (args) {
1305 var computedvalue = fn.apply(computedHost, args);
1306 if (effect.negate) {
1307 computedvalue = !computedvalue;
1308 }
1309 this._applyEffectValue(computedvalue, effect);
1310 }
1311 } else {
1312 computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute me thod `' + effect.method + '` not defined'));
1313 }
1314 },
1315 _marshalArgs: function (model, effect, path, value) {
1316 var values = [];
1317 var args = effect.args;
1318 for (var i = 0, l = args.length; i < l; i++) {
1319 var arg = args[i];
1320 var name = arg.name;
1321 var v;
1322 if (arg.literal) {
1323 v = arg.value;
1324 } else if (arg.structured) {
1325 v = Polymer.Base.get(name, model);
1326 } else {
1327 v = model[name];
1328 }
1329 if (args.length > 1 && v === undefined) {
1330 return;
1331 }
1332 if (arg.wildcard) {
1333 var baseChanged = name.indexOf(path + '.') === 0;
1334 var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;
1335 values[i] = {
1336 path: matches ? path : name,
1337 value: matches ? value : v,
1338 base: v
1339 };
1340 } else {
1341 values[i] = v;
1342 }
1343 }
1344 return values;
1345 }
1346 });
1347 Polymer.Base._addFeature({
1348 _addPropertyEffect: function (property, kind, effect) {
1349 Polymer.Bind.addPropertyEffect(this, property, kind, effect);
1350 },
1351 _prepEffects: function () {
1352 Polymer.Bind.prepareModel(this);
1353 this._addAnnotationEffects(this._notes);
1354 },
1355 _prepBindings: function () {
1356 Polymer.Bind.createBindings(this);
1357 },
1358 _addPropertyEffects: function (properties) {
1359 if (properties) {
1360 for (var p in properties) {
1361 var prop = properties[p];
1362 if (prop.observer) {
1363 this._addObserverEffect(p, prop.observer);
1364 }
1365 if (prop.computed) {
1366 this._addComputedEffect(p, prop.computed);
1367 }
1368 if (prop.notify) {
1369 this._addPropertyEffect(p, 'notify');
1370 }
1371 if (prop.reflectToAttribute) {
1372 this._addPropertyEffect(p, 'reflect');
1373 }
1374 if (prop.readOnly) {
1375 Polymer.Bind.ensurePropertyEffects(this, p);
1376 }
1377 }
1378 }
1379 },
1380 _addComputedEffect: function (name, expression) {
1381 var sig = this._parseMethod(expression);
1382 sig.args.forEach(function (arg) {
1383 this._addPropertyEffect(arg.model, 'compute', {
1384 method: sig.method,
1385 args: sig.args,
1386 trigger: arg,
1387 property: name
1388 });
1389 }, this);
1390 },
1391 _addObserverEffect: function (property, observer) {
1392 this._addPropertyEffect(property, 'observer', {
1393 method: observer,
1394 property: property
1395 });
1396 },
1397 _addComplexObserverEffects: function (observers) {
1398 if (observers) {
1399 observers.forEach(function (observer) {
1400 this._addComplexObserverEffect(observer);
1401 }, this);
1402 }
1403 },
1404 _addComplexObserverEffect: function (observer) {
1405 var sig = this._parseMethod(observer);
1406 sig.args.forEach(function (arg) {
1407 this._addPropertyEffect(arg.model, 'complexObserver', {
1408 method: sig.method,
1409 args: sig.args,
1410 trigger: arg
1411 });
1412 }, this);
1413 },
1414 _addAnnotationEffects: function (notes) {
1415 this._nodes = [];
1416 notes.forEach(function (note) {
1417 var index = this._nodes.push(note) - 1;
1418 note.bindings.forEach(function (binding) {
1419 this._addAnnotationEffect(binding, index);
1420 }, this);
1421 }, this);
1422 },
1423 _addAnnotationEffect: function (note, index) {
1424 if (Polymer.Bind._shouldAddListener(note)) {
1425 Polymer.Bind._addAnnotatedListener(this, index, note.name, note.value, note.even t);
1426 }
1427 if (note.signature) {
1428 this._addAnnotatedComputationEffect(note, index);
1429 } else {
1430 note.index = index;
1431 this._addPropertyEffect(note.model, 'annotation', note);
1432 }
1433 },
1434 _addAnnotatedComputationEffect: function (note, index) {
1435 var sig = note.signature;
1436 if (sig.static) {
1437 this.__addAnnotatedComputationEffect('__static__', index, note, sig, null);
1438 } else {
1439 sig.args.forEach(function (arg) {
1440 if (!arg.literal) {
1441 this.__addAnnotatedComputationEffect(arg.model, index, note, sig, arg);
1442 }
1443 }, this);
1444 }
1445 },
1446 __addAnnotatedComputationEffect: function (property, index, note, sig, trigger) {
1447 this._addPropertyEffect(property, 'annotatedComputation', {
1448 index: index,
1449 kind: note.kind,
1450 property: note.name,
1451 negate: note.negate,
1452 method: sig.method,
1453 args: sig.args,
1454 trigger: trigger
1455 });
1456 },
1457 _parseMethod: function (expression) {
1458 var m = expression.match(/(\w*)\((.*)\)/);
1459 if (m) {
1460 var sig = {
1461 method: m[1],
1462 static: true
1463 };
1464 if (m[2].trim()) {
1465 var args = m[2].replace(/\\,/g, '&comma;').split(',');
1466 return this._parseArgs(args, sig);
1467 } else {
1468 sig.args = Polymer.nar;
1469 return sig;
1470 }
1471 }
1472 },
1473 _parseArgs: function (argList, sig) {
1474 sig.args = argList.map(function (rawArg) {
1475 var arg = this._parseArg(rawArg);
1476 if (!arg.literal) {
1477 sig.static = false;
1478 }
1479 return arg;
1480 }, this);
1481 return sig;
1482 },
1483 _parseArg: function (rawArg) {
1484 var arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\(.)/g, '$1');
1485 var a = {
1486 name: arg,
1487 model: this._modelForPath(arg)
1488 };
1489 var fc = arg[0];
1490 if (fc >= '0' && fc <= '9') {
1491 fc = '#';
1492 }
1493 switch (fc) {
1494 case '\'':
1495 case '"':
1496 a.value = arg.slice(1, -1);
1497 a.literal = true;
1498 break;
1499 case '#':
1500 a.value = Number(arg);
1501 a.literal = true;
1502 break;
1503 }
1504 if (!a.literal) {
1505 a.structured = arg.indexOf('.') > 0;
1506 if (a.structured) {
1507 a.wildcard = arg.slice(-2) == '.*';
1508 if (a.wildcard) {
1509 a.name = arg.slice(0, -2);
1510 }
1511 }
1512 }
1513 return a;
1514 },
1515 _marshalInstanceEffects: function () {
1516 Polymer.Bind.prepareInstance(this);
1517 Polymer.Bind.setupBindListeners(this);
1518 },
1519 _applyEffectValue: function (value, info) {
1520 var node = this._nodes[info.index];
1521 var property = info.property || info.name || 'textContent';
1522 if (info.kind == 'attribute') {
1523 this.serializeValueToAttribute(value, property, node);
1524 } else {
1525 if (property === 'className') {
1526 value = this._scopeElementClass(node, value);
1527 }
1528 if (property === 'textContent' || node.localName == 'input' && property == 'valu e') {
1529 value = value == undefined ? '' : value;
1530 }
1531 return node[property] = value;
1532 }
1533 },
1534 _executeStaticEffects: function () {
1535 if (this._propertyEffects.__static__) {
1536 this._effectEffects('__static__', null, this._propertyEffects.__static__);
1537 }
1538 }
1539 });
1540 Polymer.Base._addFeature({
1541 _setupConfigure: function (initialConfig) {
1542 this._config = initialConfig || {};
1543 this._handlers = [];
1544 },
1545 _marshalAttributes: function () {
1546 this._takeAttributesToModel(this._config);
1547 },
1548 _configValue: function (name, value) {
1549 this._config[name] = value;
1550 },
1551 _beforeClientsReady: function () {
1552 this._configure();
1553 },
1554 _configure: function () {
1555 this._configureAnnotationReferences();
1556 var config = {};
1557 this.behaviors.forEach(function (b) {
1558 this._configureProperties(b.properties, config);
1559 }, this);
1560 this._configureProperties(this.properties, config);
1561 this._mixinConfigure(config, this._config);
1562 this._config = config;
1563 this._distributeConfig(this._config);
1564 },
1565 _configureProperties: function (properties, config) {
1566 for (var i in properties) {
1567 var c = properties[i];
1568 if (c.value !== undefined) {
1569 var value = c.value;
1570 if (typeof value == 'function') {
1571 value = value.call(this, this._config);
1572 }
1573 config[i] = value;
1574 }
1575 }
1576 },
1577 _mixinConfigure: function (a, b) {
1578 for (var prop in b) {
1579 if (!this.getPropertyInfo(prop).readOnly) {
1580 a[prop] = b[prop];
1581 }
1582 }
1583 },
1584 _distributeConfig: function (config) {
1585 var fx$ = this._propertyEffects;
1586 if (fx$) {
1587 for (var p in config) {
1588 var fx = fx$[p];
1589 if (fx) {
1590 for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
1591 if (x.kind === 'annotation') {
1592 var node = this._nodes[x.effect.index];
1593 if (node._configValue) {
1594 var value = p === x.effect.value ? config[p] : this.get(x.effect.value, config);
1595 node._configValue(x.effect.name, value);
1596 }
1597 }
1598 }
1599 }
1600 }
1601 }
1602 },
1603 _afterClientsReady: function () {
1604 this._executeStaticEffects();
1605 this._applyConfig(this._config);
1606 this._flushHandlers();
1607 },
1608 _applyConfig: function (config) {
1609 for (var n in config) {
1610 if (this[n] === undefined) {
1611 var effects = this._propertyEffects[n];
1612 if (effects) {
1613 this._propertySet(n, config[n], effects);
1614 } else {
1615 this[n] = config[n];
1616 }
1617 }
1618 }
1619 },
1620 _notifyListener: function (fn, e) {
1621 if (!this._clientsReadied) {
1622 this._queueHandler([
1623 fn,
1624 e,
1625 e.target
1626 ]);
1627 } else {
1628 return fn.call(this, e, e.target);
1629 }
1630 },
1631 _queueHandler: function (args) {
1632 this._handlers.push(args);
1633 },
1634 _flushHandlers: function () {
1635 var h$ = this._handlers;
1636 for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
1637 h[0].call(this, h[1], h[2]);
1638 }
1639 }
1640 });
1641 (function () {
1642 'use strict';
1643 Polymer.Base._addFeature({
1644 notifyPath: function (path, value, fromAbove) {
1645 var old = this._propertySet(path, value);
1646 if (old !== value && (old === old || value === value)) {
1647 this._pathEffector(path, value);
1648 if (!fromAbove) {
1649 this._notifyPath(path, value);
1650 }
1651 }
1652 },
1653 _getPathParts: function (path) {
1654 if (Array.isArray(path)) {
1655 var parts = [];
1656 for (var i = 0; i < path.length; i++) {
1657 var args = path[i].toString().split('.');
1658 for (var j = 0; j < args.length; j++) {
1659 parts.push(args[j]);
1660 }
1661 }
1662 return parts;
1663 } else {
1664 return path.toString().split('.');
1665 }
1666 },
1667 set: function (path, value, root) {
1668 var prop = root || this;
1669 var parts = this._getPathParts(path);
1670 var array;
1671 var last = parts[parts.length - 1];
1672 if (parts.length > 1) {
1673 for (var i = 0; i < parts.length - 1; i++) {
1674 prop = prop[parts[i]];
1675 if (array) {
1676 parts[i] = Polymer.Collection.get(array).getKey(prop);
1677 }
1678 if (!prop) {
1679 return;
1680 }
1681 array = Array.isArray(prop) ? prop : null;
1682 }
1683 prop[last] = value;
1684 if (!root) {
1685 this.notifyPath(parts.join('.'), value);
1686 }
1687 } else {
1688 prop[path] = value;
1689 }
1690 },
1691 get: function (path, root) {
1692 var prop = root || this;
1693 var parts = this._getPathParts(path);
1694 var last = parts.pop();
1695 while (parts.length) {
1696 prop = prop[parts.shift()];
1697 if (!prop) {
1698 return;
1699 }
1700 }
1701 return prop[last];
1702 },
1703 _pathEffector: function (path, value) {
1704 var model = this._modelForPath(path);
1705 var fx$ = this._propertyEffects[model];
1706 if (fx$) {
1707 fx$.forEach(function (fx) {
1708 var fxFn = this['_' + fx.kind + 'PathEffect'];
1709 if (fxFn) {
1710 fxFn.call(this, path, value, fx.effect);
1711 }
1712 }, this);
1713 }
1714 if (this._boundPaths) {
1715 this._notifyBoundPaths(path, value);
1716 }
1717 },
1718 _annotationPathEffect: function (path, value, effect) {
1719 if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
1720 Polymer.Bind._annotationEffect.call(this, path, value, effect);
1721 } else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
1722 var node = this._nodes[effect.index];
1723 if (node && node.notifyPath) {
1724 var p = this._fixPath(effect.name, effect.value, path);
1725 node.notifyPath(p, value, true);
1726 }
1727 }
1728 },
1729 _complexObserverPathEffect: function (path, value, effect) {
1730 if (this._pathMatchesEffect(path, effect)) {
1731 Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
1732 }
1733 },
1734 _computePathEffect: function (path, value, effect) {
1735 if (this._pathMatchesEffect(path, effect)) {
1736 Polymer.Bind._computeEffect.call(this, path, value, effect);
1737 }
1738 },
1739 _annotatedComputationPathEffect: function (path, value, effect) {
1740 if (this._pathMatchesEffect(path, effect)) {
1741 Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect);
1742 }
1743 },
1744 _pathMatchesEffect: function (path, effect) {
1745 var effectArg = effect.trigger.name;
1746 return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigge r.wildcard && path.indexOf(effectArg) === 0;
1747 },
1748 linkPaths: function (to, from) {
1749 this._boundPaths = this._boundPaths || {};
1750 if (from) {
1751 this._boundPaths[to] = from;
1752 } else {
1753 this.unbindPath(to);
1754 }
1755 },
1756 unlinkPaths: function (path) {
1757 if (this._boundPaths) {
1758 delete this._boundPaths[path];
1759 }
1760 },
1761 _notifyBoundPaths: function (path, value) {
1762 var from, to;
1763 for (var a in this._boundPaths) {
1764 var b = this._boundPaths[a];
1765 if (path.indexOf(a + '.') == 0) {
1766 from = a;
1767 to = b;
1768 break;
1769 }
1770 if (path.indexOf(b + '.') == 0) {
1771 from = b;
1772 to = a;
1773 break;
1774 }
1775 }
1776 if (from && to) {
1777 var p = this._fixPath(to, from, path);
1778 this.notifyPath(p, value);
1779 }
1780 },
1781 _fixPath: function (property, root, path) {
1782 return property + path.slice(root.length);
1783 },
1784 _notifyPath: function (path, value) {
1785 var rootName = this._modelForPath(path);
1786 var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
1787 var eventName = dashCaseName + this._EVENT_CHANGED;
1788 this.fire(eventName, {
1789 path: path,
1790 value: value
1791 }, { bubbles: false });
1792 },
1793 _modelForPath: function (path) {
1794 var dot = path.indexOf('.');
1795 return dot < 0 ? path : path.slice(0, dot);
1796 },
1797 _EVENT_CHANGED: '-changed',
1798 _notifySplice: function (array, path, index, added, removed) {
1799 var splices = [{
1800 index: index,
1801 addedCount: added,
1802 removed: removed,
1803 object: array,
1804 type: 'splice'
1805 }];
1806 var change = {
1807 keySplices: Polymer.Collection.applySplices(array, splices),
1808 indexSplices: splices
1809 };
1810 this.set(path + '.splices', change);
1811 if (added != removed.length) {
1812 this.notifyPath(path + '.length', array.length);
1813 }
1814 change.keySplices = null;
1815 change.indexSplices = null;
1816 },
1817 push: function (path) {
1818 var array = this.get(path);
1819 var args = Array.prototype.slice.call(arguments, 1);
1820 var len = array.length;
1821 var ret = array.push.apply(array, args);
1822 this._notifySplice(array, path, len, args.length, []);
1823 return ret;
1824 },
1825 pop: function (path) {
1826 var array = this.get(path);
1827 var args = Array.prototype.slice.call(arguments, 1);
1828 var rem = array.slice(-1);
1829 var ret = array.pop.apply(array, args);
1830 this._notifySplice(array, path, array.length, 0, rem);
1831 return ret;
1832 },
1833 splice: function (path, start, deleteCount) {
1834 var array = this.get(path);
1835 var args = Array.prototype.slice.call(arguments, 1);
1836 var rem = array.slice(start, start + deleteCount);
1837 var ret = array.splice.apply(array, args);
1838 this._notifySplice(array, path, start, args.length - 2, rem);
1839 return ret;
1840 },
1841 shift: function (path) {
1842 var array = this.get(path);
1843 var args = Array.prototype.slice.call(arguments, 1);
1844 var ret = array.shift.apply(array, args);
1845 this._notifySplice(array, path, 0, 0, [ret]);
1846 return ret;
1847 },
1848 unshift: function (path) {
1849 var array = this.get(path);
1850 var args = Array.prototype.slice.call(arguments, 1);
1851 var ret = array.unshift.apply(array, args);
1852 this._notifySplice(array, path, 0, args.length, []);
1853 return ret;
1854 }
1855 });
1856 }());
1857 Polymer.Base._addFeature({
1858 resolveUrl: function (url) {
1859 var module = Polymer.DomModule.import(this.is);
1860 var root = '';
1861 if (module) {
1862 var assetPath = module.getAttribute('assetpath') || '';
1863 root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);
1864 }
1865 return Polymer.ResolveUrl.resolveUrl(url, root);
1866 }
1867 });
1868 Polymer.CssParse = function () {
1869 var api = {
1870 parse: function (text) {
1871 text = this._clean(text);
1872 return this._parseCss(this._lex(text), text);
1873 },
1874 _clean: function (cssText) {
1875 return cssText.replace(rx.comments, '').replace(rx.port, '');
1876 },
1877 _lex: function (text) {
1878 var root = {
1879 start: 0,
1880 end: text.length
1881 };
1882 var n = root;
1883 for (var i = 0, s = 0, l = text.length; i < l; i++) {
1884 switch (text[i]) {
1885 case this.OPEN_BRACE:
1886 if (!n.rules) {
1887 n.rules = [];
1888 }
1889 var p = n;
1890 var previous = p.rules[p.rules.length - 1];
1891 n = {
1892 start: i + 1,
1893 parent: p,
1894 previous: previous
1895 };
1896 p.rules.push(n);
1897 break;
1898 case this.CLOSE_BRACE:
1899 n.end = i + 1;
1900 n = n.parent || root;
1901 break;
1902 }
1903 }
1904 return root;
1905 },
1906 _parseCss: function (node, text) {
1907 var t = text.substring(node.start, node.end - 1);
1908 node.parsedCssText = node.cssText = t.trim();
1909 if (node.parent) {
1910 var ss = node.previous ? node.previous.end : node.parent.start;
1911 t = text.substring(ss, node.start - 1);
1912 t = t.substring(t.lastIndexOf(';') + 1);
1913 var s = node.parsedSelector = node.selector = t.trim();
1914 node.atRule = s.indexOf(AT_START) === 0;
1915 if (node.atRule) {
1916 if (s.indexOf(MEDIA_START) === 0) {
1917 node.type = this.types.MEDIA_RULE;
1918 } else if (s.match(rx.keyframesRule)) {
1919 node.type = this.types.KEYFRAMES_RULE;
1920 }
1921 } else {
1922 if (s.indexOf(VAR_START) === 0) {
1923 node.type = this.types.MIXIN_RULE;
1924 } else {
1925 node.type = this.types.STYLE_RULE;
1926 }
1927 }
1928 }
1929 var r$ = node.rules;
1930 if (r$) {
1931 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
1932 this._parseCss(r, text);
1933 }
1934 }
1935 return node;
1936 },
1937 stringify: function (node, preserveProperties, text) {
1938 text = text || '';
1939 var cssText = '';
1940 if (node.cssText || node.rules) {
1941 var r$ = node.rules;
1942 if (r$ && (preserveProperties || !hasMixinRules(r$))) {
1943 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
1944 cssText = this.stringify(r, preserveProperties, cssText);
1945 }
1946 } else {
1947 cssText = preserveProperties ? node.cssText : removeCustomProps(node.cssText);
1948 cssText = cssText.trim();
1949 if (cssText) {
1950 cssText = ' ' + cssText + '\n';
1951 }
1952 }
1953 }
1954 if (cssText) {
1955 if (node.selector) {
1956 text += node.selector + ' ' + this.OPEN_BRACE + '\n';
1957 }
1958 text += cssText;
1959 if (node.selector) {
1960 text += this.CLOSE_BRACE + '\n\n';
1961 }
1962 }
1963 return text;
1964 },
1965 types: {
1966 STYLE_RULE: 1,
1967 KEYFRAMES_RULE: 7,
1968 MEDIA_RULE: 4,
1969 MIXIN_RULE: 1000
1970 },
1971 OPEN_BRACE: '{',
1972 CLOSE_BRACE: '}'
1973 };
1974 function hasMixinRules(rules) {
1975 return rules[0].selector.indexOf(VAR_START) >= 0;
1976 }
1977 function removeCustomProps(cssText) {
1978 return cssText.replace(rx.customProp, '').replace(rx.mixinProp, '').replace(rx.m ixinApply, '').replace(rx.varApply, '');
1979 }
1980 var VAR_START = '--';
1981 var MEDIA_START = '@media';
1982 var AT_START = '@';
1983 var rx = {
1984 comments: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
1985 port: /@import[^;]*;/gim,
1986 customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?;/gim,
1987 mixinProp: /(?:^|[\s;])--[^;{]*?:[^{;]*?{[^}]*?};?/gim,
1988 mixinApply: /@apply[\s]*\([^)]*?\)[\s]*;/gim,
1989 varApply: /[^;:]*?:[^;]*var[^;]*;/gim,
1990 keyframesRule: /^@[^\s]*keyframes/
1991 };
1992 return api;
1993 }();
1994 Polymer.StyleUtil = function () {
1995 return {
1996 MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css]',
1997 toCssText: function (rules, callback, preserveProperties) {
1998 if (typeof rules === 'string') {
1999 rules = this.parser.parse(rules);
2000 }
2001 if (callback) {
2002 this.forEachStyleRule(rules, callback);
2003 }
2004 return this.parser.stringify(rules, preserveProperties);
2005 },
2006 forRulesInStyles: function (styles, callback) {
2007 for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
2008 this.forEachStyleRule(this.rulesForStyle(s), callback);
2009 }
2010 },
2011 rulesForStyle: function (style) {
2012 if (!style.__cssRules && style.textContent) {
2013 style.__cssRules = this.parser.parse(style.textContent);
2014 }
2015 return style.__cssRules;
2016 },
2017 clearStyleRules: function (style) {
2018 style.__cssRules = null;
2019 },
2020 forEachStyleRule: function (node, callback) {
2021 var s = node.selector;
2022 var skipRules = false;
2023 if (node.type === this.ruleTypes.STYLE_RULE) {
2024 callback(node);
2025 } else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.rul eTypes.MIXIN_RULE) {
2026 skipRules = true;
2027 }
2028 var r$ = node.rules;
2029 if (r$ && !skipRules) {
2030 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
2031 this.forEachStyleRule(r, callback);
2032 }
2033 }
2034 },
2035 applyCss: function (cssText, moniker, target, afterNode) {
2036 var style = document.createElement('style');
2037 if (moniker) {
2038 style.setAttribute('scope', moniker);
2039 }
2040 style.textContent = cssText;
2041 target = target || document.head;
2042 if (!afterNode) {
2043 var n$ = target.querySelectorAll('style[scope]');
2044 afterNode = n$[n$.length - 1];
2045 }
2046 target.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChi ld);
2047 return style;
2048 },
2049 cssFromModule: function (moduleId) {
2050 var m = Polymer.DomModule.import(moduleId);
2051 if (m && !m._cssText) {
2052 var cssText = '';
2053 var e$ = Array.prototype.slice.call(m.querySelectorAll(this.MODULE_STYLES_SELECT OR));
2054 for (var i = 0, e; i < e$.length; i++) {
2055 e = e$[i];
2056 if (e.localName === 'style') {
2057 e = e.__appliedElement || e;
2058 e.parentNode.removeChild(e);
2059 } else {
2060 e = e.import && e.import.body;
2061 }
2062 if (e) {
2063 cssText += Polymer.ResolveUrl.resolveCss(e.textContent, e.ownerDocument);
2064 }
2065 }
2066 m._cssText = cssText;
2067 }
2068 return m && m._cssText || '';
2069 },
2070 parser: Polymer.CssParse,
2071 ruleTypes: Polymer.CssParse.types
2072 };
2073 }();
2074 Polymer.StyleTransformer = function () {
2075 var nativeShadow = Polymer.Settings.useNativeShadow;
2076 var styleUtil = Polymer.StyleUtil;
2077 var api = {
2078 dom: function (node, scope, useAttr, shouldRemoveScope) {
2079 this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
2080 },
2081 _transformDom: function (node, selector, useAttr, shouldRemoveScope) {
2082 if (node.setAttribute) {
2083 this.element(node, selector, useAttr, shouldRemoveScope);
2084 }
2085 var c$ = Polymer.dom(node).childNodes;
2086 for (var i = 0; i < c$.length; i++) {
2087 this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
2088 }
2089 },
2090 element: function (element, scope, useAttr, shouldRemoveScope) {
2091 if (useAttr) {
2092 if (shouldRemoveScope) {
2093 element.removeAttribute(SCOPE_NAME);
2094 } else {
2095 element.setAttribute(SCOPE_NAME, scope);
2096 }
2097 } else {
2098 if (scope) {
2099 if (element.classList) {
2100 if (shouldRemoveScope) {
2101 element.classList.remove(SCOPE_NAME);
2102 element.classList.remove(scope);
2103 } else {
2104 element.classList.add(SCOPE_NAME);
2105 element.classList.add(scope);
2106 }
2107 } else if (element.getAttribute) {
2108 var c = element.getAttribute(CLASS);
2109 if (shouldRemoveScope) {
2110 if (c) {
2111 element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));
2112 }
2113 } else {
2114 element.setAttribute(CLASS, c + (c ? ' ' : '') + SCOPE_NAME + ' ' + scope);
2115 }
2116 }
2117 }
2118 }
2119 },
2120 elementStyles: function (element, callback) {
2121 var styles = element._styles;
2122 var cssText = '';
2123 for (var i = 0, l = styles.length, s, text; i < l && (s = styles[i]); i++) {
2124 var rules = styleUtil.rulesForStyle(s);
2125 cssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n';
2126 }
2127 return cssText.trim();
2128 },
2129 css: function (rules, scope, ext, callback, useAttr) {
2130 var hostScope = this._calcHostScope(scope, ext);
2131 scope = this._calcElementScope(scope, useAttr);
2132 var self = this;
2133 return styleUtil.toCssText(rules, function (rule) {
2134 if (!rule.isScoped) {
2135 self.rule(rule, scope, hostScope);
2136 rule.isScoped = true;
2137 }
2138 if (callback) {
2139 callback(rule, scope, hostScope);
2140 }
2141 });
2142 },
2143 _calcElementScope: function (scope, useAttr) {
2144 if (scope) {
2145 return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;
2146 } else {
2147 return '';
2148 }
2149 },
2150 _calcHostScope: function (scope, ext) {
2151 return ext ? '[is=' + scope + ']' : scope;
2152 },
2153 rule: function (rule, scope, hostScope) {
2154 this._transformRule(rule, this._transformComplexSelector, scope, hostScope);
2155 },
2156 _transformRule: function (rule, transformer, scope, hostScope) {
2157 var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
2158 for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
2159 p$[i] = transformer.call(this, p, scope, hostScope);
2160 }
2161 rule.selector = p$.join(COMPLEX_SELECTOR_SEP);
2162 },
2163 _transformComplexSelector: function (selector, scope, hostScope) {
2164 var stop = false;
2165 var self = this;
2166 selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {
2167 if (!stop) {
2168 var o = self._transformCompoundSelector(s, c, scope, hostScope);
2169 if (o.stop) {
2170 stop = true;
2171 }
2172 c = o.combinator;
2173 s = o.value;
2174 } else {
2175 s = s.replace(SCOPE_JUMP, ' ');
2176 }
2177 return c + s;
2178 });
2179 return selector;
2180 },
2181 _transformCompoundSelector: function (selector, combinator, scope, hostScope) {
2182 var jumpIndex = selector.search(SCOPE_JUMP);
2183 if (selector.indexOf(HOST) >= 0) {
2184 selector = selector.replace(HOST_PAREN, function (m, host, paren) {
2185 return hostScope + paren;
2186 });
2187 selector = selector.replace(HOST, hostScope);
2188 } else if (jumpIndex !== 0) {
2189 selector = scope ? this._transformSimpleSelector(selector, scope) : selector;
2190 }
2191 if (selector.indexOf(CONTENT) >= 0) {
2192 combinator = '';
2193 }
2194 var stop;
2195 if (jumpIndex >= 0) {
2196 selector = selector.replace(SCOPE_JUMP, ' ');
2197 stop = true;
2198 }
2199 return {
2200 value: selector,
2201 combinator: combinator,
2202 stop: stop
2203 };
2204 },
2205 _transformSimpleSelector: function (selector, scope) {
2206 var p$ = selector.split(PSEUDO_PREFIX);
2207 p$[0] += scope;
2208 return p$.join(PSEUDO_PREFIX);
2209 },
2210 documentRule: function (rule) {
2211 rule.selector = rule.parsedSelector;
2212 this.normalizeRootSelector(rule);
2213 if (!nativeShadow) {
2214 this._transformRule(rule, this._transformDocumentSelector);
2215 }
2216 },
2217 normalizeRootSelector: function (rule) {
2218 if (rule.selector === ROOT) {
2219 rule.selector = 'body';
2220 }
2221 },
2222 _transformDocumentSelector: function (selector) {
2223 return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCO PE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELE CTOR);
2224 },
2225 SCOPE_NAME: 'style-scope'
2226 };
2227 var SCOPE_NAME = api.SCOPE_NAME;
2228 var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';
2229 var COMPLEX_SELECTOR_SEP = ',';
2230 var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
2231 var HOST = ':host';
2232 var ROOT = ':root';
2233 var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
2234 var CONTENT = '::content';
2235 var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
2236 var CSS_CLASS_PREFIX = '.';
2237 var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
2238 var CSS_ATTR_SUFFIX = ']';
2239 var PSEUDO_PREFIX = ':';
2240 var CLASS = 'class';
2241 return api;
2242 }();
2243 Polymer.StyleExtends = function () {
2244 var styleUtil = Polymer.StyleUtil;
2245 return {
2246 hasExtends: function (cssText) {
2247 return Boolean(cssText.match(this.rx.EXTEND));
2248 },
2249 transform: function (style) {
2250 var rules = styleUtil.rulesForStyle(style);
2251 var self = this;
2252 styleUtil.forEachStyleRule(rules, function (rule) {
2253 var map = self._mapRule(rule);
2254 if (rule.parent) {
2255 var m;
2256 while (m = self.rx.EXTEND.exec(rule.cssText)) {
2257 var extend = m[1];
2258 var extendor = self._findExtendor(extend, rule);
2259 if (extendor) {
2260 self._extendRule(rule, extendor);
2261 }
2262 }
2263 }
2264 rule.cssText = rule.cssText.replace(self.rx.EXTEND, '');
2265 });
2266 return styleUtil.toCssText(rules, function (rule) {
2267 if (rule.selector.match(self.rx.STRIP)) {
2268 rule.cssText = '';
2269 }
2270 }, true);
2271 },
2272 _mapRule: function (rule) {
2273 if (rule.parent) {
2274 var map = rule.parent.map || (rule.parent.map = {});
2275 var parts = rule.selector.split(',');
2276 for (var i = 0, p; i < parts.length; i++) {
2277 p = parts[i];
2278 map[p.trim()] = rule;
2279 }
2280 return map;
2281 }
2282 },
2283 _findExtendor: function (extend, rule) {
2284 return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findEx tendor(extend, rule.parent);
2285 },
2286 _extendRule: function (target, source) {
2287 if (target.parent !== source.parent) {
2288 this._cloneAndAddRuleToParent(source, target.parent);
2289 }
2290 target.extends = target.extends || (target.extends = []);
2291 target.extends.push(source);
2292 source.selector = source.selector.replace(this.rx.STRIP, '');
2293 source.selector = (source.selector && source.selector + ',\n') + target.selector ;
2294 if (source.extends) {
2295 source.extends.forEach(function (e) {
2296 this._extendRule(target, e);
2297 }, this);
2298 }
2299 },
2300 _cloneAndAddRuleToParent: function (rule, parent) {
2301 rule = Object.create(rule);
2302 rule.parent = parent;
2303 if (rule.extends) {
2304 rule.extends = rule.extends.slice();
2305 }
2306 parent.rules.push(rule);
2307 },
2308 rx: {
2309 EXTEND: /@extends\(([^)]*)\)\s*?;/gim,
2310 STRIP: /%[^,]*$/
2311 }
2312 };
2313 }();
2314 (function () {
2315 var prepElement = Polymer.Base._prepElement;
2316 var nativeShadow = Polymer.Settings.useNativeShadow;
2317 var styleUtil = Polymer.StyleUtil;
2318 var styleTransformer = Polymer.StyleTransformer;
2319 var styleExtends = Polymer.StyleExtends;
2320 Polymer.Base._addFeature({
2321 _prepElement: function (element) {
2322 if (this._encapsulateStyle) {
2323 styleTransformer.element(element, this.is, this._scopeCssViaAttr);
2324 }
2325 prepElement.call(this, element);
2326 },
2327 _prepStyles: function () {
2328 if (this._encapsulateStyle === undefined) {
2329 this._encapsulateStyle = !nativeShadow && Boolean(this._template);
2330 }
2331 this._styles = this._collectStyles();
2332 var cssText = styleTransformer.elementStyles(this);
2333 if (cssText && this._template) {
2334 var style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.c ontent : null);
2335 if (!nativeShadow) {
2336 this._scopeStyle = style;
2337 }
2338 }
2339 },
2340 _collectStyles: function () {
2341 var styles = [];
2342 var cssText = '', m$ = this.styleModules;
2343 if (m$) {
2344 for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {
2345 cssText += styleUtil.cssFromModule(m);
2346 }
2347 }
2348 cssText += styleUtil.cssFromModule(this.is);
2349 if (cssText) {
2350 var style = document.createElement('style');
2351 style.textContent = cssText;
2352 if (styleExtends.hasExtends(style.textContent)) {
2353 cssText = styleExtends.transform(style);
2354 }
2355 styles.push(style);
2356 }
2357 return styles;
2358 },
2359 _elementAdd: function (node) {
2360 if (this._encapsulateStyle) {
2361 if (node.__styleScoped) {
2362 node.__styleScoped = false;
2363 } else {
2364 styleTransformer.dom(node, this.is, this._scopeCssViaAttr);
2365 }
2366 }
2367 },
2368 _elementRemove: function (node) {
2369 if (this._encapsulateStyle) {
2370 styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
2371 }
2372 },
2373 scopeSubtree: function (container, shouldObserve) {
2374 if (nativeShadow) {
2375 return;
2376 }
2377 var self = this;
2378 var scopify = function (node) {
2379 if (node.nodeType === Node.ELEMENT_NODE) {
2380 node.className = self._scopeElementClass(node, node.className);
2381 var n$ = node.querySelectorAll('*');
2382 Array.prototype.forEach.call(n$, function (n) {
2383 n.className = self._scopeElementClass(n, n.className);
2384 });
2385 }
2386 };
2387 scopify(container);
2388 if (shouldObserve) {
2389 var mo = new MutationObserver(function (mxns) {
2390 mxns.forEach(function (m) {
2391 if (m.addedNodes) {
2392 for (var i = 0; i < m.addedNodes.length; i++) {
2393 scopify(m.addedNodes[i]);
2394 }
2395 }
2396 });
2397 });
2398 mo.observe(container, {
2399 childList: true,
2400 subtree: true
2401 });
2402 return mo;
2403 }
2404 }
2405 });
2406 }());
2407 Polymer.StyleProperties = function () {
2408 'use strict';
2409 var nativeShadow = Polymer.Settings.useNativeShadow;
2410 var matchesSelector = Polymer.DomApi.matchesSelector;
2411 var styleUtil = Polymer.StyleUtil;
2412 var styleTransformer = Polymer.StyleTransformer;
2413 return {
2414 decorateStyles: function (styles) {
2415 var self = this, props = {};
2416 styleUtil.forRulesInStyles(styles, function (rule) {
2417 self.decorateRule(rule);
2418 self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
2419 });
2420 var names = [];
2421 for (var i in props) {
2422 names.push(i);
2423 }
2424 return names;
2425 },
2426 decorateRule: function (rule) {
2427 if (rule.propertyInfo) {
2428 return rule.propertyInfo;
2429 }
2430 var info = {}, properties = {};
2431 var hasProperties = this.collectProperties(rule, properties);
2432 if (hasProperties) {
2433 info.properties = properties;
2434 rule.rules = null;
2435 }
2436 info.cssText = this.collectCssText(rule);
2437 rule.propertyInfo = info;
2438 return info;
2439 },
2440 collectProperties: function (rule, properties) {
2441 var info = rule.propertyInfo;
2442 if (info) {
2443 if (info.properties) {
2444 Polymer.Base.mixin(properties, info.properties);
2445 return true;
2446 }
2447 } else {
2448 var m, rx = this.rx.VAR_ASSIGN;
2449 var cssText = rule.parsedCssText;
2450 var any;
2451 while (m = rx.exec(cssText)) {
2452 properties[m[1]] = (m[2] || m[3]).trim();
2453 any = true;
2454 }
2455 return any;
2456 }
2457 },
2458 collectCssText: function (rule) {
2459 var customCssText = '';
2460 var cssText = rule.parsedCssText;
2461 cssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '') ;
2462 var parts = cssText.split(';');
2463 for (var i = 0, p; i < parts.length; i++) {
2464 p = parts[i];
2465 if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
2466 customCssText += p + ';\n';
2467 }
2468 }
2469 return customCssText;
2470 },
2471 collectPropertiesInCssText: function (cssText, props) {
2472 var m;
2473 while (m = this.rx.VAR_CAPTURE.exec(cssText)) {
2474 props[m[1]] = true;
2475 var def = m[2];
2476 if (def && def.match(this.rx.IS_VAR)) {
2477 props[def] = true;
2478 }
2479 }
2480 },
2481 reify: function (props) {
2482 var names = Object.getOwnPropertyNames(props);
2483 for (var i = 0, n; i < names.length; i++) {
2484 n = names[i];
2485 props[n] = this.valueForProperty(props[n], props);
2486 }
2487 },
2488 valueForProperty: function (property, props) {
2489 if (property) {
2490 if (property.indexOf(';') >= 0) {
2491 property = this.valueForProperties(property, props);
2492 } else {
2493 var self = this;
2494 var fn = function (all, prefix, value, fallback) {
2495 var propertyValue = self.valueForProperty(props[value], props) || (props[fallbac k] ? self.valueForProperty(props[fallback], props) : fallback);
2496 return prefix + (propertyValue || '');
2497 };
2498 property = property.replace(this.rx.VAR_MATCH, fn);
2499 }
2500 }
2501 return property && property.trim() || '';
2502 },
2503 valueForProperties: function (property, props) {
2504 var parts = property.split(';');
2505 for (var i = 0, p, m; i < parts.length && (p = parts[i]); i++) {
2506 m = p.match(this.rx.MIXIN_MATCH);
2507 if (m) {
2508 p = this.valueForProperty(props[m[1]], props);
2509 } else {
2510 var pp = p.split(':');
2511 if (pp[1]) {
2512 pp[1] = pp[1].trim();
2513 pp[1] = this.valueForProperty(pp[1], props) || pp[1];
2514 }
2515 p = pp.join(':');
2516 }
2517 parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';
2518 }
2519 return parts.join(';');
2520 },
2521 applyProperties: function (rule, props) {
2522 var output = '';
2523 if (!rule.propertyInfo) {
2524 this.decorateRule(rule);
2525 }
2526 if (rule.propertyInfo.cssText) {
2527 output = this.valueForProperties(rule.propertyInfo.cssText, props);
2528 }
2529 rule.cssText = output;
2530 },
2531 propertyDataFromStyles: function (styles, element) {
2532 var props = {}, self = this;
2533 var o = [], i = 0;
2534 styleUtil.forRulesInStyles(styles, function (rule) {
2535 if (!rule.propertyInfo) {
2536 self.decorateRule(rule);
2537 }
2538 if (element && rule.propertyInfo.properties && matchesSelector.call(element, rul e.selector)) {
2539 self.collectProperties(rule, props);
2540 addToBitMask(i, o);
2541 }
2542 i++;
2543 });
2544 return {
2545 properties: props,
2546 key: o
2547 };
2548 },
2549 scopePropertiesFromStyles: function (styles) {
2550 if (!styles._scopeStyleProperties) {
2551 styles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SC OPE_SELECTORS);
2552 }
2553 return styles._scopeStyleProperties;
2554 },
2555 hostPropertiesFromStyles: function (styles) {
2556 if (!styles._hostStyleProperties) {
2557 styles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOS T_SELECTORS);
2558 }
2559 return styles._hostStyleProperties;
2560 },
2561 selectedPropertiesFromStyles: function (styles, selectors) {
2562 var props = {}, self = this;
2563 styleUtil.forRulesInStyles(styles, function (rule) {
2564 if (!rule.propertyInfo) {
2565 self.decorateRule(rule);
2566 }
2567 for (var i = 0; i < selectors.length; i++) {
2568 if (rule.parsedSelector === selectors[i]) {
2569 self.collectProperties(rule, props);
2570 return;
2571 }
2572 }
2573 });
2574 return props;
2575 },
2576 transformStyles: function (element, properties, scopeSelector) {
2577 var self = this;
2578 var hostSelector = styleTransformer._calcHostScope(element.is, element.extends);
2579 var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector;
2580 var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFF IX);
2581 return styleTransformer.elementStyles(element, function (rule) {
2582 self.applyProperties(rule, properties);
2583 if (rule.cssText && !nativeShadow) {
2584 self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeS elector);
2585 }
2586 });
2587 },
2588 _scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {
2589 rule.transformedSelector = rule.transformedSelector || rule.selector;
2590 var selector = rule.transformedSelector;
2591 var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;
2592 var parts = selector.split(',');
2593 for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
2594 parts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : sco pe + ' ' + p;
2595 }
2596 rule.selector = parts.join(',');
2597 },
2598 applyElementScopeSelector: function (element, selector, old, viaAttr) {
2599 var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.cl assName;
2600 var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;
2601 if (c !== v) {
2602 if (viaAttr) {
2603 element.setAttribute(styleTransformer.SCOPE_NAME, v);
2604 } else {
2605 element.className = v;
2606 }
2607 }
2608 },
2609 applyElementStyle: function (element, properties, selector, style) {
2610 var cssText = style ? style.textContent || '' : this.transformStyles(element, pr operties, selector);
2611 var s = element._customStyle;
2612 if (s && !nativeShadow && s !== style) {
2613 s._useCount--;
2614 if (s._useCount <= 0) {
2615 s.parentNode.removeChild(s);
2616 }
2617 }
2618 if (nativeShadow || (!style || !style.parentNode)) {
2619 if (nativeShadow && element._customStyle) {
2620 element._customStyle.textContent = cssText;
2621 style = element._customStyle;
2622 } else if (cssText) {
2623 style = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null , element._scopeStyle);
2624 }
2625 }
2626 if (style) {
2627 style._useCount = style._useCount || 0;
2628 if (element._customStyle != style) {
2629 style._useCount++;
2630 }
2631 element._customStyle = style;
2632 }
2633 return style;
2634 },
2635 rx: {
2636 VAR_ASSIGN: /(?:^|;\s*)(--[^\:;]*?):\s*?(?:([^;{]*?)|{([^}]*)})(?=;)/gim,
2637 MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\);?/im,
2638 VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)) )[\s]*?\)/gim,
2639 VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gim,
2640 IS_VAR: /^--/,
2641 BRACKETED: /\{[^}]*\}/g,
2642 HOST_PREFIX: '(?:^|[^.])',
2643 HOST_SUFFIX: '($|[.:[\\s>+~])'
2644 },
2645 HOST_SELECTORS: [':host'],
2646 SCOPE_SELECTORS: [':root'],
2647 XSCOPE_NAME: 'x-scope'
2648 };
2649 function addToBitMask(n, bits) {
2650 var o = parseInt(n / 32);
2651 var v = 1 << n % 32;
2652 bits[o] = (bits[o] || 0) | v;
2653 }
2654 }();
2655 Polymer.StyleDefaults = function () {
2656 var styleProperties = Polymer.StyleProperties;
2657 var styleUtil = Polymer.StyleUtil;
2658 var api = {
2659 _styles: [],
2660 _properties: null,
2661 addStyle: function (style) {
2662 this._styles.push(style);
2663 this._properties = null;
2664 },
2665 get _styleProperties() {
2666 if (!this._properties) {
2667 styleProperties.decorateStyles(this._styles);
2668 this._styles._scopeStyleProperties = null;
2669 this._properties = styleProperties.scopePropertiesFromStyles(this._styles);
2670 styleProperties.reify(this._properties);
2671 }
2672 return this._properties;
2673 },
2674 _needsStyleProperties: function () {
2675 },
2676 _computeStyleProperties: function () {
2677 return this._styleProperties;
2678 },
2679 updateStyles: function () {
2680 this._styleCache.clear();
2681 for (var i = 0, s; i < this._styles.length; i++) {
2682 s = this._styles[i];
2683 s = s.__importElement || s;
2684 s._apply();
2685 }
2686 }
2687 };
2688 return api;
2689 }();
2690 (function () {
2691 Polymer.StyleCache = function () {
2692 this.cache = {};
2693 };
2694 Polymer.StyleCache.prototype = {
2695 MAX: 100,
2696 store: function (is, data, keyValues, keyStyles) {
2697 data.keyValues = keyValues;
2698 data.styles = keyStyles;
2699 var s$ = this.cache[is] = this.cache[is] || [];
2700 s$.push(data);
2701 if (s$.length > this.MAX) {
2702 s$.shift();
2703 }
2704 },
2705 retrieve: function (is, keyValues, keyStyles) {
2706 var cache = this.cache[is];
2707 if (cache) {
2708 for (var i = cache.length - 1, data; i >= 0; i--) {
2709 data = cache[i];
2710 if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {
2711 return data;
2712 }
2713 }
2714 }
2715 },
2716 clear: function () {
2717 this.cache = {};
2718 },
2719 _objectsEqual: function (target, source) {
2720 for (var i in target) {
2721 if (target[i] !== source[i]) {
2722 return false;
2723 }
2724 }
2725 if (Array.isArray(target)) {
2726 return target.length === source.length;
2727 }
2728 return true;
2729 }
2730 };
2731 }());
2732 (function () {
2733 'use strict';
2734 var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
2735 var propertyUtils = Polymer.StyleProperties;
2736 var styleTransformer = Polymer.StyleTransformer;
2737 var styleUtil = Polymer.StyleUtil;
2738 var styleDefaults = Polymer.StyleDefaults;
2739 var nativeShadow = Polymer.Settings.useNativeShadow;
2740 Polymer.Base._addFeature({
2741 _prepStyleProperties: function () {
2742 this._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._ styles) : [];
2743 },
2744 _setupStyleProperties: function () {
2745 this.customStyle = {};
2746 },
2747 _needsStyleProperties: function () {
2748 return Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length );
2749 },
2750 _beforeAttached: function () {
2751 if (!this._scopeSelector && this._needsStyleProperties()) {
2752 this._updateStyleProperties();
2753 }
2754 },
2755 _updateStyleProperties: function () {
2756 var info, scope = this.domHost || styleDefaults;
2757 if (!scope._styleCache) {
2758 scope._styleCache = new Polymer.StyleCache();
2759 }
2760 var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);
2761 info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
2762 var scopeCached = Boolean(info);
2763 if (scopeCached) {
2764 this._styleProperties = info._styleProperties;
2765 } else {
2766 this._computeStyleProperties(scopeData.properties);
2767 }
2768 this._computeOwnStyleProperties();
2769 if (!scopeCached) {
2770 info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);
2771 }
2772 var globalCached = Boolean(info) && !scopeCached;
2773 var style = this._applyStyleProperties(info);
2774 if (!scopeCached) {
2775 var cacheableStyle = style;
2776 if (nativeShadow) {
2777 cacheableStyle = style.cloneNode ? style.cloneNode(true) : Object.create(style | | null);
2778 }
2779 info = {
2780 style: cacheableStyle,
2781 _scopeSelector: this._scopeSelector,
2782 _styleProperties: this._styleProperties
2783 };
2784 scope._styleCache.store(this.is, info, scopeData.key, this._styles);
2785 if (!globalCached) {
2786 styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._s tyles);
2787 }
2788 }
2789 },
2790 _computeStyleProperties: function (scopeProps) {
2791 var scope = this.domHost || styleDefaults;
2792 if (!scope._styleProperties) {
2793 scope._computeStyleProperties();
2794 }
2795 var props = Object.create(scope._styleProperties);
2796 this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
2797 scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, t his).properties;
2798 this.mixin(props, scopeProps);
2799 this.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles));
2800 this.mixin(props, this.customStyle);
2801 propertyUtils.reify(props);
2802 this._styleProperties = props;
2803 },
2804 _computeOwnStyleProperties: function () {
2805 var props = {};
2806 for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {
2807 n = this._ownStylePropertyNames[i];
2808 props[n] = this._styleProperties[n];
2809 }
2810 this._ownStyleProperties = props;
2811 },
2812 _scopeCount: 0,
2813 _applyStyleProperties: function (info) {
2814 var oldScopeSelector = this._scopeSelector;
2815 this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto_ _._scopeCount++;
2816 var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._s copeSelector, info && info.style);
2817 if ((style || oldScopeSelector) && !nativeShadow) {
2818 propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelec tor, this._scopeCssViaAttr);
2819 }
2820 return style || {};
2821 },
2822 serializeValueToAttribute: function (value, attribute, node) {
2823 node = node || this;
2824 if (attribute === 'class') {
2825 var host = node === this ? this.domHost || this.dataHost : this;
2826 if (host) {
2827 value = host._scopeElementClass(node, value);
2828 }
2829 }
2830 node = Polymer.dom(node);
2831 serializeValueToAttribute.call(this, value, attribute, node);
2832 },
2833 _scopeElementClass: function (element, selector) {
2834 if (!nativeShadow && !this._scopeCssViaAttr) {
2835 selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scope Selector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');
2836 }
2837 return selector;
2838 },
2839 updateStyles: function () {
2840 if (this.isAttached) {
2841 if (this._needsStyleProperties()) {
2842 this._updateStyleProperties();
2843 } else {
2844 this._styleProperties = null;
2845 }
2846 if (this._styleCache) {
2847 this._styleCache.clear();
2848 }
2849 this._updateRootStyles();
2850 }
2851 },
2852 _updateRootStyles: function (root) {
2853 root = root || this.root;
2854 var c$ = Polymer.dom(root)._query(function (e) {
2855 return e.shadyRoot || e.shadowRoot;
2856 });
2857 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
2858 if (c.updateStyles) {
2859 c.updateStyles();
2860 }
2861 }
2862 }
2863 });
2864 Polymer.updateStyles = function () {
2865 styleDefaults.updateStyles();
2866 Polymer.Base._updateRootStyles(document);
2867 };
2868 var styleCache = new Polymer.StyleCache();
2869 Polymer.customStyleCache = styleCache;
2870 var SCOPE_NAME = styleTransformer.SCOPE_NAME;
2871 var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
2872 }());
2873 Polymer.Base._addFeature({
2874 _registerFeatures: function () {
2875 this._prepIs();
2876 this._prepAttributes();
2877 this._prepExtends();
2878 this._prepConstructor();
2879 this._prepTemplate();
2880 this._prepStyles();
2881 this._prepStyleProperties();
2882 this._prepAnnotations();
2883 this._prepEffects();
2884 this._prepBehaviors();
2885 this._prepBindings();
2886 this._prepShady();
2887 },
2888 _prepBehavior: function (b) {
2889 this._addPropertyEffects(b.properties);
2890 this._addComplexObserverEffects(b.observers);
2891 this._addHostAttributes(b.hostAttributes);
2892 },
2893 _initFeatures: function () {
2894 this._poolContent();
2895 this._setupConfigure();
2896 this._setupStyleProperties();
2897 this._pushHost();
2898 this._stampTemplate();
2899 this._popHost();
2900 this._marshalAnnotationReferences();
2901 this._marshalHostAttributes();
2902 this._setupDebouncers();
2903 this._marshalInstanceEffects();
2904 this._marshalBehaviors();
2905 this._marshalAttributes();
2906 this._tryReady();
2907 },
2908 _marshalBehavior: function (b) {
2909 this._listenListeners(b.listeners);
2910 }
2911 });
2912 (function () {
2913 var nativeShadow = Polymer.Settings.useNativeShadow;
2914 var propertyUtils = Polymer.StyleProperties;
2915 var styleUtil = Polymer.StyleUtil;
2916 var styleDefaults = Polymer.StyleDefaults;
2917 var styleTransformer = Polymer.StyleTransformer;
2918 Polymer({
2919 is: 'custom-style',
2920 extends: 'style',
2921 created: function () {
2922 this._tryApply();
2923 },
2924 attached: function () {
2925 this._tryApply();
2926 },
2927 _tryApply: function () {
2928 if (!this._appliesToDocument) {
2929 if (this.parentNode && this.parentNode.localName !== 'dom-module') {
2930 this._appliesToDocument = true;
2931 var e = this.__appliedElement || this;
2932 styleDefaults.addStyle(e);
2933 if (e.textContent) {
2934 this._apply();
2935 } else {
2936 var observer = new MutationObserver(function () {
2937 observer.disconnect();
2938 this._apply();
2939 }.bind(this));
2940 observer.observe(e, { childList: true });
2941 }
2942 }
2943 }
2944 },
2945 _apply: function () {
2946 var e = this.__appliedElement || this;
2947 this._computeStyleProperties();
2948 var props = this._styleProperties;
2949 var self = this;
2950 e.textContent = styleUtil.toCssText(styleUtil.rulesForStyle(e), function (rule) {
2951 var css = rule.cssText = rule.parsedCssText;
2952 if (rule.propertyInfo && rule.propertyInfo.cssText) {
2953 css = css.replace(propertyUtils.rx.VAR_ASSIGN, '');
2954 rule.cssText = propertyUtils.valueForProperties(css, props);
2955 }
2956 styleTransformer.documentRule(rule);
2957 });
2958 }
2959 });
2960 }());
2961 Polymer.Templatizer = {
2962 properties: { _hideTemplateChildren: { observer: '_showHideChildren' } },
2963 _templatizerStatic: {
2964 count: 0,
2965 callbacks: {},
2966 debouncer: null
2967 },
2968 _instanceProps: Polymer.nob,
2969 created: function () {
2970 this._templatizerId = this._templatizerStatic.count++;
2971 },
2972 templatize: function (template) {
2973 if (!template._content) {
2974 template._content = template.content;
2975 }
2976 if (template._content._ctor) {
2977 this.ctor = template._content._ctor;
2978 this._prepParentProperties(this.ctor.prototype, template);
2979 return;
2980 }
2981 var archetype = Object.create(Polymer.Base);
2982 this._customPrepAnnotations(archetype, template);
2983 archetype._prepEffects();
2984 this._customPrepEffects(archetype);
2985 archetype._prepBehaviors();
2986 archetype._prepBindings();
2987 this._prepParentProperties(archetype, template);
2988 archetype._notifyPath = this._notifyPathImpl;
2989 archetype._scopeElementClass = this._scopeElementClassImpl;
2990 archetype.listen = this._listenImpl;
2991 var _constructor = this._constructorImpl;
2992 var ctor = function TemplateInstance(model, host) {
2993 _constructor.call(this, model, host);
2994 };
2995 ctor.prototype = archetype;
2996 archetype.constructor = ctor;
2997 template._content._ctor = ctor;
2998 this.ctor = ctor;
2999 },
3000 _getRootDataHost: function () {
3001 return this.dataHost && this.dataHost._rootDataHost || this.dataHost;
3002 },
3003 _showHideChildren: function (hidden) {
3004 },
3005 _debounceTemplate: function (fn) {
3006 this._templatizerStatic.callbacks[this._templatizerId] = fn.bind(this);
3007 this._templatizerStatic.debouncer = Polymer.Debounce(this._templatizerStatic.deb ouncer, this._flushTemplates.bind(this, true));
3008 },
3009 _flushTemplates: function (debouncerExpired) {
3010 var db = this._templatizerStatic.debouncer;
3011 while (debouncerExpired || db && db.finish) {
3012 db.stop();
3013 var cbs = this._templatizerStatic.callbacks;
3014 this._templatizerStatic.callbacks = {};
3015 for (var id in cbs) {
3016 cbs[id]();
3017 }
3018 debouncerExpired = false;
3019 }
3020 },
3021 _customPrepEffects: function (archetype) {
3022 var parentProps = archetype._parentProps;
3023 for (var prop in parentProps) {
3024 archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop ));
3025 }
3026 },
3027 _customPrepAnnotations: function (archetype, template) {
3028 archetype._template = template;
3029 var c = template._content;
3030 if (!c._notes) {
3031 var rootDataHost = archetype._rootDataHost;
3032 if (rootDataHost) {
3033 Polymer.Annotations.prepElement = rootDataHost._prepElement.bind(rootDataHost);
3034 }
3035 c._notes = Polymer.Annotations.parseAnnotations(template);
3036 Polymer.Annotations.prepElement = null;
3037 this._processAnnotations(c._notes);
3038 }
3039 archetype._notes = c._notes;
3040 archetype._parentProps = c._parentProps;
3041 },
3042 _prepParentProperties: function (archetype, template) {
3043 var parentProps = this._parentProps = archetype._parentProps;
3044 if (this._forwardParentProp && parentProps) {
3045 var proto = archetype._parentPropProto;
3046 var prop;
3047 if (!proto) {
3048 for (prop in this._instanceProps) {
3049 delete parentProps[prop];
3050 }
3051 proto = archetype._parentPropProto = Object.create(null);
3052 if (template != this) {
3053 Polymer.Bind.prepareModel(proto);
3054 }
3055 for (prop in parentProps) {
3056 var parentProp = '_parent_' + prop;
3057 var effects = [
3058 {
3059 kind: 'function',
3060 effect: this._createForwardPropEffector(prop)
3061 },
3062 { kind: 'notify' }
3063 ];
3064 Polymer.Bind._createAccessors(proto, parentProp, effects);
3065 }
3066 }
3067 if (template != this) {
3068 Polymer.Bind.prepareInstance(template);
3069 template._forwardParentProp = this._forwardParentProp.bind(this);
3070 }
3071 this._extendTemplate(template, proto);
3072 }
3073 },
3074 _createForwardPropEffector: function (prop) {
3075 return function (source, value) {
3076 this._forwardParentProp(prop, value);
3077 };
3078 },
3079 _createHostPropEffector: function (prop) {
3080 return function (source, value) {
3081 this.dataHost['_parent_' + prop] = value;
3082 };
3083 },
3084 _extendTemplate: function (template, proto) {
3085 Object.getOwnPropertyNames(proto).forEach(function (n) {
3086 var val = template[n];
3087 var pd = Object.getOwnPropertyDescriptor(proto, n);
3088 Object.defineProperty(template, n, pd);
3089 if (val !== undefined) {
3090 template._propertySet(n, val);
3091 }
3092 });
3093 },
3094 _forwardInstancePath: function (inst, path, value) {
3095 },
3096 _notifyPathImpl: function (path, value) {
3097 var dataHost = this.dataHost;
3098 var dot = path.indexOf('.');
3099 var root = dot < 0 ? path : path.slice(0, dot);
3100 dataHost._forwardInstancePath.call(dataHost, this, path, value);
3101 if (root in dataHost._parentProps) {
3102 dataHost.notifyPath('_parent_' + path, value);
3103 }
3104 },
3105 _pathEffector: function (path, value, fromAbove) {
3106 if (this._forwardParentPath) {
3107 if (path.indexOf('_parent_') === 0) {
3108 this._forwardParentPath(path.substring(8), value);
3109 }
3110 }
3111 Polymer.Base._pathEffector.apply(this, arguments);
3112 },
3113 _constructorImpl: function (model, host) {
3114 this._rootDataHost = host._getRootDataHost();
3115 this._setupConfigure(model);
3116 this._pushHost(host);
3117 this.root = this.instanceTemplate(this._template);
3118 this.root.__styleScoped = true;
3119 this._popHost();
3120 this._marshalAnnotatedNodes();
3121 this._marshalInstanceEffects();
3122 this._marshalAnnotatedListeners();
3123 var children = [];
3124 for (var n = this.root.firstChild; n; n = n.nextSibling) {
3125 children.push(n);
3126 n._templateInstance = this;
3127 }
3128 this._children = children;
3129 this._tryReady();
3130 },
3131 _listenImpl: function (node, eventName, methodName) {
3132 var model = this;
3133 var host = this._rootDataHost;
3134 var handler = host._createEventHandler(node, eventName, methodName);
3135 var decorated = function (e) {
3136 e.model = model;
3137 handler(e);
3138 };
3139 host._listen(node, eventName, decorated);
3140 },
3141 _scopeElementClassImpl: function (node, value) {
3142 var host = this._rootDataHost;
3143 if (host) {
3144 return host._scopeElementClass(node, value);
3145 }
3146 },
3147 stamp: function (model) {
3148 model = model || {};
3149 if (this._parentProps) {
3150 for (var prop in this._parentProps) {
3151 model[prop] = this['_parent_' + prop];
3152 }
3153 }
3154 return new this.ctor(model, this);
3155 }
3156 };
3157 Polymer({
3158 is: 'dom-template',
3159 extends: 'template',
3160 behaviors: [Polymer.Templatizer],
3161 ready: function () {
3162 this.templatize(this);
3163 }
3164 });
3165 Polymer._collections = new WeakMap();
3166 Polymer.Collection = function (userArray) {
3167 Polymer._collections.set(userArray, this);
3168 this.userArray = userArray;
3169 this.store = userArray.slice();
3170 this.initMap();
3171 };
3172 Polymer.Collection.prototype = {
3173 constructor: Polymer.Collection,
3174 initMap: function () {
3175 var omap = this.omap = new WeakMap();
3176 var pmap = this.pmap = {};
3177 var s = this.store;
3178 for (var i = 0; i < s.length; i++) {
3179 var item = s[i];
3180 if (item && typeof item == 'object') {
3181 omap.set(item, i);
3182 } else {
3183 pmap[item] = i;
3184 }
3185 }
3186 },
3187 add: function (item) {
3188 var key = this.store.push(item) - 1;
3189 if (item && typeof item == 'object') {
3190 this.omap.set(item, key);
3191 } else {
3192 this.pmap[item] = key;
3193 }
3194 return key;
3195 },
3196 removeKey: function (key) {
3197 this._removeFromMap(this.store[key]);
3198 delete this.store[key];
3199 },
3200 _removeFromMap: function (item) {
3201 if (typeof item == 'object') {
3202 this.omap.delete(item);
3203 } else {
3204 delete this.pmap[item];
3205 }
3206 },
3207 remove: function (item) {
3208 var key = this.getKey(item);
3209 this.removeKey(key);
3210 return key;
3211 },
3212 getKey: function (item) {
3213 if (typeof item == 'object') {
3214 return this.omap.get(item);
3215 } else {
3216 return this.pmap[item];
3217 }
3218 },
3219 getKeys: function () {
3220 return Object.keys(this.store);
3221 },
3222 setItem: function (key, value) {
3223 this.store[key] = value;
3224 },
3225 getItem: function (key) {
3226 return this.store[key];
3227 },
3228 getItems: function () {
3229 var items = [], store = this.store;
3230 for (var key in store) {
3231 items.push(store[key]);
3232 }
3233 return items;
3234 },
3235 _applySplices: function (splices) {
3236 var keySplices = [];
3237 for (var i = 0; i < splices.length; i++) {
3238 var j, o, key, s = splices[i];
3239 var removed = [];
3240 for (j = 0; j < s.removed.length; j++) {
3241 o = s.removed[j];
3242 key = this.remove(o);
3243 removed.push(key);
3244 }
3245 var added = [];
3246 for (j = 0; j < s.addedCount; j++) {
3247 o = this.userArray[s.index + j];
3248 key = this.add(o);
3249 added.push(key);
3250 }
3251 keySplices.push({
3252 index: s.index,
3253 removed: removed,
3254 removedItems: s.removed,
3255 added: added
3256 });
3257 }
3258 return keySplices;
3259 }
3260 };
3261 Polymer.Collection.get = function (userArray) {
3262 return Polymer._collections.get(userArray) || new Polymer.Collection(userArray);
3263 };
3264 Polymer.Collection.applySplices = function (userArray, splices) {
3265 var coll = Polymer._collections.get(userArray);
3266 return coll ? coll._applySplices(splices) : null;
3267 };
3268 Polymer({
3269 is: 'dom-repeat',
3270 extends: 'template',
3271 properties: {
3272 items: { type: Array },
3273 as: {
3274 type: String,
3275 value: 'item'
3276 },
3277 indexAs: {
3278 type: String,
3279 value: 'index'
3280 },
3281 sort: {
3282 type: Function,
3283 observer: '_sortChanged'
3284 },
3285 filter: {
3286 type: Function,
3287 observer: '_filterChanged'
3288 },
3289 observe: {
3290 type: String,
3291 observer: '_observeChanged'
3292 },
3293 delay: Number
3294 },
3295 behaviors: [Polymer.Templatizer],
3296 observers: ['_itemsChanged(items.*)'],
3297 detached: function () {
3298 if (this.rows) {
3299 for (var i = 0; i < this.rows.length; i++) {
3300 this._detachRow(i);
3301 }
3302 }
3303 },
3304 attached: function () {
3305 if (this.rows) {
3306 var parentNode = Polymer.dom(this).parentNode;
3307 for (var i = 0; i < this.rows.length; i++) {
3308 Polymer.dom(parentNode).insertBefore(this.rows[i].root, this);
3309 }
3310 }
3311 },
3312 ready: function () {
3313 this._instanceProps = { __key__: true };
3314 this._instanceProps[this.as] = true;
3315 this._instanceProps[this.indexAs] = true;
3316 if (!this.ctor) {
3317 this.templatize(this);
3318 }
3319 },
3320 _sortChanged: function () {
3321 var dataHost = this._getRootDataHost();
3322 var sort = this.sort;
3323 this._sortFn = sort && (typeof sort == 'function' ? sort : function () {
3324 return dataHost[sort].apply(dataHost, arguments);
3325 });
3326 this._fullRefresh = true;
3327 if (this.items) {
3328 this._debounceTemplate(this._render);
3329 }
3330 },
3331 _filterChanged: function () {
3332 var dataHost = this._getRootDataHost();
3333 var filter = this.filter;
3334 this._filterFn = filter && (typeof filter == 'function' ? filter : function () {
3335 return dataHost[filter].apply(dataHost, arguments);
3336 });
3337 this._fullRefresh = true;
3338 if (this.items) {
3339 this._debounceTemplate(this._render);
3340 }
3341 },
3342 _observeChanged: function () {
3343 this._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');
3344 },
3345 _itemsChanged: function (change) {
3346 if (change.path == 'items') {
3347 if (Array.isArray(this.items)) {
3348 this.collection = Polymer.Collection.get(this.items);
3349 } else if (!this.items) {
3350 this.collection = null;
3351 } else {
3352 this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', t his.items));
3353 }
3354 this._splices = [];
3355 this._fullRefresh = true;
3356 this._debounceTemplate(this._render);
3357 } else if (change.path == 'items.splices') {
3358 this._splices = this._splices.concat(change.value.keySplices);
3359 this._debounceTemplate(this._render);
3360 } else {
3361 var subpath = change.path.slice(6);
3362 this._forwardItemPath(subpath, change.value);
3363 this._checkObservedPaths(subpath);
3364 }
3365 },
3366 _checkObservedPaths: function (path) {
3367 if (this._observePaths) {
3368 path = path.substring(path.indexOf('.') + 1);
3369 var paths = this._observePaths;
3370 for (var i = 0; i < paths.length; i++) {
3371 if (path.indexOf(paths[i]) === 0) {
3372 this._fullRefresh = true;
3373 if (this.delay) {
3374 this.debounce('render', this._render, this.delay);
3375 } else {
3376 this._debounceTemplate(this._render);
3377 }
3378 return;
3379 }
3380 }
3381 }
3382 },
3383 render: function () {
3384 this._fullRefresh = true;
3385 this.debounce('render', this._render);
3386 this._flushTemplates();
3387 },
3388 _render: function () {
3389 var c = this.collection;
3390 if (!this._fullRefresh) {
3391 if (this._sortFn) {
3392 this._applySplicesViewSort(this._splices);
3393 } else {
3394 if (this._filterFn) {
3395 this._fullRefresh = true;
3396 } else {
3397 this._applySplicesArraySort(this._splices);
3398 }
3399 }
3400 }
3401 if (this._fullRefresh) {
3402 this._sortAndFilter();
3403 this._fullRefresh = false;
3404 }
3405 this._splices = [];
3406 var rowForKey = this._rowForKey = {};
3407 var keys = this._orderedKeys;
3408 this.rows = this.rows || [];
3409 for (var i = 0; i < keys.length; i++) {
3410 var key = keys[i];
3411 var item = c.getItem(key);
3412 var row = this.rows[i];
3413 rowForKey[key] = i;
3414 if (!row) {
3415 this.rows.push(row = this._insertRow(i, null, item));
3416 }
3417 row[this.as] = item;
3418 row.__key__ = key;
3419 row[this.indexAs] = i;
3420 }
3421 for (; i < this.rows.length; i++) {
3422 this._detachRow(i);
3423 }
3424 this.rows.splice(keys.length, this.rows.length - keys.length);
3425 this.fire('dom-change');
3426 },
3427 _sortAndFilter: function () {
3428 var c = this.collection;
3429 if (!this._sortFn) {
3430 this._orderedKeys = [];
3431 var items = this.items;
3432 if (items) {
3433 for (var i = 0; i < items.length; i++) {
3434 this._orderedKeys.push(c.getKey(items[i]));
3435 }
3436 }
3437 } else {
3438 this._orderedKeys = c ? c.getKeys() : [];
3439 }
3440 if (this._filterFn) {
3441 this._orderedKeys = this._orderedKeys.filter(function (a) {
3442 return this._filterFn(c.getItem(a));
3443 }, this);
3444 }
3445 if (this._sortFn) {
3446 this._orderedKeys.sort(function (a, b) {
3447 return this._sortFn(c.getItem(a), c.getItem(b));
3448 }.bind(this));
3449 }
3450 },
3451 _keySort: function (a, b) {
3452 return this.collection.getKey(a) - this.collection.getKey(b);
3453 },
3454 _applySplicesViewSort: function (splices) {
3455 var c = this.collection;
3456 var keys = this._orderedKeys;
3457 var rows = this.rows;
3458 var removedRows = [];
3459 var addedKeys = [];
3460 var pool = [];
3461 var sortFn = this._sortFn || this._keySort.bind(this);
3462 splices.forEach(function (s) {
3463 for (var i = 0; i < s.removed.length; i++) {
3464 var idx = this._rowForKey[s.removed[i]];
3465 if (idx != null) {
3466 removedRows.push(idx);
3467 }
3468 }
3469 for (var i = 0; i < s.added.length; i++) {
3470 addedKeys.push(s.added[i]);
3471 }
3472 }, this);
3473 if (removedRows.length) {
3474 removedRows.sort();
3475 for (var i = removedRows.length - 1; i >= 0; i--) {
3476 var idx = removedRows[i];
3477 pool.push(this._detachRow(idx));
3478 rows.splice(idx, 1);
3479 keys.splice(idx, 1);
3480 }
3481 }
3482 if (addedKeys.length) {
3483 if (this._filterFn) {
3484 addedKeys = addedKeys.filter(function (a) {
3485 return this._filterFn(c.getItem(a));
3486 }, this);
3487 }
3488 addedKeys.sort(function (a, b) {
3489 return this._sortFn(c.getItem(a), c.getItem(b));
3490 }.bind(this));
3491 var start = 0;
3492 for (var i = 0; i < addedKeys.length; i++) {
3493 start = this._insertRowIntoViewSort(start, addedKeys[i], pool);
3494 }
3495 }
3496 },
3497 _insertRowIntoViewSort: function (start, key, pool) {
3498 var c = this.collection;
3499 var item = c.getItem(key);
3500 var end = this.rows.length - 1;
3501 var idx = -1;
3502 var sortFn = this._sortFn || this._keySort.bind(this);
3503 while (start <= end) {
3504 var mid = start + end >> 1;
3505 var midKey = this._orderedKeys[mid];
3506 var cmp = sortFn(c.getItem(midKey), item);
3507 if (cmp < 0) {
3508 start = mid + 1;
3509 } else if (cmp > 0) {
3510 end = mid - 1;
3511 } else {
3512 idx = mid;
3513 break;
3514 }
3515 }
3516 if (idx < 0) {
3517 idx = end + 1;
3518 }
3519 this._orderedKeys.splice(idx, 0, key);
3520 this.rows.splice(idx, 0, this._insertRow(idx, pool, c.getItem(key)));
3521 return idx;
3522 },
3523 _applySplicesArraySort: function (splices) {
3524 var keys = this._orderedKeys;
3525 var pool = [];
3526 splices.forEach(function (s) {
3527 for (var i = 0; i < s.removed.length; i++) {
3528 pool.push(this._detachRow(s.index + i));
3529 }
3530 this.rows.splice(s.index, s.removed.length);
3531 }, this);
3532 var c = this.collection;
3533 splices.forEach(function (s) {
3534 var args = [
3535 s.index,
3536 s.removed.length
3537 ].concat(s.added);
3538 keys.splice.apply(keys, args);
3539 for (var i = 0; i < s.added.length; i++) {
3540 var item = c.getItem(s.added[i]);
3541 var row = this._insertRow(s.index + i, pool, item);
3542 this.rows.splice(s.index + i, 0, row);
3543 }
3544 }, this);
3545 },
3546 _detachRow: function (idx) {
3547 var row = this.rows[idx];
3548 var parentNode = Polymer.dom(this).parentNode;
3549 for (var i = 0; i < row._children.length; i++) {
3550 var el = row._children[i];
3551 Polymer.dom(row.root).appendChild(el);
3552 }
3553 return row;
3554 },
3555 _insertRow: function (idx, pool, item) {
3556 var row = pool && pool.pop() || this._generateRow(idx, item);
3557 var beforeRow = this.rows[idx];
3558 var beforeNode = beforeRow ? beforeRow._children[0] : this;
3559 var parentNode = Polymer.dom(this).parentNode;
3560 Polymer.dom(parentNode).insertBefore(row.root, beforeNode);
3561 return row;
3562 },
3563 _generateRow: function (idx, item) {
3564 var model = { __key__: this.collection.getKey(item) };
3565 model[this.as] = item;
3566 model[this.indexAs] = idx;
3567 var row = this.stamp(model);
3568 return row;
3569 },
3570 _showHideChildren: function (hidden) {
3571 if (this.rows) {
3572 for (var i = 0; i < this.rows.length; i++) {
3573 var c$ = this.rows[i]._children;
3574 for (var j = 0; j < c$.length; j++) {
3575 var c = c$[j];
3576 if (c.style) {
3577 c.style.display = hidden ? 'none' : '';
3578 }
3579 c._hideTemplateChildren = hidden;
3580 }
3581 }
3582 }
3583 },
3584 _forwardInstancePath: function (row, path, value) {
3585 if (path.indexOf(this.as + '.') === 0) {
3586 this.notifyPath('items.' + row.__key__ + '.' + path.slice(this.as.length + 1), v alue);
3587 return true;
3588 }
3589 },
3590 _forwardParentProp: function (prop, value) {
3591 if (this.rows) {
3592 this.rows.forEach(function (row) {
3593 row[prop] = value;
3594 }, this);
3595 }
3596 },
3597 _forwardParentPath: function (path, value) {
3598 if (this.rows) {
3599 this.rows.forEach(function (row) {
3600 row.notifyPath(path, value, true);
3601 }, this);
3602 }
3603 },
3604 _forwardItemPath: function (path, value) {
3605 if (this._rowForKey) {
3606 var dot = path.indexOf('.');
3607 var key = path.substring(0, dot < 0 ? path.length : dot);
3608 var idx = this._rowForKey[key];
3609 var row = this.rows[idx];
3610 if (row) {
3611 if (dot >= 0) {
3612 path = this.as + '.' + path.substring(dot + 1);
3613 row.notifyPath(path, value, true);
3614 } else {
3615 row[this.as] = value;
3616 }
3617 }
3618 }
3619 },
3620 modelForElement: function (el) {
3621 var model;
3622 while (el) {
3623 if (model = el._templateInstance) {
3624 if (model.dataHost != this) {
3625 el = model.dataHost;
3626 } else {
3627 return model;
3628 }
3629 } else {
3630 el = el.parentNode;
3631 }
3632 }
3633 },
3634 itemForElement: function (el) {
3635 var instance = this.modelForElement(el);
3636 return instance && instance[this.as];
3637 },
3638 keyForElement: function (el) {
3639 var instance = this.modelForElement(el);
3640 return instance && instance.__key__;
3641 },
3642 indexForElement: function (el) {
3643 var instance = this.modelForElement(el);
3644 return instance && instance[this.indexAs];
3645 }
3646 });
3647 Polymer({
3648 is: 'array-selector',
3649 properties: {
3650 items: {
3651 type: Array,
3652 observer: '_itemsChanged'
3653 },
3654 selected: {
3655 type: Object,
3656 notify: true
3657 },
3658 toggle: Boolean,
3659 multi: Boolean
3660 },
3661 _itemsChanged: function () {
3662 if (Array.isArray(this.selected)) {
3663 for (var i = 0; i < this.selected.length; i++) {
3664 this.unlinkPaths('selected.' + i);
3665 }
3666 } else {
3667 this.unlinkPaths('selected');
3668 }
3669 if (this.multi) {
3670 this.selected = [];
3671 } else {
3672 this.selected = null;
3673 }
3674 },
3675 deselect: function (item) {
3676 if (this.multi) {
3677 var scol = Polymer.Collection.get(this.selected);
3678 var sidx = this.selected.indexOf(item);
3679 if (sidx >= 0) {
3680 var skey = scol.getKey(item);
3681 this.splice('selected', sidx, 1);
3682 this.unlinkPaths('selected.' + skey);
3683 return true;
3684 }
3685 } else {
3686 this.selected = null;
3687 this.unlinkPaths('selected');
3688 }
3689 },
3690 select: function (item) {
3691 var icol = Polymer.Collection.get(this.items);
3692 var key = icol.getKey(item);
3693 if (this.multi) {
3694 var scol = Polymer.Collection.get(this.selected);
3695 var skey = scol.getKey(item);
3696 if (skey >= 0) {
3697 if (this.toggle) {
3698 this.deselect(item);
3699 }
3700 } else {
3701 this.push('selected', item);
3702 this.async(function () {
3703 skey = scol.getKey(item);
3704 this.linkPaths('selected.' + skey, 'items.' + key);
3705 });
3706 }
3707 } else {
3708 if (this.toggle && item == this.selected) {
3709 this.deselect();
3710 } else {
3711 this.linkPaths('selected', 'items.' + key);
3712 this.selected = item;
3713 }
3714 }
3715 }
3716 });
3717 Polymer({
3718 is: 'dom-if',
3719 extends: 'template',
3720 properties: {
3721 'if': {
3722 type: Boolean,
3723 value: false
3724 },
3725 restamp: {
3726 type: Boolean,
3727 value: false
3728 }
3729 },
3730 behaviors: [Polymer.Templatizer],
3731 observers: ['_queueRender(if, restamp)'],
3732 _queueRender: function () {
3733 this._debounceTemplate(this._render);
3734 },
3735 detached: function () {
3736 this._teardownInstance();
3737 },
3738 attached: function () {
3739 if (this.if && this.ctor) {
3740 this.async(this._ensureInstance);
3741 }
3742 },
3743 render: function () {
3744 this._flushTemplates();
3745 },
3746 _render: function () {
3747 if (this.if) {
3748 if (!this.ctor) {
3749 this._wrapTextNodes(this._content || this.content);
3750 this.templatize(this);
3751 }
3752 this._ensureInstance();
3753 this._showHideChildren();
3754 } else if (this.restamp) {
3755 this._teardownInstance();
3756 }
3757 if (!this.restamp && this._instance) {
3758 this._showHideChildren();
3759 }
3760 if (this.if != this._lastIf) {
3761 this.fire('dom-change');
3762 this._lastIf = this.if;
3763 }
3764 },
3765 _ensureInstance: function () {
3766 if (!this._instance) {
3767 this._instance = this.stamp();
3768 var root = this._instance.root;
3769 var parent = Polymer.dom(Polymer.dom(this).parentNode);
3770 parent.insertBefore(root, this);
3771 }
3772 },
3773 _teardownInstance: function () {
3774 if (this._instance) {
3775 var c = this._instance._children;
3776 if (c) {
3777 var parent = Polymer.dom(Polymer.dom(c[0]).parentNode);
3778 c.forEach(function (n) {
3779 parent.removeChild(n);
3780 });
3781 }
3782 this._instance = null;
3783 }
3784 },
3785 _wrapTextNodes: function (root) {
3786 for (var n = root.firstChild; n; n = n.nextSibling) {
3787 if (n.nodeType === Node.TEXT_NODE) {
3788 var s = document.createElement('span');
3789 root.insertBefore(s, n);
3790 s.appendChild(n);
3791 n = s;
3792 }
3793 }
3794 },
3795 _showHideChildren: function () {
3796 var hidden = this._hideTemplateChildren || !this.if;
3797 if (this._instance) {
3798 var c$ = this._instance._children;
3799 for (var i = 0; i < c$.length; i++) {
3800 var c = c$[i];
3801 c.style.display = hidden ? 'none' : '';
3802 c._hideTemplateChildren = hidden;
3803 }
3804 }
3805 },
3806 _forwardParentProp: function (prop, value) {
3807 if (this._instance) {
3808 this._instance[prop] = value;
3809 }
3810 },
3811 _forwardParentPath: function (path, value) {
3812 if (this._instance) {
3813 this._instance.notifyPath(path, value, true);
3814 }
3815 }
3816 });
3817 Polymer.ImportStatus = {
3818 _ready: false,
3819 _callbacks: [],
3820 whenLoaded: function (cb) {
3821 if (this._ready) {
3822 cb();
3823 } else {
3824 this._callbacks.push(cb);
3825 }
3826 },
3827 _importsLoaded: function () {
3828 this._ready = true;
3829 this._callbacks.forEach(function (cb) {
3830 cb();
3831 });
3832 this._callbacks = [];
3833 }
3834 };
3835 window.addEventListener('load', function () {
3836 Polymer.ImportStatus._importsLoaded();
3837 });
3838 if (window.HTMLImports) {
3839 HTMLImports.whenReady(function () {
3840 Polymer.ImportStatus._importsLoaded();
3841 });
3842 }
3843 Polymer({
3844 is: 'dom-bind',
3845 extends: 'template',
3846 created: function () {
3847 Polymer.ImportStatus.whenLoaded(this._readySelf.bind(this));
3848 },
3849 _registerFeatures: function () {
3850 this._prepExtends();
3851 this._prepConstructor();
3852 },
3853 _insertChildren: function () {
3854 var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
3855 parentDom.insertBefore(this.root, this);
3856 },
3857 _removeChildren: function () {
3858 if (this._children) {
3859 for (var i = 0; i < this._children.length; i++) {
3860 this.root.appendChild(this._children[i]);
3861 }
3862 }
3863 },
3864 _initFeatures: function () {
3865 },
3866 _scopeElementClass: function (element, selector) {
3867 if (this.dataHost) {
3868 return this.dataHost._scopeElementClass(element, selector);
3869 } else {
3870 return selector;
3871 }
3872 },
3873 _prepConfigure: function () {
3874 var config = {};
3875 for (var prop in this._propertyEffects) {
3876 config[prop] = this[prop];
3877 }
3878 this._setupConfigure = this._setupConfigure.bind(this, config);
3879 },
3880 attached: function () {
3881 if (!this._children) {
3882 this._template = this;
3883 this._prepAnnotations();
3884 this._prepEffects();
3885 this._prepBehaviors();
3886 this._prepConfigure();
3887 this._prepBindings();
3888 Polymer.Base._initFeatures.call(this);
3889 this._children = Array.prototype.slice.call(this.root.childNodes);
3890 }
3891 this._insertChildren();
3892 this.fire('dom-change');
3893 },
3894 detached: function () {
3895 this._removeChildren();
3896 }
3897 });</script>
OLDNEW
« no previous file with comments | « polymer_1.0.4/bower_components/polymer/build.log ('k') | polymer_1.0.4/bower_components/polymer/polymer-micro.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698