| 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 | |
| 124 window.CustomElements = {flags:{}}; | 28 window.CustomElements = {flags:{}}; |
| 125 // SideTable is a weak map where possible. If WeakMap is not available the | 29 // SideTable is a weak map where possible. If WeakMap is not available the |
| 126 // association is stored as an expando property. | 30 // association is stored as an expando property. |
| 127 var SideTable; | 31 var SideTable; |
| 128 // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox | 32 // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox |
| 129 if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') <
0) { | 33 if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') <
0) { |
| 130 SideTable = WeakMap; | 34 SideTable = WeakMap; |
| 131 } else { | 35 } else { |
| 132 (function() { | 36 (function() { |
| 133 var defineProperty = Object.defineProperty; | 37 var defineProperty = Object.defineProperty; |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 if (find(e, data) !== true) { | 626 if (find(e, data) !== true) { |
| 723 findAll(e, find, data); | 627 findAll(e, find, data); |
| 724 } | 628 } |
| 725 e = e.nextElementSibling; | 629 e = e.nextElementSibling; |
| 726 } | 630 } |
| 727 return null; | 631 return null; |
| 728 } | 632 } |
| 729 | 633 |
| 730 // walk all shadowRoots on a given node. | 634 // walk all shadowRoots on a given node. |
| 731 function forRoots(node, cb) { | 635 function forRoots(node, cb) { |
| 732 var root = node.webkitShadowRoot; | 636 var root = node.shadowRoot; |
| 733 while(root) { | 637 while(root) { |
| 734 forSubtree(root, cb); | 638 forSubtree(root, cb); |
| 735 root = root.olderShadowRoot; | 639 root = root.olderShadowRoot; |
| 736 } | 640 } |
| 737 } | 641 } |
| 738 | 642 |
| 739 // walk the subtree rooted at node, including descent into shadow-roots, | 643 // walk the subtree rooted at node, including descent into shadow-roots, |
| 740 // applying 'cb' to each element | 644 // applying 'cb' to each element |
| 741 function forSubtree(node, cb) { | 645 function forSubtree(node, cb) { |
| 742 //logFlags.dom && node.childNodes && node.childNodes.length && console.group('
subTree: ', node); | 646 //logFlags.dom && node.childNodes && node.childNodes.length && console.group('
subTree: ', node); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 | 693 |
| 790 function insertedNode(node) { | 694 function insertedNode(node) { |
| 791 inserted(node); | 695 inserted(node); |
| 792 if (inDocument(node)) { | 696 if (inDocument(node)) { |
| 793 forSubtree(node, function(e) { | 697 forSubtree(node, function(e) { |
| 794 inserted(e); | 698 inserted(e); |
| 795 }); | 699 }); |
| 796 } | 700 } |
| 797 } | 701 } |
| 798 | 702 |
| 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 |
| 799 // TODO(sjmiles): if there are descents into trees that can never have inDocumen
t(*) true, fix this | 745 // TODO(sjmiles): if there are descents into trees that can never have inDocumen
t(*) true, fix this |
| 800 | 746 function _inserted(element) { |
| 801 function inserted(element) { | |
| 802 // TODO(sjmiles): it's possible we were inserted and removed in the space | 747 // TODO(sjmiles): it's possible we were inserted and removed in the space |
| 803 // of one microtask, in which case we won't be 'inDocument' here | 748 // of one microtask, in which case we won't be 'inDocument' here |
| 804 // But there are other cases where we are testing for inserted without | 749 // But there are other cases where we are testing for inserted without |
| 805 // specific knowledge of mutations, and must test 'inDocument' to determine | 750 // specific knowledge of mutations, and must test 'inDocument' to determine |
| 806 // whether to call inserted | 751 // whether to call inserted |
| 807 // If we can factor these cases into separate code paths we can have | 752 // If we can factor these cases into separate code paths we can have |
| 808 // better diagnostics. | 753 // better diagnostics. |
| 809 // TODO(sjmiles): when logging, do work on all custom elements so we can | 754 // TODO(sjmiles): when logging, do work on all custom elements so we can |
| 810 // track behavior even when callbacks not defined | 755 // track behavior even when callbacks not defined |
| 811 //console.log('inserted: ', element.localName); | 756 //console.log('inserted: ', element.localName); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 830 } | 775 } |
| 831 } | 776 } |
| 832 | 777 |
| 833 function removedNode(node) { | 778 function removedNode(node) { |
| 834 removed(node); | 779 removed(node); |
| 835 forSubtree(node, function(e) { | 780 forSubtree(node, function(e) { |
| 836 removed(e); | 781 removed(e); |
| 837 }); | 782 }); |
| 838 } | 783 } |
| 839 | 784 |
| 785 |
| 786 function removed(element) { |
| 787 if (hasPolyfillMutations) { |
| 788 deferMutation(function() { |
| 789 _removed(element); |
| 790 }); |
| 791 } else { |
| 792 _removed(element); |
| 793 } |
| 794 } |
| 795 |
| 840 function removed(element) { | 796 function removed(element) { |
| 841 // TODO(sjmiles): temporary: do work on all custom elements so we can track | 797 // TODO(sjmiles): temporary: do work on all custom elements so we can track |
| 842 // behavior even when callbacks not defined | 798 // behavior even when callbacks not defined |
| 843 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) { | 799 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) { |
| 844 logFlags.dom && console.log('removed:', element.localName); | 800 logFlags.dom && console.log('removed:', element.localName); |
| 845 if (!inDocument(element)) { | 801 if (!inDocument(element)) { |
| 846 element.__inserted = (element.__inserted || 0) - 1; | 802 element.__inserted = (element.__inserted || 0) - 1; |
| 847 // if we are in a 'inserted' state, bluntly adjust to an 'removed' state | 803 // if we are in a 'inserted' state, bluntly adjust to an 'removed' state |
| 848 if (element.__inserted > 0) { | 804 if (element.__inserted > 0) { |
| 849 element.__inserted = 0; | 805 element.__inserted = 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 865 window.ShadowDOMPolyfill.wrapIfNeeded(document) || document; | 821 window.ShadowDOMPolyfill.wrapIfNeeded(document) || document; |
| 866 while (p) { | 822 while (p) { |
| 867 if (p == doc) { | 823 if (p == doc) { |
| 868 return true; | 824 return true; |
| 869 } | 825 } |
| 870 p = p.parentNode || p.host; | 826 p = p.parentNode || p.host; |
| 871 } | 827 } |
| 872 } | 828 } |
| 873 | 829 |
| 874 function watchShadow(node) { | 830 function watchShadow(node) { |
| 875 if (node.webkitShadowRoot && !node.webkitShadowRoot.__watched) { | 831 if (node.shadowRoot && !node.shadowRoot.__watched) { |
| 876 logFlags.dom && console.log('watching shadow-root for: ', node.localName); | 832 logFlags.dom && console.log('watching shadow-root for: ', node.localName); |
| 877 // watch all unwatched roots... | 833 // watch all unwatched roots... |
| 878 var root = node.webkitShadowRoot; | 834 var root = node.shadowRoot; |
| 879 while (root) { | 835 while (root) { |
| 880 watchRoot(root); | 836 watchRoot(root); |
| 881 root = root.olderShadowRoot; | 837 root = root.olderShadowRoot; |
| 882 } | 838 } |
| 883 } | 839 } |
| 884 } | 840 } |
| 885 | 841 |
| 886 function watchRoot(root) { | 842 function watchRoot(root) { |
| 887 if (!root.__watched) { | 843 if (!root.__watched) { |
| 888 observe(root); | 844 observe(root); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 //logFlags.dom && console.groupEnd(); | 896 //logFlags.dom && console.groupEnd(); |
| 941 }); | 897 }); |
| 942 logFlags.dom && console.groupEnd(); | 898 logFlags.dom && console.groupEnd(); |
| 943 }; | 899 }; |
| 944 | 900 |
| 945 var observer = new MutationObserver(handler); | 901 var observer = new MutationObserver(handler); |
| 946 | 902 |
| 947 function takeRecords() { | 903 function takeRecords() { |
| 948 // TODO(sjmiles): ask Raf why we have to call handler ourselves | 904 // TODO(sjmiles): ask Raf why we have to call handler ourselves |
| 949 handler(observer.takeRecords()); | 905 handler(observer.takeRecords()); |
| 906 takeMutations(); |
| 950 } | 907 } |
| 951 | 908 |
| 952 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); | 909 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); |
| 953 | 910 |
| 954 function observe(inRoot) { | 911 function observe(inRoot) { |
| 955 observer.observe(inRoot, {childList: true, subtree: true}); | 912 observer.observe(inRoot, {childList: true, subtree: true}); |
| 956 } | 913 } |
| 957 | 914 |
| 958 function observeDocument(document) { | 915 function observeDocument(document) { |
| 959 observe(document); | 916 observe(document); |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 window.CustomEvent = function(inType) { | 1410 window.CustomEvent = function(inType) { |
| 1454 var e = document.createEvent('HTMLEvents'); | 1411 var e = document.createEvent('HTMLEvents'); |
| 1455 e.initEvent(inType, true, true); | 1412 e.initEvent(inType, true, true); |
| 1456 return e; | 1413 return e; |
| 1457 }; | 1414 }; |
| 1458 } | 1415 } |
| 1459 | 1416 |
| 1460 if (document.readyState === 'complete') { | 1417 if (document.readyState === 'complete') { |
| 1461 bootstrap(); | 1418 bootstrap(); |
| 1462 } else { | 1419 } else { |
| 1463 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded'; | 1420 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : |
| 1421 document.readyState == 'loading' ? 'DOMContentLoaded' : 'load'; |
| 1464 window.addEventListener(loadEvent, bootstrap); | 1422 window.addEventListener(loadEvent, bootstrap); |
| 1465 } | 1423 } |
| 1466 | 1424 |
| 1467 })(); | 1425 })(); |
| 1426 |
| 1427 (function() { |
| 1428 // Patch to allow custom element and shadow dom to work together, from: |
| 1429 // https://github.com/Polymer/platform/blob/master/src/patches-shadowdom-polyfil
l.js |
| 1430 // include .host reference |
| 1431 if (HTMLElement.prototype.createShadowRoot) { |
| 1432 var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot; |
| 1433 HTMLElement.prototype.createShadowRoot = function() { |
| 1434 var root = originalCreateShadowRoot.call(this); |
| 1435 root.host = this; |
| 1436 return root; |
| 1437 } |
| 1438 } |
| 1439 })(); |
| OLD | NEW |