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

Side by Side Diff: chrome/browser/resources/md_downloads/crisper.js

Issue 1428833005: MD Downloads: track downloads in C++, dispatch discrete JS updates (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: asdf Created 5 years, 1 month 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 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 if (typeof Polymer == 'undefined') 5 if (typeof Polymer == 'undefined')
6 Polymer = {dom: 'shadow'}; 6 Polymer = {dom: 'shadow'};
7 else 7 else
8 console.error('Polymer is already defined.'); 8 console.error('Polymer is already defined.');
9 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 9 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
10 // Use of this source code is governed by a BSD-style license that can be 10 // Use of this source code is governed by a BSD-style license that can be
(...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 /** 1458 /**
1459 * Verify |condition| is truthy and return |condition| if so. 1459 * Verify |condition| is truthy and return |condition| if so.
1460 * @template T 1460 * @template T
1461 * @param {T} condition A condition to check for truthiness. Note that this 1461 * @param {T} condition A condition to check for truthiness. Note that this
1462 * may be used to test whether a value is defined or not, and we don't want 1462 * may be used to test whether a value is defined or not, and we don't want
1463 * to force a cast to Boolean. 1463 * to force a cast to Boolean.
1464 * @param {string=} opt_message A message to show on failure. 1464 * @param {string=} opt_message A message to show on failure.
1465 * @return {T} A non-null |condition|. 1465 * @return {T} A non-null |condition|.
1466 */ 1466 */
1467 function assert(condition, opt_message) { 1467 function assert(condition, opt_message) {
1468 'use strict';
1469 if (!condition) { 1468 if (!condition) {
1470 var msg = 'Assertion failed'; 1469 var message = 'Assertion failed';
1471 if (opt_message) 1470 if (opt_message)
1472 msg = msg + ': ' + opt_message; 1471 message = message + ': ' + opt_message;
1473 throw new Error(msg); 1472 var error = new Error(message);
1473 var global = function() { return this; }();
1474 if (global.traceAssertionsForTesting)
1475 console.warn(error.stack);
1476 throw error;
1474 } 1477 }
1475 return condition; 1478 return condition;
1476 } 1479 }
1477 1480
1478 /** 1481 /**
1479 * Call this from places in the code that should never be reached. 1482 * Call this from places in the code that should never be reached.
1480 * 1483 *
1481 * For example, handling all the values of enum with a switch() like this: 1484 * For example, handling all the values of enum with a switch() like this:
1482 * 1485 *
1483 * function getValueFromEnum(enum) { 1486 * function getValueFromEnum(enum) {
1484 * switch (enum) { 1487 * switch (enum) {
1485 * case ENUM_FIRST_OF_TWO: 1488 * case ENUM_FIRST_OF_TWO:
1486 * return first 1489 * return first
1487 * case ENUM_LAST_OF_TWO: 1490 * case ENUM_LAST_OF_TWO:
1488 * return last; 1491 * return last;
1489 * } 1492 * }
1490 * assertNotReached(); 1493 * assertNotReached();
1491 * return document; 1494 * return document;
1492 * } 1495 * }
1493 * 1496 *
1494 * This code should only be hit in the case of serious programmer error or 1497 * This code should only be hit in the case of serious programmer error or
1495 * unexpected input. 1498 * unexpected input.
1496 * 1499 *
1497 * @param {string=} opt_message A message to show when this is hit. 1500 * @param {string=} opt_message A message to show when this is hit.
1498 */ 1501 */
1499 function assertNotReached(opt_message) { 1502 function assertNotReached(opt_message) {
1500 throw new Error(opt_message || 'Unreachable code hit'); 1503 assert(false, opt_message || 'Unreachable code hit');
1501 } 1504 }
1502 1505
1503 /** 1506 /**
1504 * @param {*} value The value to check. 1507 * @param {*} value The value to check.
1505 * @param {function(new: T, ...)} type A user-defined constructor. 1508 * @param {function(new: T, ...)} type A user-defined constructor.
1506 * @param {string=} opt_message A message to show when this is hit. 1509 * @param {string=} opt_message A message to show when this is hit.
1507 * @return {T} 1510 * @return {T}
1508 * @template T 1511 * @template T
1509 */ 1512 */
1510 function assertInstanceof(value, type, opt_message) { 1513 function assertInstanceof(value, type, opt_message) {
1511 if (!(value instanceof type)) { 1514 assert(value instanceof type,
1512 throw new Error(opt_message || 1515 opt_message || value + ' is not a[n] ' + (type.name || typeof type));
1513 value + ' is not a[n] ' + (type.name || typeof type));
1514 }
1515 return value; 1516 return value;
1516 }; 1517 };
1517 // Copyright 2015 The Chromium Authors. All rights reserved. 1518 // Copyright 2015 The Chromium Authors. All rights reserved.
1518 // Use of this source code is governed by a BSD-style license that can be 1519 // Use of this source code is governed by a BSD-style license that can be
1519 // found in the LICENSE file. 1520 // found in the LICENSE file.
1520 1521
1521 cr.define('downloads', function() { 1522 cr.define('downloads', function() {
1522 /** 1523 /**
1523 * @param {string} chromeSendName 1524 * @param {string} chromeSendName
1524 * @return {function(string):void} A chrome.send() callback with curried name. 1525 * @return {function(string):void} A chrome.send() callback with curried name.
(...skipping 29 matching lines...) Expand all
1554 }, 1555 },
1555 1556
1556 /** @param {string} id ID of the download that the user started dragging. */ 1557 /** @param {string} id ID of the download that the user started dragging. */
1557 drag: chromeSendWithId('drag'), 1558 drag: chromeSendWithId('drag'),
1558 1559
1559 /** 1560 /**
1560 * @return {boolean} Whether the user is currently searching for downloads 1561 * @return {boolean} Whether the user is currently searching for downloads
1561 * (i.e. has a non-empty search term). 1562 * (i.e. has a non-empty search term).
1562 */ 1563 */
1563 isSearching: function() { 1564 isSearching: function() {
1564 return this.searchText_.length > 0; 1565 return (this.searchText_ || '').length > 0;
1565 }, 1566 },
1566 1567
1567 /** Opens the current local destination for downloads. */ 1568 /** Opens the current local destination for downloads. */
1568 openDownloadsFolder: chrome.send.bind(chrome, 'openDownloadsFolder'), 1569 openDownloadsFolder: chrome.send.bind(chrome, 'openDownloadsFolder'),
1569 1570
1570 /** 1571 /**
1571 * @param {string} id ID of the download to run locally on the user's box. 1572 * @param {string} id ID of the download to run locally on the user's box.
1572 */ 1573 */
1573 openFile: chromeSendWithId('openFile'), 1574 openFile: chromeSendWithId('openFile'),
1574 1575
(...skipping 12 matching lines...) Expand all
1587 */ 1588 */
1588 saveDangerous: chromeSendWithId('saveDangerous'), 1589 saveDangerous: chromeSendWithId('saveDangerous'),
1589 1590
1590 /** @param {string} searchText What to search for. */ 1591 /** @param {string} searchText What to search for. */
1591 search: function(searchText) { 1592 search: function(searchText) {
1592 if (this.searchText_ == searchText) 1593 if (this.searchText_ == searchText)
1593 return; 1594 return;
1594 1595
1595 this.searchText_ = searchText; 1596 this.searchText_ = searchText;
1596 1597
1598 /**
1599 * @param {string} s
1600 * @return {string} |s| without whitespace at the ends (trimmed).
1601 */
1602 function trim(s) { return s.trim(); }
1603
1597 // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']). 1604 // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
1598 function trim(s) { return s.trim(); } 1605 var terms = searchText ? searchText.split(/"([^"]*)"/).map(trim) : [];
1599 chrome.send('getDownloads', searchText.split(/"([^"]*)"/).map(trim)); 1606
1607 chrome.send('getDownloads', terms);
1600 }, 1608 },
1601 1609
1602 /** 1610 /**
1603 * Shows the local folder a finished download resides in. 1611 * Shows the local folder a finished download resides in.
1604 * @param {string} id ID of the download to show. 1612 * @param {string} id ID of the download to show.
1605 */ 1613 */
1606 show: chromeSendWithId('show'), 1614 show: chromeSendWithId('show'),
1607 1615
1608 /** Undo download removal. */ 1616 /** Undo download removal. */
1609 undo: chrome.send.bind(chrome, 'undo'), 1617 undo: chrome.send.bind(chrome, 'undo'),
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 } 2046 }
2039 return m; 2047 return m;
2040 } 2048 }
2041 } 2049 }
2042 }); 2050 });
2043 var cePolyfill = window.CustomElements && !CustomElements.useNative; 2051 var cePolyfill = window.CustomElements && !CustomElements.useNative;
2044 document.registerElement('dom-module', DomModule); 2052 document.registerElement('dom-module', DomModule);
2045 function forceDocumentUpgrade() { 2053 function forceDocumentUpgrade() {
2046 if (cePolyfill) { 2054 if (cePolyfill) {
2047 var script = document._currentScript || document.currentScript; 2055 var script = document._currentScript || document.currentScript;
2048 var doc = script && script.ownerDocument; 2056 var doc = script && script.ownerDocument || document;
2049 if (doc) { 2057 if (doc) {
2050 CustomElements.upgradeAll(doc); 2058 CustomElements.upgradeAll(doc);
2051 } 2059 }
2052 } 2060 }
2053 } 2061 }
2054 }()); 2062 }());
2055 Polymer.Base._addFeature({ 2063 Polymer.Base._addFeature({
2056 _prepIs: function () { 2064 _prepIs: function () {
2057 if (!this.is) { 2065 if (!this.is) {
2058 var module = (document._currentScript || document.currentScript).parentNode; 2066 var module = (document._currentScript || document.currentScript).parentNode;
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 debouncer.complete(); 2358 debouncer.complete();
2351 } 2359 }
2352 }, 2360 },
2353 cancelDebouncer: function (jobName) { 2361 cancelDebouncer: function (jobName) {
2354 var debouncer = this._debouncers[jobName]; 2362 var debouncer = this._debouncers[jobName];
2355 if (debouncer) { 2363 if (debouncer) {
2356 debouncer.stop(); 2364 debouncer.stop();
2357 } 2365 }
2358 } 2366 }
2359 }); 2367 });
2360 Polymer.version = '1.1.5'; 2368 Polymer.version = '1.2.1';
2361 Polymer.Base._addFeature({ 2369 Polymer.Base._addFeature({
2362 _registerFeatures: function () { 2370 _registerFeatures: function () {
2363 this._prepIs(); 2371 this._prepIs();
2364 this._prepAttributes(); 2372 this._prepAttributes();
2365 this._prepBehaviors(); 2373 this._prepBehaviors();
2366 this._prepConstructor(); 2374 this._prepConstructor();
2367 }, 2375 },
2368 _prepBehavior: function (b) { 2376 _prepBehavior: function (b) {
2369 this._addHostAttributes(b.hostAttributes); 2377 this._addHostAttributes(b.hostAttributes);
2370 }, 2378 },
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 }, 2639 },
2632 calculateSplices: function (current, previous) { 2640 calculateSplices: function (current, previous) {
2633 return this.calcSplices(current, 0, current.length, previous, 0, previous.length ); 2641 return this.calcSplices(current, 0, current.length, previous, 0, previous.length );
2634 }, 2642 },
2635 equals: function (currentValue, previousValue) { 2643 equals: function (currentValue, previousValue) {
2636 return currentValue === previousValue; 2644 return currentValue === previousValue;
2637 } 2645 }
2638 }; 2646 };
2639 return new ArraySplice(); 2647 return new ArraySplice();
2640 }(); 2648 }();
2641 Polymer.EventApi = function () {
2642 var Settings = Polymer.Settings;
2643 var EventApi = function (event) {
2644 this.event = event;
2645 };
2646 if (Settings.useShadow) {
2647 EventApi.prototype = {
2648 get rootTarget() {
2649 return this.event.path[0];
2650 },
2651 get localTarget() {
2652 return this.event.target;
2653 },
2654 get path() {
2655 return this.event.path;
2656 }
2657 };
2658 } else {
2659 EventApi.prototype = {
2660 get rootTarget() {
2661 return this.event.target;
2662 },
2663 get localTarget() {
2664 var current = this.event.currentTarget;
2665 var currentRoot = current && Polymer.dom(current).getOwnerRoot();
2666 var p$ = this.path;
2667 for (var i = 0; i < p$.length; i++) {
2668 if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
2669 return p$[i];
2670 }
2671 }
2672 },
2673 get path() {
2674 if (!this.event._path) {
2675 var path = [];
2676 var o = this.rootTarget;
2677 while (o) {
2678 path.push(o);
2679 o = Polymer.dom(o).parentNode || o.host;
2680 }
2681 path.push(window);
2682 this.event._path = path;
2683 }
2684 return this.event._path;
2685 }
2686 };
2687 }
2688 var factory = function (event) {
2689 if (!event.__eventApi) {
2690 event.__eventApi = new EventApi(event);
2691 }
2692 return event.__eventApi;
2693 };
2694 return { factory: factory };
2695 }();
2696 Polymer.domInnerHTML = function () { 2649 Polymer.domInnerHTML = function () {
2697 var escapeAttrRegExp = /[&\u00A0"]/g; 2650 var escapeAttrRegExp = /[&\u00A0"]/g;
2698 var escapeDataRegExp = /[&\u00A0<>]/g; 2651 var escapeDataRegExp = /[&\u00A0<>]/g;
2699 function escapeReplace(c) { 2652 function escapeReplace(c) {
2700 switch (c) { 2653 switch (c) {
2701 case '&': 2654 case '&':
2702 return '&amp;'; 2655 return '&amp;';
2703 case '<': 2656 case '<':
2704 return '&lt;'; 2657 return '&lt;';
2705 case '>': 2658 case '>':
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 this.node = wrap(node); 2764 this.node = wrap(node);
2812 if (this.patch) { 2765 if (this.patch) {
2813 this.patch(); 2766 this.patch();
2814 } 2767 }
2815 }; 2768 };
2816 } 2769 }
2817 DomApi.prototype = { 2770 DomApi.prototype = {
2818 flush: function () { 2771 flush: function () {
2819 Polymer.dom.flush(); 2772 Polymer.dom.flush();
2820 }, 2773 },
2774 deepContains: function (node) {
2775 if (this.node.contains(node)) {
2776 return true;
2777 }
2778 var n = node;
2779 var wrappedDocument = wrap(document);
2780 while (n && n !== wrappedDocument && n !== this.node) {
2781 n = Polymer.dom(n).parentNode || n.host;
2782 }
2783 return n === this.node;
2784 },
2821 _lazyDistribute: function (host) { 2785 _lazyDistribute: function (host) {
2822 if (host.shadyRoot && host.shadyRoot._distributionClean) { 2786 if (host.shadyRoot && host.shadyRoot._distributionClean) {
2823 host.shadyRoot._distributionClean = false; 2787 host.shadyRoot._distributionClean = false;
2824 Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent)); 2788 Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent));
2825 } 2789 }
2826 }, 2790 },
2827 appendChild: function (node) { 2791 appendChild: function (node) {
2828 return this._addNode(node); 2792 return this._addNode(node);
2829 }, 2793 },
2830 insertBefore: function (node, ref_node) { 2794 insertBefore: function (node, ref_node) {
2831 return this._addNode(node, ref_node); 2795 return this._addNode(node, ref_node);
2832 }, 2796 },
2833 _addNode: function (node, ref_node) { 2797 _addNode: function (node, ref_node) {
2834 this._removeNodeFromHost(node, true); 2798 this._removeNodeFromParent(node);
2835 var addedInsertionPoint; 2799 var addedInsertionPoint;
2836 var root = this.getOwnerRoot(); 2800 var root = this.getOwnerRoot();
2837 if (root) { 2801 if (root) {
2838 addedInsertionPoint = this._maybeAddInsertionPoint(node, this.node); 2802 addedInsertionPoint = this._maybeAddInsertionPoint(node, this.node);
2839 } 2803 }
2840 if (this._nodeHasLogicalChildren(this.node)) { 2804 if (this._nodeHasLogicalChildren(this.node)) {
2841 if (ref_node) { 2805 if (ref_node) {
2842 var children = this.childNodes; 2806 var children = this.childNodes;
2843 var index = children.indexOf(ref_node); 2807 var index = children.indexOf(ref_node);
2844 if (index < 0) { 2808 if (index < 0) {
(...skipping 11 matching lines...) Expand all
2856 addToComposedParent(container, node, ref_node); 2820 addToComposedParent(container, node, ref_node);
2857 if (ref_node) { 2821 if (ref_node) {
2858 nativeInsertBefore.call(container, node, ref_node); 2822 nativeInsertBefore.call(container, node, ref_node);
2859 } else { 2823 } else {
2860 nativeAppendChild.call(container, node); 2824 nativeAppendChild.call(container, node);
2861 } 2825 }
2862 } 2826 }
2863 if (addedInsertionPoint) { 2827 if (addedInsertionPoint) {
2864 this._updateInsertionPoints(root.host); 2828 this._updateInsertionPoints(root.host);
2865 } 2829 }
2830 this.notifyObserver();
2866 return node; 2831 return node;
2867 }, 2832 },
2868 removeChild: function (node) { 2833 removeChild: function (node) {
2869 if (factory(node).parentNode !== this.node) { 2834 if (factory(node).parentNode !== this.node) {
2870 console.warn('The node to be removed is not a child of this node', node); 2835 console.warn('The node to be removed is not a child of this node', node);
2871 } 2836 }
2872 this._removeNodeFromHost(node); 2837 this._removeNodeFromHost(node);
2873 if (!this._maybeDistribute(node, this.node)) { 2838 if (!this._maybeDistribute(node, this.node)) {
2874 var container = this.node._isShadyRoot ? this.node.host : this.node; 2839 var container = this.node._isShadyRoot ? this.node.host : this.node;
2875 if (container === node.parentNode) { 2840 if (container === node.parentNode) {
2876 removeFromComposedParent(container, node); 2841 removeFromComposedParent(container, node);
2877 nativeRemoveChild.call(container, node); 2842 nativeRemoveChild.call(container, node);
2878 } 2843 }
2879 } 2844 }
2845 this.notifyObserver();
2880 return node; 2846 return node;
2881 }, 2847 },
2882 replaceChild: function (node, ref_node) { 2848 replaceChild: function (node, ref_node) {
2883 this.insertBefore(node, ref_node); 2849 this.insertBefore(node, ref_node);
2884 this.removeChild(ref_node); 2850 this.removeChild(ref_node);
2885 return node; 2851 return node;
2886 }, 2852 },
2887 _hasCachedOwnerRoot: function (node) { 2853 _hasCachedOwnerRoot: function (node) {
2888 return Boolean(node._ownerShadyRoot !== undefined); 2854 return Boolean(node._ownerShadyRoot !== undefined);
2889 }, 2855 },
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 saveLightChildrenIfNeeded(c); 2928 saveLightChildrenIfNeeded(c);
2963 saveLightChildrenIfNeeded(factory(c).parentNode); 2929 saveLightChildrenIfNeeded(factory(c).parentNode);
2964 } 2930 }
2965 }, 2931 },
2966 _nodeHasLogicalChildren: function (node) { 2932 _nodeHasLogicalChildren: function (node) {
2967 return Boolean(node._lightChildren !== undefined); 2933 return Boolean(node._lightChildren !== undefined);
2968 }, 2934 },
2969 _parentNeedsDistribution: function (parent) { 2935 _parentNeedsDistribution: function (parent) {
2970 return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot); 2936 return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
2971 }, 2937 },
2938 _removeNodeFromParent: function (node) {
2939 var parent = node._lightParent || node.parentNode;
2940 if (parent && hasDomApi(parent)) {
2941 factory(parent).notifyObserver();
2942 }
2943 this._removeNodeFromHost(node, true);
2944 },
2972 _removeNodeFromHost: function (node, ensureComposedRemoval) { 2945 _removeNodeFromHost: function (node, ensureComposedRemoval) {
2973 var hostNeedsDist; 2946 var hostNeedsDist;
2974 var root; 2947 var root;
2975 var parent = node._lightParent; 2948 var parent = node._lightParent;
2976 if (parent) { 2949 if (parent) {
2977 factory(node)._distributeParent(); 2950 factory(node)._distributeParent();
2978 root = this._ownerShadyRootForNode(node); 2951 root = this._ownerShadyRootForNode(node);
2979 if (root) { 2952 if (root) {
2980 root.host._elementRemove(node); 2953 root.host._elementRemove(node);
2981 hostNeedsDist = this._removeDistributedChildren(root, node); 2954 hostNeedsDist = this._removeDistributedChildren(root, node);
2982 } 2955 }
2983 this._removeLogicalInfo(node, node._lightParent); 2956 this._removeLogicalInfo(node, parent);
2984 } 2957 }
2985 this._removeOwnerShadyRoot(node); 2958 this._removeOwnerShadyRoot(node);
2986 if (root && hostNeedsDist) { 2959 if (root && hostNeedsDist) {
2987 this._updateInsertionPoints(root.host); 2960 this._updateInsertionPoints(root.host);
2988 this._lazyDistribute(root.host); 2961 this._lazyDistribute(root.host);
2989 } else if (ensureComposedRemoval) { 2962 } else if (ensureComposedRemoval) {
2990 removeFromComposedParent(getComposedParent(node), node); 2963 removeFromComposedParent(getComposedParent(node), node);
2991 } 2964 }
2992 }, 2965 },
2993 _removeDistributedChildren: function (root, container) { 2966 _removeDistributedChildren: function (root, container) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 } 3065 }
3093 this._queryElements(factory(node).childNodes, matcher, list); 3066 this._queryElements(factory(node).childNodes, matcher, list);
3094 }, 3067 },
3095 getDestinationInsertionPoints: function () { 3068 getDestinationInsertionPoints: function () {
3096 return this.node._destinationInsertionPoints || []; 3069 return this.node._destinationInsertionPoints || [];
3097 }, 3070 },
3098 getDistributedNodes: function () { 3071 getDistributedNodes: function () {
3099 return this.node._distributedNodes || []; 3072 return this.node._distributedNodes || [];
3100 }, 3073 },
3101 queryDistributedElements: function (selector) { 3074 queryDistributedElements: function (selector) {
3102 var c$ = this.childNodes; 3075 var c$ = this.getEffectiveChildNodes();
3103 var list = []; 3076 var list = [];
3104 this._distributedFilter(selector, c$, list);
3105 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { 3077 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
3106 if (c.localName === CONTENT) { 3078 if (c.nodeType === Node.ELEMENT_NODE && matchesSelector.call(c, selector)) {
3107 this._distributedFilter(selector, factory(c).getDistributedNodes(), list); 3079 list.push(c);
3108 } 3080 }
3109 } 3081 }
3110 return list; 3082 return list;
3111 }, 3083 },
3112 _distributedFilter: function (selector, list, results) { 3084 getEffectiveChildNodes: function () {
3113 results = results || []; 3085 var list = [];
3114 for (var i = 0, l = list.length, d; i < l && (d = list[i]); i++) { 3086 var c$ = this.childNodes;
3115 if (d.nodeType === Node.ELEMENT_NODE && d.localName !== CONTENT && matchesSelect or.call(d, selector)) { 3087 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
3116 results.push(d); 3088 if (c.localName === CONTENT) {
3089 var d$ = factory(c).getDistributedNodes();
3090 for (var j = 0; j < d$.length; j++) {
3091 list.push(d$[j]);
3092 }
3093 } else {
3094 list.push(c);
3117 } 3095 }
3118 } 3096 }
3119 return results; 3097 return list;
3120 }, 3098 },
3121 _clear: function () { 3099 _clear: function () {
3122 while (this.childNodes.length) { 3100 while (this.childNodes.length) {
3123 this.removeChild(this.childNodes[0]); 3101 this.removeChild(this.childNodes[0]);
3124 } 3102 }
3125 }, 3103 },
3126 setAttribute: function (name, value) { 3104 setAttribute: function (name, value) {
3127 this.node.setAttribute(name, value); 3105 this.node.setAttribute(name, value);
3128 this._distributeParent(); 3106 this._distributeParent();
3129 }, 3107 },
(...skipping 23 matching lines...) Expand all
3153 var n = nativeImportNode.call(doc, externalNode, false); 3131 var n = nativeImportNode.call(doc, externalNode, false);
3154 if (deep) { 3132 if (deep) {
3155 var c$ = factory(externalNode).childNodes; 3133 var c$ = factory(externalNode).childNodes;
3156 var d = factory(n); 3134 var d = factory(n);
3157 for (var i = 0, nc; i < c$.length; i++) { 3135 for (var i = 0, nc; i < c$.length; i++) {
3158 nc = factory(doc).importNode(c$[i], true); 3136 nc = factory(doc).importNode(c$[i], true);
3159 d.appendChild(nc); 3137 d.appendChild(nc);
3160 } 3138 }
3161 } 3139 }
3162 return n; 3140 return n;
3141 },
3142 observeNodes: function (callback) {
3143 if (callback) {
3144 if (!this.observer) {
3145 this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObs erver(this) : new DomApi.EffectiveNodesObserver(this);
3163 } 3146 }
3164 }; 3147 return this.observer.addListener(callback);
3165 Object.defineProperty(DomApi.prototype, 'classList', {
3166 get: function () {
3167 if (!this._classList) {
3168 this._classList = new DomApi.ClassList(this);
3169 } 3148 }
3170 return this._classList;
3171 }, 3149 },
3172 configurable: true 3150 unobserveNodes: function (handle) {
3173 }); 3151 if (this.observer) {
3174 DomApi.ClassList = function (host) { 3152 this.observer.removeListener(handle);
3175 this.domApi = host; 3153 }
3176 this.node = host.node;
3177 };
3178 DomApi.ClassList.prototype = {
3179 add: function () {
3180 this.node.classList.add.apply(this.node.classList, arguments);
3181 this.domApi._distributeParent();
3182 }, 3154 },
3183 remove: function () { 3155 notifyObserver: function () {
3184 this.node.classList.remove.apply(this.node.classList, arguments); 3156 if (this.observer) {
3185 this.domApi._distributeParent(); 3157 this.observer.notify();
3186 }, 3158 }
3187 toggle: function () {
3188 this.node.classList.toggle.apply(this.node.classList, arguments);
3189 this.domApi._distributeParent();
3190 },
3191 contains: function () {
3192 return this.node.classList.contains.apply(this.node.classList, arguments);
3193 } 3159 }
3194 }; 3160 };
3195 if (!Settings.useShadow) { 3161 if (!Settings.useShadow) {
3196 Object.defineProperties(DomApi.prototype, { 3162 Object.defineProperties(DomApi.prototype, {
3197 childNodes: { 3163 childNodes: {
3198 get: function () { 3164 get: function () {
3199 var c$ = getLightChildren(this.node); 3165 var c$ = getLightChildren(this.node);
3200 return Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$); 3166 return Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$);
3201 }, 3167 },
3202 configurable: true 3168 configurable: true
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3364 DomApi.prototype.getDestinationInsertionPoints = function () { 3330 DomApi.prototype.getDestinationInsertionPoints = function () {
3365 var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInse rtionPoints(); 3331 var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInse rtionPoints();
3366 return n$ ? Array.prototype.slice.call(n$) : []; 3332 return n$ ? Array.prototype.slice.call(n$) : [];
3367 }; 3333 };
3368 DomApi.prototype.getDistributedNodes = function () { 3334 DomApi.prototype.getDistributedNodes = function () {
3369 var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes(); 3335 var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes();
3370 return n$ ? Array.prototype.slice.call(n$) : []; 3336 return n$ ? Array.prototype.slice.call(n$) : [];
3371 }; 3337 };
3372 DomApi.prototype._distributeParent = function () { 3338 DomApi.prototype._distributeParent = function () {
3373 }; 3339 };
3340 var nativeForwards = [
3341 'appendChild',
3342 'insertBefore',
3343 'removeChild',
3344 'replaceChild'
3345 ];
3346 nativeForwards.forEach(function (forward) {
3347 DomApi.prototype[forward] = function () {
3348 return this.node[forward].apply(this.node, arguments);
3349 };
3350 });
3374 Object.defineProperties(DomApi.prototype, { 3351 Object.defineProperties(DomApi.prototype, {
3375 childNodes: { 3352 childNodes: {
3376 get: function () { 3353 get: function () {
3377 return Array.prototype.slice.call(this.node.childNodes); 3354 return Array.prototype.slice.call(this.node.childNodes);
3378 }, 3355 },
3379 configurable: true 3356 configurable: true
3380 }, 3357 },
3381 children: { 3358 children: {
3382 get: function () { 3359 get: function () {
3383 return Array.prototype.slice.call(this.node.children); 3360 return Array.prototype.slice.call(this.node.children);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3417 forwardProperties.forEach(function (name) { 3394 forwardProperties.forEach(function (name) {
3418 Object.defineProperty(DomApi.prototype, name, { 3395 Object.defineProperty(DomApi.prototype, name, {
3419 get: function () { 3396 get: function () {
3420 return this.node[name]; 3397 return this.node[name];
3421 }, 3398 },
3422 configurable: true 3399 configurable: true
3423 }); 3400 });
3424 }); 3401 });
3425 } 3402 }
3426 var CONTENT = 'content'; 3403 var CONTENT = 'content';
3427 var factory = function (node, patch) { 3404 function factory(node, patch) {
3428 node = node || document; 3405 node = node || document;
3429 if (!node.__domApi) { 3406 if (!node.__domApi) {
3430 node.__domApi = new DomApi(node, patch); 3407 node.__domApi = new DomApi(node, patch);
3431 } 3408 }
3432 return node.__domApi; 3409 return node.__domApi;
3433 }; 3410 }
3411 ;
3412 function hasDomApi(node) {
3413 return Boolean(node.__domApi);
3414 }
3434 Polymer.dom = function (obj, patch) { 3415 Polymer.dom = function (obj, patch) {
3435 if (obj instanceof Event) { 3416 if (obj instanceof Event) {
3436 return Polymer.EventApi.factory(obj); 3417 return Polymer.EventApi.factory(obj);
3437 } else { 3418 } else {
3438 return factory(obj, patch); 3419 return factory(obj, patch);
3439 } 3420 }
3440 }; 3421 };
3441 Polymer.Base.extend(Polymer.dom, {
3442 _flushGuard: 0,
3443 _FLUSH_MAX: 100,
3444 _needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
3445 _debouncers: [],
3446 _finishDebouncer: null,
3447 flush: function () {
3448 for (var i = 0; i < this._debouncers.length; i++) {
3449 this._debouncers[i].complete();
3450 }
3451 if (this._finishDebouncer) {
3452 this._finishDebouncer.complete();
3453 }
3454 this._flushPolyfills();
3455 if (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
3456 this._flushGuard++;
3457 this.flush();
3458 } else {
3459 if (this._flushGuard >= this._FLUSH_MAX) {
3460 console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
3461 }
3462 this._flushGuard = 0;
3463 }
3464 },
3465 _flushPolyfills: function () {
3466 if (this._needsTakeRecords) {
3467 CustomElements.takeRecords();
3468 }
3469 },
3470 addDebouncer: function (debouncer) {
3471 this._debouncers.push(debouncer);
3472 this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlus h);
3473 },
3474 _finishFlush: function () {
3475 Polymer.dom._debouncers = [];
3476 }
3477 });
3478 function getLightChildren(node) { 3422 function getLightChildren(node) {
3479 var children = node._lightChildren; 3423 var children = node._lightChildren;
3480 return children ? children : node.childNodes; 3424 return children ? children : node.childNodes;
3481 } 3425 }
3482 function getComposedChildren(node) { 3426 function getComposedChildren(node) {
3483 if (!node._composedChildren) { 3427 if (!node._composedChildren) {
3484 node._composedChildren = Array.prototype.slice.call(node.childNodes); 3428 node._composedChildren = Array.prototype.slice.call(node.childNodes);
3485 } 3429 }
3486 return node._composedChildren; 3430 return node._composedChildren;
3487 } 3431 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3531 var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector; 3475 var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;
3532 return { 3476 return {
3533 getLightChildren: getLightChildren, 3477 getLightChildren: getLightChildren,
3534 getComposedParent: getComposedParent, 3478 getComposedParent: getComposedParent,
3535 getComposedChildren: getComposedChildren, 3479 getComposedChildren: getComposedChildren,
3536 removeFromComposedParent: removeFromComposedParent, 3480 removeFromComposedParent: removeFromComposedParent,
3537 saveLightChildrenIfNeeded: saveLightChildrenIfNeeded, 3481 saveLightChildrenIfNeeded: saveLightChildrenIfNeeded,
3538 matchesSelector: matchesSelector, 3482 matchesSelector: matchesSelector,
3539 hasInsertionPoint: hasInsertionPoint, 3483 hasInsertionPoint: hasInsertionPoint,
3540 ctor: DomApi, 3484 ctor: DomApi,
3541 factory: factory 3485 factory: factory,
3542 }; 3486 hasDomApi: hasDomApi
3487 };
3488 }();
3489 Polymer.Base.extend(Polymer.dom, {
3490 _flushGuard: 0,
3491 _FLUSH_MAX: 100,
3492 _needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
3493 _debouncers: [],
3494 _staticFlushList: [],
3495 _finishDebouncer: null,
3496 flush: function () {
3497 this._flushGuard = 0;
3498 this._prepareFlush();
3499 while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
3500 for (var i = 0; i < this._debouncers.length; i++) {
3501 this._debouncers[i].complete();
3502 }
3503 if (this._finishDebouncer) {
3504 this._finishDebouncer.complete();
3505 }
3506 this._prepareFlush();
3507 this._flushGuard++;
3508 }
3509 if (this._flushGuard >= this._FLUSH_MAX) {
3510 console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
3511 }
3512 },
3513 _prepareFlush: function () {
3514 if (this._needsTakeRecords) {
3515 CustomElements.takeRecords();
3516 }
3517 for (var i = 0; i < this._staticFlushList.length; i++) {
3518 this._staticFlushList[i]();
3519 }
3520 },
3521 addStaticFlush: function (fn) {
3522 this._staticFlushList.push(fn);
3523 },
3524 removeStaticFlush: function (fn) {
3525 var i = this._staticFlushList.indexOf(fn);
3526 if (i >= 0) {
3527 this._staticFlushList.splice(i, 1);
3528 }
3529 },
3530 addDebouncer: function (debouncer) {
3531 this._debouncers.push(debouncer);
3532 this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlus h);
3533 },
3534 _finishFlush: function () {
3535 Polymer.dom._debouncers = [];
3536 }
3537 });
3538 Polymer.EventApi = function () {
3539 'use strict';
3540 var DomApi = Polymer.DomApi.ctor;
3541 var Settings = Polymer.Settings;
3542 DomApi.Event = function (event) {
3543 this.event = event;
3544 };
3545 if (Settings.useShadow) {
3546 DomApi.Event.prototype = {
3547 get rootTarget() {
3548 return this.event.path[0];
3549 },
3550 get localTarget() {
3551 return this.event.target;
3552 },
3553 get path() {
3554 return this.event.path;
3555 }
3556 };
3557 } else {
3558 DomApi.Event.prototype = {
3559 get rootTarget() {
3560 return this.event.target;
3561 },
3562 get localTarget() {
3563 var current = this.event.currentTarget;
3564 var currentRoot = current && Polymer.dom(current).getOwnerRoot();
3565 var p$ = this.path;
3566 for (var i = 0; i < p$.length; i++) {
3567 if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
3568 return p$[i];
3569 }
3570 }
3571 },
3572 get path() {
3573 if (!this.event._path) {
3574 var path = [];
3575 var o = this.rootTarget;
3576 while (o) {
3577 path.push(o);
3578 o = Polymer.dom(o).parentNode || o.host;
3579 }
3580 path.push(window);
3581 this.event._path = path;
3582 }
3583 return this.event._path;
3584 }
3585 };
3586 }
3587 var factory = function (event) {
3588 if (!event.__eventApi) {
3589 event.__eventApi = new DomApi.Event(event);
3590 }
3591 return event.__eventApi;
3592 };
3593 return { factory: factory };
3543 }(); 3594 }();
3544 (function () { 3595 (function () {
3596 'use strict';
3597 var DomApi = Polymer.DomApi.ctor;
3598 Object.defineProperty(DomApi.prototype, 'classList', {
3599 get: function () {
3600 if (!this._classList) {
3601 this._classList = new DomApi.ClassList(this);
3602 }
3603 return this._classList;
3604 },
3605 configurable: true
3606 });
3607 DomApi.ClassList = function (host) {
3608 this.domApi = host;
3609 this.node = host.node;
3610 };
3611 DomApi.ClassList.prototype = {
3612 add: function () {
3613 this.node.classList.add.apply(this.node.classList, arguments);
3614 this.domApi._distributeParent();
3615 },
3616 remove: function () {
3617 this.node.classList.remove.apply(this.node.classList, arguments);
3618 this.domApi._distributeParent();
3619 },
3620 toggle: function () {
3621 this.node.classList.toggle.apply(this.node.classList, arguments);
3622 this.domApi._distributeParent();
3623 },
3624 contains: function () {
3625 return this.node.classList.contains.apply(this.node.classList, arguments);
3626 }
3627 };
3628 }());
3629 (function () {
3630 'use strict';
3631 var DomApi = Polymer.DomApi.ctor;
3632 var Settings = Polymer.Settings;
3633 var hasDomApi = Polymer.DomApi.hasDomApi;
3634 DomApi.EffectiveNodesObserver = function (domApi) {
3635 this.domApi = domApi;
3636 this.node = this.domApi.node;
3637 this._listeners = [];
3638 };
3639 DomApi.EffectiveNodesObserver.prototype = {
3640 addListener: function (callback) {
3641 if (!this._isSetup) {
3642 this._setup();
3643 this._isSetup = true;
3644 }
3645 var listener = {
3646 fn: callback,
3647 _nodes: []
3648 };
3649 this._listeners.push(listener);
3650 this._scheduleNotify();
3651 return listener;
3652 },
3653 removeListener: function (handle) {
3654 var i = this._listeners.indexOf(handle);
3655 if (i >= 0) {
3656 this._listeners.splice(i, 1);
3657 handle._nodes = [];
3658 }
3659 if (!this._hasListeners()) {
3660 this._cleanup();
3661 this._isSetup = false;
3662 }
3663 },
3664 _setup: function () {
3665 this._observeContentElements(this.domApi.childNodes);
3666 },
3667 _cleanup: function () {
3668 this._unobserveContentElements(this.domApi.childNodes);
3669 },
3670 _hasListeners: function () {
3671 return Boolean(this._listeners.length);
3672 },
3673 _scheduleNotify: function () {
3674 if (this._debouncer) {
3675 this._debouncer.stop();
3676 }
3677 this._debouncer = Polymer.Debounce(this._debouncer, this._notify);
3678 this._debouncer.context = this;
3679 Polymer.dom.addDebouncer(this._debouncer);
3680 },
3681 notify: function () {
3682 if (this._hasListeners()) {
3683 this._scheduleNotify();
3684 }
3685 },
3686 _notify: function (mxns) {
3687 this._beforeCallListeners();
3688 this._callListeners();
3689 },
3690 _beforeCallListeners: function () {
3691 this._updateContentElements();
3692 },
3693 _updateContentElements: function () {
3694 this._observeContentElements(this.domApi.childNodes);
3695 },
3696 _observeContentElements: function (elements) {
3697 for (var i = 0, n; i < elements.length && (n = elements[i]); i++) {
3698 if (this._isContent(n)) {
3699 n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
3700 if (!n.__observeNodesMap.has(this)) {
3701 n.__observeNodesMap.set(this, this._observeContent(n));
3702 }
3703 }
3704 }
3705 },
3706 _observeContent: function (content) {
3707 var h = Polymer.dom(content).observeNodes(this._scheduleNotify.bind(this));
3708 h._avoidChangeCalculation = true;
3709 return h;
3710 },
3711 _unobserveContentElements: function (elements) {
3712 for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) {
3713 if (this._isContent(n)) {
3714 h = n.__observeNodesMap.get(this);
3715 if (h) {
3716 Polymer.dom(n).unobserveNodes(h);
3717 n.__observeNodesMap.delete(this);
3718 }
3719 }
3720 }
3721 },
3722 _isContent: function (node) {
3723 return node.localName === 'content';
3724 },
3725 _callListeners: function () {
3726 var o$ = this._listeners;
3727 var nodes = this._getEffectiveNodes();
3728 for (var i = 0, o; i < o$.length && (o = o$[i]); i++) {
3729 var info = this._generateListenerInfo(o, nodes);
3730 if (info || o._alwaysNotify) {
3731 this._callListener(o, info);
3732 }
3733 }
3734 },
3735 _getEffectiveNodes: function () {
3736 return this.domApi.getEffectiveChildNodes();
3737 },
3738 _generateListenerInfo: function (listener, newNodes) {
3739 if (listener._avoidChangeCalculation) {
3740 return true;
3741 }
3742 var oldNodes = listener._nodes;
3743 var info = {
3744 target: this.node,
3745 addedNodes: [],
3746 removedNodes: []
3747 };
3748 var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes);
3749 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
3750 for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
3751 info.removedNodes.push(n);
3752 }
3753 }
3754 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
3755 for (var j = s.index; j < s.index + s.addedCount; j++) {
3756 info.addedNodes.push(newNodes[j]);
3757 }
3758 }
3759 listener._nodes = newNodes;
3760 if (info.addedNodes.length || info.removedNodes.length) {
3761 return info;
3762 }
3763 },
3764 _callListener: function (listener, info) {
3765 return listener.fn.call(this.node, info);
3766 },
3767 enableShadowAttributeTracking: function () {
3768 }
3769 };
3770 if (Settings.useShadow) {
3771 var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup;
3772 var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup;
3773 var beforeCallListeners = DomApi.EffectiveNodesObserver.prototype._beforeCallLis teners;
3774 Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, {
3775 _setup: function () {
3776 if (!this._observer) {
3777 var self = this;
3778 this._mutationHandler = function (mxns) {
3779 if (mxns && mxns.length) {
3780 self._scheduleNotify();
3781 }
3782 };
3783 this._observer = new MutationObserver(this._mutationHandler);
3784 this._boundFlush = this._flush.bind(this);
3785 Polymer.dom.addStaticFlush(this._boundFlush);
3786 this._observer.observe(this.node, { childList: true });
3787 }
3788 baseSetup.call(this);
3789 },
3790 _cleanup: function () {
3791 this._observer.disconnect();
3792 this._observer = null;
3793 this._mutationHandler = null;
3794 Polymer.dom.removeStaticFlush(this._boundFlush);
3795 baseCleanup.call(this);
3796 },
3797 _flush: function () {
3798 if (this._observer) {
3799 this._mutationHandler(this._observer.takeRecords());
3800 }
3801 },
3802 enableShadowAttributeTracking: function () {
3803 if (this._observer) {
3804 this._makeContentListenersAlwaysNotify();
3805 this._observer.disconnect();
3806 this._observer.observe(this.node, {
3807 childList: true,
3808 attributes: true,
3809 subtree: true
3810 });
3811 var root = this.domApi.getOwnerRoot();
3812 var host = root && root.host;
3813 if (host && Polymer.dom(host).observer) {
3814 Polymer.dom(host).observer.enableShadowAttributeTracking();
3815 }
3816 }
3817 },
3818 _makeContentListenersAlwaysNotify: function () {
3819 for (var i = 0, h; i < this._listeners.length; i++) {
3820 h = this._listeners[i];
3821 h._alwaysNotify = h._isContentListener;
3822 }
3823 }
3824 });
3825 }
3826 }());
3827 (function () {
3828 'use strict';
3829 var DomApi = Polymer.DomApi.ctor;
3830 var Settings = Polymer.Settings;
3831 DomApi.DistributedNodesObserver = function (domApi) {
3832 DomApi.EffectiveNodesObserver.call(this, domApi);
3833 };
3834 DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesO bserver.prototype);
3835 Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
3836 _setup: function () {
3837 },
3838 _cleanup: function () {
3839 },
3840 _beforeCallListeners: function () {
3841 },
3842 _getEffectiveNodes: function () {
3843 return this.domApi.getDistributedNodes();
3844 }
3845 });
3846 if (Settings.useShadow) {
3847 Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
3848 _setup: function () {
3849 if (!this._observer) {
3850 var root = this.domApi.getOwnerRoot();
3851 var host = root && root.host;
3852 if (host) {
3853 this._observer = Polymer.dom(host).observeNodes(this._scheduleNotify.bind(this)) ;
3854 this._observer._isContentListener = true;
3855 if (this._hasAttrSelect()) {
3856 Polymer.dom(host).observer.enableShadowAttributeTracking();
3857 }
3858 }
3859 }
3860 },
3861 _hasAttrSelect: function () {
3862 var select = this.node.getAttribute('select');
3863 return select && select.match(/[[.]+/);
3864 },
3865 _cleanup: function () {
3866 var root = this.domApi.getOwnerRoot();
3867 var host = root && root.host;
3868 if (host) {
3869 Polymer.dom(host).unobserveNodes(this._observer);
3870 }
3871 this._observer = null;
3872 }
3873 });
3874 }
3875 }());
3876 (function () {
3877 var hasDomApi = Polymer.DomApi.hasDomApi;
3545 Polymer.Base._addFeature({ 3878 Polymer.Base._addFeature({
3546 _prepShady: function () { 3879 _prepShady: function () {
3547 this._useContent = this._useContent || Boolean(this._template); 3880 this._useContent = this._useContent || Boolean(this._template);
3548 }, 3881 },
3549 _poolContent: function () { 3882 _poolContent: function () {
3550 if (this._useContent) { 3883 if (this._useContent) {
3551 saveLightChildrenIfNeeded(this); 3884 saveLightChildrenIfNeeded(this);
3552 } 3885 }
3553 }, 3886 },
3554 _setupRoot: function () { 3887 _setupRoot: function () {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3605 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { 3938 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
3606 c._distributeContent(); 3939 c._distributeContent();
3607 } 3940 }
3608 this.shadyRoot._dirtyRoots = []; 3941 this.shadyRoot._dirtyRoots = [];
3609 }, 3942 },
3610 _finishDistribute: function () { 3943 _finishDistribute: function () {
3611 if (this._useContent) { 3944 if (this._useContent) {
3612 this.shadyRoot._distributionClean = true; 3945 this.shadyRoot._distributionClean = true;
3613 if (hasInsertionPoint(this.shadyRoot)) { 3946 if (hasInsertionPoint(this.shadyRoot)) {
3614 this._composeTree(); 3947 this._composeTree();
3948 notifyContentObservers(this.shadyRoot);
3615 } else { 3949 } else {
3616 if (!this.shadyRoot._hasDistributed) { 3950 if (!this.shadyRoot._hasDistributed) {
3617 this.textContent = ''; 3951 this.textContent = '';
3618 this._composedChildren = null; 3952 this._composedChildren = null;
3619 this.appendChild(this.shadyRoot); 3953 this.appendChild(this.shadyRoot);
3620 } else { 3954 } else {
3621 var children = this._composeNode(this); 3955 var children = this._composeNode(this);
3622 this._updateChildNodes(this, children); 3956 this._updateChildNodes(this, children);
3623 } 3957 }
3624 } 3958 }
3959 if (!this.shadyRoot._hasDistributed) {
3960 notifyInitialDistribution(this);
3961 }
3625 this.shadyRoot._hasDistributed = true; 3962 this.shadyRoot._hasDistributed = true;
3626 } 3963 }
3627 }, 3964 },
3628 elementMatches: function (selector, node) { 3965 elementMatches: function (selector, node) {
3629 node = node || this; 3966 node = node || this;
3630 return matchesSelector.call(node, selector); 3967 return matchesSelector.call(node, selector);
3631 }, 3968 },
3632 _resetDistribution: function () { 3969 _resetDistribution: function () {
3633 var children = getLightChildren(this); 3970 var children = getLightChildren(this);
3634 for (var i = 0; i < children.length; i++) { 3971 for (var i = 0; i < children.length; i++) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 } 4169 }
3833 function hostNeedsRedistribution(host) { 4170 function hostNeedsRedistribution(host) {
3834 var c$ = Polymer.dom(host).children; 4171 var c$ = Polymer.dom(host).children;
3835 for (var i = 0, c; i < c$.length; i++) { 4172 for (var i = 0, c; i < c$.length; i++) {
3836 c = c$[i]; 4173 c = c$[i];
3837 if (c.localName === 'content') { 4174 if (c.localName === 'content') {
3838 return host.domHost; 4175 return host.domHost;
3839 } 4176 }
3840 } 4177 }
3841 } 4178 }
4179 function notifyContentObservers(root) {
4180 for (var i = 0, c; i < root._insertionPoints.length; i++) {
4181 c = root._insertionPoints[i];
4182 if (hasDomApi(c)) {
4183 Polymer.dom(c).notifyObserver();
4184 }
4185 }
4186 }
4187 function notifyInitialDistribution(host) {
4188 if (hasDomApi(host)) {
4189 Polymer.dom(host).notifyObserver();
4190 }
4191 }
3842 var needsUpgrade = window.CustomElements && !CustomElements.useNative; 4192 var needsUpgrade = window.CustomElements && !CustomElements.useNative;
3843 function upgradeLightChildren(children) { 4193 function upgradeLightChildren(children) {
3844 if (needsUpgrade && children) { 4194 if (needsUpgrade && children) {
3845 for (var i = 0; i < children.length; i++) { 4195 for (var i = 0; i < children.length; i++) {
3846 CustomElements.upgrade(children[i]); 4196 CustomElements.upgrade(children[i]);
3847 } 4197 }
3848 } 4198 }
3849 } 4199 }
3850 }()); 4200 }());
3851 if (Polymer.Settings.useShadow) { 4201 if (Polymer.Settings.useShadow) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3897 Polymer.Annotations = { 4247 Polymer.Annotations = {
3898 parseAnnotations: function (template) { 4248 parseAnnotations: function (template) {
3899 var list = []; 4249 var list = [];
3900 var content = template._content || template.content; 4250 var content = template._content || template.content;
3901 this._parseNodeAnnotations(content, list); 4251 this._parseNodeAnnotations(content, list);
3902 return list; 4252 return list;
3903 }, 4253 },
3904 _parseNodeAnnotations: function (node, list) { 4254 _parseNodeAnnotations: function (node, list) {
3905 return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, li st) : this._parseElementAnnotations(node, list); 4255 return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, li st) : this._parseElementAnnotations(node, list);
3906 }, 4256 },
3907 _testEscape: function (value) { 4257 _bindingRegex: /([^{[]*)({{|\[\[)([^}\]]*)(?:]]|}})/g,
3908 var escape = value.slice(0, 2); 4258 _parseBindings: function (text) {
3909 if (escape === '{{' || escape === '[[') { 4259 var re = this._bindingRegex;
3910 return escape; 4260 var parts = [];
4261 var m, lastIndex;
4262 while ((m = re.exec(text)) !== null) {
4263 if (m[1]) {
4264 parts.push({ literal: m[1] });
4265 }
4266 var mode = m[2][0];
4267 var value = m[3].trim();
4268 var negate = false;
4269 if (value[0] == '!') {
4270 negate = true;
4271 value = value.substring(1).trim();
4272 }
4273 var customEvent, notifyEvent, colon;
4274 if (mode == '{' && (colon = value.indexOf('::')) > 0) {
4275 notifyEvent = value.substring(colon + 2);
4276 value = value.substring(0, colon);
4277 customEvent = true;
4278 }
4279 parts.push({
4280 compoundIndex: parts.length,
4281 value: value,
4282 mode: mode,
4283 negate: negate,
4284 event: notifyEvent,
4285 customEvent: customEvent
4286 });
4287 lastIndex = re.lastIndex;
4288 }
4289 if (lastIndex && lastIndex < text.length) {
4290 var literal = text.substring(lastIndex);
4291 if (literal) {
4292 parts.push({ literal: literal });
4293 }
4294 }
4295 if (parts.length) {
4296 return parts;
3911 } 4297 }
3912 }, 4298 },
4299 _literalFromParts: function (parts) {
4300 var s = '';
4301 for (var i = 0; i < parts.length; i++) {
4302 var literal = parts[i].literal;
4303 s += literal || '';
4304 }
4305 return s;
4306 },
3913 _parseTextNodeAnnotation: function (node, list) { 4307 _parseTextNodeAnnotation: function (node, list) {
3914 var v = node.textContent; 4308 var parts = this._parseBindings(node.textContent);
3915 var escape = this._testEscape(v); 4309 if (parts) {
3916 if (escape) { 4310 node.textContent = this._literalFromParts(parts) || ' ';
3917 node.textContent = ' ';
3918 var annote = { 4311 var annote = {
3919 bindings: [{ 4312 bindings: [{
3920 kind: 'text', 4313 kind: 'text',
3921 mode: escape[0], 4314 name: 'textContent',
3922 value: v.slice(2, -2).trim() 4315 parts: parts,
4316 isCompound: parts.length !== 1
3923 }] 4317 }]
3924 }; 4318 };
3925 list.push(annote); 4319 list.push(annote);
3926 return annote; 4320 return annote;
3927 } 4321 }
3928 }, 4322 },
3929 _parseElementAnnotations: function (element, list) { 4323 _parseElementAnnotations: function (element, list) {
3930 var annote = { 4324 var annote = {
3931 bindings: [], 4325 bindings: [],
3932 events: [] 4326 events: []
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3974 content.appendChild(node.content); 4368 content.appendChild(node.content);
3975 list.push({ 4369 list.push({
3976 bindings: Polymer.nar, 4370 bindings: Polymer.nar,
3977 events: Polymer.nar, 4371 events: Polymer.nar,
3978 templateContent: content, 4372 templateContent: content,
3979 parent: parent, 4373 parent: parent,
3980 index: index 4374 index: index
3981 }); 4375 });
3982 }, 4376 },
3983 _parseNodeAttributeAnnotations: function (node, annotation) { 4377 _parseNodeAttributeAnnotations: function (node, annotation) {
3984 for (var i = node.attributes.length - 1, a; a = node.attributes[i]; i--) { 4378 var attrs = Array.prototype.slice.call(node.attributes);
3985 var n = a.name, v = a.value; 4379 for (var i = attrs.length - 1, a; a = attrs[i]; i--) {
3986 if (n === 'id' && !this._testEscape(v)) { 4380 var n = a.name;
3987 annotation.id = v; 4381 var v = a.value;
3988 } else if (n.slice(0, 3) === 'on-') { 4382 var b;
4383 if (n.slice(0, 3) === 'on-') {
3989 node.removeAttribute(n); 4384 node.removeAttribute(n);
3990 annotation.events.push({ 4385 annotation.events.push({
3991 name: n.slice(3), 4386 name: n.slice(3),
3992 value: v 4387 value: v
3993 }); 4388 });
3994 } else { 4389 } else if (b = this._parseNodeAttributeAnnotation(node, n, v)) {
3995 var b = this._parseNodeAttributeAnnotation(node, n, v);
3996 if (b) {
3997 annotation.bindings.push(b); 4390 annotation.bindings.push(b);
3998 } 4391 } else if (n === 'id') {
4392 annotation.id = v;
3999 } 4393 }
4000 } 4394 }
4001 }, 4395 },
4002 _parseNodeAttributeAnnotation: function (node, n, v) { 4396 _parseNodeAttributeAnnotation: function (node, name, value) {
4003 var escape = this._testEscape(v); 4397 var parts = this._parseBindings(value);
4004 if (escape) { 4398 if (parts) {
4005 var customEvent; 4399 var origName = name;
4006 var name = n;
4007 var mode = escape[0];
4008 v = v.slice(2, -2).trim();
4009 var not = false;
4010 if (v[0] == '!') {
4011 v = v.substring(1);
4012 not = true;
4013 }
4014 var kind = 'property'; 4400 var kind = 'property';
4015 if (n[n.length - 1] == '$') { 4401 if (name[name.length - 1] == '$') {
4016 name = n.slice(0, -1); 4402 name = name.slice(0, -1);
4017 kind = 'attribute'; 4403 kind = 'attribute';
4018 } 4404 }
4019 var notifyEvent, colon; 4405 var literal = this._literalFromParts(parts);
4020 if (mode == '{' && (colon = v.indexOf('::')) > 0) { 4406 if (literal && kind == 'attribute') {
4021 notifyEvent = v.substring(colon + 2); 4407 node.setAttribute(name, literal);
4022 v = v.substring(0, colon);
4023 customEvent = true;
4024 } 4408 }
4025 if (node.localName == 'input' && n == 'value') { 4409 if (node.localName == 'input' && name == 'value') {
4026 node.setAttribute(n, ''); 4410 node.setAttribute(origName, '');
4027 } 4411 }
4028 node.removeAttribute(n); 4412 node.removeAttribute(origName);
4029 if (kind === 'property') { 4413 if (kind === 'property') {
4030 name = Polymer.CaseMap.dashToCamelCase(name); 4414 name = Polymer.CaseMap.dashToCamelCase(name);
4031 } 4415 }
4032 return { 4416 return {
4033 kind: kind, 4417 kind: kind,
4034 mode: mode,
4035 name: name, 4418 name: name,
4036 value: v, 4419 parts: parts,
4037 negate: not, 4420 literal: literal,
4038 event: notifyEvent, 4421 isCompound: parts.length !== 1
4039 customEvent: customEvent
4040 }; 4422 };
4041 } 4423 }
4042 }, 4424 },
4043 _localSubTree: function (node, host) { 4425 _localSubTree: function (node, host) {
4044 return node === host ? node.childNodes : node._lightChildren || node.childNodes; 4426 return node === host ? node.childNodes : node._lightChildren || node.childNodes;
4045 }, 4427 },
4046 findAnnotatedNode: function (root, annote) { 4428 findAnnotatedNode: function (root, annote) {
4047 var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote .parent); 4429 var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote .parent);
4048 return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.i ndex]; 4430 return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.i ndex];
4049 } 4431 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 } 4502 }
4121 this._processAnnotations(this._notes); 4503 this._processAnnotations(this._notes);
4122 Polymer.Annotations.prepElement = null; 4504 Polymer.Annotations.prepElement = null;
4123 } 4505 }
4124 }, 4506 },
4125 _processAnnotations: function (notes) { 4507 _processAnnotations: function (notes) {
4126 for (var i = 0; i < notes.length; i++) { 4508 for (var i = 0; i < notes.length; i++) {
4127 var note = notes[i]; 4509 var note = notes[i];
4128 for (var j = 0; j < note.bindings.length; j++) { 4510 for (var j = 0; j < note.bindings.length; j++) {
4129 var b = note.bindings[j]; 4511 var b = note.bindings[j];
4130 b.signature = this._parseMethod(b.value); 4512 for (var k = 0; k < b.parts.length; k++) {
4131 if (!b.signature) { 4513 var p = b.parts[k];
4132 b.model = this._modelForPath(b.value); 4514 if (!p.literal) {
4515 p.signature = this._parseMethod(p.value);
4516 if (!p.signature) {
4517 p.model = this._modelForPath(p.value);
4518 }
4519 }
4133 } 4520 }
4134 } 4521 }
4135 if (note.templateContent) { 4522 if (note.templateContent) {
4136 this._processAnnotations(note.templateContent._notes); 4523 this._processAnnotations(note.templateContent._notes);
4137 var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(n ote.templateContent._notes); 4524 var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(n ote.templateContent._notes);
4138 var bindings = []; 4525 var bindings = [];
4139 for (var prop in pp) { 4526 for (var prop in pp) {
4140 bindings.push({ 4527 bindings.push({
4141 index: note.index, 4528 index: note.index,
4142 kind: 'property', 4529 kind: 'property',
4530 name: '_parent_' + prop,
4531 parts: [{
4143 mode: '{', 4532 mode: '{',
4144 name: '_parent_' + prop,
4145 model: prop, 4533 model: prop,
4146 value: prop 4534 value: prop
4535 }]
4147 }); 4536 });
4148 } 4537 }
4149 note.bindings = note.bindings.concat(bindings); 4538 note.bindings = note.bindings.concat(bindings);
4150 } 4539 }
4151 } 4540 }
4152 }, 4541 },
4153 _discoverTemplateParentProps: function (notes) { 4542 _discoverTemplateParentProps: function (notes) {
4154 var pp = {}; 4543 var pp = {};
4155 notes.forEach(function (n) { 4544 notes.forEach(function (n) {
4156 n.bindings.forEach(function (b) { 4545 n.bindings.forEach(function (b) {
4157 if (b.signature) { 4546 b.parts.forEach(function (p) {
4158 var args = b.signature.args; 4547 if (p.signature) {
4548 var args = p.signature.args;
4159 for (var k = 0; k < args.length; k++) { 4549 for (var k = 0; k < args.length; k++) {
4160 pp[args[k].model] = true; 4550 pp[args[k].model] = true;
4161 } 4551 }
4162 } else { 4552 } else {
4163 pp[b.model] = true; 4553 pp[p.model] = true;
4164 } 4554 }
4165 }); 4555 });
4556 });
4166 if (n.templateContent) { 4557 if (n.templateContent) {
4167 var tpp = n.templateContent._parentProps; 4558 var tpp = n.templateContent._parentProps;
4168 Polymer.Base.mixin(pp, tpp); 4559 Polymer.Base.mixin(pp, tpp);
4169 } 4560 }
4170 }); 4561 });
4171 return pp; 4562 return pp;
4172 }, 4563 },
4173 _prepElement: function (element) { 4564 _prepElement: function (element) {
4174 Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument); 4565 Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
4175 }, 4566 },
4176 _findAnnotatedNode: Polymer.Annotations.findAnnotatedNode, 4567 _findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
4177 _marshalAnnotationReferences: function () { 4568 _marshalAnnotationReferences: function () {
4178 if (this._template) { 4569 if (this._template) {
4179 this._marshalIdNodes(); 4570 this._marshalIdNodes();
4180 this._marshalAnnotatedNodes(); 4571 this._marshalAnnotatedNodes();
4181 this._marshalAnnotatedListeners(); 4572 this._marshalAnnotatedListeners();
4182 } 4573 }
4183 }, 4574 },
4184 _configureAnnotationReferences: function () { 4575 _configureAnnotationReferences: function (config) {
4185 this._configureTemplateContent(); 4576 var notes = this._notes;
4577 var nodes = this._nodes;
4578 for (var i = 0; i < notes.length; i++) {
4579 var note = notes[i];
4580 var node = nodes[i];
4581 this._configureTemplateContent(note, node);
4582 this._configureCompoundBindings(note, node);
4583 }
4186 }, 4584 },
4187 _configureTemplateContent: function () { 4585 _configureTemplateContent: function (note, node) {
4188 this._notes.forEach(function (note, i) {
4189 if (note.templateContent) { 4586 if (note.templateContent) {
4190 this._nodes[i]._content = note.templateContent; 4587 node._content = note.templateContent;
4191 } 4588 }
4192 }, this); 4589 },
4590 _configureCompoundBindings: function (note, node) {
4591 var bindings = note.bindings;
4592 for (var i = 0; i < bindings.length; i++) {
4593 var binding = bindings[i];
4594 if (binding.isCompound) {
4595 var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {});
4596 var parts = binding.parts;
4597 var literals = new Array(parts.length);
4598 for (var j = 0; j < parts.length; j++) {
4599 literals[j] = parts[j].literal;
4600 }
4601 var name = binding.name;
4602 storage[name] = literals;
4603 if (binding.literal && binding.kind == 'property') {
4604 if (node._configValue) {
4605 node._configValue(name, binding.literal);
4606 } else {
4607 node[name] = binding.literal;
4608 }
4609 }
4610 }
4611 }
4193 }, 4612 },
4194 _marshalIdNodes: function () { 4613 _marshalIdNodes: function () {
4195 this.$ = {}; 4614 this.$ = {};
4196 this._notes.forEach(function (a) { 4615 this._notes.forEach(function (a) {
4197 if (a.id) { 4616 if (a.id) {
4198 this.$[a.id] = this._findAnnotatedNode(this.root, a); 4617 this.$[a.id] = this._findAnnotatedNode(this.root, a);
4199 } 4618 }
4200 }, this); 4619 }, this);
4201 }, 4620 },
4202 _marshalAnnotatedNodes: function () { 4621 _marshalAnnotatedNodes: function () {
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
4974 this._lastVal += i; 5393 this._lastVal += i;
4975 this._twiddle.textContent = this._twiddleContent++; 5394 this._twiddle.textContent = this._twiddleContent++;
4976 throw e; 5395 throw e;
4977 } 5396 }
4978 } 5397 }
4979 } 5398 }
4980 this._callbacks.splice(0, len); 5399 this._callbacks.splice(0, len);
4981 this._lastVal += len; 5400 this._lastVal += len;
4982 } 5401 }
4983 }; 5402 };
4984 new (window.MutationObserver || JsMutationObserver)(Polymer.Async._atEndOfMicrot ask.bind(Polymer.Async)).observe(Polymer.Async._twiddle, { characterData: true } ); 5403 new window.MutationObserver(function () {
5404 Polymer.Async._atEndOfMicrotask();
5405 }).observe(Polymer.Async._twiddle, { characterData: true });
4985 Polymer.Debounce = function () { 5406 Polymer.Debounce = function () {
4986 var Async = Polymer.Async; 5407 var Async = Polymer.Async;
4987 var Debouncer = function (context) { 5408 var Debouncer = function (context) {
4988 this.context = context; 5409 this.context = context;
4989 this.boundComplete = this.complete.bind(this); 5410 this.boundComplete = this.complete.bind(this);
4990 }; 5411 };
4991 Debouncer.prototype = { 5412 Debouncer.prototype = {
4992 go: function (callback, wait) { 5413 go: function (callback, wait) {
4993 var h; 5414 var h;
4994 this.finish = function () { 5415 this.finish = function () {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
5056 } 5477 }
5057 }, 5478 },
5058 attributeFollows: function (name, toElement, fromElement) { 5479 attributeFollows: function (name, toElement, fromElement) {
5059 if (fromElement) { 5480 if (fromElement) {
5060 Polymer.dom(fromElement).removeAttribute(name); 5481 Polymer.dom(fromElement).removeAttribute(name);
5061 } 5482 }
5062 if (toElement) { 5483 if (toElement) {
5063 Polymer.dom(toElement).setAttribute(name, ''); 5484 Polymer.dom(toElement).setAttribute(name, '');
5064 } 5485 }
5065 }, 5486 },
5487 getEffectiveChildNodes: function () {
5488 return Polymer.dom(this).getEffectiveChildNodes();
5489 },
5490 getEffectiveChildren: function () {
5491 var list = Polymer.dom(this).getEffectiveChildNodes();
5492 return list.filter(function (n) {
5493 return n.nodeType === Node.ELEMENT_NODE;
5494 });
5495 },
5496 getEffectiveTextContent: function () {
5497 var cn = this.getEffectiveChildNodes();
5498 var tc = [];
5499 for (var i = 0, c; c = cn[i]; i++) {
5500 if (c.nodeType !== Node.COMMENT_NODE) {
5501 tc.push(Polymer.dom(c).textContent);
5502 }
5503 }
5504 return tc.join('');
5505 },
5506 queryEffectiveChildren: function (slctr) {
5507 var e$ = Polymer.dom(this).queryDistributedElements(slctr);
5508 return e$ && e$[0];
5509 },
5510 queryAllEffectiveChildren: function (slctr) {
5511 return Polymer.dom(this).queryAllDistributedElements(slctr);
5512 },
5066 getContentChildNodes: function (slctr) { 5513 getContentChildNodes: function (slctr) {
5067 var content = Polymer.dom(this.root).querySelector(slctr || 'content'); 5514 var content = Polymer.dom(this.root).querySelector(slctr || 'content');
5068 return content ? Polymer.dom(content).getDistributedNodes() : []; 5515 return content ? Polymer.dom(content).getDistributedNodes() : [];
5069 }, 5516 },
5070 getContentChildren: function (slctr) { 5517 getContentChildren: function (slctr) {
5071 return this.getContentChildNodes(slctr).filter(function (n) { 5518 return this.getContentChildNodes(slctr).filter(function (n) {
5072 return n.nodeType === Node.ELEMENT_NODE; 5519 return n.nodeType === Node.ELEMENT_NODE;
5073 }); 5520 });
5074 }, 5521 },
5075 fire: function (type, detail, options) { 5522 fire: function (type, detail, options) {
(...skipping 17 matching lines...) Expand all
5093 Polymer.Async.cancel(handle); 5540 Polymer.Async.cancel(handle);
5094 }, 5541 },
5095 arrayDelete: function (path, item) { 5542 arrayDelete: function (path, item) {
5096 var index; 5543 var index;
5097 if (Array.isArray(path)) { 5544 if (Array.isArray(path)) {
5098 index = path.indexOf(item); 5545 index = path.indexOf(item);
5099 if (index >= 0) { 5546 if (index >= 0) {
5100 return path.splice(index, 1); 5547 return path.splice(index, 1);
5101 } 5548 }
5102 } else { 5549 } else {
5103 var arr = this.get(path); 5550 var arr = this._get(path);
5104 index = arr.indexOf(item); 5551 index = arr.indexOf(item);
5105 if (index >= 0) { 5552 if (index >= 0) {
5106 return this.splice(path, index, 1); 5553 return this.splice(path, index, 1);
5107 } 5554 }
5108 } 5555 }
5109 }, 5556 },
5110 transform: function (transform, node) { 5557 transform: function (transform, node) {
5111 node = node || this; 5558 node = node || this;
5112 node.style.webkitTransform = transform; 5559 node.style.webkitTransform = transform;
5113 node.style.transform = transform; 5560 node.style.transform = transform;
(...skipping 18 matching lines...) Expand all
5132 create: function (tag, props) { 5579 create: function (tag, props) {
5133 var elt = document.createElement(tag); 5580 var elt = document.createElement(tag);
5134 if (props) { 5581 if (props) {
5135 for (var n in props) { 5582 for (var n in props) {
5136 elt[n] = props[n]; 5583 elt[n] = props[n];
5137 } 5584 }
5138 } 5585 }
5139 return elt; 5586 return elt;
5140 }, 5587 },
5141 isLightDescendant: function (node) { 5588 isLightDescendant: function (node) {
5142 return this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(n ode).getOwnerRoot(); 5589 return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
5143 }, 5590 },
5144 isLocalDescendant: function (node) { 5591 isLocalDescendant: function (node) {
5145 return this.root === Polymer.dom(node).getOwnerRoot(); 5592 return this.root === Polymer.dom(node).getOwnerRoot();
5146 } 5593 }
5147 }); 5594 });
5148 Polymer.Bind = { 5595 Polymer.Bind = {
5149 prepareModel: function (model) { 5596 prepareModel: function (model) {
5150 model._propertyEffects = {}; 5597 model._propertyEffects = {};
5151 model._bindListeners = []; 5598 model._bindListeners = [];
5152 Polymer.Base.mixin(model, this._modelApi); 5599 Polymer.Base.mixin(model, this._modelApi);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5275 _isStructured: function (path) { 5722 _isStructured: function (path) {
5276 return path.indexOf('.') > 0; 5723 return path.indexOf('.') > 0;
5277 }, 5724 },
5278 _isEventBogus: function (e, target) { 5725 _isEventBogus: function (e, target) {
5279 return e.path && e.path[0] !== target; 5726 return e.path && e.path[0] !== target;
5280 }, 5727 },
5281 _notedListenerFactory: function (property, path, isStructured, bogusTest) { 5728 _notedListenerFactory: function (property, path, isStructured, bogusTest) {
5282 return function (e, target) { 5729 return function (e, target) {
5283 if (!bogusTest(e, target)) { 5730 if (!bogusTest(e, target)) {
5284 if (e.detail && e.detail.path) { 5731 if (e.detail && e.detail.path) {
5285 this.notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value); 5732 this._notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);
5286 } else { 5733 } else {
5287 var value = target[property]; 5734 var value = target[property];
5288 if (!isStructured) { 5735 if (!isStructured) {
5289 this[path] = target[property]; 5736 this[path] = target[property];
5290 } else { 5737 } else {
5291 if (this.__data__[path] != value) { 5738 if (this.__data__[path] != value) {
5292 this.set(path, value); 5739 this.set(path, value);
5293 } 5740 }
5294 } 5741 }
5295 } 5742 }
5296 } 5743 }
5297 }; 5744 };
5298 }, 5745 },
5299 prepareInstance: function (inst) { 5746 prepareInstance: function (inst) {
5300 inst.__data__ = Object.create(null); 5747 inst.__data__ = Object.create(null);
5301 }, 5748 },
5302 setupBindListeners: function (inst) { 5749 setupBindListeners: function (inst) {
5303 inst._bindListeners.forEach(function (info) { 5750 inst._bindListeners.forEach(function (info) {
5304 var node = inst._nodes[info.index]; 5751 var node = inst._nodes[info.index];
5305 node.addEventListener(info.event, inst._notifyListener.bind(inst, info.changedFn )); 5752 node.addEventListener(info.event, inst._notifyListener.bind(inst, info.changedFn ));
5306 }); 5753 });
5307 } 5754 }
5308 }; 5755 };
5309 Polymer.Base.extend(Polymer.Bind, { 5756 Polymer.Base.extend(Polymer.Bind, {
5310 _shouldAddListener: function (effect) { 5757 _shouldAddListener: function (effect) {
5311 return effect.name && effect.mode === '{' && !effect.negate && effect.kind != 'a ttribute'; 5758 return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !ef fect.isCompound && effect.parts[0].mode === '{' && !effect.parts[0].negate;
5312 }, 5759 },
5313 _annotationEffect: function (source, value, effect) { 5760 _annotationEffect: function (source, value, effect) {
5314 if (source != effect.value) { 5761 if (source != effect.value) {
5315 value = this.get(effect.value); 5762 value = this._get(effect.value);
5316 this.__data__[effect.value] = value; 5763 this.__data__[effect.value] = value;
5317 } 5764 }
5318 var calc = effect.negate ? !value : value; 5765 var calc = effect.negate ? !value : value;
5319 if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) { 5766 if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
5320 return this._applyEffectValue(calc, effect); 5767 return this._applyEffectValue(effect, calc);
5321 } 5768 }
5322 }, 5769 },
5323 _reflectEffect: function (source) { 5770 _reflectEffect: function (source) {
5324 this.reflectPropertyToAttribute(source); 5771 this.reflectPropertyToAttribute(source);
5325 }, 5772 },
5326 _notifyEffect: function (source, value, effect, old, fromAbove) { 5773 _notifyEffect: function (source, value, effect, old, fromAbove) {
5327 if (!fromAbove) { 5774 if (!fromAbove) {
5328 this._notifyChange(source); 5775 this._notifyChange(source);
5329 } 5776 }
5330 }, 5777 },
(...skipping 17 matching lines...) Expand all
5348 } 5795 }
5349 } else { 5796 } else {
5350 this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.met hod + '` not defined')); 5797 this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.met hod + '` not defined'));
5351 } 5798 }
5352 }, 5799 },
5353 _computeEffect: function (source, value, effect) { 5800 _computeEffect: function (source, value, effect) {
5354 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); 5801 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
5355 if (args) { 5802 if (args) {
5356 var fn = this[effect.method]; 5803 var fn = this[effect.method];
5357 if (fn) { 5804 if (fn) {
5358 this.__setProperty(effect.property, fn.apply(this, args)); 5805 this.__setProperty(effect.name, fn.apply(this, args));
5359 } else { 5806 } else {
5360 this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined')); 5807 this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
5361 } 5808 }
5362 } 5809 }
5363 }, 5810 },
5364 _annotatedComputationEffect: function (source, value, effect) { 5811 _annotatedComputationEffect: function (source, value, effect) {
5365 var computedHost = this._rootDataHost || this; 5812 var computedHost = this._rootDataHost || this;
5366 var fn = computedHost[effect.method]; 5813 var fn = computedHost[effect.method];
5367 if (fn) { 5814 if (fn) {
5368 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); 5815 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
5369 if (args) { 5816 if (args) {
5370 var computedvalue = fn.apply(computedHost, args); 5817 var computedvalue = fn.apply(computedHost, args);
5371 if (effect.negate) { 5818 if (effect.negate) {
5372 computedvalue = !computedvalue; 5819 computedvalue = !computedvalue;
5373 } 5820 }
5374 this._applyEffectValue(computedvalue, effect); 5821 this._applyEffectValue(effect, computedvalue);
5375 } 5822 }
5376 } else { 5823 } else {
5377 computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute me thod `' + effect.method + '` not defined')); 5824 computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute me thod `' + effect.method + '` not defined'));
5378 } 5825 }
5379 }, 5826 },
5380 _marshalArgs: function (model, effect, path, value) { 5827 _marshalArgs: function (model, effect, path, value) {
5381 var values = []; 5828 var values = [];
5382 var args = effect.args; 5829 var args = effect.args;
5383 for (var i = 0, l = args.length; i < l; i++) { 5830 for (var i = 0, l = args.length; i < l; i++) {
5384 var arg = args[i]; 5831 var arg = args[i];
5385 var name = arg.name; 5832 var name = arg.name;
5386 var v; 5833 var v;
5387 if (arg.literal) { 5834 if (arg.literal) {
5388 v = arg.value; 5835 v = arg.value;
5389 } else if (arg.structured) { 5836 } else if (arg.structured) {
5390 v = Polymer.Base.get(name, model); 5837 v = Polymer.Base._get(name, model);
5391 } else { 5838 } else {
5392 v = model[name]; 5839 v = model[name];
5393 } 5840 }
5394 if (args.length > 1 && v === undefined) { 5841 if (args.length > 1 && v === undefined) {
5395 return; 5842 return;
5396 } 5843 }
5397 if (arg.wildcard) { 5844 if (arg.wildcard) {
5398 var baseChanged = name.indexOf(path + '.') === 0; 5845 var baseChanged = name.indexOf(path + '.') === 0;
5399 var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged; 5846 var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;
5400 values[i] = { 5847 values[i] = {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5443 } 5890 }
5444 } 5891 }
5445 }, 5892 },
5446 _addComputedEffect: function (name, expression) { 5893 _addComputedEffect: function (name, expression) {
5447 var sig = this._parseMethod(expression); 5894 var sig = this._parseMethod(expression);
5448 sig.args.forEach(function (arg) { 5895 sig.args.forEach(function (arg) {
5449 this._addPropertyEffect(arg.model, 'compute', { 5896 this._addPropertyEffect(arg.model, 'compute', {
5450 method: sig.method, 5897 method: sig.method,
5451 args: sig.args, 5898 args: sig.args,
5452 trigger: arg, 5899 trigger: arg,
5453 property: name 5900 name: name
5454 }); 5901 });
5455 }, this); 5902 }, this);
5456 }, 5903 },
5457 _addObserverEffect: function (property, observer) { 5904 _addObserverEffect: function (property, observer) {
5458 this._addPropertyEffect(property, 'observer', { 5905 this._addPropertyEffect(property, 'observer', {
5459 method: observer, 5906 method: observer,
5460 property: property 5907 property: property
5461 }); 5908 });
5462 }, 5909 },
5463 _addComplexObserverEffects: function (observers) { 5910 _addComplexObserverEffects: function (observers) {
(...skipping 17 matching lines...) Expand all
5481 this._nodes = []; 5928 this._nodes = [];
5482 notes.forEach(function (note) { 5929 notes.forEach(function (note) {
5483 var index = this._nodes.push(note) - 1; 5930 var index = this._nodes.push(note) - 1;
5484 note.bindings.forEach(function (binding) { 5931 note.bindings.forEach(function (binding) {
5485 this._addAnnotationEffect(binding, index); 5932 this._addAnnotationEffect(binding, index);
5486 }, this); 5933 }, this);
5487 }, this); 5934 }, this);
5488 }, 5935 },
5489 _addAnnotationEffect: function (note, index) { 5936 _addAnnotationEffect: function (note, index) {
5490 if (Polymer.Bind._shouldAddListener(note)) { 5937 if (Polymer.Bind._shouldAddListener(note)) {
5491 Polymer.Bind._addAnnotatedListener(this, index, note.name, note.value, note.even t); 5938 Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event);
5492 } 5939 }
5493 if (note.signature) { 5940 for (var i = 0; i < note.parts.length; i++) {
5494 this._addAnnotatedComputationEffect(note, index); 5941 var part = note.parts[i];
5495 } else { 5942 if (part.signature) {
5496 note.index = index; 5943 this._addAnnotatedComputationEffect(note, part, index);
5497 this._addPropertyEffect(note.model, 'annotation', note); 5944 } else if (!part.literal) {
5945 this._addPropertyEffect(part.model, 'annotation', {
5946 kind: note.kind,
5947 index: index,
5948 name: note.name,
5949 value: part.value,
5950 isCompound: note.isCompound,
5951 compoundIndex: part.compoundIndex,
5952 event: part.event,
5953 customEvent: part.customEvent,
5954 negate: part.negate
5955 });
5956 }
5498 } 5957 }
5499 }, 5958 },
5500 _addAnnotatedComputationEffect: function (note, index) { 5959 _addAnnotatedComputationEffect: function (note, part, index) {
5501 var sig = note.signature; 5960 var sig = part.signature;
5502 if (sig.static) { 5961 if (sig.static) {
5503 this.__addAnnotatedComputationEffect('__static__', index, note, sig, null); 5962 this.__addAnnotatedComputationEffect('__static__', index, note, part, null);
5504 } else { 5963 } else {
5505 sig.args.forEach(function (arg) { 5964 sig.args.forEach(function (arg) {
5506 if (!arg.literal) { 5965 if (!arg.literal) {
5507 this.__addAnnotatedComputationEffect(arg.model, index, note, sig, arg); 5966 this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg);
5508 } 5967 }
5509 }, this); 5968 }, this);
5510 } 5969 }
5511 }, 5970 },
5512 __addAnnotatedComputationEffect: function (property, index, note, sig, trigger) { 5971 __addAnnotatedComputationEffect: function (property, index, note, part, trigger) {
5513 this._addPropertyEffect(property, 'annotatedComputation', { 5972 this._addPropertyEffect(property, 'annotatedComputation', {
5514 index: index, 5973 index: index,
5974 isCompound: note.isCompound,
5975 compoundIndex: part.compoundIndex,
5515 kind: note.kind, 5976 kind: note.kind,
5516 property: note.name, 5977 name: note.name,
5517 negate: note.negate, 5978 negate: part.negate,
5518 method: sig.method, 5979 method: part.signature.method,
5519 args: sig.args, 5980 args: part.signature.args,
5520 trigger: trigger 5981 trigger: trigger
5521 }); 5982 });
5522 }, 5983 },
5523 _parseMethod: function (expression) { 5984 _parseMethod: function (expression) {
5524 var m = expression.match(/([^\s]+)\((.*)\)/); 5985 var m = expression.match(/([^\s]+)\((.*)\)/);
5525 if (m) { 5986 if (m) {
5526 var sig = { 5987 var sig = {
5527 method: m[1], 5988 method: m[1],
5528 static: true 5989 static: true
5529 }; 5990 };
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
5578 a.name = arg.slice(0, -2); 6039 a.name = arg.slice(0, -2);
5579 } 6040 }
5580 } 6041 }
5581 } 6042 }
5582 return a; 6043 return a;
5583 }, 6044 },
5584 _marshalInstanceEffects: function () { 6045 _marshalInstanceEffects: function () {
5585 Polymer.Bind.prepareInstance(this); 6046 Polymer.Bind.prepareInstance(this);
5586 Polymer.Bind.setupBindListeners(this); 6047 Polymer.Bind.setupBindListeners(this);
5587 }, 6048 },
5588 _applyEffectValue: function (value, info) { 6049 _applyEffectValue: function (info, value) {
5589 var node = this._nodes[info.index]; 6050 var node = this._nodes[info.index];
5590 var property = info.property || info.name || 'textContent'; 6051 var property = info.name;
6052 if (info.isCompound) {
6053 var storage = node.__compoundStorage__[property];
6054 storage[info.compoundIndex] = value;
6055 value = storage.join('');
6056 }
5591 if (info.kind == 'attribute') { 6057 if (info.kind == 'attribute') {
5592 this.serializeValueToAttribute(value, property, node); 6058 this.serializeValueToAttribute(value, property, node);
5593 } else { 6059 } else {
5594 if (property === 'className') { 6060 if (property === 'className') {
5595 value = this._scopeElementClass(node, value); 6061 value = this._scopeElementClass(node, value);
5596 } 6062 }
5597 if (property === 'textContent' || node.localName == 'input' && property == 'valu e') { 6063 if (property === 'textContent' || node.localName == 'input' && property == 'valu e') {
5598 value = value == undefined ? '' : value; 6064 value = value == undefined ? '' : value;
5599 } 6065 }
5600 return node[property] = value; 6066 return node[property] = value;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 } 6126 }
5661 } 6127 }
5662 }, 6128 },
5663 _distributeConfig: function (config) { 6129 _distributeConfig: function (config) {
5664 var fx$ = this._propertyEffects; 6130 var fx$ = this._propertyEffects;
5665 if (fx$) { 6131 if (fx$) {
5666 for (var p in config) { 6132 for (var p in config) {
5667 var fx = fx$[p]; 6133 var fx = fx$[p];
5668 if (fx) { 6134 if (fx) {
5669 for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) { 6135 for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
5670 if (x.kind === 'annotation') { 6136 if (x.kind === 'annotation' && !x.isCompound) {
5671 var node = this._nodes[x.effect.index]; 6137 var node = this._nodes[x.effect.index];
5672 if (node._configValue) { 6138 if (node._configValue) {
5673 var value = p === x.effect.value ? config[p] : this.get(x.effect.value, config); 6139 var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config) ;
5674 node._configValue(x.effect.name, value); 6140 node._configValue(x.effect.name, value);
5675 } 6141 }
5676 } 6142 }
5677 } 6143 }
5678 } 6144 }
5679 } 6145 }
5680 } 6146 }
5681 }, 6147 },
5682 _afterClientsReady: function () { 6148 _afterClientsReady: function () {
5683 this._executeStaticEffects(); 6149 this._executeStaticEffects();
(...skipping 26 matching lines...) Expand all
5710 for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) { 6176 for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
5711 h[0].call(this, h[1], h[2]); 6177 h[0].call(this, h[1], h[2]);
5712 } 6178 }
5713 this._handlers = []; 6179 this._handlers = [];
5714 } 6180 }
5715 }); 6181 });
5716 (function () { 6182 (function () {
5717 'use strict'; 6183 'use strict';
5718 Polymer.Base._addFeature({ 6184 Polymer.Base._addFeature({
5719 notifyPath: function (path, value, fromAbove) { 6185 notifyPath: function (path, value, fromAbove) {
6186 var info = {};
6187 this._get(path, this, info);
6188 this._notifyPath(info.path, value, fromAbove);
6189 },
6190 _notifyPath: function (path, value, fromAbove) {
5720 var old = this._propertySetter(path, value); 6191 var old = this._propertySetter(path, value);
5721 if (old !== value && (old === old || value === value)) { 6192 if (old !== value && (old === old || value === value)) {
5722 this._pathEffector(path, value); 6193 this._pathEffector(path, value);
5723 if (!fromAbove) { 6194 if (!fromAbove) {
5724 this._notifyPath(path, value); 6195 this._notifyPathUp(path, value);
5725 } 6196 }
5726 return true; 6197 return true;
5727 } 6198 }
5728 }, 6199 },
5729 _getPathParts: function (path) { 6200 _getPathParts: function (path) {
5730 if (Array.isArray(path)) { 6201 if (Array.isArray(path)) {
5731 var parts = []; 6202 var parts = [];
5732 for (var i = 0; i < path.length; i++) { 6203 for (var i = 0; i < path.length; i++) {
5733 var args = path[i].toString().split('.'); 6204 var args = path[i].toString().split('.');
5734 for (var j = 0; j < args.length; j++) { 6205 for (var j = 0; j < args.length; j++) {
5735 parts.push(args[j]); 6206 parts.push(args[j]);
5736 } 6207 }
5737 } 6208 }
5738 return parts; 6209 return parts;
5739 } else { 6210 } else {
5740 return path.toString().split('.'); 6211 return path.toString().split('.');
5741 } 6212 }
5742 }, 6213 },
5743 set: function (path, value, root) { 6214 set: function (path, value, root) {
5744 var prop = root || this; 6215 var prop = root || this;
5745 var parts = this._getPathParts(path); 6216 var parts = this._getPathParts(path);
5746 var array; 6217 var array;
5747 var last = parts[parts.length - 1]; 6218 var last = parts[parts.length - 1];
5748 if (parts.length > 1) { 6219 if (parts.length > 1) {
5749 for (var i = 0; i < parts.length - 1; i++) { 6220 for (var i = 0; i < parts.length - 1; i++) {
5750 var part = parts[i]; 6221 var part = parts[i];
6222 if (array && part[0] == '#') {
6223 prop = Polymer.Collection.get(array).getItem(part);
6224 } else {
5751 prop = prop[part]; 6225 prop = prop[part];
5752 if (array && parseInt(part) == part) { 6226 if (array && parseInt(part, 10) == part) {
5753 parts[i] = Polymer.Collection.get(array).getKey(prop); 6227 parts[i] = Polymer.Collection.get(array).getKey(prop);
5754 } 6228 }
6229 }
5755 if (!prop) { 6230 if (!prop) {
5756 return; 6231 return;
5757 } 6232 }
5758 array = Array.isArray(prop) ? prop : null; 6233 array = Array.isArray(prop) ? prop : null;
5759 } 6234 }
5760 if (array && parseInt(last) == last) { 6235 if (array) {
5761 var coll = Polymer.Collection.get(array); 6236 var coll = Polymer.Collection.get(array);
6237 if (last[0] == '#') {
6238 var key = last;
6239 var old = coll.getItem(key);
6240 last = array.indexOf(old);
6241 coll.setItem(key, value);
6242 } else if (parseInt(last, 10) == last) {
5762 var old = prop[last]; 6243 var old = prop[last];
5763 var key = coll.getKey(old); 6244 var key = coll.getKey(old);
5764 parts[i] = key; 6245 parts[i] = key;
5765 coll.setItem(key, value); 6246 coll.setItem(key, value);
5766 } 6247 }
6248 }
5767 prop[last] = value; 6249 prop[last] = value;
5768 if (!root) { 6250 if (!root) {
5769 this.notifyPath(parts.join('.'), value); 6251 this._notifyPath(parts.join('.'), value);
5770 } 6252 }
5771 } else { 6253 } else {
5772 prop[path] = value; 6254 prop[path] = value;
5773 } 6255 }
5774 }, 6256 },
5775 get: function (path, root) { 6257 get: function (path, root) {
6258 return this._get(path, root);
6259 },
6260 _get: function (path, root, info) {
5776 var prop = root || this; 6261 var prop = root || this;
5777 var parts = this._getPathParts(path); 6262 var parts = this._getPathParts(path);
5778 var last = parts.pop(); 6263 var array;
5779 while (parts.length) { 6264 for (var i = 0; i < parts.length; i++) {
5780 prop = prop[parts.shift()];
5781 if (!prop) { 6265 if (!prop) {
5782 return; 6266 return;
5783 } 6267 }
6268 var part = parts[i];
6269 if (array && part[0] == '#') {
6270 prop = Polymer.Collection.get(array).getItem(part);
6271 } else {
6272 prop = prop[part];
6273 if (info && array && parseInt(part, 10) == part) {
6274 parts[i] = Polymer.Collection.get(array).getKey(prop);
5784 } 6275 }
5785 return prop[last]; 6276 }
6277 array = Array.isArray(prop) ? prop : null;
6278 }
6279 if (info) {
6280 info.path = parts.join('.');
6281 }
6282 return prop;
5786 }, 6283 },
5787 _pathEffector: function (path, value) { 6284 _pathEffector: function (path, value) {
5788 var model = this._modelForPath(path); 6285 var model = this._modelForPath(path);
5789 var fx$ = this._propertyEffects[model]; 6286 var fx$ = this._propertyEffects[model];
5790 if (fx$) { 6287 if (fx$) {
5791 fx$.forEach(function (fx) { 6288 fx$.forEach(function (fx) {
5792 var fxFn = this['_' + fx.kind + 'PathEffect']; 6289 var fxFn = this['_' + fx.kind + 'PathEffect'];
5793 if (fxFn) { 6290 if (fxFn) {
5794 fxFn.call(this, path, value, fx.effect); 6291 fxFn.call(this, path, value, fx.effect);
5795 } 6292 }
5796 }, this); 6293 }, this);
5797 } 6294 }
5798 if (this._boundPaths) { 6295 if (this._boundPaths) {
5799 this._notifyBoundPaths(path, value); 6296 this._notifyBoundPaths(path, value);
5800 } 6297 }
5801 }, 6298 },
5802 _annotationPathEffect: function (path, value, effect) { 6299 _annotationPathEffect: function (path, value, effect) {
5803 if (effect.value === path || effect.value.indexOf(path + '.') === 0) { 6300 if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
5804 Polymer.Bind._annotationEffect.call(this, path, value, effect); 6301 Polymer.Bind._annotationEffect.call(this, path, value, effect);
5805 } else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) { 6302 } else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
5806 var node = this._nodes[effect.index]; 6303 var node = this._nodes[effect.index];
5807 if (node && node.notifyPath) { 6304 if (node && node._notifyPath) {
5808 var p = this._fixPath(effect.name, effect.value, path); 6305 var p = this._fixPath(effect.name, effect.value, path);
5809 node.notifyPath(p, value, true); 6306 node._notifyPath(p, value, true);
5810 } 6307 }
5811 } 6308 }
5812 }, 6309 },
5813 _complexObserverPathEffect: function (path, value, effect) { 6310 _complexObserverPathEffect: function (path, value, effect) {
5814 if (this._pathMatchesEffect(path, effect)) { 6311 if (this._pathMatchesEffect(path, effect)) {
5815 Polymer.Bind._complexObserverEffect.call(this, path, value, effect); 6312 Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
5816 } 6313 }
5817 }, 6314 },
5818 _computePathEffect: function (path, value, effect) { 6315 _computePathEffect: function (path, value, effect) {
5819 if (this._pathMatchesEffect(path, effect)) { 6316 if (this._pathMatchesEffect(path, effect)) {
(...skipping 19 matching lines...) Expand all
5839 }, 6336 },
5840 unlinkPaths: function (path) { 6337 unlinkPaths: function (path) {
5841 if (this._boundPaths) { 6338 if (this._boundPaths) {
5842 delete this._boundPaths[path]; 6339 delete this._boundPaths[path];
5843 } 6340 }
5844 }, 6341 },
5845 _notifyBoundPaths: function (path, value) { 6342 _notifyBoundPaths: function (path, value) {
5846 for (var a in this._boundPaths) { 6343 for (var a in this._boundPaths) {
5847 var b = this._boundPaths[a]; 6344 var b = this._boundPaths[a];
5848 if (path.indexOf(a + '.') == 0) { 6345 if (path.indexOf(a + '.') == 0) {
5849 this.notifyPath(this._fixPath(b, a, path), value); 6346 this._notifyPath(this._fixPath(b, a, path), value);
5850 } else if (path.indexOf(b + '.') == 0) { 6347 } else if (path.indexOf(b + '.') == 0) {
5851 this.notifyPath(this._fixPath(a, b, path), value); 6348 this._notifyPath(this._fixPath(a, b, path), value);
5852 } 6349 }
5853 } 6350 }
5854 }, 6351 },
5855 _fixPath: function (property, root, path) { 6352 _fixPath: function (property, root, path) {
5856 return property + path.slice(root.length); 6353 return property + path.slice(root.length);
5857 }, 6354 },
5858 _notifyPath: function (path, value) { 6355 _notifyPathUp: function (path, value) {
5859 var rootName = this._modelForPath(path); 6356 var rootName = this._modelForPath(path);
5860 var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName); 6357 var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
5861 var eventName = dashCaseName + this._EVENT_CHANGED; 6358 var eventName = dashCaseName + this._EVENT_CHANGED;
5862 this.fire(eventName, { 6359 this.fire(eventName, {
5863 path: path, 6360 path: path,
5864 value: value 6361 value: value
5865 }, { bubbles: false }); 6362 }, { bubbles: false });
5866 }, 6363 },
5867 _modelForPath: function (path) { 6364 _modelForPath: function (path) {
5868 var dot = path.indexOf('.'); 6365 var dot = path.indexOf('.');
5869 return dot < 0 ? path : path.slice(0, dot); 6366 return dot < 0 ? path : path.slice(0, dot);
5870 }, 6367 },
5871 _EVENT_CHANGED: '-changed', 6368 _EVENT_CHANGED: '-changed',
6369 notifySplices: function (path, splices) {
6370 var info = {};
6371 var array = this._get(path, this, info);
6372 this._notifySplices(array, info.path, splices);
6373 },
6374 _notifySplices: function (array, path, splices) {
6375 var change = {
6376 keySplices: Polymer.Collection.applySplices(array, splices),
6377 indexSplices: splices
6378 };
6379 if (!array.hasOwnProperty('splices')) {
6380 Object.defineProperty(array, 'splices', {
6381 configurable: true,
6382 writable: true
6383 });
6384 }
6385 array.splices = change;
6386 this._notifyPath(path + '.splices', change);
6387 this._notifyPath(path + '.length', array.length);
6388 change.keySplices = null;
6389 change.indexSplices = null;
6390 },
5872 _notifySplice: function (array, path, index, added, removed) { 6391 _notifySplice: function (array, path, index, added, removed) {
5873 var splices = [{ 6392 this._notifySplices(array, path, [{
5874 index: index, 6393 index: index,
5875 addedCount: added, 6394 addedCount: added,
5876 removed: removed, 6395 removed: removed,
5877 object: array, 6396 object: array,
5878 type: 'splice' 6397 type: 'splice'
5879 }]; 6398 }]);
5880 var change = {
5881 keySplices: Polymer.Collection.applySplices(array, splices),
5882 indexSplices: splices
5883 };
5884 this.set(path + '.splices', change);
5885 if (added != removed.length) {
5886 this.notifyPath(path + '.length', array.length);
5887 }
5888 change.keySplices = null;
5889 change.indexSplices = null;
5890 }, 6399 },
5891 push: function (path) { 6400 push: function (path) {
5892 var array = this.get(path); 6401 var info = {};
6402 var array = this._get(path, this, info);
5893 var args = Array.prototype.slice.call(arguments, 1); 6403 var args = Array.prototype.slice.call(arguments, 1);
5894 var len = array.length; 6404 var len = array.length;
5895 var ret = array.push.apply(array, args); 6405 var ret = array.push.apply(array, args);
5896 if (args.length) { 6406 if (args.length) {
5897 this._notifySplice(array, path, len, args.length, []); 6407 this._notifySplice(array, info.path, len, args.length, []);
5898 } 6408 }
5899 return ret; 6409 return ret;
5900 }, 6410 },
5901 pop: function (path) { 6411 pop: function (path) {
5902 var array = this.get(path); 6412 var info = {};
6413 var array = this._get(path, this, info);
5903 var hadLength = Boolean(array.length); 6414 var hadLength = Boolean(array.length);
5904 var args = Array.prototype.slice.call(arguments, 1); 6415 var args = Array.prototype.slice.call(arguments, 1);
5905 var ret = array.pop.apply(array, args); 6416 var ret = array.pop.apply(array, args);
5906 if (hadLength) { 6417 if (hadLength) {
5907 this._notifySplice(array, path, array.length, 0, [ret]); 6418 this._notifySplice(array, info.path, array.length, 0, [ret]);
5908 } 6419 }
5909 return ret; 6420 return ret;
5910 }, 6421 },
5911 splice: function (path, start, deleteCount) { 6422 splice: function (path, start, deleteCount) {
5912 var array = this.get(path); 6423 var info = {};
6424 var array = this._get(path, this, info);
5913 if (start < 0) { 6425 if (start < 0) {
5914 start = array.length - Math.floor(-start); 6426 start = array.length - Math.floor(-start);
5915 } else { 6427 } else {
5916 start = Math.floor(start); 6428 start = Math.floor(start);
5917 } 6429 }
5918 if (!start) { 6430 if (!start) {
5919 start = 0; 6431 start = 0;
5920 } 6432 }
5921 var args = Array.prototype.slice.call(arguments, 1); 6433 var args = Array.prototype.slice.call(arguments, 1);
5922 var ret = array.splice.apply(array, args); 6434 var ret = array.splice.apply(array, args);
5923 var addedCount = Math.max(args.length - 2, 0); 6435 var addedCount = Math.max(args.length - 2, 0);
5924 if (addedCount || ret.length) { 6436 if (addedCount || ret.length) {
5925 this._notifySplice(array, path, start, addedCount, ret); 6437 this._notifySplice(array, info.path, start, addedCount, ret);
5926 } 6438 }
5927 return ret; 6439 return ret;
5928 }, 6440 },
5929 shift: function (path) { 6441 shift: function (path) {
5930 var array = this.get(path); 6442 var info = {};
6443 var array = this._get(path, this, info);
5931 var hadLength = Boolean(array.length); 6444 var hadLength = Boolean(array.length);
5932 var args = Array.prototype.slice.call(arguments, 1); 6445 var args = Array.prototype.slice.call(arguments, 1);
5933 var ret = array.shift.apply(array, args); 6446 var ret = array.shift.apply(array, args);
5934 if (hadLength) { 6447 if (hadLength) {
5935 this._notifySplice(array, path, 0, 0, [ret]); 6448 this._notifySplice(array, info.path, 0, 0, [ret]);
5936 } 6449 }
5937 return ret; 6450 return ret;
5938 }, 6451 },
5939 unshift: function (path) { 6452 unshift: function (path) {
5940 var array = this.get(path); 6453 var info = {};
6454 var array = this._get(path, this, info);
5941 var args = Array.prototype.slice.call(arguments, 1); 6455 var args = Array.prototype.slice.call(arguments, 1);
5942 var ret = array.unshift.apply(array, args); 6456 var ret = array.unshift.apply(array, args);
5943 if (args.length) { 6457 if (args.length) {
5944 this._notifySplice(array, path, 0, args.length, []); 6458 this._notifySplice(array, info.path, 0, args.length, []);
5945 } 6459 }
5946 return ret; 6460 return ret;
5947 }, 6461 },
5948 prepareModelNotifyPath: function (model) { 6462 prepareModelNotifyPath: function (model) {
5949 this.mixin(model, { 6463 this.mixin(model, {
5950 fire: Polymer.Base.fire, 6464 fire: Polymer.Base.fire,
5951 notifyPath: Polymer.Base.notifyPath, 6465 notifyPath: Polymer.Base.notifyPath,
6466 _get: Polymer.Base._get,
5952 _EVENT_CHANGED: Polymer.Base._EVENT_CHANGED, 6467 _EVENT_CHANGED: Polymer.Base._EVENT_CHANGED,
5953 _notifyPath: Polymer.Base._notifyPath, 6468 _notifyPath: Polymer.Base._notifyPath,
6469 _notifyPathUp: Polymer.Base._notifyPathUp,
5954 _pathEffector: Polymer.Base._pathEffector, 6470 _pathEffector: Polymer.Base._pathEffector,
5955 _annotationPathEffect: Polymer.Base._annotationPathEffect, 6471 _annotationPathEffect: Polymer.Base._annotationPathEffect,
5956 _complexObserverPathEffect: Polymer.Base._complexObserverPathEffect, 6472 _complexObserverPathEffect: Polymer.Base._complexObserverPathEffect,
5957 _annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect, 6473 _annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect,
5958 _computePathEffect: Polymer.Base._computePathEffect, 6474 _computePathEffect: Polymer.Base._computePathEffect,
5959 _modelForPath: Polymer.Base._modelForPath, 6475 _modelForPath: Polymer.Base._modelForPath,
5960 _pathMatchesEffect: Polymer.Base._pathMatchesEffect, 6476 _pathMatchesEffect: Polymer.Base._pathMatchesEffect,
5961 _notifyBoundPaths: Polymer.Base._notifyBoundPaths 6477 _notifyBoundPaths: Polymer.Base._notifyBoundPaths,
6478 _getPathParts: Polymer.Base._getPathParts
5962 }); 6479 });
5963 } 6480 }
5964 }); 6481 });
5965 }()); 6482 }());
5966 Polymer.Base._addFeature({ 6483 Polymer.Base._addFeature({
5967 resolveUrl: function (url) { 6484 resolveUrl: function (url) {
5968 var module = Polymer.DomModule.import(this.is); 6485 var module = Polymer.DomModule.import(this.is);
5969 var root = ''; 6486 var root = '';
5970 if (module) { 6487 if (module) {
5971 var assetPath = module.getAttribute('assetpath') || ''; 6488 var assetPath = module.getAttribute('assetpath') || '';
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
6088 KEYFRAMES_RULE: 7, 6605 KEYFRAMES_RULE: 7,
6089 MEDIA_RULE: 4, 6606 MEDIA_RULE: 4,
6090 MIXIN_RULE: 1000 6607 MIXIN_RULE: 1000
6091 }, 6608 },
6092 OPEN_BRACE: '{', 6609 OPEN_BRACE: '{',
6093 CLOSE_BRACE: '}', 6610 CLOSE_BRACE: '}',
6094 _rx: { 6611 _rx: {
6095 comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, 6612 comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,
6096 port: /@import[^;]*;/gim, 6613 port: /@import[^;]*;/gim,
6097 customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim, 6614 customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim,
6098 mixinProp: /(?:^|[\s;])--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim, 6615 mixinProp: /(?:^|[\s;])?--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
6099 mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim, 6616 mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim,
6100 varApply: /[^;:]*?:[^;]*var[^;]*(?:[;\n]|$)?/gim, 6617 varApply: /[^;:]*?:[^;]*var[^;]*(?:[;\n]|$)?/gim,
6101 keyframesRule: /^@[^\s]*keyframes/ 6618 keyframesRule: /^@[^\s]*keyframes/
6102 }, 6619 },
6103 VAR_START: '--', 6620 VAR_START: '--',
6104 MEDIA_START: '@media', 6621 MEDIA_START: '@media',
6105 AT_START: '@' 6622 AT_START: '@'
6106 }; 6623 };
6107 return api; 6624 return api;
6108 }(); 6625 }();
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
6791 mixinCustomStyle: function (props, customStyle) { 7308 mixinCustomStyle: function (props, customStyle) {
6792 var v; 7309 var v;
6793 for (var i in customStyle) { 7310 for (var i in customStyle) {
6794 v = customStyle[i]; 7311 v = customStyle[i];
6795 if (v || v === 0) { 7312 if (v || v === 0) {
6796 props[i] = v; 7313 props[i] = v;
6797 } 7314 }
6798 } 7315 }
6799 }, 7316 },
6800 rx: { 7317 rx: {
6801 VAR_ASSIGN: /(?:^|[;\n]\s*)(--[\w-]*?):\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\n])|$)/ gi, 7318 VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}] )|$)/gi,
6802 MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i, 7319 MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
6803 VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)) )[\s]*?\)/gi, 7320 VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)) )[\s]*?\)/gi,
6804 VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi, 7321 VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
6805 IS_VAR: /^--/, 7322 IS_VAR: /^--/,
6806 BRACKETED: /\{[^}]*\}/g, 7323 BRACKETED: /\{[^}]*\}/g,
6807 HOST_PREFIX: '(?:^|[^.#[:])', 7324 HOST_PREFIX: '(?:^|[^.#[:])',
6808 HOST_SUFFIX: '($|[.:[\\s>+~])' 7325 HOST_SUFFIX: '($|[.:[\\s>+~])'
6809 }, 7326 },
6810 HOST_SELECTORS: [':host'], 7327 HOST_SELECTORS: [':host'],
6811 SCOPE_SELECTORS: [':root'], 7328 SCOPE_SELECTORS: [':root'],
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
7175 this._prepParentProperties(this.ctor.prototype, template); 7692 this._prepParentProperties(this.ctor.prototype, template);
7176 return; 7693 return;
7177 } 7694 }
7178 var archetype = Object.create(Polymer.Base); 7695 var archetype = Object.create(Polymer.Base);
7179 this._customPrepAnnotations(archetype, template); 7696 this._customPrepAnnotations(archetype, template);
7180 this._prepParentProperties(archetype, template); 7697 this._prepParentProperties(archetype, template);
7181 archetype._prepEffects(); 7698 archetype._prepEffects();
7182 this._customPrepEffects(archetype); 7699 this._customPrepEffects(archetype);
7183 archetype._prepBehaviors(); 7700 archetype._prepBehaviors();
7184 archetype._prepBindings(); 7701 archetype._prepBindings();
7185 archetype._notifyPath = this._notifyPathImpl; 7702 archetype._notifyPathUp = this._notifyPathUpImpl;
7186 archetype._scopeElementClass = this._scopeElementClassImpl; 7703 archetype._scopeElementClass = this._scopeElementClassImpl;
7187 archetype.listen = this._listenImpl; 7704 archetype.listen = this._listenImpl;
7188 archetype._showHideChildren = this._showHideChildrenImpl; 7705 archetype._showHideChildren = this._showHideChildrenImpl;
7189 var _constructor = this._constructorImpl; 7706 var _constructor = this._constructorImpl;
7190 var ctor = function TemplateInstance(model, host) { 7707 var ctor = function TemplateInstance(model, host) {
7191 _constructor.call(this, model, host); 7708 _constructor.call(this, model, host);
7192 }; 7709 };
7193 ctor.prototype = archetype; 7710 ctor.prototype = archetype;
7194 archetype.constructor = ctor; 7711 archetype.constructor = ctor;
7195 template._content._ctor = ctor; 7712 template._content._ctor = ctor;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7313 template._propertySetter(n, val); 7830 template._propertySetter(n, val);
7314 } 7831 }
7315 }); 7832 });
7316 }, 7833 },
7317 _showHideChildren: function (hidden) { 7834 _showHideChildren: function (hidden) {
7318 }, 7835 },
7319 _forwardInstancePath: function (inst, path, value) { 7836 _forwardInstancePath: function (inst, path, value) {
7320 }, 7837 },
7321 _forwardInstanceProp: function (inst, prop, value) { 7838 _forwardInstanceProp: function (inst, prop, value) {
7322 }, 7839 },
7323 _notifyPathImpl: function (path, value) { 7840 _notifyPathUpImpl: function (path, value) {
7324 var dataHost = this.dataHost; 7841 var dataHost = this.dataHost;
7325 var dot = path.indexOf('.'); 7842 var dot = path.indexOf('.');
7326 var root = dot < 0 ? path : path.slice(0, dot); 7843 var root = dot < 0 ? path : path.slice(0, dot);
7327 dataHost._forwardInstancePath.call(dataHost, this, path, value); 7844 dataHost._forwardInstancePath.call(dataHost, this, path, value);
7328 if (root in dataHost._parentProps) { 7845 if (root in dataHost._parentProps) {
7329 dataHost._templatized.notifyPath(dataHost._parentPropPrefix + path, value); 7846 dataHost._templatized.notifyPath(dataHost._parentPropPrefix + path, value);
7330 } 7847 }
7331 }, 7848 },
7332 _pathEffectorImpl: function (path, value, fromAbove) { 7849 _pathEffectorImpl: function (path, value, fromAbove) {
7333 if (this._forwardParentPath) { 7850 if (this._forwardParentPath) {
7334 if (path.indexOf(this._parentPropPrefix) === 0) { 7851 if (path.indexOf(this._parentPropPrefix) === 0) {
7335 var subPath = path.substring(this._parentPropPrefix.length); 7852 var subPath = path.substring(this._parentPropPrefix.length);
7853 var model = this._modelForPath(subPath);
7854 if (model in this._parentProps) {
7336 this._forwardParentPath(subPath, value); 7855 this._forwardParentPath(subPath, value);
7337 } 7856 }
7338 } 7857 }
7858 }
7339 Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove); 7859 Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove);
7340 }, 7860 },
7341 _constructorImpl: function (model, host) { 7861 _constructorImpl: function (model, host) {
7342 this._rootDataHost = host._getRootDataHost(); 7862 this._rootDataHost = host._getRootDataHost();
7343 this._setupConfigure(model); 7863 this._setupConfigure(model);
7344 this._pushHost(host); 7864 this._pushHost(host);
7345 this.root = this.instanceTemplate(this._template); 7865 this.root = this.instanceTemplate(this._template);
7346 this.root.__noContent = !this._notes._hasContent; 7866 this.root.__noContent = !this._notes._hasContent;
7347 this.root.__styleScoped = true; 7867 this.root.__styleScoped = true;
7348 this._popHost(); 7868 this._popHost();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
7431 } 7951 }
7432 } 7952 }
7433 }, 7953 },
7434 add: function (item) { 7954 add: function (item) {
7435 var key = this.store.push(item) - 1; 7955 var key = this.store.push(item) - 1;
7436 if (item && typeof item == 'object') { 7956 if (item && typeof item == 'object') {
7437 this.omap.set(item, key); 7957 this.omap.set(item, key);
7438 } else { 7958 } else {
7439 this.pmap[item] = key; 7959 this.pmap[item] = key;
7440 } 7960 }
7441 return key; 7961 return '#' + key;
7442 }, 7962 },
7443 removeKey: function (key) { 7963 removeKey: function (key) {
7964 key = this._parseKey(key);
7444 this._removeFromMap(this.store[key]); 7965 this._removeFromMap(this.store[key]);
7445 delete this.store[key]; 7966 delete this.store[key];
7446 }, 7967 },
7447 _removeFromMap: function (item) { 7968 _removeFromMap: function (item) {
7448 if (item && typeof item == 'object') { 7969 if (item && typeof item == 'object') {
7449 this.omap.delete(item); 7970 this.omap.delete(item);
7450 } else { 7971 } else {
7451 delete this.pmap[item]; 7972 delete this.pmap[item];
7452 } 7973 }
7453 }, 7974 },
7454 remove: function (item) { 7975 remove: function (item) {
7455 var key = this.getKey(item); 7976 var key = this.getKey(item);
7456 this.removeKey(key); 7977 this.removeKey(key);
7457 return key; 7978 return key;
7458 }, 7979 },
7459 getKey: function (item) { 7980 getKey: function (item) {
7981 var key;
7460 if (item && typeof item == 'object') { 7982 if (item && typeof item == 'object') {
7461 return this.omap.get(item); 7983 key = this.omap.get(item);
7462 } else { 7984 } else {
7463 return this.pmap[item]; 7985 key = this.pmap[item];
7986 }
7987 if (key != undefined) {
7988 return '#' + key;
7464 } 7989 }
7465 }, 7990 },
7466 getKeys: function () { 7991 getKeys: function () {
7467 return Object.keys(this.store); 7992 return Object.keys(this.store).map(function (key) {
7993 return '#' + key;
7994 });
7995 },
7996 _parseKey: function (key) {
7997 if (key[0] == '#') {
7998 return key.slice(1);
7999 }
8000 throw new Error('unexpected key ' + key);
7468 }, 8001 },
7469 setItem: function (key, item) { 8002 setItem: function (key, item) {
8003 key = this._parseKey(key);
7470 var old = this.store[key]; 8004 var old = this.store[key];
7471 if (old) { 8005 if (old) {
7472 this._removeFromMap(old); 8006 this._removeFromMap(old);
7473 } 8007 }
7474 if (item && typeof item == 'object') { 8008 if (item && typeof item == 'object') {
7475 this.omap.set(item, key); 8009 this.omap.set(item, key);
7476 } else { 8010 } else {
7477 this.pmap[item] = key; 8011 this.pmap[item] = key;
7478 } 8012 }
7479 this.store[key] = item; 8013 this.store[key] = item;
7480 }, 8014 },
7481 getItem: function (key) { 8015 getItem: function (key) {
8016 key = this._parseKey(key);
7482 return this.store[key]; 8017 return this.store[key];
7483 }, 8018 },
7484 getItems: function () { 8019 getItems: function () {
7485 var items = [], store = this.store; 8020 var items = [], store = this.store;
7486 for (var key in store) { 8021 for (var key in store) {
7487 items.push(store[key]); 8022 items.push(store[key]);
7488 } 8023 }
7489 return items; 8024 return items;
7490 }, 8025 },
7491 _applySplices: function (splices) { 8026 _applySplices: function (splices) {
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
7865 if (this._sortFn || this._filterFn) { 8400 if (this._sortFn || this._filterFn) {
7866 idx = this.items.indexOf(this.collection.getItem(inst.__key__)); 8401 idx = this.items.indexOf(this.collection.getItem(inst.__key__));
7867 } else { 8402 } else {
7868 idx = inst[this.indexAs]; 8403 idx = inst[this.indexAs];
7869 } 8404 }
7870 this.set('items.' + idx, value); 8405 this.set('items.' + idx, value);
7871 } 8406 }
7872 }, 8407 },
7873 _forwardInstancePath: function (inst, path, value) { 8408 _forwardInstancePath: function (inst, path, value) {
7874 if (path.indexOf(this.as + '.') === 0) { 8409 if (path.indexOf(this.as + '.') === 0) {
7875 this.notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value); 8410 this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
7876 } 8411 }
7877 }, 8412 },
7878 _forwardParentProp: function (prop, value) { 8413 _forwardParentProp: function (prop, value) {
7879 this._instances.forEach(function (inst) { 8414 this._instances.forEach(function (inst) {
7880 inst.__setProperty(prop, value, true); 8415 inst.__setProperty(prop, value, true);
7881 }, this); 8416 }, this);
7882 }, 8417 },
7883 _forwardParentPath: function (path, value) { 8418 _forwardParentPath: function (path, value) {
7884 this._instances.forEach(function (inst) { 8419 this._instances.forEach(function (inst) {
7885 inst.notifyPath(path, value, true); 8420 inst._notifyPath(path, value, true);
7886 }, this); 8421 }, this);
7887 }, 8422 },
7888 _forwardItemPath: function (path, value) { 8423 _forwardItemPath: function (path, value) {
7889 if (this._keyToInstIdx) { 8424 if (this._keyToInstIdx) {
7890 var dot = path.indexOf('.'); 8425 var dot = path.indexOf('.');
7891 var key = path.substring(0, dot < 0 ? path.length : dot); 8426 var key = path.substring(0, dot < 0 ? path.length : dot);
7892 var idx = this._keyToInstIdx[key]; 8427 var idx = this._keyToInstIdx[key];
7893 var inst = this._instances[idx]; 8428 var inst = this._instances[idx];
7894 if (inst) { 8429 if (inst) {
7895 if (dot >= 0) { 8430 if (dot >= 0) {
7896 path = this.as + '.' + path.substring(dot + 1); 8431 path = this.as + '.' + path.substring(dot + 1);
7897 inst.notifyPath(path, value, true); 8432 inst._notifyPath(path, value, true);
7898 } else { 8433 } else {
7899 inst.__setProperty(this.as, value, true); 8434 inst.__setProperty(this.as, value, true);
7900 } 8435 }
7901 } 8436 }
7902 } 8437 }
7903 }, 8438 },
7904 itemForElement: function (el) { 8439 itemForElement: function (el) {
7905 var instance = this.modelForElement(el); 8440 var instance = this.modelForElement(el);
7906 return instance && instance[this.as]; 8441 return instance && instance[this.as];
7907 }, 8442 },
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
7939 value: false 8474 value: false
7940 } 8475 }
7941 }, 8476 },
7942 clearSelection: function () { 8477 clearSelection: function () {
7943 if (Array.isArray(this.selected)) { 8478 if (Array.isArray(this.selected)) {
7944 for (var i = 0; i < this.selected.length; i++) { 8479 for (var i = 0; i < this.selected.length; i++) {
7945 this.unlinkPaths('selected.' + i); 8480 this.unlinkPaths('selected.' + i);
7946 } 8481 }
7947 } else { 8482 } else {
7948 this.unlinkPaths('selected'); 8483 this.unlinkPaths('selected');
8484 this.unlinkPaths('selectedItem');
7949 } 8485 }
7950 if (this.multi) { 8486 if (this.multi) {
7951 if (!this.selected || this.selected.length) { 8487 if (!this.selected || this.selected.length) {
7952 this.selected = []; 8488 this.selected = [];
7953 this._selectedColl = Polymer.Collection.get(this.selected); 8489 this._selectedColl = Polymer.Collection.get(this.selected);
7954 } 8490 }
7955 } else { 8491 } else {
7956 this.selected = null; 8492 this.selected = null;
7957 this._selectedColl = null; 8493 this._selectedColl = null;
7958 } 8494 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
8078 this._instance._showHideChildren(hidden); 8614 this._instance._showHideChildren(hidden);
8079 } 8615 }
8080 }, 8616 },
8081 _forwardParentProp: function (prop, value) { 8617 _forwardParentProp: function (prop, value) {
8082 if (this._instance) { 8618 if (this._instance) {
8083 this._instance[prop] = value; 8619 this._instance[prop] = value;
8084 } 8620 }
8085 }, 8621 },
8086 _forwardParentPath: function (path, value) { 8622 _forwardParentPath: function (path, value) {
8087 if (this._instance) { 8623 if (this._instance) {
8088 this._instance.notifyPath(path, value, true); 8624 this._instance._notifyPath(path, value, true);
8089 } 8625 }
8090 } 8626 }
8091 }); 8627 });
8092 Polymer({ 8628 Polymer({
8093 is: 'dom-bind', 8629 is: 'dom-bind',
8094 extends: 'template', 8630 extends: 'template',
8095 created: function () { 8631 created: function () {
8096 Polymer.RenderStatus.whenReady(this._markImportsReady.bind(this)); 8632 Polymer.RenderStatus.whenReady(this._markImportsReady.bind(this));
8097 }, 8633 },
8098 _ensureReady: function () { 8634 _ensureReady: function () {
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
8559 _itemsRendered: false, 9095 _itemsRendered: false,
8560 9096
8561 /** 9097 /**
8562 * The bottom of the physical content. 9098 * The bottom of the physical content.
8563 */ 9099 */
8564 get _physicalBottom() { 9100 get _physicalBottom() {
8565 return this._physicalTop + this._physicalSize; 9101 return this._physicalTop + this._physicalSize;
8566 }, 9102 },
8567 9103
8568 /** 9104 /**
9105 * The bottom of the scroll.
9106 */
9107 get _scrollBottom() {
9108 return this._scrollPosition + this._viewportSize;
9109 },
9110
9111 /**
8569 * The n-th item rendered in the last physical item. 9112 * The n-th item rendered in the last physical item.
8570 */ 9113 */
8571 get _virtualEnd() { 9114 get _virtualEnd() {
8572 return this._virtualStartVal + this._physicalCount - 1; 9115 return this._virtualStartVal + this._physicalCount - 1;
8573 }, 9116 },
8574 9117
8575 /** 9118 /**
8576 * The lowest n-th value for an item such that it can be rendered in `_physi calStart`. 9119 * The lowest n-th value for an item such that it can be rendered in `_physi calStart`.
8577 */ 9120 */
8578 _minVirtualStart: 0, 9121 _minVirtualStart: 0,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
8713 var scrollerStyle = window.getComputedStyle(this._scroller); 9256 var scrollerStyle = window.getComputedStyle(this._scroller);
8714 this._scrollerPaddingTop = parseInt(scrollerStyle['padding-top'], 10); 9257 this._scrollerPaddingTop = parseInt(scrollerStyle['padding-top'], 10);
8715 this._viewportSize = this._scroller.offsetHeight; 9258 this._viewportSize = this._scroller.offsetHeight;
8716 }, 9259 },
8717 9260
8718 /** 9261 /**
8719 * Update the models, the position of the 9262 * Update the models, the position of the
8720 * items in the viewport and recycle tiles as needed. 9263 * items in the viewport and recycle tiles as needed.
8721 */ 9264 */
8722 _refresh: function() { 9265 _refresh: function() {
8723 var SCROLL_DIRECTION_UP = -1;
8724 var SCROLL_DIRECTION_DOWN = 1;
8725 var SCROLL_DIRECTION_NONE = 0;
8726
8727 // clamp the `scrollTop` value 9266 // clamp the `scrollTop` value
8728 // IE 10|11 scrollTop may go above `_maxScrollTop` 9267 // IE 10|11 scrollTop may go above `_maxScrollTop`
8729 // iOS `scrollTop` may go below 0 and above `_maxScrollTop` 9268 // iOS `scrollTop` may go below 0 and above `_maxScrollTop`
8730 var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scroller.sc rollTop)); 9269 var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scroller.sc rollTop));
8731 9270 var tileHeight, tileTop, kth, recycledTileSet, scrollBottom;
8732 var tileHeight, kth, recycledTileSet;
8733 var ratio = this._ratio; 9271 var ratio = this._ratio;
8734 var delta = scrollTop - this._scrollPosition; 9272 var delta = scrollTop - this._scrollPosition;
8735 var direction = SCROLL_DIRECTION_NONE;
8736 var recycledTiles = 0; 9273 var recycledTiles = 0;
8737 var hiddenContentSize = this._hiddenContentSize; 9274 var hiddenContentSize = this._hiddenContentSize;
8738 var currentRatio = ratio; 9275 var currentRatio = ratio;
8739 var movingUp = []; 9276 var movingUp = [];
8740 9277
8741 // track the last `scrollTop` 9278 // track the last `scrollTop`
8742 this._scrollPosition = scrollTop; 9279 this._scrollPosition = scrollTop;
8743 9280
8744 // clear cached visible index 9281 // clear cached visible index
8745 this._firstVisibleIndexVal = null; 9282 this._firstVisibleIndexVal = null;
8746 9283
9284 scrollBottom = this._scrollBottom;
9285
8747 // random access 9286 // random access
8748 if (Math.abs(delta) > this._physicalSize) { 9287 if (Math.abs(delta) > this._physicalSize) {
8749 this._physicalTop += delta; 9288 this._physicalTop += delta;
8750 direction = SCROLL_DIRECTION_NONE;
8751 recycledTiles = Math.round(delta / this._physicalAverage); 9289 recycledTiles = Math.round(delta / this._physicalAverage);
8752 } 9290 }
8753 // scroll up 9291 // scroll up
8754 else if (delta < 0) { 9292 else if (delta < 0) {
8755 var topSpace = scrollTop - this._physicalTop; 9293 var topSpace = scrollTop - this._physicalTop;
8756 var virtualStart = this._virtualStart; 9294 var virtualStart = this._virtualStart;
9295 var physicalBottom = this._physicalBottom;
8757 9296
8758 direction = SCROLL_DIRECTION_UP;
8759 recycledTileSet = []; 9297 recycledTileSet = [];
8760 9298
8761 kth = this._physicalEnd; 9299 kth = this._physicalEnd;
8762 currentRatio = topSpace / hiddenContentSize; 9300 currentRatio = topSpace / hiddenContentSize;
8763 9301
8764 // move tiles from bottom to top 9302 // move tiles from bottom to top
8765 while ( 9303 while (
8766 // approximate `currentRatio` to `ratio` 9304 // approximate `currentRatio` to `ratio`
8767 currentRatio < ratio && 9305 currentRatio < ratio &&
8768 // recycle less physical items than the total 9306 // recycle less physical items than the total
8769 recycledTiles < this._physicalCount && 9307 recycledTiles < this._physicalCount &&
8770 // ensure that these recycled tiles are needed 9308 // ensure that these recycled tiles are needed
8771 virtualStart - recycledTiles > 0 9309 virtualStart - recycledTiles > 0 &&
9310 // ensure that the tile is not visible
9311 physicalBottom - this._physicalSizes[kth] > scrollBottom
8772 ) { 9312 ) {
8773 9313
8774 tileHeight = this._physicalSizes[kth] || this._physicalAverage; 9314 tileHeight = this._physicalSizes[kth];
8775 currentRatio += tileHeight / hiddenContentSize; 9315 currentRatio += tileHeight / hiddenContentSize;
8776 9316 physicalBottom -= tileHeight;
8777 recycledTileSet.push(kth); 9317 recycledTileSet.push(kth);
8778 recycledTiles++; 9318 recycledTiles++;
8779 kth = (kth === 0) ? this._physicalCount - 1 : kth - 1; 9319 kth = (kth === 0) ? this._physicalCount - 1 : kth - 1;
8780 } 9320 }
8781 9321
8782 movingUp = recycledTileSet; 9322 movingUp = recycledTileSet;
8783 recycledTiles = -recycledTiles; 9323 recycledTiles = -recycledTiles;
8784
8785 } 9324 }
8786 // scroll down 9325 // scroll down
8787 else if (delta > 0) { 9326 else if (delta > 0) {
8788 var bottomSpace = this._physicalBottom - (scrollTop + this._viewportSize ); 9327 var bottomSpace = this._physicalBottom - scrollBottom;
8789 var virtualEnd = this._virtualEnd; 9328 var virtualEnd = this._virtualEnd;
8790 var lastVirtualItemIndex = this._virtualCount-1; 9329 var lastVirtualItemIndex = this._virtualCount-1;
8791 9330
8792 direction = SCROLL_DIRECTION_DOWN;
8793 recycledTileSet = []; 9331 recycledTileSet = [];
8794 9332
8795 kth = this._physicalStart; 9333 kth = this._physicalStart;
8796 currentRatio = bottomSpace / hiddenContentSize; 9334 currentRatio = bottomSpace / hiddenContentSize;
8797 9335
8798 // move tiles from top to bottom 9336 // move tiles from top to bottom
8799 while ( 9337 while (
8800 // approximate `currentRatio` to `ratio` 9338 // approximate `currentRatio` to `ratio`
8801 currentRatio < ratio && 9339 currentRatio < ratio &&
8802 // recycle less physical items than the total 9340 // recycle less physical items than the total
8803 recycledTiles < this._physicalCount && 9341 recycledTiles < this._physicalCount &&
8804 // ensure that these recycled tiles are needed 9342 // ensure that these recycled tiles are needed
8805 virtualEnd + recycledTiles < lastVirtualItemIndex 9343 virtualEnd + recycledTiles < lastVirtualItemIndex &&
9344 // ensure that the tile is not visible
9345 this._physicalTop + this._physicalSizes[kth] < scrollTop
8806 ) { 9346 ) {
8807 9347
8808 tileHeight = this._physicalSizes[kth] || this._physicalAverage; 9348 tileHeight = this._physicalSizes[kth];
8809 currentRatio += tileHeight / hiddenContentSize; 9349 currentRatio += tileHeight / hiddenContentSize;
8810 9350
8811 this._physicalTop += tileHeight; 9351 this._physicalTop += tileHeight;
8812 recycledTileSet.push(kth); 9352 recycledTileSet.push(kth);
8813 recycledTiles++; 9353 recycledTiles++;
8814 kth = (kth + 1) % this._physicalCount; 9354 kth = (kth + 1) % this._physicalCount;
8815 } 9355 }
8816 } 9356 }
8817 9357
8818 if (recycledTiles !== 0) { 9358 if (recycledTiles === 0) {
9359 // If the list ever reach this case, the physical average is not signifi cant enough
9360 // to create all the items needed to cover the entire viewport.
9361 // e.g. A few items have a height that differs from the average by serve ral order of magnitude.
9362 if (this._increasePoolIfNeeded()) {
9363 // yield and set models to the new items
9364 this.async(this._update);
9365 }
9366 } else {
8819 this._virtualStart = this._virtualStart + recycledTiles; 9367 this._virtualStart = this._virtualStart + recycledTiles;
8820 this._update(recycledTileSet, movingUp); 9368 this._update(recycledTileSet, movingUp);
8821 } 9369 }
8822 }, 9370 },
8823 9371
8824 /** 9372 /**
8825 * Update the list of items, starting from the `_virtualStartVal` item. 9373 * Update the list of items, starting from the `_virtualStartVal` item.
8826 * @param {!Array<number>=} itemSet 9374 * @param {!Array<number>=} itemSet
8827 * @param {!Array<number>=} movingUp 9375 * @param {!Array<number>=} movingUp
8828 */ 9376 */
(...skipping 11 matching lines...) Expand all
8840 } 9388 }
8841 } 9389 }
8842 // update the position of the items 9390 // update the position of the items
8843 this._positionItems(); 9391 this._positionItems();
8844 9392
8845 // set the scroller size 9393 // set the scroller size
8846 this._updateScrollerSize(); 9394 this._updateScrollerSize();
8847 9395
8848 // increase the pool of physical items if needed 9396 // increase the pool of physical items if needed
8849 if (this._increasePoolIfNeeded()) { 9397 if (this._increasePoolIfNeeded()) {
8850 // set models to the new items 9398 // yield set models to the new items
8851 this.async(this._update); 9399 this.async(this._update);
8852 } 9400 }
8853 }, 9401 },
8854 9402
8855 /** 9403 /**
8856 * Creates a pool of DOM elements and attaches them to the local dom. 9404 * Creates a pool of DOM elements and attaches them to the local dom.
8857 */ 9405 */
8858 _createPool: function(size) { 9406 _createPool: function(size) {
8859 var physicalItems = new Array(size); 9407 var physicalItems = new Array(size);
8860 9408
8861 this._ensureTemplatized(); 9409 this._ensureTemplatized();
8862 9410
8863 for (var i = 0; i < size; i++) { 9411 for (var i = 0; i < size; i++) {
8864 var inst = this.stamp(null); 9412 var inst = this.stamp(null);
8865 9413
8866 // First element child is item; Safari doesn't support children[0] 9414 // First element child is item; Safari doesn't support children[0]
8867 // on a doc fragment 9415 // on a doc fragment
8868 physicalItems[i] = inst.root.querySelector('*'); 9416 physicalItems[i] = inst.root.querySelector('*');
8869 Polymer.dom(this).appendChild(inst.root); 9417 Polymer.dom(this).appendChild(inst.root);
8870 } 9418 }
8871 9419
8872 return physicalItems; 9420 return physicalItems;
8873 }, 9421 },
8874 9422
8875 /** 9423 /**
8876 * Increases the pool size. That is, the physical items in the DOM. 9424 * Increases the pool of physical items only if needed.
8877 * This function will allocate additional physical items 9425 * This function will allocate additional physical items
8878 * (limited by `MAX_PHYSICAL_COUNT`) if the content size is shorter than 9426 * (limited by `MAX_PHYSICAL_COUNT`) if the content size is shorter than
8879 * `_optPhysicalSize` 9427 * `_optPhysicalSize`
8880 * 9428 *
8881 * @return boolean 9429 * @return boolean
8882 */ 9430 */
8883 _increasePoolIfNeeded: function() { 9431 _increasePoolIfNeeded: function() {
8884 if (this._physicalSize >= this._optPhysicalSize || this._physicalAverage = == 0) { 9432 if (this._physicalAverage === 0) {
8885 return false; 9433 return false;
8886 } 9434 }
9435 if (this._physicalBottom < this._scrollBottom || this._physicalTop > this. _scrollPosition) {
9436 return this._increasePool(1);
9437 }
9438 if (this._physicalSize < this._optPhysicalSize) {
9439 return this._increasePool(Math.round((this._optPhysicalSize - this._phys icalSize) * 1.2 / this._physicalAverage));
9440 }
9441 return false;
9442 },
8887 9443
8888 // the estimated number of physical items that we will need to reach 9444 /**
8889 // the cap established by `_optPhysicalSize`. 9445 * Increases the pool size.
8890 var missingItems = Math.round( 9446 */
8891 (this._optPhysicalSize - this._physicalSize) * 1.2 / this._physicalAve rage 9447 _increasePool: function(missingItems) {
8892 );
8893
8894 // limit the size 9448 // limit the size
8895 var nextPhysicalCount = Math.min( 9449 var nextPhysicalCount = Math.min(
8896 this._physicalCount + missingItems, 9450 this._physicalCount + missingItems,
8897 this._virtualCount, 9451 this._virtualCount,
8898 MAX_PHYSICAL_COUNT 9452 MAX_PHYSICAL_COUNT
8899 ); 9453 );
8900 9454
8901 var prevPhysicalCount = this._physicalCount; 9455 var prevPhysicalCount = this._physicalCount;
8902 var delta = nextPhysicalCount - prevPhysicalCount; 9456 var delta = nextPhysicalCount - prevPhysicalCount;
8903 9457
8904 if (delta <= 0) { 9458 if (delta <= 0) {
8905 return false; 9459 return false;
8906 } 9460 }
8907 9461
8908 var newPhysicalItems = this._createPool(delta); 9462 [].push.apply(this._physicalItems, this._createPool(delta));
8909 var emptyArray = new Array(delta); 9463 [].push.apply(this._physicalSizes, new Array(delta));
8910
8911 [].push.apply(this._physicalItems, newPhysicalItems);
8912 [].push.apply(this._physicalSizes, emptyArray);
8913 9464
8914 this._physicalCount = prevPhysicalCount + delta; 9465 this._physicalCount = prevPhysicalCount + delta;
8915 9466
8916 return true; 9467 return true;
8917 }, 9468 },
8918 9469
8919 /** 9470 /**
8920 * Render a new list of items. This method does exactly the same as `update` , 9471 * Render a new list of items. This method does exactly the same as `update` ,
8921 * but it also ensures that only one `update` cycle is created. 9472 * but it also ensures that only one `update` cycle is created.
8922 */ 9473 */
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
9297 this._updateScrollerSize(true); 9848 this._updateScrollerSize(true);
9298 9849
9299 // update the position of the items 9850 // update the position of the items
9300 this._positionItems(); 9851 this._positionItems();
9301 9852
9302 // set the new scroll position 9853 // set the new scroll position
9303 this._resetScrollPosition(this._physicalTop + targetOffsetTop + 1); 9854 this._resetScrollPosition(this._physicalTop + targetOffsetTop + 1);
9304 9855
9305 // increase the pool of physical items if needed 9856 // increase the pool of physical items if needed
9306 if (this._increasePoolIfNeeded()) { 9857 if (this._increasePoolIfNeeded()) {
9307 // set models to the new items 9858 // yield set models to the new items
9308 this.async(this._update); 9859 this.async(this._update);
9309 } 9860 }
9310
9311 // clear cached visible index 9861 // clear cached visible index
9312 this._firstVisibleIndexVal = null; 9862 this._firstVisibleIndexVal = null;
9313 }, 9863 },
9314 9864
9315 /** 9865 /**
9316 * Reset the physical average and the average count. 9866 * Reset the physical average and the average count.
9317 */ 9867 */
9318 _resetAverage: function() { 9868 _resetAverage: function() {
9319 this._physicalAverage = 0; 9869 this._physicalAverage = 0;
9320 this._physicalAverageCount = 0; 9870 this._physicalAverageCount = 0;
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
9731 } 10281 }
9732 10282
9733 }); 10283 });
9734 10284
9735 })(); 10285 })();
9736 (function() { 10286 (function() {
9737 10287
9738 // monostate data 10288 // monostate data
9739 var metaDatas = {}; 10289 var metaDatas = {};
9740 var metaArrays = {}; 10290 var metaArrays = {};
10291 var singleton = null;
9741 10292
9742 Polymer.IronMeta = Polymer({ 10293 Polymer.IronMeta = Polymer({
9743 10294
9744 is: 'iron-meta', 10295 is: 'iron-meta',
9745 10296
9746 properties: { 10297 properties: {
9747 10298
9748 /** 10299 /**
9749 * The type of meta-data. All meta-data of the same type is stored 10300 * The type of meta-data. All meta-data of the same type is stored
9750 * together. 10301 * together.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
9783 /** 10334 /**
9784 * Array of all meta-data values for the given type. 10335 * Array of all meta-data values for the given type.
9785 */ 10336 */
9786 list: { 10337 list: {
9787 type: Array, 10338 type: Array,
9788 notify: true 10339 notify: true
9789 } 10340 }
9790 10341
9791 }, 10342 },
9792 10343
10344 hostAttributes: {
10345 hidden: true
10346 },
10347
9793 /** 10348 /**
9794 * Only runs if someone invokes the factory/constructor directly 10349 * Only runs if someone invokes the factory/constructor directly
9795 * e.g. `new Polymer.IronMeta()` 10350 * e.g. `new Polymer.IronMeta()`
10351 *
10352 * @param {{type: (string|undefined), key: (string|undefined), value}=} co nfig
9796 */ 10353 */
9797 factoryImpl: function(config) { 10354 factoryImpl: function(config) {
9798 if (config) { 10355 if (config) {
9799 for (var n in config) { 10356 for (var n in config) {
9800 switch(n) { 10357 switch(n) {
9801 case 'type': 10358 case 'type':
9802 case 'key': 10359 case 'key':
9803 case 'value': 10360 case 'value':
9804 this[n] = config[n]; 10361 this[n] = config[n];
9805 break; 10362 break;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
9877 if (key in data) { 10434 if (key in data) {
9878 var value = data[key]; 10435 var value = data[key];
9879 delete data[key]; 10436 delete data[key];
9880 this.arrayDelete(list, value); 10437 this.arrayDelete(list, value);
9881 } 10438 }
9882 } 10439 }
9883 } 10440 }
9884 10441
9885 }); 10442 });
9886 10443
10444 Polymer.IronMeta.getIronMeta = function getIronMeta() {
10445 if (singleton === null) {
10446 singleton = new Polymer.IronMeta();
10447 }
10448 return singleton;
10449 };
10450
9887 /** 10451 /**
9888 `iron-meta-query` can be used to access infomation stored in `iron-meta`. 10452 `iron-meta-query` can be used to access infomation stored in `iron-meta`.
9889 10453
9890 Examples: 10454 Examples:
9891 10455
9892 If I create an instance like this: 10456 If I create an instance like this:
9893 10457
9894 <iron-meta key="info" value="foo/bar"></iron-meta> 10458 <iron-meta key="info" value="foo/bar"></iron-meta>
9895 10459
9896 Note that value="foo/bar" is the metadata I've defined. I could define more 10460 Note that value="foo/bar" is the metadata I've defined. I could define more
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
9943 list: { 10507 list: {
9944 type: Array, 10508 type: Array,
9945 notify: true 10509 notify: true
9946 } 10510 }
9947 10511
9948 }, 10512 },
9949 10513
9950 /** 10514 /**
9951 * Actually a factory method, not a true constructor. Only runs if 10515 * Actually a factory method, not a true constructor. Only runs if
9952 * someone invokes it directly (via `new Polymer.IronMeta()`); 10516 * someone invokes it directly (via `new Polymer.IronMeta()`);
10517 *
10518 * @param {{type: (string|undefined), key: (string|undefined)}=} config
9953 */ 10519 */
9954 factoryImpl: function(config) { 10520 factoryImpl: function(config) {
9955 if (config) { 10521 if (config) {
9956 for (var n in config) { 10522 for (var n in config) {
9957 switch(n) { 10523 switch(n) {
9958 case 'type': 10524 case 'type':
9959 case 'key': 10525 case 'key':
9960 this[n] = config[n]; 10526 this[n] = config[n];
9961 break; 10527 break;
9962 } 10528 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
10079 } 10645 }
10080 } 10646 }
10081 10647
10082 }); 10648 });
10083 /** 10649 /**
10084 * The `iron-iconset-svg` element allows users to define their own icon sets 10650 * The `iron-iconset-svg` element allows users to define their own icon sets
10085 * that contain svg icons. The svg icon elements should be children of the 10651 * that contain svg icons. The svg icon elements should be children of the
10086 * `iron-iconset-svg` element. Multiple icons should be given distinct id's. 10652 * `iron-iconset-svg` element. Multiple icons should be given distinct id's.
10087 * 10653 *
10088 * Using svg elements to create icons has a few advantages over traditional 10654 * Using svg elements to create icons has a few advantages over traditional
10089 * bitmap graphics like jpg or png. Icons that use svg are vector based so the y 10655 * bitmap graphics like jpg or png. Icons that use svg are vector based so
10090 * are resolution independent and should look good on any device. They are 10656 * they are resolution independent and should look good on any device. They
10091 * stylable via css. Icons can be themed, colorized, and even animated. 10657 * are stylable via css. Icons can be themed, colorized, and even animated.
10092 * 10658 *
10093 * Example: 10659 * Example:
10094 * 10660 *
10095 * <iron-iconset-svg name="my-svg-icons" size="24"> 10661 * <iron-iconset-svg name="my-svg-icons" size="24">
10096 * <svg> 10662 * <svg>
10097 * <defs> 10663 * <defs>
10098 * <g id="shape"> 10664 * <g id="shape">
10099 * <rect x="50" y="50" width="50" height="50" /> 10665 * <rect x="12" y="0" width="12" height="24" />
10100 * <circle cx="50" cy="50" r="50" /> 10666 * <circle cx="12" cy="12" r="12" />
10101 * </g> 10667 * </g>
10102 * </defs> 10668 * </defs>
10103 * </svg> 10669 * </svg>
10104 * </iron-iconset-svg> 10670 * </iron-iconset-svg>
10105 * 10671 *
10106 * This will automatically register the icon set "my-svg-icons" to the iconset 10672 * This will automatically register the icon set "my-svg-icons" to the iconset
10107 * database. To use these icons from within another element, make a 10673 * database. To use these icons from within another element, make a
10108 * `iron-iconset` element and call the `byId` method 10674 * `iron-iconset` element and call the `byId` method
10109 * to retrieve a given iconset. To apply a particular icon inside an 10675 * to retrieve a given iconset. To apply a particular icon inside an
10110 * element use the `applyIcon` method. For example: 10676 * element use the `applyIcon` method. For example:
10111 * 10677 *
10112 * iconset.applyIcon(iconNode, 'car'); 10678 * iconset.applyIcon(iconNode, 'car');
10113 * 10679 *
10114 * @element iron-iconset-svg 10680 * @element iron-iconset-svg
10115 * @demo demo/index.html 10681 * @demo demo/index.html
10682 * @implements {Polymer.Iconset}
10116 */ 10683 */
10117 Polymer({ 10684 Polymer({
10118
10119 is: 'iron-iconset-svg', 10685 is: 'iron-iconset-svg',
10120 10686
10121 properties: { 10687 properties: {
10122 10688
10123 /** 10689 /**
10124 * The name of the iconset. 10690 * The name of the iconset.
10125 *
10126 * @attribute name
10127 * @type string
10128 */ 10691 */
10129 name: { 10692 name: {
10130 type: String, 10693 type: String,
10131 observer: '_nameChanged' 10694 observer: '_nameChanged'
10132 }, 10695 },
10133 10696
10134 /** 10697 /**
10135 * The size of an individual icon. Note that icons must be square. 10698 * The size of an individual icon. Note that icons must be square.
10136 *
10137 * @attribute iconSize
10138 * @type number
10139 * @default 24
10140 */ 10699 */
10141 size: { 10700 size: {
10142 type: Number, 10701 type: Number,
10143 value: 24 10702 value: 24
10144 } 10703 }
10145 10704
10146 }, 10705 },
10147 10706
10707 attached: function() {
10708 this.style.display = 'none';
10709 },
10710
10148 /** 10711 /**
10149 * Construct an array of all icon names in this iconset. 10712 * Construct an array of all icon names in this iconset.
10150 * 10713 *
10151 * @return {!Array} Array of icon names. 10714 * @return {!Array} Array of icon names.
10152 */ 10715 */
10153 getIconNames: function() { 10716 getIconNames: function() {
10154 this._icons = this._createIconMap(); 10717 this._icons = this._createIconMap();
10155 return Object.keys(this._icons).map(function(n) { 10718 return Object.keys(this._icons).map(function(n) {
10156 return this.name + ':' + n; 10719 return this.name + ':' + n;
10157 }, this); 10720 }, this);
10158 }, 10721 },
10159 10722
10160 /** 10723 /**
10161 * Applies an icon to the given element. 10724 * Applies an icon to the given element.
10162 * 10725 *
10163 * An svg icon is prepended to the element's shadowRoot if it exists, 10726 * An svg icon is prepended to the element's shadowRoot if it exists,
10164 * otherwise to the element itself. 10727 * otherwise to the element itself.
10165 * 10728 *
10166 * @method applyIcon 10729 * @method applyIcon
10167 * @param {Element} element Element to which the icon is applied. 10730 * @param {Element} element Element to which the icon is applied.
10168 * @param {string} iconName Name of the icon to apply. 10731 * @param {string} iconName Name of the icon to apply.
10169 * @return {Element} The svg element which renders the icon. 10732 * @return {?Element} The svg element which renders the icon.
10170 */ 10733 */
10171 applyIcon: function(element, iconName) { 10734 applyIcon: function(element, iconName) {
10172 // insert svg element into shadow root, if it exists 10735 // insert svg element into shadow root, if it exists
10173 element = element.root || element; 10736 element = element.root || element;
10174 // Remove old svg element 10737 // Remove old svg element
10175 this.removeIcon(element); 10738 this.removeIcon(element);
10176 // install new svg element 10739 // install new svg element
10177 var svg = this._cloneIcon(iconName); 10740 var svg = this._cloneIcon(iconName);
10178 if (svg) { 10741 if (svg) {
10179 var pde = Polymer.dom(element); 10742 var pde = Polymer.dom(element);
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
10499 /** 11062 /**
10500 * The HTMLElement that will be firing relevant KeyboardEvents. 11063 * The HTMLElement that will be firing relevant KeyboardEvents.
10501 */ 11064 */
10502 keyEventTarget: { 11065 keyEventTarget: {
10503 type: Object, 11066 type: Object,
10504 value: function() { 11067 value: function() {
10505 return this; 11068 return this;
10506 } 11069 }
10507 }, 11070 },
10508 11071
11072 /**
11073 * If true, this property will cause the implementing element to
11074 * automatically stop propagation on any handled KeyboardEvents.
11075 */
11076 stopKeyboardEventPropagation: {
11077 type: Boolean,
11078 value: false
11079 },
11080
10509 _boundKeyHandlers: { 11081 _boundKeyHandlers: {
10510 type: Array, 11082 type: Array,
10511 value: function() { 11083 value: function() {
10512 return []; 11084 return [];
10513 } 11085 }
10514 }, 11086 },
10515 11087
10516 // We use this due to a limitation in IE10 where instances will have 11088 // We use this due to a limitation in IE10 where instances will have
10517 // own properties of everything on the "prototype". 11089 // own properties of everything on the "prototype".
10518 _imperativeKeyBindings: { 11090 _imperativeKeyBindings: {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
10642 keyHandlerTuple = this._boundKeyHandlers.pop(); 11214 keyHandlerTuple = this._boundKeyHandlers.pop();
10643 keyEventTarget = keyHandlerTuple[0]; 11215 keyEventTarget = keyHandlerTuple[0];
10644 eventName = keyHandlerTuple[1]; 11216 eventName = keyHandlerTuple[1];
10645 boundKeyHandler = keyHandlerTuple[2]; 11217 boundKeyHandler = keyHandlerTuple[2];
10646 11218
10647 keyEventTarget.removeEventListener(eventName, boundKeyHandler); 11219 keyEventTarget.removeEventListener(eventName, boundKeyHandler);
10648 } 11220 }
10649 }, 11221 },
10650 11222
10651 _onKeyBindingEvent: function(keyBindings, event) { 11223 _onKeyBindingEvent: function(keyBindings, event) {
11224 if (this.stopKeyboardEventPropagation) {
11225 event.stopPropagation();
11226 }
11227
10652 keyBindings.forEach(function(keyBinding) { 11228 keyBindings.forEach(function(keyBinding) {
10653 var keyCombo = keyBinding[0]; 11229 var keyCombo = keyBinding[0];
10654 var handlerName = keyBinding[1]; 11230 var handlerName = keyBinding[1];
10655 11231
10656 if (!event.defaultPrevented && keyComboMatchesEvent(keyCombo, event)) { 11232 if (!event.defaultPrevented && keyComboMatchesEvent(keyCombo, event)) {
10657 this._triggerKeyHandler(keyCombo, handlerName, event); 11233 this._triggerKeyHandler(keyCombo, handlerName, event);
10658 } 11234 }
10659 }, this); 11235 }, this);
10660 }, 11236 },
10661 11237
10662 _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) { 11238 _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
10663 var detail = Object.create(keyCombo); 11239 var detail = Object.create(keyCombo);
10664 detail.keyboardEvent = keyboardEvent; 11240 detail.keyboardEvent = keyboardEvent;
10665 11241 var event = new CustomEvent(keyCombo.event, {
10666 this[handlerName].call(this, new CustomEvent(keyCombo.event, { 11242 detail: detail,
10667 detail: detail 11243 cancelable: true
10668 })); 11244 });
11245 this[handlerName].call(this, event);
11246 if (event.defaultPrevented) {
11247 keyboardEvent.preventDefault();
11248 }
10669 } 11249 }
10670 }; 11250 };
10671 })(); 11251 })();
10672 /** 11252 /**
10673 * @demo demo/index.html 11253 * @demo demo/index.html
10674 * @polymerBehavior 11254 * @polymerBehavior
10675 */ 11255 */
10676 Polymer.IronControlState = { 11256 Polymer.IronControlState = {
10677 11257
10678 properties: { 11258 properties: {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
10722 }, 11302 },
10723 11303
10724 _focusBlurHandler: function(event) { 11304 _focusBlurHandler: function(event) {
10725 // NOTE(cdata): if we are in ShadowDOM land, `event.target` will 11305 // NOTE(cdata): if we are in ShadowDOM land, `event.target` will
10726 // eventually become `this` due to retargeting; if we are not in 11306 // eventually become `this` due to retargeting; if we are not in
10727 // ShadowDOM land, `event.target` will eventually become `this` due 11307 // ShadowDOM land, `event.target` will eventually become `this` due
10728 // to the second conditional which fires a synthetic event (that is also 11308 // to the second conditional which fires a synthetic event (that is also
10729 // handled). In either case, we can disregard `event.path`. 11309 // handled). In either case, we can disregard `event.path`.
10730 11310
10731 if (event.target === this) { 11311 if (event.target === this) {
10732 var focused = event.type === 'focus'; 11312 this._setFocused(event.type === 'focus');
10733 this._setFocused(focused); 11313 } else if (!this.shadowRoot && !this.isLightDescendant(event.target)) {
10734 } else if (!this.shadowRoot) {
10735 this.fire(event.type, {sourceEvent: event}, { 11314 this.fire(event.type, {sourceEvent: event}, {
10736 node: this, 11315 node: this,
10737 bubbles: event.bubbles, 11316 bubbles: event.bubbles,
10738 cancelable: event.cancelable 11317 cancelable: event.cancelable
10739 }); 11318 });
10740 } 11319 }
10741 }, 11320 },
10742 11321
10743 _disabledChanged: function(disabled, old) { 11322 _disabledChanged: function(disabled, old) {
10744 this.setAttribute('aria-disabled', disabled ? 'true' : 'false'); 11323 this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
10875 this._setPointerDown(true); 11454 this._setPointerDown(true);
10876 this._setPressed(true); 11455 this._setPressed(true);
10877 this._setReceivedFocusFromKeyboard(false); 11456 this._setReceivedFocusFromKeyboard(false);
10878 }, 11457 },
10879 11458
10880 _upHandler: function() { 11459 _upHandler: function() {
10881 this._setPointerDown(false); 11460 this._setPointerDown(false);
10882 this._setPressed(false); 11461 this._setPressed(false);
10883 }, 11462 },
10884 11463
11464 __isFocusedLightDescendant: function(target) {
11465 var root = Polymer.dom(this).getOwnerRoot() || document;
11466 var focusedElement = root.activeElement;
11467
11468 // TODO(noms): remove the `this !== target` check once polymer#2610 is fix ed.
11469 return this !== target && this.isLightDescendant(target) && target == focu sedElement;
11470 },
11471
11472 /**
11473 * @param {!KeyboardEvent} event .
11474 */
10885 _spaceKeyDownHandler: function(event) { 11475 _spaceKeyDownHandler: function(event) {
10886 var keyboardEvent = event.detail.keyboardEvent; 11476 var keyboardEvent = event.detail.keyboardEvent;
11477 var target = Polymer.dom(keyboardEvent).localTarget;
11478
11479 // Ignore the event if this is coming from a focused light child, since th at
11480 // element will deal with it.
11481 if (this.__isFocusedLightDescendant(target))
11482 return;
11483
10887 keyboardEvent.preventDefault(); 11484 keyboardEvent.preventDefault();
10888 keyboardEvent.stopImmediatePropagation(); 11485 keyboardEvent.stopImmediatePropagation();
10889 this._setPressed(true); 11486 this._setPressed(true);
10890 }, 11487 },
10891 11488
10892 _spaceKeyUpHandler: function() { 11489 /**
11490 * @param {!KeyboardEvent} event .
11491 */
11492 _spaceKeyUpHandler: function(event) {
11493 var keyboardEvent = event.detail.keyboardEvent;
11494 var target = Polymer.dom(keyboardEvent).localTarget;
11495
11496 // Ignore the event if this is coming from a focused light child, since th at
11497 // element will deal with it.
11498 if (this.__isFocusedLightDescendant(target))
11499 return;
11500
10893 if (this.pressed) { 11501 if (this.pressed) {
10894 this._asyncClick(); 11502 this._asyncClick();
10895 } 11503 }
10896 this._setPressed(false); 11504 this._setPressed(false);
10897 }, 11505 },
10898 11506
10899 // trigger click asynchronously, the asynchrony is useful to allow one 11507 // trigger click asynchronously, the asynchrony is useful to allow one
10900 // event handler to unwind before triggering another event 11508 // event handler to unwind before triggering another event
10901 _asyncClick: function() { 11509 _asyncClick: function() {
10902 this.async(function() { 11510 this.async(function() {
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
11659 _noinkChanged: function(noink) { 12267 _noinkChanged: function(noink) {
11660 if (this.hasRipple()) { 12268 if (this.hasRipple()) {
11661 this._ripple.noink = noink; 12269 this._ripple.noink = noink;
11662 } 12270 }
11663 } 12271 }
11664 12272
11665 }; 12273 };
11666 /** 12274 /**
11667 * `Polymer.PaperInkyFocusBehavior` implements a ripple when the element has k eyboard focus. 12275 * `Polymer.PaperInkyFocusBehavior` implements a ripple when the element has k eyboard focus.
11668 * 12276 *
11669 * @polymerBehavior Polymer.PaperInkyFocusBehaviorImpl 12277 * @polymerBehavior Polymer.PaperInkyFocusBehavior
11670 */ 12278 */
11671 Polymer.PaperInkyFocusBehaviorImpl = { 12279 Polymer.PaperInkyFocusBehaviorImpl = {
11672 12280
11673 observers: [ 12281 observers: [
11674 '_focusedChanged(receivedFocusFromKeyboard)' 12282 '_focusedChanged(receivedFocusFromKeyboard)'
11675 ], 12283 ],
11676 12284
11677 _focusedChanged: function(receivedFocusFromKeyboard) { 12285 _focusedChanged: function(receivedFocusFromKeyboard) {
11678 if (receivedFocusFromKeyboard) { 12286 if (receivedFocusFromKeyboard) {
11679 this.ensureRipple(); 12287 this.ensureRipple();
(...skipping 17 matching lines...) Expand all
11697 Polymer.PaperInkyFocusBehavior = [ 12305 Polymer.PaperInkyFocusBehavior = [
11698 Polymer.IronButtonState, 12306 Polymer.IronButtonState,
11699 Polymer.IronControlState, 12307 Polymer.IronControlState,
11700 Polymer.PaperRippleBehavior, 12308 Polymer.PaperRippleBehavior,
11701 Polymer.PaperInkyFocusBehaviorImpl 12309 Polymer.PaperInkyFocusBehaviorImpl
11702 ]; 12310 ];
11703 Polymer({ 12311 Polymer({
11704 is: 'paper-material', 12312 is: 'paper-material',
11705 12313
11706 properties: { 12314 properties: {
11707
11708 /** 12315 /**
11709 * The z-depth of this element, from 0-5. Setting to 0 will remove the 12316 * The z-depth of this element, from 0-5. Setting to 0 will remove the
11710 * shadow, and each increasing number greater than 0 will be "deeper" 12317 * shadow, and each increasing number greater than 0 will be "deeper"
11711 * than the last. 12318 * than the last.
11712 * 12319 *
11713 * @attribute elevation 12320 * @attribute elevation
11714 * @type number 12321 * @type number
11715 * @default 1 12322 * @default 1
11716 */ 12323 */
11717 elevation: { 12324 elevation: {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
11839 }, 12446 },
11840 12447
11841 _calculateElevation: function() { 12448 _calculateElevation: function() {
11842 if (!this.raised) { 12449 if (!this.raised) {
11843 this.elevation = 0; 12450 this.elevation = 0;
11844 } else { 12451 } else {
11845 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this); 12452 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
11846 } 12453 }
11847 } 12454 }
11848 }); 12455 });
11849 /** 12456 /**
11850 * `iron-range-behavior` provides the behavior for something with a minimum to m aximum range. 12457 * `iron-range-behavior` provides the behavior for something with a minimum to m aximum range.
11851 * 12458 *
11852 * @demo demo/index.html 12459 * @demo demo/index.html
11853 * @polymerBehavior 12460 * @polymerBehavior
11854 */ 12461 */
11855 Polymer.IronRangeBehavior = { 12462 Polymer.IronRangeBehavior = {
11856 12463
11857 properties: { 12464 properties: {
11858 12465
11859 /** 12466 /**
11860 * The number that represents the current value. 12467 * The number that represents the current value.
11861 */ 12468 */
11862 value: { 12469 value: {
11863 type: Number, 12470 type: Number,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
11912 return (this._clampValue(value) - this.min) / (this.max - this.min); 12519 return (this._clampValue(value) - this.min) / (this.max - this.min);
11913 }, 12520 },
11914 12521
11915 _clampValue: function(value) { 12522 _clampValue: function(value) {
11916 return Math.min(this.max, Math.max(this.min, this._calcStep(value))); 12523 return Math.min(this.max, Math.max(this.min, this._calcStep(value)));
11917 }, 12524 },
11918 12525
11919 _calcStep: function(value) { 12526 _calcStep: function(value) {
11920 /** 12527 /**
11921 * if we calculate the step using 12528 * if we calculate the step using
11922 * `Math.round(value / step) * step` we may hit a precision point issue 12529 * `Math.round(value / step) * step` we may hit a precision point issue
11923 * eg. 0.1 * 0.2 = 0.020000000000000004 12530 * eg. 0.1 * 0.2 = 0.020000000000000004
11924 * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html 12531 * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
11925 * 12532 *
11926 * as a work around we can divide by the reciprocal of `step` 12533 * as a work around we can divide by the reciprocal of `step`
11927 */ 12534 */
11928 // polymer/issues/2493 12535 // polymer/issues/2493
11929 value = parseFloat(value); 12536 value = parseFloat(value);
11930 return this.step ? (Math.round((value + this.min) / this.step) / (1 / this.s tep)) - this.min : value; 12537 return this.step ? (Math.round((value + this.min) / this.step) -
12538 (this.min / this.step)) / (1 / this.step) : value;
11931 }, 12539 },
11932 12540
11933 _validateValue: function() { 12541 _validateValue: function() {
11934 var v = this._clampValue(this.value); 12542 var v = this._clampValue(this.value);
11935 this.value = this.oldValue = isNaN(v) ? this.oldValue : v; 12543 this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
11936 return this.value !== v; 12544 return this.value !== v;
11937 }, 12545 },
11938 12546
11939 _update: function() { 12547 _update: function() {
11940 this._validateValue(); 12548 this._validateValue();
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
12375 12983
12376 return { 12984 return {
12377 InkyTextButton: InkyTextButton, 12985 InkyTextButton: InkyTextButton,
12378 Item: Item, 12986 Item: Item,
12379 }; 12987 };
12380 }); 12988 });
12381 Polymer({ 12989 Polymer({
12382 is: 'paper-item', 12990 is: 'paper-item',
12383 12991
12384 hostAttributes: { 12992 hostAttributes: {
12385 role: 'listitem', 12993 role: 'option',
12386 tabindex: '0' 12994 tabindex: '0'
12387 }, 12995 },
12388 12996
12389 behaviors: [ 12997 behaviors: [
12390 Polymer.IronControlState, 12998 Polymer.IronControlState,
12391 Polymer.IronButtonState 12999 Polymer.IronButtonState
12392 ] 13000 ]
12393 }); 13001 });
12394 /** 13002 /**
12395 * @param {!Function} selectCallback 13003 * @param {!Function} selectCallback
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
12535 /** 13143 /**
12536 * Gets or sets the selected element. The default is to use the index of t he item. 13144 * Gets or sets the selected element. The default is to use the index of t he item.
12537 */ 13145 */
12538 selected: { 13146 selected: {
12539 type: String, 13147 type: String,
12540 notify: true 13148 notify: true
12541 }, 13149 },
12542 13150
12543 /** 13151 /**
12544 * Returns the currently selected item. 13152 * Returns the currently selected item.
13153 *
13154 * @type {?Object}
12545 */ 13155 */
12546 selectedItem: { 13156 selectedItem: {
12547 type: Object, 13157 type: Object,
12548 readOnly: true, 13158 readOnly: true,
12549 notify: true 13159 notify: true
12550 }, 13160 },
12551 13161
12552 /** 13162 /**
12553 * The event that fires from items when they are selected. Selectable 13163 * The event that fires from items when they are selected. Selectable
12554 * will listen for this event from items and update the selection state. 13164 * will listen for this event from items and update the selection state.
(...skipping 21 matching lines...) Expand all
12576 13186
12577 /** 13187 /**
12578 * The attribute to set on elements when selected. 13188 * The attribute to set on elements when selected.
12579 */ 13189 */
12580 selectedAttribute: { 13190 selectedAttribute: {
12581 type: String, 13191 type: String,
12582 value: null 13192 value: null
12583 }, 13193 },
12584 13194
12585 /** 13195 /**
13196 * The list of items from which a selection can be made.
13197 */
13198 items: {
13199 type: Array,
13200 readOnly: true,
13201 value: function() {
13202 return [];
13203 }
13204 },
13205
13206 /**
12586 * The set of excluded elements where the key is the `localName` 13207 * The set of excluded elements where the key is the `localName`
12587 * of the element that will be ignored from the item list. 13208 * of the element that will be ignored from the item list.
12588 * 13209 *
12589 * @type {object}
12590 * @default {template: 1} 13210 * @default {template: 1}
12591 */ 13211 */
12592 _excludedLocalNames: { 13212 _excludedLocalNames: {
12593 type: Object, 13213 type: Object,
12594 value: function() { 13214 value: function() {
12595 return { 13215 return {
12596 'template': 1 13216 'template': 1
12597 }; 13217 };
12598 } 13218 }
12599 } 13219 }
12600 }, 13220 },
12601 13221
12602 observers: [ 13222 observers: [
12603 '_updateSelected(attrForSelected, selected)' 13223 '_updateSelected(attrForSelected, selected)'
12604 ], 13224 ],
12605 13225
12606 created: function() { 13226 created: function() {
12607 this._bindFilterItem = this._filterItem.bind(this); 13227 this._bindFilterItem = this._filterItem.bind(this);
12608 this._selection = new Polymer.IronSelection(this._applySelection.bind(this )); 13228 this._selection = new Polymer.IronSelection(this._applySelection.bind(this ));
12609 // TODO(cdata): When polymer/polymer#2535 lands, we do not need to do this
12610 // book keeping anymore:
12611 this.__listeningForActivate = false;
12612 }, 13229 },
12613 13230
12614 attached: function() { 13231 attached: function() {
12615 this._observer = this._observeItems(this); 13232 this._observer = this._observeItems(this);
12616 this._contentObserver = this._observeContent(this); 13233 this._updateItems();
12617 if (!this.selectedItem && this.selected) { 13234 if (!this._shouldUpdateSelection) {
12618 this._updateSelected(this.attrForSelected,this.selected) 13235 this._updateSelected(this.attrForSelected,this.selected)
12619 } 13236 }
12620 this._addListener(this.activateEvent); 13237 this._addListener(this.activateEvent);
12621 }, 13238 },
12622 13239
12623 detached: function() { 13240 detached: function() {
12624 if (this._observer) { 13241 if (this._observer) {
12625 this._observer.disconnect(); 13242 Polymer.dom(this).unobserveNodes(this._observer);
12626 }
12627 if (this._contentObserver) {
12628 this._contentObserver.disconnect();
12629 } 13243 }
12630 this._removeListener(this.activateEvent); 13244 this._removeListener(this.activateEvent);
12631 }, 13245 },
12632 13246
12633 /** 13247 /**
12634 * Returns an array of selectable items.
12635 *
12636 * @property items
12637 * @type Array
12638 */
12639 get items() {
12640 var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
12641 return Array.prototype.filter.call(nodes, this._bindFilterItem);
12642 },
12643
12644 /**
12645 * Returns the index of the given item. 13248 * Returns the index of the given item.
12646 * 13249 *
12647 * @method indexOf 13250 * @method indexOf
12648 * @param {Object} item 13251 * @param {Object} item
12649 * @returns Returns the index of the item 13252 * @returns Returns the index of the item
12650 */ 13253 */
12651 indexOf: function(item) { 13254 indexOf: function(item) {
12652 return this.items.indexOf(item); 13255 return this.items.indexOf(item);
12653 }, 13256 },
12654 13257
(...skipping 21 matching lines...) Expand all
12676 /** 13279 /**
12677 * Selects the next item. 13280 * Selects the next item.
12678 * 13281 *
12679 * @method selectNext 13282 * @method selectNext
12680 */ 13283 */
12681 selectNext: function() { 13284 selectNext: function() {
12682 var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.l ength; 13285 var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.l ength;
12683 this.selected = this._indexToValue(index); 13286 this.selected = this._indexToValue(index);
12684 }, 13287 },
12685 13288
13289 get _shouldUpdateSelection() {
13290 return this.selected != null;
13291 },
13292
12686 _addListener: function(eventName) { 13293 _addListener: function(eventName) {
12687 if (!this.isAttached || this.__listeningForActivate) {
12688 return;
12689 }
12690
12691 this.__listeningForActivate = true;
12692 this.listen(this, eventName, '_activateHandler'); 13294 this.listen(this, eventName, '_activateHandler');
12693 }, 13295 },
12694 13296
12695 _removeListener: function(eventName) { 13297 _removeListener: function(eventName) {
12696 this.unlisten(this, eventName, '_activateHandler'); 13298 this.unlisten(this, eventName, '_activateHandler');
12697 this.__listeningForActivate = false;
12698 }, 13299 },
12699 13300
12700 _activateEventChanged: function(eventName, old) { 13301 _activateEventChanged: function(eventName, old) {
12701 this._removeListener(old); 13302 this._removeListener(old);
12702 this._addListener(eventName); 13303 this._addListener(eventName);
12703 }, 13304 },
12704 13305
13306 _updateItems: function() {
13307 var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
13308 nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
13309 this._setItems(nodes);
13310 },
13311
12705 _updateSelected: function() { 13312 _updateSelected: function() {
12706 this._selectSelected(this.selected); 13313 this._selectSelected(this.selected);
12707 }, 13314 },
12708 13315
12709 _selectSelected: function(selected) { 13316 _selectSelected: function(selected) {
12710 this._selection.select(this._valueToItem(this.selected)); 13317 this._selection.select(this._valueToItem(this.selected));
12711 }, 13318 },
12712 13319
12713 _filterItem: function(node) { 13320 _filterItem: function(node) {
12714 return !this._excludedLocalNames[node.localName]; 13321 return !this._excludedLocalNames[node.localName];
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
12753 this.toggleAttribute(this.selectedAttribute, isSelected, item); 13360 this.toggleAttribute(this.selectedAttribute, isSelected, item);
12754 } 13361 }
12755 this._selectionChange(); 13362 this._selectionChange();
12756 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item}); 13363 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item});
12757 }, 13364 },
12758 13365
12759 _selectionChange: function() { 13366 _selectionChange: function() {
12760 this._setSelectedItem(this._selection.get()); 13367 this._setSelectedItem(this._selection.get());
12761 }, 13368 },
12762 13369
12763 // observe content changes under the given node.
12764 _observeContent: function(node) {
12765 var content = node.querySelector('content');
12766 if (content && content.parentElement === node) {
12767 return this._observeItems(node.domHost);
12768 }
12769 },
12770
12771 // observe items change under the given node. 13370 // observe items change under the given node.
12772 _observeItems: function(node) { 13371 _observeItems: function(node) {
12773 // TODO(cdata): Update this when we get distributed children changed. 13372 return Polymer.dom(node).observeNodes(function(mutations) {
12774 var observer = new MutationObserver(function(mutations) {
12775 // Let other interested parties know about the change so that 13373 // Let other interested parties know about the change so that
12776 // we don't have to recreate mutation observers everywher. 13374 // we don't have to recreate mutation observers everywher.
12777 this.fire('iron-items-changed', mutations, { 13375 this.fire('iron-items-changed', mutations, {
12778 bubbles: false, 13376 bubbles: false,
12779 cancelable: false 13377 cancelable: false
12780 }); 13378 });
12781 13379
12782 if (this.selected != null) { 13380 this._updateItems();
13381
13382 if (this._shouldUpdateSelection) {
12783 this._updateSelected(); 13383 this._updateSelected();
12784 } 13384 }
12785 }.bind(this));
12786 observer.observe(node, {
12787 childList: true,
12788 subtree: true
12789 }); 13385 });
12790 return observer;
12791 }, 13386 },
12792 13387
12793 _activateHandler: function(e) { 13388 _activateHandler: function(e) {
12794 var t = e.target; 13389 var t = e.target;
12795 var items = this.items; 13390 var items = this.items;
12796 while (t && t != this) { 13391 while (t && t != this) {
12797 var i = items.indexOf(t); 13392 var i = items.indexOf(t);
12798 if (i >= 0) { 13393 if (i >= 0) {
12799 var value = this._indexToValue(i); 13394 var value = this._indexToValue(i);
12800 this._itemActivate(value, t); 13395 this._itemActivate(value, t);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
12865 } 13460 }
12866 } else { 13461 } else {
12867 this.selected = value; 13462 this.selected = value;
12868 } 13463 }
12869 }, 13464 },
12870 13465
12871 multiChanged: function(multi) { 13466 multiChanged: function(multi) {
12872 this._selection.multi = multi; 13467 this._selection.multi = multi;
12873 }, 13468 },
12874 13469
13470 get _shouldUpdateSelection() {
13471 return this.selected != null ||
13472 (this.selectedValues != null && this.selectedValues.length);
13473 },
13474
12875 _updateSelected: function() { 13475 _updateSelected: function() {
12876 if (this.multi) { 13476 if (this.multi) {
12877 this._selectMulti(this.selectedValues); 13477 this._selectMulti(this.selectedValues);
12878 } else { 13478 } else {
12879 this._selectSelected(this.selected); 13479 this._selectSelected(this.selected);
12880 } 13480 }
12881 }, 13481 },
12882 13482
12883 _selectMulti: function(values) { 13483 _selectMulti: function(values) {
12884 this._selection.clear(); 13484 this._selection.clear();
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
13409 */ 14009 */
13410 constrain: function() { 14010 constrain: function() {
13411 var info = this._fitInfo; 14011 var info = this._fitInfo;
13412 // position at (0px, 0px) if not already positioned, so we can measure the natural size. 14012 // position at (0px, 0px) if not already positioned, so we can measure the natural size.
13413 if (!this._fitInfo.positionedBy.vertically) { 14013 if (!this._fitInfo.positionedBy.vertically) {
13414 this.style.top = '0px'; 14014 this.style.top = '0px';
13415 } 14015 }
13416 if (!this._fitInfo.positionedBy.horizontally) { 14016 if (!this._fitInfo.positionedBy.horizontally) {
13417 this.style.left = '0px'; 14017 this.style.left = '0px';
13418 } 14018 }
14019 if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy. horizontally) {
14020 // need position:fixed to properly size the element
14021 this.style.position = 'fixed';
14022 }
13419 // need border-box for margin/padding 14023 // need border-box for margin/padding
13420 this.sizingTarget.style.boxSizing = 'border-box'; 14024 this.sizingTarget.style.boxSizing = 'border-box';
13421 // constrain the width and height if not already set 14025 // constrain the width and height if not already set
13422 var rect = this.getBoundingClientRect(); 14026 var rect = this.getBoundingClientRect();
13423 if (!info.sizedBy.height) { 14027 if (!info.sizedBy.height) {
13424 this._sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height'); 14028 this._sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');
13425 } 14029 }
13426 if (!info.sizedBy.width) { 14030 if (!info.sizedBy.width) {
13427 this._sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right ', 'Width'); 14031 this._sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right ', 'Width');
13428 } 14032 }
(...skipping 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after
15400 _altChanged: function(newValue, oldValue) { 16004 _altChanged: function(newValue, oldValue) {
15401 var label = this.getAttribute('aria-label'); 16005 var label = this.getAttribute('aria-label');
15402 16006
15403 // Don't stomp over a user-set aria-label. 16007 // Don't stomp over a user-set aria-label.
15404 if (!label || oldValue == label) { 16008 if (!label || oldValue == label) {
15405 this.setAttribute('aria-label', newValue); 16009 this.setAttribute('aria-label', newValue);
15406 } 16010 }
15407 } 16011 }
15408 }); 16012 });
15409 /** 16013 /**
15410 * Use `Polymer.IronValidatableBehavior` to implement an element that validate s user input. 16014 * `Use Polymer.IronValidatableBehavior` to implement an element that validate s user input.
16015 * Use the related `Polymer.IronValidatorBehavior` to add custom validation lo gic to an iron-input.
16016 *
16017 * By default, an `<iron-form>` element validates its fields when the user pre sses the submit button.
16018 * To validate a form imperatively, call the form's `validate()` method, which in turn will
16019 * call `validate()` on all its children. By using `Polymer.IronValidatableBeh avior`, your
16020 * custom element will get a public `validate()`, which
16021 * will return the validity of the element, and a corresponding `invalid` attr ibute,
16022 * which can be used for styling.
16023 *
16024 * To implement the custom validation logic of your element, you must override
16025 * the protected `_getValidity()` method of this behaviour, rather than `valid ate()`.
16026 * See [this](https://github.com/PolymerElements/iron-form/blob/master/demo/si mple-element.html)
16027 * for an example.
15411 * 16028 *
15412 * ### Accessibility 16029 * ### Accessibility
15413 * 16030 *
15414 * Changing the `invalid` property, either manually or by calling `validate()` will update the 16031 * Changing the `invalid` property, either manually or by calling `validate()` will update the
15415 * `aria-invalid` attribute. 16032 * `aria-invalid` attribute.
15416 * 16033 *
15417 * @demo demo/index.html 16034 * @demo demo/index.html
15418 * @polymerBehavior 16035 * @polymerBehavior
15419 */ 16036 */
15420 Polymer.IronValidatableBehavior = { 16037 Polymer.IronValidatableBehavior = {
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
15876 } 16493 }
15877 }, 16494 },
15878 16495
15879 attached: function() { 16496 attached: function() {
15880 // Only validate when attached if the input already has a value. 16497 // Only validate when attached if the input already has a value.
15881 if (this._inputElementValue != '') { 16498 if (this._inputElementValue != '') {
15882 this._handleValueAndAutoValidate(this._inputElement); 16499 this._handleValueAndAutoValidate(this._inputElement);
15883 } else { 16500 } else {
15884 this._handleValue(this._inputElement); 16501 this._handleValue(this._inputElement);
15885 } 16502 }
16503
16504 this._numberOfPrefixNodes = 0;
16505 this._prefixObserver = Polymer.dom(this.$.prefix).observeNodes(
16506 function(mutations) {
16507 // Keep track whether there's at least one prefix node, since it
16508 // affects laying out the floating label.
16509 this._numberOfPrefixNodes += mutations.addedNodes.length -
16510 mutations.removedNodes.length;
16511 }.bind(this));
16512 },
16513
16514 detached: function() {
16515 if (this._prefixObserver) {
16516 Polymer.dom(this.$.prefix).unobserveNodes(this._prefixObserver);
16517 }
15886 }, 16518 },
15887 16519
15888 _onAddonAttached: function(event) { 16520 _onAddonAttached: function(event) {
15889 if (!this._addons) { 16521 if (!this._addons) {
15890 this._addons = []; 16522 this._addons = [];
15891 } 16523 }
15892 var target = event.target; 16524 var target = event.target;
15893 if (this._addons.indexOf(target) === -1) { 16525 if (this._addons.indexOf(target) === -1) {
15894 this._addons.push(target); 16526 this._addons.push(target);
15895 if (this.isAttached) { 16527 if (this.isAttached) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
15972 if (!noLabelFloat) { 16604 if (!noLabelFloat) {
15973 var label = this.querySelector('label'); 16605 var label = this.querySelector('label');
15974 16606
15975 if (alwaysFloatLabel || _inputHasContent) { 16607 if (alwaysFloatLabel || _inputHasContent) {
15976 cls += ' label-is-floating'; 16608 cls += ' label-is-floating';
15977 if (invalid) { 16609 if (invalid) {
15978 cls += ' is-invalid'; 16610 cls += ' is-invalid';
15979 } else if (focused) { 16611 } else if (focused) {
15980 cls += " label-is-highlighted"; 16612 cls += " label-is-highlighted";
15981 } 16613 }
15982 // The label might have a horizontal offset if a prefix element exists 16614 // If a prefix element exists, the label has a horizontal offset
15983 // which needs to be undone when displayed as a floating label. 16615 // which needs to be undone when displayed as a floating label.
15984 if (Polymer.dom(this.$.prefix).getDistributedNodes().length > 0 && 16616 if (this._numberOfPrefixNodes > 0) {
15985 label && label.offsetParent) { 16617 this.$.labelAndInputContainer.style.position = 'static';
15986 label.style.left = -label.offsetParent.offsetLeft + 'px';
15987 } 16618 }
15988 } else { 16619 } else {
15989 // When the label is not floating, it should overlap the input element . 16620 // When the label is not floating, it should overlap the input element .
15990 if (label) { 16621 if (label) {
15991 label.style.left = 0; 16622 this.$.labelAndInputContainer.style.position = 'relative';
15992 } 16623 }
15993 } 16624 }
15994 } else { 16625 } else {
15995 if (_inputHasContent) { 16626 if (_inputHasContent) {
15996 cls += ' label-is-hidden'; 16627 cls += ' label-is-hidden';
15997 } 16628 }
15998 } 16629 }
15999 return cls; 16630 return cls;
16000 }, 16631 },
16001 16632
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
16193 // Copyright 2015 The Chromium Authors. All rights reserved. 16824 // Copyright 2015 The Chromium Authors. All rights reserved.
16194 // Use of this source code is governed by a BSD-style license that can be 16825 // Use of this source code is governed by a BSD-style license that can be
16195 // found in the LICENSE file. 16826 // found in the LICENSE file.
16196 16827
16197 cr.define('downloads', function() { 16828 cr.define('downloads', function() {
16198 var Manager = Polymer({ 16829 var Manager = Polymer({
16199 is: 'downloads-manager', 16830 is: 'downloads-manager',
16200 16831
16201 properties: { 16832 properties: {
16202 hasDownloads_: { 16833 hasDownloads_: {
16834 observer: 'hasDownloadsChanged_',
16203 type: Boolean, 16835 type: Boolean,
16204 value: false,
16205 }, 16836 },
16206 16837
16207 items_: { 16838 items_: {
16208 type: Array, 16839 type: Array,
16840 value: function() { return []; },
16209 }, 16841 },
16210 }, 16842 },
16211 16843
16844 observers: [
16845 'itemsChanged_(items_.*)',
16846 ],
16847
16848 /** @private */
16849 clearAll_: function() {
16850 this.set('items_', []);
16851 },
16852
16853 /** @private */
16854 hasDownloadsChanged_: function() {
16855 if (loadTimeData.getBoolean('allowDeletingHistory'))
16856 this.$.toolbar.downloadsShowing = this.hasDownloads_;
16857
16858 if (this.hasDownloads_) {
16859 this.$['downloads-list'].fire('iron-resize');
16860 } else {
16861 var isSearching = downloads.ActionService.getInstance().isSearching();
16862 var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
16863 this.$['no-downloads'].querySelector('span').textContent =
16864 loadTimeData.getString(messageToShow);
16865 }
16866 },
16867
16868 /**
16869 * @param {number} index
16870 * @param {!Array<!downloads.Data>} list
16871 * @private
16872 */
16873 insertItems_: function(index, list) {
16874 this.splice.apply(this, ['items_', index, 0].concat(list));
16875 this.updateHideDates_(index, index + list.length);
16876 this.$.panel.classList.remove('loading');
16877 },
16878
16879 /** @private */
16880 itemsChanged_: function() {
16881 this.hasDownloads_ = this.items_.length > 0;
16882 },
16883
16212 /** 16884 /**
16213 * @param {Event} e 16885 * @param {Event} e
16214 * @private 16886 * @private
16215 */ 16887 */
16216 onCanExecute_: function(e) { 16888 onCanExecute_: function(e) {
16217 e = /** @type {cr.ui.CanExecuteEvent} */(e); 16889 e = /** @type {cr.ui.CanExecuteEvent} */(e);
16218 switch (e.command.id) { 16890 switch (e.command.id) {
16219 case 'undo-command': 16891 case 'undo-command':
16220 e.canExecute = this.$.toolbar.canUndo(); 16892 e.canExecute = this.$.toolbar.canUndo();
16221 break; 16893 break;
(...skipping 18 matching lines...) Expand all
16240 onLoad_: function() { 16912 onLoad_: function() {
16241 cr.ui.decorate('command', cr.ui.Command); 16913 cr.ui.decorate('command', cr.ui.Command);
16242 document.addEventListener('canExecute', this.onCanExecute_.bind(this)); 16914 document.addEventListener('canExecute', this.onCanExecute_.bind(this));
16243 document.addEventListener('command', this.onCommand_.bind(this)); 16915 document.addEventListener('command', this.onCommand_.bind(this));
16244 16916
16245 // Shows all downloads. 16917 // Shows all downloads.
16246 downloads.ActionService.getInstance().search(''); 16918 downloads.ActionService.getInstance().search('');
16247 }, 16919 },
16248 16920
16249 /** 16921 /**
16250 * @return {number} The number of downloads shown on the page. 16922 * @param {number} index
16251 * @private 16923 * @private
16252 */ 16924 */
16253 size_: function() { 16925 removeItem_: function(index) {
16254 return this.items_.length; 16926 this.splice('items_', index, 1);
16927 this.updateHideDates_(index, index);
16255 }, 16928 },
16256 16929
16257 /** 16930 /**
16258 * Called when all items need to be updated. 16931 * @param {number} start
16259 * @param {!Array<!downloads.Data>} list A list of new download data. 16932 * @param {number} end
16260 * @private 16933 * @private
16261 */ 16934 */
16262 updateAll_: function(list) { 16935 updateHideDates_: function(start, end) {
16263 /** @private {!Object<number>} */ 16936 for (var i = start; i <= end; ++i) {
16264 this.idToIndex_ = {}; 16937 var current = this.items_[i];
16265 16938 if (!current)
16266 for (var i = 0; i < list.length; ++i) { 16939 continue;
16267 var data = list[i]; 16940 var prev = this.items_[i - 1];
16268 16941 current.hideDate = !!prev && prev.date_string == current.date_string;
16269 this.idToIndex_[data.id] = data.index = i;
16270
16271 var prev = list[i - 1];
16272 data.hideDate = !!prev && prev.date_string == data.date_string;
16273 } 16942 }
16274
16275 // TODO(dbeam): this resets the scroll position, which is a huge bummer.
16276 // Removing something from the bottom of the list should not scroll you
16277 // back to the top. The grand plan is to restructure how the C++ sends the
16278 // JS data so that it only gets updates (rather than the most recent set
16279 // of items). TL;DR - we can't ship with this bug.
16280 this.items_ = list;
16281
16282 var hasDownloads = this.size_() > 0;
16283 if (!hasDownloads) {
16284 var isSearching = downloads.ActionService.getInstance().isSearching();
16285 var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
16286 this.$['no-downloads'].querySelector('span').textContent =
16287 loadTimeData.getString(messageToShow);
16288 }
16289 this.hasDownloads_ = hasDownloads;
16290
16291 if (loadTimeData.getBoolean('allowDeletingHistory'))
16292 this.$.toolbar.downloadsShowing = this.hasDownloads_;
16293
16294 this.$.panel.classList.remove('loading');
16295 }, 16943 },
16296 16944
16297 /** 16945 /**
16946 * @param {number} index
16298 * @param {!downloads.Data} data 16947 * @param {!downloads.Data} data
16299 * @private 16948 * @private
16300 */ 16949 */
16301 updateItem_: function(data) { 16950 updateItem_: function(index, data) {
16302 var index = this.idToIndex_[data.id];
16303 this.set('items_.' + index, data); 16951 this.set('items_.' + index, data);
16952 this.updateHideDates_(index, index);
16304 this.$['downloads-list'].updateSizeForItem(index); 16953 this.$['downloads-list'].updateSizeForItem(index);
16305 }, 16954 },
16306 }); 16955 });
16307 16956
16308 Manager.size = function() { 16957 Manager.clearAll = function() {
16309 return document.querySelector('downloads-manager').size_(); 16958 Manager.get().clearAll_();
16310 }; 16959 };
16311 16960
16312 Manager.updateAll = function(list) { 16961 /** @return {!downloads.Manager} */
16313 document.querySelector('downloads-manager').updateAll_(list); 16962 Manager.get = function() {
16963 return queryRequiredElement('downloads-manager');
16314 }; 16964 };
16315 16965
16316 Manager.updateItem = function(item) { 16966 Manager.insertItems = function(index, list) {
16317 document.querySelector('downloads-manager').updateItem_(item); 16967 Manager.get().insertItems_(index, list);
16318 }; 16968 };
16319 16969
16320 Manager.onLoad = function() { 16970 Manager.onLoad = function() {
16321 document.querySelector('downloads-manager').onLoad_(); 16971 Manager.get().onLoad_();
16972 };
16973
16974 Manager.removeItem = function(index) {
16975 Manager.get().removeItem_(index);
16976 };
16977
16978 Manager.updateItem = function(index, data) {
16979 Manager.get().updateItem_(index, data);
16322 }; 16980 };
16323 16981
16324 return {Manager: Manager}; 16982 return {Manager: Manager};
16325 }); 16983 });
16326 // Copyright 2015 The Chromium Authors. All rights reserved. 16984 // Copyright 2015 The Chromium Authors. All rights reserved.
16327 // Use of this source code is governed by a BSD-style license that can be 16985 // Use of this source code is governed by a BSD-style license that can be
16328 // found in the LICENSE file. 16986 // found in the LICENSE file.
16329 16987
16330 window.addEventListener('load', downloads.Manager.onLoad); 16988 window.addEventListener('load', downloads.Manager.onLoad);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698