| OLD | NEW |
| 1 // Copyright (c) 2012 The Polymer Authors. All rights reserved. | 1 // Copyright (c) 2012 The Polymer Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
| 5 // met: | 5 // met: |
| 6 // | 6 // |
| 7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following disclaimer | 10 // copyright notice, this list of conditions and the following disclaimer |
| 11 // in the documentation and/or other materials provided with the | 11 // in the documentation and/or other materials provided with the |
| 12 // distribution. | 12 // distribution. |
| 13 // * Neither the name of Google Inc. nor the names of its | 13 // * Neither the name of Google Inc. nor the names of its |
| 14 // contributors may be used to endorse or promote products derived from | 14 // contributors may be used to endorse or promote products derived from |
| 15 // this software without specific prior written permission. | 15 // this software without specific prior written permission. |
| 16 // | 16 // |
| 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 (function() { |
| 29 |
| 30 var scope = window.PolymerLoader = {}; |
| 31 var flags = {}; |
| 32 |
| 33 // convert url arguments to flags |
| 34 |
| 35 if (!flags.noOpts) { |
| 36 location.search.slice(1).split('&').forEach(function(o) { |
| 37 o = o.split('='); |
| 38 o[0] && (flags[o[0]] = o[1] || true); |
| 39 }); |
| 40 } |
| 41 |
| 42 // process global logFlags |
| 43 |
| 44 parseLogFlags(flags); |
| 45 |
| 46 function load(scopeName) { |
| 47 // imports |
| 48 |
| 49 var scope = window[scopeName]; |
| 50 var entryPointName = scope.entryPointName; |
| 51 var processFlags = scope.processFlags; |
| 52 |
| 53 // acquire attributes and base path from entry point |
| 54 |
| 55 var entryPoint = findScript(entryPointName); |
| 56 var base = entryPoint.basePath; |
| 57 |
| 58 // acquire common flags |
| 59 var flags = scope.flags; |
| 60 |
| 61 // convert attributes to flags |
| 62 var flags = PolymerLoader.flags; |
| 63 for (var i=0, a; (a=entryPoint.attributes[i]); i++) { |
| 64 if (a.name !== 'src') { |
| 65 flags[a.name] = a.value || true; |
| 66 } |
| 67 } |
| 68 |
| 69 // parse log flags into global |
| 70 parseLogFlags(flags); |
| 71 |
| 72 // exports |
| 73 |
| 74 scope.basePath = base; |
| 75 scope.flags = flags; |
| 76 |
| 77 // process flags for dynamic dependencies |
| 78 |
| 79 if (processFlags) { |
| 80 processFlags.call(scope, flags); |
| 81 } |
| 82 |
| 83 // post-process imports |
| 84 |
| 85 var modules = scope.modules || []; |
| 86 var sheets = scope.sheets || []; |
| 87 |
| 88 // write script tags for dependencies |
| 89 |
| 90 modules.forEach(function(src) { |
| 91 document.write('<script src="' + base + src + '"></script>'); |
| 92 }); |
| 93 |
| 94 // write link tags for styles |
| 95 |
| 96 sheets.forEach(function(src) { |
| 97 document.write('<link rel="stylesheet" href="' + base + src + '">'); |
| 98 }); |
| 99 } |
| 100 |
| 101 // utility method |
| 102 |
| 103 function findScript(fileName) { |
| 104 var script = document.querySelector('script[src*="' + fileName + '"]'); |
| 105 var src = script.attributes.src.value; |
| 106 script.basePath = src.slice(0, src.indexOf(fileName)); |
| 107 return script; |
| 108 } |
| 109 |
| 110 function parseLogFlags(flags) { |
| 111 var logFlags = window.logFlags = window.logFlags || {}; |
| 112 if (flags.log) { |
| 113 flags.log.split(',').forEach(function(f) { |
| 114 logFlags[f] = true; |
| 115 }); |
| 116 } |
| 117 } |
| 118 |
| 119 scope.flags = flags; |
| 120 scope.load = load; |
| 121 |
| 122 })(); |
| 123 |
| 28 window.CustomElements = {flags:{}}; | 124 window.CustomElements = {flags:{}}; |
| 29 // SideTable is a weak map where possible. If WeakMap is not available the | 125 // SideTable is a weak map where possible. If WeakMap is not available the |
| 30 // association is stored as an expando property. | 126 // association is stored as an expando property. |
| 31 var SideTable; | 127 var SideTable; |
| 32 // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox | 128 // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox |
| 33 if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') <
0) { | 129 if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') <
0) { |
| 34 SideTable = WeakMap; | 130 SideTable = WeakMap; |
| 35 } else { | 131 } else { |
| 36 (function() { | 132 (function() { |
| 37 var defineProperty = Object.defineProperty; | 133 var defineProperty = Object.defineProperty; |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 if (find(e, data) !== true) { | 722 if (find(e, data) !== true) { |
| 627 findAll(e, find, data); | 723 findAll(e, find, data); |
| 628 } | 724 } |
| 629 e = e.nextElementSibling; | 725 e = e.nextElementSibling; |
| 630 } | 726 } |
| 631 return null; | 727 return null; |
| 632 } | 728 } |
| 633 | 729 |
| 634 // walk all shadowRoots on a given node. | 730 // walk all shadowRoots on a given node. |
| 635 function forRoots(node, cb) { | 731 function forRoots(node, cb) { |
| 636 var root = node.shadowRoot; | 732 var root = node.webkitShadowRoot; |
| 637 while(root) { | 733 while(root) { |
| 638 forSubtree(root, cb); | 734 forSubtree(root, cb); |
| 639 root = root.olderShadowRoot; | 735 root = root.olderShadowRoot; |
| 640 } | 736 } |
| 641 } | 737 } |
| 642 | 738 |
| 643 // walk the subtree rooted at node, including descent into shadow-roots, | 739 // walk the subtree rooted at node, including descent into shadow-roots, |
| 644 // applying 'cb' to each element | 740 // applying 'cb' to each element |
| 645 function forSubtree(node, cb) { | 741 function forSubtree(node, cb) { |
| 646 //logFlags.dom && node.childNodes && node.childNodes.length && console.group('
subTree: ', node); | 742 //logFlags.dom && node.childNodes && node.childNodes.length && console.group('
subTree: ', node); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 789 |
| 694 function insertedNode(node) { | 790 function insertedNode(node) { |
| 695 inserted(node); | 791 inserted(node); |
| 696 if (inDocument(node)) { | 792 if (inDocument(node)) { |
| 697 forSubtree(node, function(e) { | 793 forSubtree(node, function(e) { |
| 698 inserted(e); | 794 inserted(e); |
| 699 }); | 795 }); |
| 700 } | 796 } |
| 701 } | 797 } |
| 702 | 798 |
| 703 | |
| 704 // TODO(sorvell): on platforms without MutationObserver, mutations may not be | |
| 705 // reliable and therefore entered/leftView are not reliable. | |
| 706 // To make these callbacks less likely to fail, we defer all inserts and removes | |
| 707 // to give a chance for elements to be inserted into dom. | |
| 708 // This ensures enteredViewCallback fires for elements that are created and | |
| 709 // immediately added to dom. | |
| 710 var hasPolyfillMutations = (!window.MutationObserver || | |
| 711 (window.MutationObserver === window.JsMutationObserver)); | |
| 712 scope.hasPolyfillMutations = hasPolyfillMutations; | |
| 713 | |
| 714 var isPendingMutations = false; | |
| 715 var pendingMutations = []; | |
| 716 function deferMutation(fn) { | |
| 717 pendingMutations.push(fn); | |
| 718 if (!isPendingMutations) { | |
| 719 isPendingMutations = true; | |
| 720 var async = (window.Platform && window.Platform.endOfMicrotask) || | |
| 721 setTimeout; | |
| 722 async(takeMutations); | |
| 723 } | |
| 724 } | |
| 725 | |
| 726 function takeMutations() { | |
| 727 isPendingMutations = false; | |
| 728 var $p = pendingMutations; | |
| 729 for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) { | |
| 730 p(); | |
| 731 } | |
| 732 pendingMutations = []; | |
| 733 } | |
| 734 | |
| 735 function inserted(element) { | |
| 736 if (hasPolyfillMutations) { | |
| 737 deferMutation(function() { | |
| 738 _inserted(element); | |
| 739 }); | |
| 740 } else { | |
| 741 _inserted(element); | |
| 742 } | |
| 743 } | |
| 744 | |
| 745 // TODO(sjmiles): if there are descents into trees that can never have inDocumen
t(*) true, fix this | 799 // TODO(sjmiles): if there are descents into trees that can never have inDocumen
t(*) true, fix this |
| 746 function _inserted(element) { | 800 |
| 801 function inserted(element) { |
| 747 // TODO(sjmiles): it's possible we were inserted and removed in the space | 802 // TODO(sjmiles): it's possible we were inserted and removed in the space |
| 748 // of one microtask, in which case we won't be 'inDocument' here | 803 // of one microtask, in which case we won't be 'inDocument' here |
| 749 // But there are other cases where we are testing for inserted without | 804 // But there are other cases where we are testing for inserted without |
| 750 // specific knowledge of mutations, and must test 'inDocument' to determine | 805 // specific knowledge of mutations, and must test 'inDocument' to determine |
| 751 // whether to call inserted | 806 // whether to call inserted |
| 752 // If we can factor these cases into separate code paths we can have | 807 // If we can factor these cases into separate code paths we can have |
| 753 // better diagnostics. | 808 // better diagnostics. |
| 754 // TODO(sjmiles): when logging, do work on all custom elements so we can | 809 // TODO(sjmiles): when logging, do work on all custom elements so we can |
| 755 // track behavior even when callbacks not defined | 810 // track behavior even when callbacks not defined |
| 756 //console.log('inserted: ', element.localName); | 811 //console.log('inserted: ', element.localName); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 775 } | 830 } |
| 776 } | 831 } |
| 777 | 832 |
| 778 function removedNode(node) { | 833 function removedNode(node) { |
| 779 removed(node); | 834 removed(node); |
| 780 forSubtree(node, function(e) { | 835 forSubtree(node, function(e) { |
| 781 removed(e); | 836 removed(e); |
| 782 }); | 837 }); |
| 783 } | 838 } |
| 784 | 839 |
| 785 | |
| 786 function removed(element) { | |
| 787 if (hasPolyfillMutations) { | |
| 788 deferMutation(function() { | |
| 789 _removed(element); | |
| 790 }); | |
| 791 } else { | |
| 792 _removed(element); | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 function removed(element) { | 840 function removed(element) { |
| 797 // TODO(sjmiles): temporary: do work on all custom elements so we can track | 841 // TODO(sjmiles): temporary: do work on all custom elements so we can track |
| 798 // behavior even when callbacks not defined | 842 // behavior even when callbacks not defined |
| 799 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) { | 843 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) { |
| 800 logFlags.dom && console.log('removed:', element.localName); | 844 logFlags.dom && console.log('removed:', element.localName); |
| 801 if (!inDocument(element)) { | 845 if (!inDocument(element)) { |
| 802 element.__inserted = (element.__inserted || 0) - 1; | 846 element.__inserted = (element.__inserted || 0) - 1; |
| 803 // if we are in a 'inserted' state, bluntly adjust to an 'removed' state | 847 // if we are in a 'inserted' state, bluntly adjust to an 'removed' state |
| 804 if (element.__inserted > 0) { | 848 if (element.__inserted > 0) { |
| 805 element.__inserted = 0; | 849 element.__inserted = 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 821 window.ShadowDOMPolyfill.wrapIfNeeded(document) || document; | 865 window.ShadowDOMPolyfill.wrapIfNeeded(document) || document; |
| 822 while (p) { | 866 while (p) { |
| 823 if (p == doc) { | 867 if (p == doc) { |
| 824 return true; | 868 return true; |
| 825 } | 869 } |
| 826 p = p.parentNode || p.host; | 870 p = p.parentNode || p.host; |
| 827 } | 871 } |
| 828 } | 872 } |
| 829 | 873 |
| 830 function watchShadow(node) { | 874 function watchShadow(node) { |
| 831 if (node.shadowRoot && !node.shadowRoot.__watched) { | 875 if (node.webkitShadowRoot && !node.webkitShadowRoot.__watched) { |
| 832 logFlags.dom && console.log('watching shadow-root for: ', node.localName); | 876 logFlags.dom && console.log('watching shadow-root for: ', node.localName); |
| 833 // watch all unwatched roots... | 877 // watch all unwatched roots... |
| 834 var root = node.shadowRoot; | 878 var root = node.webkitShadowRoot; |
| 835 while (root) { | 879 while (root) { |
| 836 watchRoot(root); | 880 watchRoot(root); |
| 837 root = root.olderShadowRoot; | 881 root = root.olderShadowRoot; |
| 838 } | 882 } |
| 839 } | 883 } |
| 840 } | 884 } |
| 841 | 885 |
| 842 function watchRoot(root) { | 886 function watchRoot(root) { |
| 843 if (!root.__watched) { | 887 if (!root.__watched) { |
| 844 observe(root); | 888 observe(root); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 //logFlags.dom && console.groupEnd(); | 940 //logFlags.dom && console.groupEnd(); |
| 897 }); | 941 }); |
| 898 logFlags.dom && console.groupEnd(); | 942 logFlags.dom && console.groupEnd(); |
| 899 }; | 943 }; |
| 900 | 944 |
| 901 var observer = new MutationObserver(handler); | 945 var observer = new MutationObserver(handler); |
| 902 | 946 |
| 903 function takeRecords() { | 947 function takeRecords() { |
| 904 // TODO(sjmiles): ask Raf why we have to call handler ourselves | 948 // TODO(sjmiles): ask Raf why we have to call handler ourselves |
| 905 handler(observer.takeRecords()); | 949 handler(observer.takeRecords()); |
| 906 takeMutations(); | |
| 907 } | 950 } |
| 908 | 951 |
| 909 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); | 952 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); |
| 910 | 953 |
| 911 function observe(inRoot) { | 954 function observe(inRoot) { |
| 912 observer.observe(inRoot, {childList: true, subtree: true}); | 955 observer.observe(inRoot, {childList: true, subtree: true}); |
| 913 } | 956 } |
| 914 | 957 |
| 915 function observeDocument(document) { | 958 function observeDocument(document) { |
| 916 observe(document); | 959 observe(document); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 } | 1458 } |
| 1416 | 1459 |
| 1417 if (document.readyState === 'complete') { | 1460 if (document.readyState === 'complete') { |
| 1418 bootstrap(); | 1461 bootstrap(); |
| 1419 } else { | 1462 } else { |
| 1420 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded'; | 1463 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded'; |
| 1421 window.addEventListener(loadEvent, bootstrap); | 1464 window.addEventListener(loadEvent, bootstrap); |
| 1422 } | 1465 } |
| 1423 | 1466 |
| 1424 })(); | 1467 })(); |
| 1425 | |
| 1426 (function() { | |
| 1427 // Patch to allow custom element and shadow dom to work together, from: | |
| 1428 // https://github.com/Polymer/platform/blob/master/src/patches-shadowdom-polyfil
l.js | |
| 1429 // include .host reference | |
| 1430 if (HTMLElement.prototype.createShadowRoot) { | |
| 1431 var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot; | |
| 1432 HTMLElement.prototype.createShadowRoot = function() { | |
| 1433 var root = originalCreateShadowRoot.call(this); | |
| 1434 root.host = this; | |
| 1435 return root; | |
| 1436 } | |
| 1437 } | |
| 1438 })(); | |
| OLD | NEW |