| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 getNativeInterceptor(new Element.tag('article')); | 80 getNativeInterceptor(new Element.tag('article')); |
| 81 | 81 |
| 82 String baseClassName = findDispatchTagForInterceptorClass(interceptorClass); | 82 String baseClassName = findDispatchTagForInterceptorClass(interceptorClass); |
| 83 if (baseClassName == null) { | 83 if (baseClassName == null) { |
| 84 throw new ArgumentError(type); | 84 throw new ArgumentError(type); |
| 85 } | 85 } |
| 86 | 86 |
| 87 if (extendsTagName == null) { | 87 if (extendsTagName == null) { |
| 88 if (baseClassName != 'HTMLElement') { | 88 if (baseClassName != 'HTMLElement') { |
| 89 throw new UnsupportedError('Class must provide extendsTag if base ' | 89 throw new UnsupportedError('Class must provide extendsTag if base ' |
| 90 'native class is not HTMLElement'); | 90 'native class is not HtmlElement'); |
| 91 } | 91 } |
| 92 } else { | 92 } else { |
| 93 if (!JS('bool', '(#.createElement(#) instanceof window[#])', | 93 if (!JS('bool', '(#.createElement(#) instanceof window[#])', |
| 94 document, extendsTagName, baseClassName)) { | 94 document, extendsTagName, baseClassName)) { |
| 95 throw new UnsupportedError('extendsTag does not match base native class'); | 95 throw new UnsupportedError('extendsTag does not match base native class'); |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 var baseConstructor = JS('=Object', '#[#]', context, baseClassName); | 99 var baseConstructor = JS('=Object', '#[#]', context, baseClassName); |
| 100 | 100 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 121 JS('=Object', '#.extends = #', options, extendsTagName); | 121 JS('=Object', '#.extends = #', options, extendsTagName); |
| 122 } | 122 } |
| 123 | 123 |
| 124 JS('void', '#.registerElement(#, #)', document, tag, options); | 124 JS('void', '#.registerElement(#, #)', document, tag, options); |
| 125 } | 125 } |
| 126 | 126 |
| 127 //// Called by Element.created to do validation & initialization. | 127 //// Called by Element.created to do validation & initialization. |
| 128 void _initializeCustomElement(Element e) { | 128 void _initializeCustomElement(Element e) { |
| 129 // TODO(blois): Add validation that this is only in response to an upgrade. | 129 // TODO(blois): Add validation that this is only in response to an upgrade. |
| 130 } | 130 } |
| 131 |
| 132 /// Dart2JS implementation of ElementUpgrader |
| 133 class _JSElementUpgrader implements ElementUpgrader { |
| 134 var _interceptor; |
| 135 var _constructor; |
| 136 var _nativeType; |
| 137 |
| 138 _JSElementUpgrader(Document document, Type type, String extendsTag) { |
| 139 var interceptorClass = findInterceptorConstructorForType(type); |
| 140 if (interceptorClass == null) { |
| 141 throw new ArgumentError(type); |
| 142 } |
| 143 |
| 144 _constructor = findConstructorForNativeSubclassType(type, 'created'); |
| 145 if (_constructor == null) { |
| 146 throw new ArgumentError("$type has no constructor called 'created'"); |
| 147 } |
| 148 |
| 149 // Workaround for 13190- use an article element to ensure that HTMLElement's |
| 150 // interceptor is resolved correctly. |
| 151 getNativeInterceptor(new Element.tag('article')); |
| 152 |
| 153 var baseClassName = findDispatchTagForInterceptorClass(interceptorClass); |
| 154 if (baseClassName == null) { |
| 155 throw new ArgumentError(type); |
| 156 } |
| 157 |
| 158 if (extendsTag == null) { |
| 159 if (baseClassName != 'HTMLElement') { |
| 160 throw new UnsupportedError('Class must provide extendsTag if base ' |
| 161 'native class is not HtmlElement'); |
| 162 } |
| 163 _nativeType = HtmlElement; |
| 164 } else { |
| 165 var element = document.createElement(extendsTag); |
| 166 if (!JS('bool', '(# instanceof window[#])', |
| 167 element, baseClassName)) { |
| 168 throw new UnsupportedError( |
| 169 'extendsTag does not match base native class'); |
| 170 } |
| 171 _nativeType = element.runtimeType; |
| 172 } |
| 173 |
| 174 _interceptor = JS('=Object', '#.prototype', interceptorClass); |
| 175 } |
| 176 |
| 177 Element upgrade(Element element) { |
| 178 // Only exact type matches are supported- cannot be a subclass. |
| 179 if (element.runtimeType != _nativeType) { |
| 180 throw new ArgumentError('element is not subclass of $_nativeType'); |
| 181 } |
| 182 |
| 183 setNativeSubclassDispatchRecord(element, _interceptor); |
| 184 JS('', '#(#)', _constructor, element); |
| 185 return element; |
| 186 } |
| 187 } |
| OLD | NEW |