Index: tools/dom/src/dart2js_CustomElementSupport.dart |
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart |
index aa1c0372869484cefaff498db97b696d000ed05d..75a2651a0ee674c0e2a52c8e44ffc75bb6f8a8a2 100644 |
--- a/tools/dom/src/dart2js_CustomElementSupport.dart |
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart |
@@ -87,7 +87,7 @@ void _registerCustomElement(context, document, String tag, Type type, |
if (extendsTagName == null) { |
if (baseClassName != 'HTMLElement') { |
throw new UnsupportedError('Class must provide extendsTag if base ' |
- 'native class is not HTMLElement'); |
+ 'native class is not HtmlElement'); |
} |
} else { |
if (!JS('bool', '(#.createElement(#) instanceof window[#])', |
@@ -128,3 +128,55 @@ void _registerCustomElement(context, document, String tag, Type type, |
void _initializeCustomElement(Element e) { |
// TODO(blois): Add validation that this is only in response to an upgrade. |
} |
+ |
+class _JSElementUpgrader implements ElementUpgrader { |
+ var _interceptor; |
+ var _baseClassName; |
+ var _constructor; |
+ |
+ _JSElementUpgrader(Document document, Type type, String extendsTag) { |
+ var interceptorClass = findInterceptorConstructorForType(type); |
+ if (interceptorClass == null) { |
+ throw new ArgumentError(type); |
+ } |
+ |
+ _constructor = findConstructorForNativeSubclassType(type, 'created'); |
+ if (_constructor == null) { |
+ throw new ArgumentError("$type has no constructor called 'created'"); |
+ } |
+ |
+ // Workaround for 13190- use an article element to ensure that HTMLElement's |
+ // interceptor is resolved correctly. |
+ getNativeInterceptor(new Element.tag('article')); |
+ |
+ _baseClassName = findDispatchTagForInterceptorClass(interceptorClass); |
+ if (_baseClassName == null) { |
+ throw new ArgumentError(type); |
+ } |
+ |
+ if (extendsTag == null) { |
+ if (_baseClassName != 'HTMLElement') { |
+ throw new UnsupportedError('Class must provide extendsTag if base ' |
+ 'native class is not HtmlElement'); |
+ } |
+ } else { |
+ if (!JS('bool', '(#.createElement(#) instanceof window[#])', |
+ document, extendsTag, _baseClassName)) { |
+ throw new UnsupportedError( |
+ 'extendsTag does not match base native class'); |
+ } |
+ } |
+ |
+ _interceptor = JS('=Object', '#.prototype', interceptorClass); |
+ } |
+ |
+ Element upgrade(Element element) { |
+ if (!JS('bool', '(# instanceof window[#])', element, _baseClassName)) { |
+ throw new ArgumentError('element is not subclass of $_baseClassName'); |
+ } |
+ |
+ setNativeSubclassDispatchRecord(element, _interceptor); |
+ JS('', '#(#)', _constructor, element); |
+ return element; |
+ } |
+} |