| Index: tools/dom/src/dartium_CustomElementSupport.dart
|
| diff --git a/tools/dom/src/dartium_CustomElementSupport.dart b/tools/dom/src/dartium_CustomElementSupport.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a70ea5ed46eb13b7556a4e07ada74e9a9a457949
|
| --- /dev/null
|
| +++ b/tools/dom/src/dartium_CustomElementSupport.dart
|
| @@ -0,0 +1,88 @@
|
| +// 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.
|
| +
|
| +part of dart.dom.html;
|
| +
|
| +/// 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) {
|
| + // 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;
|
| + }
|
| + }
|
| + 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:');
|
| +}
|
|
|