OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.dom.html; | 5 part of dart.dom.html; |
6 | 6 |
7 _callConstructor(constructor, interceptor) { | 7 _callConstructor(constructor, interceptor) { |
8 return (receiver) { | 8 return (receiver) { |
9 setNativeSubclassDispatchRecord(receiver, interceptor); | 9 setNativeSubclassDispatchRecord(receiver, interceptor); |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 _makeCallbackMethod3(callback) { | 40 _makeCallbackMethod3(callback) { |
41 return JS('', | 41 return JS('', |
42 '''((function(invokeCallback) { | 42 '''((function(invokeCallback) { |
43 return function(arg1, arg2, arg3) { | 43 return function(arg1, arg2, arg3) { |
44 return invokeCallback(this, arg1, arg2, arg3); | 44 return invokeCallback(this, arg1, arg2, arg3); |
45 }; | 45 }; |
46 })(#))''', | 46 })(#))''', |
47 convertDartClosureToJS(callback, 4)); | 47 convertDartClosureToJS(callback, 4)); |
48 } | 48 } |
49 | 49 |
| 50 /// Checks whether the given [element] correctly extends from the native class |
| 51 /// with the given [baseClassName]. This method will throw if the base class |
| 52 /// doesn't match, except when the element extends from `template` and it's base |
| 53 /// class is `HTMLUnknownElement`. This exclusion is needed to support extension |
| 54 /// of template elements (used heavily in Polymer 1.0) on IE11 when using the |
| 55 /// webcomponents-lite.js polyfill. |
| 56 void _checkExtendsNativeClassOrTemplate( |
| 57 Element element, String extendsTag, String baseClassName) { |
| 58 if (!JS('bool', '(# instanceof window[#])', element, baseClassName) && |
| 59 !((extendsTag == 'template' && |
| 60 JS('bool', '(# instanceof window["HTMLUnknownElement"])', element)))) { |
| 61 throw new UnsupportedError('extendsTag does not match base native class'); |
| 62 } |
| 63 } |
| 64 |
50 void _registerCustomElement(context, document, String tag, Type type, | 65 void _registerCustomElement(context, document, String tag, Type type, |
51 String extendsTagName) { | 66 String extendsTagName) { |
52 // Function follows the same pattern as the following JavaScript code for | 67 // Function follows the same pattern as the following JavaScript code for |
53 // registering a custom element. | 68 // registering a custom element. |
54 // | 69 // |
55 // var proto = Object.create(HTMLElement.prototype, { | 70 // var proto = Object.create(HTMLElement.prototype, { |
56 // createdCallback: { | 71 // createdCallback: { |
57 // value: function() { | 72 // value: function() { |
58 // window.console.log('here'); | 73 // window.console.log('here'); |
59 // } | 74 // } |
(...skipping 23 matching lines...) Expand all Loading... |
83 if (baseClassName == null) { | 98 if (baseClassName == null) { |
84 throw new ArgumentError(type); | 99 throw new ArgumentError(type); |
85 } | 100 } |
86 | 101 |
87 if (extendsTagName == null) { | 102 if (extendsTagName == null) { |
88 if (baseClassName != 'HTMLElement') { | 103 if (baseClassName != 'HTMLElement') { |
89 throw new UnsupportedError('Class must provide extendsTag if base ' | 104 throw new UnsupportedError('Class must provide extendsTag if base ' |
90 'native class is not HtmlElement'); | 105 'native class is not HtmlElement'); |
91 } | 106 } |
92 } else { | 107 } else { |
93 if (!JS('bool', '(#.createElement(#) instanceof window[#])', | 108 var element = document.createElement(extendsTagName); |
94 document, extendsTagName, baseClassName)) { | 109 _checkExtendsNativeClassOrTemplate(element, extendsTagName, baseClassName); |
95 throw new UnsupportedError('extendsTag does not match base native class'); | |
96 } | |
97 } | 110 } |
98 | 111 |
99 var baseConstructor = JS('=Object', '#[#]', context, baseClassName); | 112 var baseConstructor = JS('=Object', '#[#]', context, baseClassName); |
100 | 113 |
101 var properties = JS('=Object', '{}'); | 114 var properties = JS('=Object', '{}'); |
102 | 115 |
103 JS('void', '#.createdCallback = #', properties, | 116 JS('void', '#.createdCallback = #', properties, |
104 JS('=Object', '{value: #}', | 117 JS('=Object', '{value: #}', |
105 _makeCallbackMethod(_callConstructor(constructor, interceptor)))); | 118 _makeCallbackMethod(_callConstructor(constructor, interceptor)))); |
106 JS('void', '#.attachedCallback = #', properties, | 119 JS('void', '#.attachedCallback = #', properties, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 169 } |
157 | 170 |
158 if (extendsTag == null) { | 171 if (extendsTag == null) { |
159 if (baseClassName != 'HTMLElement') { | 172 if (baseClassName != 'HTMLElement') { |
160 throw new UnsupportedError('Class must provide extendsTag if base ' | 173 throw new UnsupportedError('Class must provide extendsTag if base ' |
161 'native class is not HtmlElement'); | 174 'native class is not HtmlElement'); |
162 } | 175 } |
163 _nativeType = HtmlElement; | 176 _nativeType = HtmlElement; |
164 } else { | 177 } else { |
165 var element = document.createElement(extendsTag); | 178 var element = document.createElement(extendsTag); |
166 if (!JS('bool', '(# instanceof window[#])', element, baseClassName) && | 179 _checkExtendsNativeClassOrTemplate(element, extendsTag, baseClassName); |
167 // Exception to support template elements (extended for core pieces of | |
168 // Polymer 1.0) when using the webcomponents-lite.js polyfill on IE11: | |
169 !((extendsTag == 'template' && | |
170 JS('bool', '(# instanceof window["HTMLUnknownElement"])', element)))) { | |
171 throw new UnsupportedError( | |
172 'extendsTag does not match base native class'); | |
173 } | |
174 _nativeType = element.runtimeType; | 180 _nativeType = element.runtimeType; |
175 } | 181 } |
176 | 182 |
177 _interceptor = JS('=Object', '#.prototype', interceptorClass); | 183 _interceptor = JS('=Object', '#.prototype', interceptorClass); |
178 } | 184 } |
179 | 185 |
180 Element upgrade(Element element) { | 186 Element upgrade(Element element) { |
181 // Only exact type matches are supported- cannot be a subclass. | 187 // Only exact type matches are supported- cannot be a subclass. |
182 if (element.runtimeType != _nativeType) { | 188 if (element.runtimeType != _nativeType) { |
183 throw new ArgumentError('element is not subclass of $_nativeType'); | 189 throw new ArgumentError('element is not subclass of $_nativeType'); |
184 } | 190 } |
185 | 191 |
186 setNativeSubclassDispatchRecord(element, _interceptor); | 192 setNativeSubclassDispatchRecord(element, _interceptor); |
187 JS('', '#(#)', _constructor, element); | 193 JS('', '#(#)', _constructor, element); |
188 return element; | 194 return element; |
189 } | 195 } |
190 } | 196 } |
OLD | NEW |