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

Side by Side Diff: pkg/custom_element/lib/custom-elements.debug.js

Issue 105203006: Reverting 30868 and 30873. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/custom_element/lib/custom-elements.min.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 if (typeof WeakMap === 'undefined') { 28 window.CustomElements = {flags:{}};
29 // SideTable is a weak map where possible. If WeakMap is not available the
30 // association is stored as an expando property.
31 var SideTable;
32 // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox
33 if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) {
34 SideTable = WeakMap;
35 } else {
29 (function() { 36 (function() {
30 var defineProperty = Object.defineProperty; 37 var defineProperty = Object.defineProperty;
31 var counter = Date.now() % 1e9; 38 var counter = Date.now() % 1e9;
32 39
33 var WeakMap = function() { 40 SideTable = function() {
34 this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); 41 this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
35 }; 42 };
36 43
37 WeakMap.prototype = { 44 SideTable.prototype = {
38 set: function(key, value) { 45 set: function(key, value) {
39 var entry = key[this.name]; 46 var entry = key[this.name];
40 if (entry && entry[0] === key) 47 if (entry && entry[0] === key)
41 entry[1] = value; 48 entry[1] = value;
42 else 49 else
43 defineProperty(key, this.name, {value: [key, value], writable: true}); 50 defineProperty(key, this.name, {value: [key, value], writable: true});
44 }, 51 },
45 get: function(key) { 52 get: function(key) {
46 var entry; 53 var entry;
47 return (entry = key[this.name]) && entry[0] === key ? 54 return (entry = key[this.name]) && entry[0] === key ?
48 entry[1] : undefined; 55 entry[1] : undefined;
49 }, 56 },
50 delete: function(key) { 57 delete: function(key) {
51 this.set(key, undefined); 58 this.set(key, undefined);
52 } 59 }
53 }; 60 }
54
55 window.WeakMap = WeakMap;
56 })(); 61 })();
57 } 62 }
58 63
59 (function(global) { 64 (function(global) {
60 65
61 var registrationsTable = new WeakMap(); 66 var registrationsTable = new SideTable();
62 67
63 // We use setImmediate or postMessage for our future callback. 68 // We use setImmediate or postMessage for our future callback.
64 var setImmediate = window.msSetImmediate; 69 var setImmediate = window.msSetImmediate;
65 70
66 // Use post message to emulate setImmediate. 71 // Use post message to emulate setImmediate.
67 if (!setImmediate) { 72 if (!setImmediate) {
68 var setImmediateQueue = []; 73 var setImmediateQueue = [];
69 var sentinel = String(Math.random()); 74 var sentinel = String(Math.random());
70 window.addEventListener('message', function(e) { 75 window.addEventListener('message', function(e) {
71 if (e.data === sentinel) { 76 if (e.data === sentinel) {
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 }); 589 });
585 590
586 } 591 }
587 592
588 clearRecords(); 593 clearRecords();
589 } 594 }
590 }; 595 };
591 596
592 global.JsMutationObserver = JsMutationObserver; 597 global.JsMutationObserver = JsMutationObserver;
593 598
594 // Provide unprefixed MutationObserver with native or JS implementation
595 if (!global.MutationObserver && global.WebKitMutationObserver)
596 global.MutationObserver = global.WebKitMutationObserver;
597
598 if (!global.MutationObserver)
599 global.MutationObserver = JsMutationObserver;
600
601
602 })(this); 599 })(this);
603 600
604 window.CustomElements = window.CustomElements || {flags:{}}; 601 if (!window.MutationObserver) {
602 window.MutationObserver =
603 window.WebKitMutationObserver ||
604 window.JsMutationObserver;
605 if (!MutationObserver) {
606 throw new Error("no mutation observer support");
607 }
608 }
609
605 (function(scope){ 610 (function(scope){
606 611
607 var logFlags = window.logFlags || {}; 612 var logFlags = window.logFlags || {};
608 613
609 // walk the subtree rooted at node, applying 'find(element, data)' function 614 // walk the subtree rooted at node, applying 'find(element, data)' function
610 // to each element 615 // to each element
611 // if 'find' returns true for 'element', do not search element's subtree 616 // if 'find' returns true for 'element', do not search element's subtree
612 function findAll(node, find, data) { 617 function findAll(node, find, data) {
613 var e = node.firstElementChild; 618 var e = node.firstElementChild;
614 if (!e) { 619 if (!e) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 } 775 }
771 } 776 }
772 777
773 function removedNode(node) { 778 function removedNode(node) {
774 removed(node); 779 removed(node);
775 forSubtree(node, function(e) { 780 forSubtree(node, function(e) {
776 removed(e); 781 removed(e);
777 }); 782 });
778 } 783 }
779 784
785
780 function removed(element) { 786 function removed(element) {
781 if (hasPolyfillMutations) { 787 if (hasPolyfillMutations) {
782 deferMutation(function() { 788 deferMutation(function() {
783 _removed(element); 789 _removed(element);
784 }); 790 });
785 } else { 791 } else {
786 _removed(element); 792 _removed(element);
787 } 793 }
788 } 794 }
789 795
790 function _removed(element) { 796 function removed(element) {
791 // 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
792 // behavior even when callbacks not defined 798 // behavior even when callbacks not defined
793 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) { 799 if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) {
794 logFlags.dom && console.log('removed:', element.localName); 800 logFlags.dom && console.log('removed:', element.localName);
795 if (!inDocument(element)) { 801 if (!inDocument(element)) {
796 element.__inserted = (element.__inserted || 0) - 1; 802 element.__inserted = (element.__inserted || 0) - 1;
797 // 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
798 if (element.__inserted > 0) { 804 if (element.__inserted > 0) {
799 element.__inserted = 0; 805 element.__inserted = 0;
800 } 806 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 } 839 }
834 } 840 }
835 841
836 function watchRoot(root) { 842 function watchRoot(root) {
837 if (!root.__watched) { 843 if (!root.__watched) {
838 observe(root); 844 observe(root);
839 root.__watched = true; 845 root.__watched = true;
840 } 846 }
841 } 847 }
842 848
849 function filter(inNode) {
850 switch (inNode.localName) {
851 case 'style':
852 case 'script':
853 case 'template':
854 case undefined:
855 return true;
856 }
857 }
858
843 function handler(mutations) { 859 function handler(mutations) {
844 // 860 //
845 if (logFlags.dom) { 861 if (logFlags.dom) {
846 var mx = mutations[0]; 862 var mx = mutations[0];
847 if (mx && mx.type === 'childList' && mx.addedNodes) { 863 if (mx && mx.type === 'childList' && mx.addedNodes) {
848 if (mx.addedNodes) { 864 if (mx.addedNodes) {
849 var d = mx.addedNodes[0]; 865 var d = mx.addedNodes[0];
850 while (d && d !== document && !d.host) { 866 while (d && d !== document && !d.host) {
851 d = d.parentNode; 867 d = d.parentNode;
852 } 868 }
853 var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || ''; 869 var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';
854 u = u.split('/?').shift().split('/').pop(); 870 u = u.split('/?').shift().split('/').pop();
855 } 871 }
856 } 872 }
857 console.group('mutations (%d) [%s]', mutations.length, u || ''); 873 console.group('mutations (%d) [%s]', mutations.length, u || '');
858 } 874 }
859 // 875 //
860 mutations.forEach(function(mx) { 876 mutations.forEach(function(mx) {
861 //logFlags.dom && console.group('mutation'); 877 //logFlags.dom && console.group('mutation');
862 if (mx.type === 'childList') { 878 if (mx.type === 'childList') {
863 forEach(mx.addedNodes, function(n) { 879 forEach(mx.addedNodes, function(n) {
864 //logFlags.dom && console.log(n.localName); 880 //logFlags.dom && console.log(n.localName);
865 if (!n.localName) { 881 if (filter(n)) {
866 return; 882 return;
867 } 883 }
868 // nodes added may need lifecycle management 884 // nodes added may need lifecycle management
869 addedNode(n); 885 addedNode(n);
870 }); 886 });
871 // removed nodes may need lifecycle management 887 // removed nodes may need lifecycle management
872 forEach(mx.removedNodes, function(n) { 888 forEach(mx.removedNodes, function(n) {
873 //logFlags.dom && console.log(n.localName); 889 //logFlags.dom && console.log(n.localName);
874 if (!n.localName) { 890 if (filter(n)) {
875 return; 891 return;
876 } 892 }
877 removedNode(n); 893 removedNode(n);
878 }); 894 });
879 } 895 }
880 //logFlags.dom && console.groupEnd(); 896 //logFlags.dom && console.groupEnd();
881 }); 897 });
882 logFlags.dom && console.groupEnd(); 898 logFlags.dom && console.groupEnd();
883 }; 899 };
884 900
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 if (!name) { 1024 if (!name) {
1009 // TODO(sjmiles): replace with more appropriate error (EricB can probably 1025 // TODO(sjmiles): replace with more appropriate error (EricB can probably
1010 // offer guidance) 1026 // offer guidance)
1011 throw new Error('document.register: first argument `name` must not be empt y'); 1027 throw new Error('document.register: first argument `name` must not be empt y');
1012 } 1028 }
1013 if (name.indexOf('-') < 0) { 1029 if (name.indexOf('-') < 0) {
1014 // TODO(sjmiles): replace with more appropriate error (EricB can probably 1030 // TODO(sjmiles): replace with more appropriate error (EricB can probably
1015 // offer guidance) 1031 // offer guidance)
1016 throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.'); 1032 throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
1017 } 1033 }
1018 // elements may only be registered once 1034 // record name
1019 if (getRegisteredDefinition(name)) { 1035 definition.name = name;
1020 throw new Error('DuplicateDefinitionError: a type with name \'' + String(n ame) + '\' is already registered');
1021 }
1022 // must have a prototype, default to an extension of HTMLElement 1036 // must have a prototype, default to an extension of HTMLElement
1023 // TODO(sjmiles): probably should throw if no prototype, check spec 1037 // TODO(sjmiles): probably should throw if no prototype, check spec
1024 if (!definition.prototype) { 1038 if (!definition.prototype) {
1025 // TODO(sjmiles): replace with more appropriate error (EricB can probably 1039 // TODO(sjmiles): replace with more appropriate error (EricB can probably
1026 // offer guidance) 1040 // offer guidance)
1027 throw new Error('Options missing required prototype property'); 1041 throw new Error('Options missing required prototype property');
1028 } 1042 }
1029 // record name
1030 definition.name = name.toLowerCase();
1031 // ensure a lifecycle object so we don't have to null test it 1043 // ensure a lifecycle object so we don't have to null test it
1032 definition.lifecycle = definition.lifecycle || {}; 1044 definition.lifecycle = definition.lifecycle || {};
1033 // build a list of ancestral custom elements (for native base detection) 1045 // build a list of ancestral custom elements (for native base detection)
1034 // TODO(sjmiles): we used to need to store this, but current code only 1046 // TODO(sjmiles): we used to need to store this, but current code only
1035 // uses it in 'resolveTagName': it should probably be inlined 1047 // uses it in 'resolveTagName': it should probably be inlined
1036 definition.ancestry = ancestry(definition.extends); 1048 definition.ancestry = ancestry(definition.extends);
1037 // extensions of native specializations of HTMLElement require localName 1049 // extensions of native specializations of HTMLElement require localName
1038 // to remain native, and use secondary 'is' specifier for extension type 1050 // to remain native, and use secondary 'is' specifier for extension type
1039 resolveTagName(definition); 1051 resolveTagName(definition);
1040 // some platforms require modifications to the user-supplied prototype 1052 // some platforms require modifications to the user-supplied prototype
1041 // chain 1053 // chain
1042 resolvePrototypeChain(definition); 1054 resolvePrototypeChain(definition);
1043 // overrides to implement attributeChanged callback 1055 // overrides to implement attributeChanged callback
1044 overrideAttributeApi(definition.prototype); 1056 overrideAttributeApi(definition.prototype);
1045 // 7.1.5: Register the DEFINITION with DOCUMENT 1057 // 7.1.5: Register the DEFINITION with DOCUMENT
1046 registerDefinition(definition.name, definition); 1058 registerDefinition(name, definition);
1047 // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE 1059 // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
1048 // 7.1.8. Return the output of the previous step. 1060 // 7.1.8. Return the output of the previous step.
1049 definition.ctor = generateConstructor(definition); 1061 definition.ctor = generateConstructor(definition);
1050 definition.ctor.prototype = definition.prototype; 1062 definition.ctor.prototype = definition.prototype;
1051 // force our .constructor to be our actual constructor 1063 // force our .constructor to be our actual constructor
1052 definition.prototype.constructor = definition.ctor; 1064 definition.prototype.constructor = definition.ctor;
1053 // if initial parsing is complete 1065 // if initial parsing is complete
1054 if (scope.ready || scope.performedInitialDocumentUpgrade) { 1066 if (scope.ready || scope.performedInitialDocumentUpgrade) {
1055 // upgrade any pre-existing nodes of this type 1067 // upgrade any pre-existing nodes of this type
1056 scope.upgradeAll(document); 1068 scope.upgradeAll(document);
1057 } 1069 }
1058 return definition.ctor; 1070 return definition.ctor;
1059 } 1071 }
1060 1072
1061 function ancestry(extnds) { 1073 function ancestry(extnds) {
1062 var extendee = getRegisteredDefinition(extnds); 1074 var extendee = registry[extnds];
1063 if (extendee) { 1075 if (extendee) {
1064 return ancestry(extendee.extends).concat([extendee]); 1076 return ancestry(extendee.extends).concat([extendee]);
1065 } 1077 }
1066 return []; 1078 return [];
1067 } 1079 }
1068 1080
1069 function resolveTagName(definition) { 1081 function resolveTagName(definition) {
1070 // if we are explicitly extending something, that thing is our 1082 // if we are explicitly extending something, that thing is our
1071 // baseTag, unless it represents a custom component 1083 // baseTag, unless it represents a custom component
1072 var baseTag = definition.extends; 1084 var baseTag = definition.extends;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 // output is a valid DOM element with the proper wrapper in place. 1132 // output is a valid DOM element with the proper wrapper in place.
1121 // 1133 //
1122 return upgrade(domCreateElement(definition.tag), definition); 1134 return upgrade(domCreateElement(definition.tag), definition);
1123 } 1135 }
1124 1136
1125 function upgrade(element, definition) { 1137 function upgrade(element, definition) {
1126 // some definitions specify an 'is' attribute 1138 // some definitions specify an 'is' attribute
1127 if (definition.is) { 1139 if (definition.is) {
1128 element.setAttribute('is', definition.is); 1140 element.setAttribute('is', definition.is);
1129 } 1141 }
1130 // remove 'unresolved' attr, which is a standin for :unresolved.
1131 element.removeAttribute('unresolved');
1132 // make 'element' implement definition.prototype 1142 // make 'element' implement definition.prototype
1133 implement(element, definition); 1143 implement(element, definition);
1134 // flag as upgraded 1144 // flag as upgraded
1135 element.__upgraded__ = true; 1145 element.__upgraded__ = true;
1136 // there should never be a shadow root on element at this point 1146 // there should never be a shadow root on element at this point
1137 // we require child nodes be upgraded before `created` 1147 // we require child nodes be upgraded before `created`
1138 scope.upgradeSubtree(element); 1148 scope.upgradeSubtree(element);
1139 // lifecycle management 1149 // lifecycle management
1140 created(element); 1150 created(element);
1141 // OUTPUT 1151 // OUTPUT
(...skipping 17 matching lines...) Expand all
1159 // TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of 1169 // TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of
1160 // any property. This set should be precalculated. We also need to 1170 // any property. This set should be precalculated. We also need to
1161 // consider this for supporting 'super'. 1171 // consider this for supporting 'super'.
1162 var used = {}; 1172 var used = {};
1163 // start with inSrc 1173 // start with inSrc
1164 var p = inSrc; 1174 var p = inSrc;
1165 // sometimes the default is HTMLUnknownElement.prototype instead of 1175 // sometimes the default is HTMLUnknownElement.prototype instead of
1166 // HTMLElement.prototype, so we add a test 1176 // HTMLElement.prototype, so we add a test
1167 // the idea is to avoid mixing in native prototypes, so adding 1177 // the idea is to avoid mixing in native prototypes, so adding
1168 // the second test is WLOG 1178 // the second test is WLOG
1169 while (p !== inNative && p !== HTMLUnknownElement.prototype) { 1179 while (p && p !== inNative && p !== HTMLUnknownElement.prototype) {
1170 var keys = Object.getOwnPropertyNames(p); 1180 var keys = Object.getOwnPropertyNames(p);
1171 for (var i=0, k; k=keys[i]; i++) { 1181 for (var i=0, k; k=keys[i]; i++) {
1172 if (!used[k]) { 1182 if (!used[k]) {
1173 Object.defineProperty(inTarget, k, 1183 Object.defineProperty(inTarget, k,
1174 Object.getOwnPropertyDescriptor(p, k)); 1184 Object.getOwnPropertyDescriptor(p, k));
1175 used[k] = 1; 1185 used[k] = 1;
1176 } 1186 }
1177 } 1187 }
1178 p = Object.getPrototypeOf(p); 1188 p = Object.getPrototypeOf(p);
1179 } 1189 }
1180 } 1190 }
1181 1191
1182 function created(element) { 1192 function created(element) {
1183 // invoke createdCallback 1193 // invoke createdCallback
1184 if (element.createdCallback) { 1194 if (element.createdCallback) {
1185 element.createdCallback(); 1195 element.createdCallback();
1186 } 1196 }
1187 } 1197 }
1188 1198
1189 // attribute watching 1199 // attribute watching
1190 1200
1191 function overrideAttributeApi(prototype) { 1201 function overrideAttributeApi(prototype) {
1192 // overrides to implement callbacks 1202 // overrides to implement callbacks
1193 // TODO(sjmiles): should support access via .attributes NamedNodeMap 1203 // TODO(sjmiles): should support access via .attributes NamedNodeMap
1194 // TODO(sjmiles): preserves user defined overrides, if any 1204 // TODO(sjmiles): preserves user defined overrides, if any
1195 if (prototype.setAttribute._polyfilled) {
1196 return;
1197 }
1198 var setAttribute = prototype.setAttribute; 1205 var setAttribute = prototype.setAttribute;
1199 prototype.setAttribute = function(name, value) { 1206 prototype.setAttribute = function(name, value) {
1200 changeAttribute.call(this, name, value, setAttribute); 1207 changeAttribute.call(this, name, value, setAttribute);
1201 } 1208 }
1202 var removeAttribute = prototype.removeAttribute; 1209 var removeAttribute = prototype.removeAttribute;
1203 prototype.removeAttribute = function(name) { 1210 prototype.removeAttribute = function(name) {
1204 changeAttribute.call(this, name, null, removeAttribute); 1211 changeAttribute.call(this, name, null, removeAttribute);
1205 } 1212 }
1206 prototype.setAttribute._polyfilled = true;
1207 } 1213 }
1208 1214
1209 // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/
1210 // index.html#dfn-attribute-changed-callback
1211 function changeAttribute(name, value, operation) { 1215 function changeAttribute(name, value, operation) {
1212 var oldValue = this.getAttribute(name); 1216 var oldValue = this.getAttribute(name);
1213 operation.apply(this, arguments); 1217 operation.apply(this, arguments);
1214 var newValue = this.getAttribute(name);
1215 if (this.attributeChangedCallback 1218 if (this.attributeChangedCallback
1216 && (newValue !== oldValue)) { 1219 && (this.getAttribute(name) !== oldValue)) {
1217 this.attributeChangedCallback(name, oldValue, newValue); 1220 this.attributeChangedCallback(name, oldValue, value);
1218 } 1221 }
1219 } 1222 }
1220 1223
1221 // element registry (maps tag names to definitions) 1224 // element registry (maps tag names to definitions)
1222 1225
1223 var registry = {}; 1226 var registry = {};
1224 1227
1225 function getRegisteredDefinition(name) { 1228 function registerDefinition(name, definition) {
1226 if (name) { 1229 if (registry[name]) {
1227 return registry[name.toLowerCase()]; 1230 throw new Error('Cannot register a tag more than once');
1228 } 1231 }
1229 }
1230
1231 function registerDefinition(name, definition) {
1232 registry[name] = definition; 1232 registry[name] = definition;
1233 } 1233 }
1234 1234
1235 function generateConstructor(definition) { 1235 function generateConstructor(definition) {
1236 return function() { 1236 return function() {
1237 return instantiate(definition); 1237 return instantiate(definition);
1238 }; 1238 };
1239 } 1239 }
1240 1240
1241 function createElement(tag, typeExtension) { 1241 function createElement(tag, typeExtension) {
1242 // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could 1242 var definition = registry[typeExtension || tag];
1243 // error check it, or perhaps there should only ever be one argument
1244 var definition = getRegisteredDefinition(typeExtension || tag);
1245 if (definition) { 1243 if (definition) {
1246 if (tag == definition.tag && typeExtension == definition.is) { 1244 if (tag == definition.tag && typeExtension == definition.is) {
1247 return new definition.ctor(); 1245 return new definition.ctor();
1248 } 1246 }
1249 // Handle empty string for type extension. 1247 // Handle empty string for type extension.
1250 if (!typeExtension && !definition.is) { 1248 if (!typeExtension && !definition.is) {
1251 return new definition.ctor(); 1249 return new definition.ctor();
1252 } 1250 }
1253 } 1251 }
1254 1252
1255 if (typeExtension) { 1253 if (typeExtension) {
1256 var element = createElement(tag); 1254 var element = createElement(tag);
1257 element.setAttribute('is', typeExtension); 1255 element.setAttribute('is', typeExtension);
1258 return element; 1256 return element;
1259 } 1257 }
1260 var element = domCreateElement(tag); 1258 var element = domCreateElement(tag);
1261 // Custom tags should be HTMLElements even if not upgraded. 1259 // Custom tags should be HTMLElements even if not upgraded.
1262 if (tag.indexOf('-') >= 0) { 1260 if (tag.indexOf('-') >= 0) {
1263 implement(element, HTMLElement); 1261 implement(element, HTMLElement);
1264 } 1262 }
1265 return element; 1263 return element;
1266 } 1264 }
1267 1265
1268 function upgradeElement(element) { 1266 function upgradeElement(element) {
1269 if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) { 1267 if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) {
1270 var type = element.getAttribute('is') || element.localName; 1268 var is = element.getAttribute('is');
1271 var definition = getRegisteredDefinition(type); 1269 var definition = registry[is || element.localName];
1272 return definition && upgrade(element, definition); 1270 if (definition) {
1271 if (is && definition.tag == element.localName) {
1272 return upgrade(element, definition);
1273 } else if (!is && !definition.extends) {
1274 return upgrade(element, definition);
1275 }
1276 }
1273 } 1277 }
1274 } 1278 }
1275 1279
1276 function cloneNode(deep) { 1280 function cloneNode(deep) {
1277 // call original clone 1281 // call original clone
1278 var n = domCloneNode.call(this, deep); 1282 var n = domCloneNode.call(this, deep);
1279 // upgrade the element and subtree 1283 // upgrade the element and subtree
1280 scope.upgradeAll(n); 1284 scope.upgradeAll(n);
1281 // return the clone 1285 // return the clone
1282 return n; 1286 return n;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 && inElt.getAttribute('rel') === IMPORT_LINK_TYPE); 1370 && inElt.getAttribute('rel') === IMPORT_LINK_TYPE);
1367 } 1371 }
1368 1372
1369 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); 1373 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
1370 1374
1371 // exports 1375 // exports
1372 1376
1373 CustomElements.parser = parser; 1377 CustomElements.parser = parser;
1374 1378
1375 })(); 1379 })();
1376 (function(scope){ 1380 (function(){
1377 1381
1378 // bootstrap parsing 1382 // bootstrap parsing
1379 function bootstrap() { 1383 function bootstrap() {
1380 // parse document 1384 // parse document
1381 CustomElements.parser.parse(document); 1385 CustomElements.parser.parse(document);
1382 // one more pass before register is 'live' 1386 // one more pass before register is 'live'
1383 CustomElements.upgradeDocument(document); 1387 CustomElements.upgradeDocument(document);
1384 CustomElements.performedInitialDocumentUpgrade = true; 1388 CustomElements.performedInitialDocumentUpgrade = true;
1385 // choose async 1389 // choose async
1386 var async = window.Platform && Platform.endOfMicrotask ? 1390 var async = window.Platform && Platform.endOfMicrotask ?
(...skipping 11 matching lines...) Expand all
1398 // notify the system that we are bootstrapped 1402 // notify the system that we are bootstrapped
1399 document.body.dispatchEvent( 1403 document.body.dispatchEvent(
1400 new CustomEvent('WebComponentsReady', {bubbles: true}) 1404 new CustomEvent('WebComponentsReady', {bubbles: true})
1401 ); 1405 );
1402 }); 1406 });
1403 } 1407 }
1404 1408
1405 // CustomEvent shim for IE 1409 // CustomEvent shim for IE
1406 if (typeof window.CustomEvent !== 'function') { 1410 if (typeof window.CustomEvent !== 'function') {
1407 window.CustomEvent = function(inType) { 1411 window.CustomEvent = function(inType) {
1408 var e = document.createEvent('HTMLEvents'); 1412 var e = document.createEvent('HTMLEvents');
1409 e.initEvent(inType, true, true); 1413 e.initEvent(inType, true, true);
1410 return e; 1414 return e;
1411 }; 1415 };
1412 } 1416 }
1413 1417
1414 // When loading at readyState complete time (or via flag), boot custom elements 1418 if (document.readyState === 'complete') {
1415 // immediately.
1416 // If relevant, HTMLImports must already be loaded.
1417 if (document.readyState === 'complete' || scope.flags.eager) {
1418 bootstrap(); 1419 bootstrap();
1419 // When loading at readyState interactive time, bootstrap only if HTMLImports
1420 // are not pending. Also avoid IE as the semantics of this state are unreliable.
1421 } else if (document.readyState === 'interactive' && !window.attachEvent &&
1422 (!window.HTMLImports || window.HTMLImports.ready)) {
1423 bootstrap();
1424 // When loading at other readyStates, wait for the appropriate DOM event to
1425 // bootstrap.
1426 } else { 1420 } else {
1427 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 1421 var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' :
1428 document.readyState == 'loading' ? 'DOMContentLoaded' : 'load'; 1422 document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
1429 window.addEventListener(loadEvent, bootstrap); 1423 window.addEventListener(loadEvent, bootstrap);
1430 } 1424 }
1431 1425
1432 })(window.CustomElements); 1426 })();
1433 1427
1434 (function() { 1428 (function() {
1435 // Patch to allow custom element and shadow dom to work together, from: 1429 // Patch to allow custom element and shadow dom to work together, from:
1436 // https://github.com/Polymer/platform/blob/master/src/patches-shadowdom-polyfil l.js 1430 // https://github.com/Polymer/platform/blob/master/src/patches-shadowdom-polyfil l.js
1437 // include .host reference 1431 // include .host reference
1438 if (HTMLElement.prototype.createShadowRoot) { 1432 if (HTMLElement.prototype.createShadowRoot) {
1439 var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot; 1433 var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
1440 HTMLElement.prototype.createShadowRoot = function() { 1434 HTMLElement.prototype.createShadowRoot = function() {
1441 var root = originalCreateShadowRoot.call(this); 1435 var root = originalCreateShadowRoot.call(this);
1442 root.host = this; 1436 root.host = this;
1443 return root; 1437 return root;
1444 } 1438 }
1445 } 1439 }
1446 1440
1447 1441
1448 // Patch to allow custom elements and shadow dom to work together, from: 1442 // Patch to allow custom elements and shadow dom to work together, from:
1449 // https://github.com/Polymer/platform-dev/blob/2bb9c56d90f9ac19c2e65cdad368668a ff514f14/src/patches-custom-elements.js 1443 // https://github.com/Polymer/platform/blob/master/src/patches-custom-elements.j s
1450 if (window.ShadowDOMPolyfill) { 1444 if (window.ShadowDOMPolyfill) {
1445 function nop() {};
1446
1447 // disable shadow dom watching
1448 CustomElements.watchShadow = nop;
1449 CustomElements.watchAllShadows = nop;
1451 1450
1452 // ensure wrapped inputs for these functions 1451 // ensure wrapped inputs for these functions
1453 var fns = ['upgradeAll', 'upgradeSubtree', 'observeDocument', 1452 var fns = ['upgradeAll', 'upgradeSubtree', 'observeDocument',
1454 'upgradeDocument']; 1453 'upgradeDocument'];
1455 1454
1456 // cache originals 1455 // cache originals
1457 var original = {}; 1456 var original = {};
1458 fns.forEach(function(fn) { 1457 fns.forEach(function(fn) {
1459 original[fn] = CustomElements[fn]; 1458 original[fn] = CustomElements[fn];
1460 }); 1459 });
1461 1460
1462 // override 1461 // override
1463 fns.forEach(function(fn) { 1462 fns.forEach(function(fn) {
1464 CustomElements[fn] = function(inNode) { 1463 CustomElements[fn] = function(inNode) {
1465 return original[fn](window.ShadowDOMPolyfill.wrapIfNeeded(inNode)); 1464 return original[fn](ShadowDOMPolyfill.wrapIfNeeded(inNode));
1466 }; 1465 };
1467 }); 1466 });
1468
1469 }
1470
1471 // Patch to make importNode work.
1472 // https://github.com/Polymer/platform-dev/blob/64a92f273462f04a84abbe2f054294f2 b62dbcd6/src/patches-mdv.js
1473 if (window.CustomElements && !CustomElements.useNative) {
1474 var originalImportNode = Document.prototype.importNode;
1475 Document.prototype.importNode = function(node, deep) {
1476 var imported = originalImportNode.call(this, node, deep);
1477 CustomElements.upgradeAll(imported);
1478 return imported;
1479 }
1480 } 1467 }
1481 1468
1482 })(); 1469 })();
OLDNEW
« no previous file with comments | « no previous file | pkg/custom_element/lib/custom-elements.min.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698