OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
| 5 // Teaches dart2js about the wrapping that is done by the Shadow DOM polyfill. |
5 (function() { | 6 (function() { |
6 var ShadowDOMPolyfill = window.ShadowDOMPolyfill; | 7 var ShadowDOMPolyfill = window.ShadowDOMPolyfill; |
7 if (!ShadowDOMPolyfill) return; | 8 if (!ShadowDOMPolyfill) return; |
8 | 9 |
9 if (navigator.userAgent.indexOf('(Dart)') !== -1) { | 10 if (navigator.userAgent.indexOf('(Dart)') !== -1) { |
10 console.error("ShadowDOMPolyfill polyfill was loaded in Dartium. This " + | 11 console.error("ShadowDOMPolyfill polyfill was loaded in Dartium. This " + |
11 "will not work. This indicates that Dartium's Chrome version is " + | 12 "will not work. This indicates that Dartium's Chrome version is " + |
12 "not compatible with this version of web_components."); | 13 "not compatible with this version of web_components."); |
13 } | 14 } |
14 | 15 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 } | 57 } |
57 return name; | 58 return name; |
58 } | 59 } |
59 | 60 |
60 obj = unwrapped; | 61 obj = unwrapped; |
61 } | 62 } |
62 return originalGetTag(obj); | 63 return originalGetTag(obj); |
63 } | 64 } |
64 }); | 65 }); |
65 })(); | 66 })(); |
| 67 |
| 68 // Updates document.registerElement so Dart can see when Javascript custom |
| 69 // elements are created, and wrap them to provide a Dart friendly API. |
| 70 (function (doc) { |
| 71 var upgraders = {}; // upgrader associated with a custom-tag. |
| 72 var unpatchableTags = {}; // set of custom-tags that can't be patched. |
| 73 var pendingElements = {}; // will upgrade when/if an upgrader is installed. |
| 74 var upgradeOldElements = true; |
| 75 |
| 76 var originalRegisterElement = doc.registerElement; |
| 77 if (!originalRegisterElement) { |
| 78 throw new Error('document.registerElement is not present.'); |
| 79 } |
| 80 |
| 81 function reportError(name) { |
| 82 console.error("Couldn't patch prototype to notify Dart when " + name + |
| 83 " elements are created. This can be fixed by making the " + |
| 84 "createdCallback in " + name + " a configurable property."); |
| 85 } |
| 86 |
| 87 function registerElement(name, options) { |
| 88 var proto, extendsOption; |
| 89 if (options !== undefined) { |
| 90 proto = options.prototype; |
| 91 } else { |
| 92 proto = Object.create(HTMLElement.prototype); |
| 93 options = {protoptype: proto}; |
| 94 } |
| 95 |
| 96 var original = proto.createdCallback; |
| 97 var newCallback = function() { |
| 98 original.call(this); |
| 99 var name = (this.getAttribute('is') || this.localName).toLowerCase(); |
| 100 var upgrader = upgraders[name]; |
| 101 if (upgrader) { |
| 102 upgrader(this); |
| 103 } else if (upgradeOldElements) { |
| 104 // Save this element in case we can upgrade it later when an upgrader is |
| 105 // registered. |
| 106 var list = pendingElements[name]; |
| 107 if (!list) { |
| 108 list = pendingElements[name] = []; |
| 109 } |
| 110 list.push(this); |
| 111 } |
| 112 }; |
| 113 |
| 114 var descriptor = Object.getOwnPropertyDescriptor(proto, 'createdCallback'); |
| 115 if (!descriptor || descriptor.writable) { |
| 116 proto.createdCallback = newCallback; |
| 117 } else if (descriptor.configurable) { |
| 118 descriptor['value'] = newCallback; |
| 119 Object.defineProperty(proto, 'createdCallback', descriptor); |
| 120 } else { |
| 121 unpatchableTags[name] = true; |
| 122 if (upgraders[name]) reportError(name); |
| 123 } |
| 124 return originalRegisterElement.call(this, name, options); |
| 125 } |
| 126 |
| 127 function registerDartTypeUpgrader(name, upgrader) { |
| 128 if (!upgrader) return; |
| 129 name = name.toLowerCase(); |
| 130 var existing = upgraders[name]; |
| 131 if (existing) { |
| 132 console.error('Already have a Dart type associated with ' + name); |
| 133 return; |
| 134 } |
| 135 upgraders[name] = upgrader; |
| 136 if (unpatchableTags[name]) reportError(name); |
| 137 if (upgradeOldElements) { |
| 138 // Upgrade elements that were created before the upgrader was registered. |
| 139 var list = pendingElements[name]; |
| 140 if (list) { |
| 141 for (var i = 0; i < list.length; i++) { |
| 142 upgrader(list[i]); |
| 143 } |
| 144 } |
| 145 delete pendingElements[name]; |
| 146 } else { |
| 147 console.warn("Didn't expect more Dart types to be registered. '" + name |
| 148 + "' elements that already exist in the page might not be wrapped."); |
| 149 } |
| 150 } |
| 151 |
| 152 function onlyUpgradeNewElements() { |
| 153 upgradeOldElements = false; |
| 154 pendingElements = null; |
| 155 } |
| 156 |
| 157 // Native custom elements outside the app in Chrome have constructor |
| 158 // names like "x-tag", which need to be translated to the DOM |
| 159 // element they extend. When using the shadow dom polyfill this is |
| 160 // take care of above. |
| 161 var ShadowDOMPolyfill = window.ShadowDOMPolyfill; |
| 162 if (!ShadowDOMPolyfill) { |
| 163 // dartNativeDispatchHooksTransformer is described on initHooks() in |
| 164 // sdk/lib/_internal/lib/native_helper.dart. |
| 165 if (typeof window.dartNativeDispatchHooksTransformer == 'undefined') |
| 166 window.dartNativeDispatchHooksTransformer = []; |
| 167 |
| 168 window.dartNativeDispatchHooksTransformer.push(function(hooks) { |
| 169 var originalGetUnknownTag = hooks.getUnknownTag; |
| 170 hooks.getUnknownTag = function(o, tag) { |
| 171 if (/-/.test(tag)) { // "x-tag" |
| 172 var s = Object.prototype.toString.call(o); |
| 173 var match = s.match(/^\[object ([A-Za-z]*Element)\]$/); |
| 174 if (match) { |
| 175 return match[1]; |
| 176 } |
| 177 return originalGetUnknownTag(o, tag); |
| 178 } |
| 179 }; |
| 180 }); |
| 181 } |
| 182 |
| 183 doc._registerDartTypeUpgrader = registerDartTypeUpgrader; |
| 184 doc._onlyUpgradeNewElements = onlyUpgradeNewElements; |
| 185 doc.registerElement = registerElement; |
| 186 })(document); |
OLD | NEW |