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

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

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

Powered by Google App Engine
This is Rietveld 408576698