Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1455)

Unified Diff: sdk/lib/html/dart2js/html_dart2js.dart

Side-by-side diff isn't available for this file because of its large size.
Issue 177113014: Adding a mechanism to 'upgrade' the Dart type of elements (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
Download patch
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..bbe65848ccc662c343de8d06df9490133900290e 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -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,6 +14463,28 @@ class HtmlDocument extends Document native "HTMLDocument" {
@Experimental()
Stream<Event> get onVisibilityChange =>
visibilityChangeEvent.forTarget(this);
+
+ /// Creates an element upgrader which can be used to change the Dart wrapper
+ /// type for elements.
+ ///
+ /// The type specified must be a subclass of HtmlElement, when an element is
+ /// upgraded then the created constructor will be invoked on that element.
+ ///
+ /// If the type is not a direct subclass of HtmlElement then the extendsTag
+ /// parameter must be provided.
+ @Experimental()
+ ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
+ return new _JSElementUpgrader(this, type, extendsTag);
+ }
+}
+
+/// A utility for changing the Dart wrapper type for elements.
+abstract class ElementUpgrader {
+ /// Upgrade the specified element to be of the Dart type this was created for.
+ ///
+ /// After upgrading the element passed in is invalid and the returned value
+ /// should be used instead.
+ 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
@@ -35318,7 +35314,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[#])',
@@ -35359,6 +35355,63 @@ 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.
}
+
+/// Dart2JS implementation of ElementUpgrader
+class _JSElementUpgrader implements ElementUpgrader {
+ var _interceptor;
+ var _constructor;
+ var _nativeType;
+
+ _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'));
+
+ var 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');
+ }
+ _nativeType = HtmlElement;
+ } else {
+ var element = document.createElement(extendsTag);
+ if (!JS('bool', '(# instanceof window[#])',
+ element, baseClassName)) {
+ throw new UnsupportedError(
+ 'extendsTag does not match base native class');
+ }
+ _nativeType = element.runtimeType;
+ }
+
+ _interceptor = JS('=Object', '#.prototype', interceptorClass);
+ }
+
+ Element upgrade(Element element) {
+ // Only exact type matches are supported- cannot be a subclass.
+ if (element.runtimeType != _nativeType) {
+ throw new ArgumentError('element is not subclass of $_nativeType');
+ }
+
+ 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.
« no previous file with comments | « no previous file | sdk/lib/html/dartium/html_dartium.dart » ('j') | tools/dom/src/dart2js_CustomElementSupport.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698