Index: sdk/lib/html/dart2js/html_dart2js.dart |
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart |
index 15967d9542aafdadef752de74c18407fda2f3671..447de5206aef562cd60dc19092ca3d709f63d5bd 100644 |
--- a/sdk/lib/html/dart2js/html_dart2js.dart |
+++ b/sdk/lib/html/dart2js/html_dart2js.dart |
@@ -12383,18 +12383,18 @@ class ElementEvents extends Events { |
/* Raw event target. */ |
final Element _ptr; |
static final webkitEvents = { |
- 'animationend' : 'webkitAnimationEnd', |
- 'animationiteration' : 'webkitAnimationIteration', |
- 'animationstart' : 'webkitAnimationStart', |
- 'fullscreenchange' : 'webkitfullscreenchange', |
+ 'animationend' : 'webkitAnimationEnd', |
+ 'animationiteration' : 'webkitAnimationIteration', |
+ 'animationstart' : 'webkitAnimationStart', |
+ 'fullscreenchange' : 'webkitfullscreenchange', |
'fullscreenerror' : 'webkitfullscreenerror', |
- 'keyadded' : 'webkitkeyadded', |
- 'keyerror' : 'webkitkeyerror', |
- 'keymessage' : 'webkitkeymessage', |
- 'needkey' : 'webkitneedkey', |
- 'pointerlockchange' : 'webkitpointerlockchange', |
- 'pointerlockerror' : 'webkitpointerlockerror', |
- 'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', |
+ 'keyadded' : 'webkitkeyadded', |
+ 'keyerror' : 'webkitkeyerror', |
+ 'keymessage' : 'webkitkeymessage', |
+ 'needkey' : 'webkitneedkey', |
+ 'pointerlockchange' : 'webkitpointerlockchange', |
+ 'pointerlockerror' : 'webkitpointerlockerror', |
+ 'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', |
'transitionend': 'webkitTransitionEnd', |
'speechchange' : 'webkitSpeechChange' |
}; |
@@ -14422,32 +14422,6 @@ class HtmlDocument extends Document native "HTMLDocument" { |
* This custom element can also be instantiated via HTML using the syntax |
* `<input is="x-bar"></input>` |
* |
- * The [nativeTagName] parameter is needed by platforms without native support |
- * when subclassing a native type other than: |
- * |
- * * HtmlElement |
- * * SvgElement |
- * * AnchorElement |
- * * AudioElement |
- * * ButtonElement |
- * * CanvasElement |
- * * DivElement |
- * * ImageElement |
- * * InputElement |
- * * LIElement |
- * * LabelElement |
- * * MenuElement |
- * * MeterElement |
- * * OListElement |
- * * OptionElement |
- * * OutputElement |
- * * ParagraphElement |
- * * PreElement |
- * * ProgressElement |
- * * SelectElement |
- * * SpanElement |
- * * UListElement |
- * * VideoElement |
*/ |
void register(String tag, Type customElementClass, {String extendsTag}) { |
_registerCustomElement(JS('', 'window'), this, tag, customElementClass, |
@@ -14489,7 +14463,21 @@ class HtmlDocument extends Document native "HTMLDocument" { |
@Experimental() |
Stream<Event> get onVisibilityChange => |
visibilityChangeEvent.forTarget(this); |
+ |
+ ElementUpgrader createElementUpgrader(Type type, [String tagName]) { |
+ return new _JSElementUpgrader(this, type, tagName); |
+ } |
+ |
+} |
+ |
+ |
+ |
+abstract class ElementUpgrader { |
+ // Validate that e is subclass of type's native type |
+ // validate that e has not been upgraded as any type |
+ Element upgrade(Element element); |
} |
+ |
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
@@ -35359,6 +35347,58 @@ 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 tagName) { |
+ 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 (tagName == 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, tagName, _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; |
+ } |
+} |
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |