Index: sdk/lib/html/dartium/html_dartium.dart |
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart |
index 3cc7cd5c47e8b433f1f15063696c152a3b32233e..f323780bc337e781a41388d669b95342ff89bb5f 100644 |
--- a/sdk/lib/html/dartium/html_dartium.dart |
+++ b/sdk/lib/html/dartium/html_dartium.dart |
@@ -14872,32 +14872,6 @@ class HtmlDocument extends Document { |
* 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}) { |
_Utils.register(this, tag, customElementClass, extendsTag); |
@@ -14928,6 +14902,28 @@ class HtmlDocument extends Document { |
@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 _VMElementUpgrader(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 |
@@ -28955,13 +28951,13 @@ class Url extends NativeFieldWrapperClass2 implements UrlUtils { |
if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) { |
return _createObjectURL_1(blob_OR_source_OR_stream); |
} |
- if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) { |
+ if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) { |
return _createObjectURL_2(blob_OR_source_OR_stream); |
} |
- if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) { |
+ if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) { |
return _createObjectURL_3(blob_OR_source_OR_stream); |
} |
- if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) { |
+ if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) { |
return _createObjectURL_4(blob_OR_source_OR_stream); |
} |
throw new ArgumentError("Incorrect number or type of arguments"); |
@@ -38050,6 +38046,94 @@ class _VariableSizeListIterator<T> implements Iterator<T> { |
T get current => _current; |
} |
+// Copyright (c) 2014, 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. |
+ |
+ |
+/// Dartium ElementUpgrader implementation. |
+class _VMElementUpgrader implements ElementUpgrader { |
+ final Type _type; |
+ final Type _nativeType; |
+ |
+ _VMElementUpgrader(Document document, Type type, String extendsTag) : |
+ _type = type, |
+ _nativeType = _validateCustomType(type).reflectedType { |
+ |
+ if (extendsTag == null) { |
+ if (_nativeType != HtmlElement) { |
+ throw new UnsupportedError('Class must provide extendsTag if base ' |
+ 'native class is not HtmlElement'); |
+ } |
+ } else { |
+ if (document.createElement(extendsTag).runtimeType != _nativeType) { |
+ throw new UnsupportedError( |
+ 'extendsTag does not match base native class'); |
+ } |
+ } |
+ } |
+ |
+ Element upgrade(Element element) { |
+ if (element.runtimeType != _nativeType) { |
+ throw new UnsupportedError('Element is incorrect type'); |
+ } |
+ return _Utils.changeElementWrapper(element, _type); |
+ return null; |
+ } |
+} |
+ |
+/// Validates that the custom type is properly formed- |
+/// |
+/// * Is a user-defined class. |
+/// * Has a created constructor with zero args. |
+/// * Derives from an Element subclass. |
+/// |
+/// Then returns the native base class. |
+ClassMirror _validateCustomType(Type type) { |
+ ClassMirror cls = reflectClass(type); |
+ if (_isBuiltinType(cls)) { |
+ throw new UnsupportedError('Invalid custom element from ' |
+ '${(cls.owner as LibraryMirror).uri}.'); |
+ } |
+ |
+ var className = MirrorSystem.getName(cls.simpleName); |
+ var createdConstructor = cls.declarations[new Symbol('$className.created')]; |
+ if (createdConstructor == null || |
+ createdConstructor is! MethodMirror || |
+ !createdConstructor.isConstructor) { |
+ throw new UnsupportedError( |
+ 'Class is missing constructor $className.created'); |
+ } |
+ |
+ if (createdConstructor.parameters.length > 0) { |
+ throw new UnsupportedError( |
+ 'Constructor $className.created must take zero arguments'); |
+ } |
+ |
+ Symbol objectName = reflectClass(Object).qualifiedName; |
+ bool isRoot(ClassMirror cls) => |
+ cls == null || cls.qualifiedName == objectName; |
+ Symbol elementName = reflectClass(HtmlElement).qualifiedName; |
+ bool isElement(ClassMirror cls) => |
+ cls != null && cls.qualifiedName == elementName; |
+ ClassMirror superClass = cls.superclass; |
+ ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null; |
+ while(!isRoot(superClass) && !isElement(superClass)) { |
+ superClass = superClass.superclass; |
+ if (nativeClass == null && _isBuiltinType(superClass)) { |
+ nativeClass = superClass; |
+ } |
+ } |
+ return nativeClass; |
+} |
+ |
+ |
+bool _isBuiltinType(ClassMirror cls) { |
+ // TODO(vsm): Find a less hackish way to do this. |
+ LibraryMirror lib = cls.owner; |
+ String libName = lib.uri.toString(); |
+ return libName.startsWith('dart:'); |
+} |
/** |
* A custom KeyboardEvent that attempts to eliminate cross-browser |
* inconsistencies, and also provide both keyCode and charCode information |
@@ -38691,48 +38775,10 @@ class _Utils { |
static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError; |
- static bool _isBuiltinType(ClassMirror cls) { |
- // TODO(vsm): Find a less hackish way to do this. |
- LibraryMirror lib = cls.owner; |
- String libName = lib.uri.toString(); |
- return libName.startsWith('dart:'); |
- } |
- |
static void register(Document document, String tag, Type type, |
String extendsTagName) { |
- // TODO(vsm): Move these checks into native code. |
- ClassMirror cls = reflectClass(type); |
- if (_isBuiltinType(cls)) { |
- throw new UnsupportedError("Invalid custom element from ${(cls.owner as LibraryMirror).uri}."); |
- } |
- var className = MirrorSystem.getName(cls.simpleName); |
- var createdConstructor = cls.declarations[new Symbol('$className.created')]; |
- if (createdConstructor == null || |
- createdConstructor is! MethodMirror || |
- !createdConstructor.isConstructor) { |
- throw new UnsupportedError( |
- 'Class is missing constructor $className.created'); |
- } |
- |
- if (createdConstructor.parameters.length > 0) { |
- throw new UnsupportedError( |
- 'Constructor $className.created must take zero arguments'); |
- } |
- |
- Symbol objectName = reflectClass(Object).qualifiedName; |
- bool isRoot(ClassMirror cls) => |
- cls == null || cls.qualifiedName == objectName; |
- Symbol elementName = reflectClass(HtmlElement).qualifiedName; |
- bool isElement(ClassMirror cls) => |
- cls != null && cls.qualifiedName == elementName; |
- ClassMirror superClass = cls.superclass; |
- ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null; |
- while(!isRoot(superClass) && !isElement(superClass)) { |
- superClass = superClass.superclass; |
- if (nativeClass == null && _isBuiltinType(superClass)) { |
- nativeClass = superClass; |
- } |
- } |
+ var nativeClass = _validateCustomType(type); |
+ |
if (extendsTagName == null) { |
if (nativeClass.reflectedType != HtmlElement) { |
throw new UnsupportedError('Class must provide extendsTag if base ' |
@@ -38749,6 +38795,8 @@ class _Utils { |
static Element createElement(Document document, String tagName) native "Utils_createElement"; |
static void initializeCustomElement(HtmlElement element) native "Utils_initializeCustomElement"; |
+ |
+ static void changeElementWrapper(HtmlElement element, Type type) native "Utils_changeElementWrapper"; |
} |
class _DOMWindowCrossFrame extends NativeFieldWrapperClass2 implements |