mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:29:48 +00:00
Hide internal methods like wrap_jso from the dart:html public interface
Issue https://github.com/dart-lang/sdk/issues/24602 R=terry@google.com Review URL: https://codereview.chromium.org/1409743003 .
This commit is contained in:
parent
568484d106
commit
a9362610ee
|
@ -1107,71 +1107,14 @@ Function _getSvgFunction(String key) {
|
|||
********** **********
|
||||
******************************************************************************/
|
||||
|
||||
// List of known tagName to DartClass for custom elements, used for upgrade.
|
||||
var _knownCustomElements = new Map<String, Map<Type, String>>();
|
||||
|
||||
void _addCustomElementType(String tagName, Type dartClass, [String extendTag]) {
|
||||
_knownCustomElements[tagName] =
|
||||
{'type': dartClass, 'extends': extendTag != null ? extendTag : "" };
|
||||
}
|
||||
|
||||
Type _getCustomElementType(object) {
|
||||
var entry = _getCustomElementEntry(object);
|
||||
if (entry != null) {
|
||||
return entry['type'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String _getCustomElementExtends(object) {
|
||||
var entry = _getCustomElementEntry(object);
|
||||
var entry = getCustomElementEntry(object);
|
||||
if (entry != null) {
|
||||
return entry['extends'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_getCustomElementEntry(element) {
|
||||
var hasAttribute = false;
|
||||
|
||||
var jsObject;
|
||||
var tag = "";
|
||||
var runtimeType = element.runtimeType;
|
||||
if (runtimeType == HtmlElement) {
|
||||
tag = element.localName;
|
||||
} else if (runtimeType == TemplateElement) {
|
||||
// Data binding with a Dart class.
|
||||
tag = element.attributes['is'];
|
||||
} else if (runtimeType == js.JsObjectImpl) {
|
||||
// It's a Polymer core element (written in JS).
|
||||
// Make sure it's an element anything else we can ignore.
|
||||
if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
|
||||
if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
|
||||
hasAttribute = true;
|
||||
// It's data binding use the is attribute.
|
||||
tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
|
||||
} else {
|
||||
// It's a custom element we want the local name.
|
||||
tag = element['localName'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
|
||||
}
|
||||
|
||||
var entry = _knownCustomElements[tag];
|
||||
if (entry != null) {
|
||||
// If there's an 'is' attribute then check if the extends tag registered
|
||||
// matches the tag if so then return the entry that's registered for this
|
||||
// extendsTag or if there's no 'is' tag then return the entry found.
|
||||
if ((hasAttribute && entry['extends'] == tag) || !hasAttribute) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return the tag name or is attribute of the custom element or data binding.
|
||||
String _getCustomElementName(element) {
|
||||
var jsObject;
|
||||
|
@ -1210,242 +1153,14 @@ class DartHtmlDomObject {
|
|||
|
||||
}
|
||||
|
||||
// Flag to disable JS interop asserts. Setting to false will speed up the
|
||||
// wrap_jso calls.
|
||||
bool __interop_checks = false;
|
||||
|
||||
/** Expando for JsObject, used by every Dart class associated with a Javascript
|
||||
* class (e.g., DOM, WebAudio, etc.).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the JsObject associated with a Dart class [dartClass_instance].
|
||||
*/
|
||||
unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type, add the JsObject as an expando
|
||||
* on the Dart class and return the created Dart class.
|
||||
*/
|
||||
wrap_jso(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
// if we have a wrapper return the Dart instance.
|
||||
if (wrapper != null) {
|
||||
var customElementClass = _getCustomElementType(wrapper.blink_jsObject);
|
||||
if (wrapper.runtimeType != customElementClass && customElementClass != null) {
|
||||
if (wrapper.runtimeType == HtmlElement && !wrapper._isBadUpgrade) {
|
||||
// We're a Dart instance if it's HtmlElement and we have a customElement
|
||||
// class then we need to upgrade.
|
||||
if (customElementClass != null) {
|
||||
var dartClass_instance;
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new _DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
// Try the most general type conversions on it.
|
||||
// TODO(alanknight): We may be able to do better. This maintains identity,
|
||||
// which is useful, but expensive. And if we nest something that only
|
||||
// this conversion handles, how does that work? e.g. a list of maps of elements.
|
||||
var converted = convertNativeToDart_SerializedScriptValue(jsObject);
|
||||
if (!identical(converted, jsObject)) {
|
||||
return converted;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var dartClass_instance;
|
||||
var customElementClass = null;
|
||||
var extendsTag = "";
|
||||
var custom = _getCustomElementEntry(jsObject);
|
||||
if (custom != null) {
|
||||
customElementClass = custom['type'];
|
||||
extendsTag = custom['extends'];
|
||||
}
|
||||
|
||||
// Custom Element to upgrade.
|
||||
// Only allow custome elements to be created in the html or svg default
|
||||
// namespace.
|
||||
var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' ||
|
||||
jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg';
|
||||
if (customElementClass != null && extendsTag == "" && defaultNS) {
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
} else {
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func == null) {
|
||||
if (jsTypeName == 'auto-binding') {
|
||||
func = getHtmlCreateFunction("HTMLTemplateElement");
|
||||
} else if (jsObject.toString() == "[object HTMLElement]") {
|
||||
// One last ditch effort could be a JS custom element.
|
||||
func = getHtmlCreateFunction("HTMLElement");
|
||||
}
|
||||
}
|
||||
if (func != null) {
|
||||
dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jacobr): cache that this is not a dart:html JS class.
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type, add the JsObject as an expando
|
||||
* on the Dart class and return the created Dart class.
|
||||
*/
|
||||
wrap_jso_no_SerializedScriptvalue(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// TODO(alanknight): With upgraded custom elements this causes a failure because
|
||||
// we need a new wrapper after the type changes. We could possibly invalidate this
|
||||
// if the constructor name didn't match?
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
if (wrapper != null) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new _DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func != null) {
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
return dartClass_instance;
|
||||
}
|
||||
return jsObject;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type that is the JS type being
|
||||
* extended using JS interop createCallback (we need the base type of the
|
||||
* custom element) not the Dart created constructor.
|
||||
*/
|
||||
wrap_jso_custom_element(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Find out what object we're extending.
|
||||
var objectName = jsObject.toString();
|
||||
// Expect to see something like '[object HTMLElement]'.
|
||||
if (!objectName.startsWith('[object ')) {
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var extendsClass = objectName.substring(8, objectName.length - 1);
|
||||
var func = getHtmlCreateFunction(extendsClass);
|
||||
if (__interop_checks)
|
||||
debug_or_assert("func != null name = ${extendsClass}", func != null);
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
|
||||
// Problem?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade a Dart HtmlElement to the user's Dart custom element class.
|
||||
/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
|
||||
_upgradeHtmlElement(dartInstance) {
|
||||
// Only try upgrading HtmlElement (Dart class) if there is a failure then
|
||||
// don't try it again - one failure is enough.
|
||||
if (dartInstance.runtimeType == HtmlElement && !dartInstance._isBadUpgrade) {
|
||||
if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
|
||||
// Must be exactly HtmlElement not something derived from it.
|
||||
|
||||
var customElementClass = _getCustomElementType(dartInstance);
|
||||
var customElementClass = getCustomElementType(dartInstance);
|
||||
|
||||
// Custom Element to upgrade.
|
||||
if (customElementClass != null) {
|
||||
|
@ -1501,53 +1216,10 @@ Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Converts a flat Dart map into a JavaScript object with properties this is
|
||||
// is the Dartium only version it uses dart:js.
|
||||
// TODO(alanknight): This could probably be unified with the dart2js conversions
|
||||
// code in html_common and be more general.
|
||||
convertDartToNative_Dictionary(Map dict) {
|
||||
if (dict == null) return null;
|
||||
var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object'));
|
||||
dict.forEach((String key, value) {
|
||||
if (value is List) {
|
||||
var jsArray = new js.JsArray();
|
||||
value.forEach((elem) {
|
||||
jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
|
||||
});
|
||||
jsObject[key] = jsArray;
|
||||
} else {
|
||||
jsObject[key] = value;
|
||||
}
|
||||
});
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Converts a Dart list into a JsArray. For the Dartium version only.
|
||||
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
|
||||
|
||||
// Conversion function place holder (currently not used in dart2js or dartium).
|
||||
List convertDartToNative_StringArray(List<String> input) => input;
|
||||
|
||||
/**
|
||||
* Wraps a JsArray and will call wrap_jso on its entries.
|
||||
*/
|
||||
class _DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
|
||||
_DartHtmlWrappingList(this.blink_jsObject);
|
||||
|
||||
final js.JsArray blink_jsObject;
|
||||
|
||||
operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
|
||||
|
||||
operator []=(int index, value) => blink_jsObject[index] = value;
|
||||
|
||||
int get length => blink_jsObject.length;
|
||||
int set length(int newLength) => blink_jsObject.length = newLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the JS HTMLElement to the Dart class. Used by Dart's Polymer.
|
||||
*/
|
||||
createCustomUpgrader(Type customElementClass, $this) {
|
||||
_createCustomUpgrader(Type customElementClass, $this) {
|
||||
var dartClass;
|
||||
try {
|
||||
dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
|
||||
|
@ -20514,7 +20186,7 @@ class HtmlDocument extends Document {
|
|||
var nativeElement = document.createElement(extendsTag);
|
||||
|
||||
// Trying to extend a native element is it the Dart class consistent with the
|
||||
// extendsTag?
|
||||
// extendsTag?
|
||||
if (nativeElement.runtimeType != customClassType.reflectedType) {
|
||||
var nativeElementClassMirror = reflectClass(nativeElement.runtimeType);
|
||||
var customClassNativeElement = MirrorSystem.getName(customClassType.simpleName);
|
||||
|
@ -20542,7 +20214,7 @@ class HtmlDocument extends Document {
|
|||
var elemProto = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), "create", [js.JsNative.getProperty(baseElement, 'prototype')]);
|
||||
|
||||
// Remember for any upgrading done in wrap_jso.
|
||||
_addCustomElementType(tag, customElementClass, extendsTag);
|
||||
addCustomElementType(tag, customElementClass, extendsTag);
|
||||
|
||||
// TODO(terry): Hack to stop recursion re-creating custom element when the
|
||||
// created() constructor of the custom element does e.g.,
|
||||
|
@ -21320,10 +20992,17 @@ class HtmlElement extends Element implements GlobalEventHandlers {
|
|||
@Experimental() // untriaged
|
||||
ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
|
||||
|
||||
// Flags to only try upgrading once if there's a failure don't try upgrading
|
||||
// Flags to only try upgrading once. If there's a failure don't try upgrading
|
||||
// anymore.
|
||||
bool _badUpgradeOccurred = false;
|
||||
bool get _isBadUpgrade => _badUpgradeOccurred;
|
||||
|
||||
/// Required for SDK Infrastructure. Internal use only.
|
||||
///
|
||||
/// Did this encounter a failure attempting to upgrade to
|
||||
/// a custom element.
|
||||
@Deprecated("Required for SDK Infrastructure. Internal use only.")
|
||||
bool get isBadUpgrade => _badUpgradeOccurred;
|
||||
|
||||
void _badUpgrade() { _badUpgradeOccurred = true; }
|
||||
}
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
|
@ -47289,16 +46968,16 @@ class _VMElementUpgrader implements ElementUpgrader {
|
|||
|
||||
// Element to extend is the real tag.
|
||||
tag = element.localName;
|
||||
} else if (tag != null && element.localName != tag) {
|
||||
} else if (tag != null && element.localName != tag) {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected native Html or Svg element to extend.');
|
||||
} else if (tag == null) {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObjectImpl.');
|
||||
}
|
||||
|
||||
// Remember Dart class to tagName for any upgrading done in wrap_jso.
|
||||
_addCustomElementType(tag, _type, _extendsTag);
|
||||
addCustomElementType(tag, _type, _extendsTag);
|
||||
|
||||
return createCustomUpgrader(_type, jsObject);
|
||||
return _createCustomUpgrader(_type, jsObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,3 +91,9 @@ Future convertNativePromiseToDartFuture(promise) {
|
|||
var newPromise = JS('', '#.then(#).catch(#)', promise, then, error);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Wrap a JS object with an instance of the matching dart:html class. Used only in Dartium.
|
||||
wrap_jso(jsObject) => jsObject;
|
||||
|
||||
/// Find the underlying JS object for a dart:html Dart object.
|
||||
unwrap_jso(dartClass_instance) => dartClass_instance;
|
||||
|
|
|
@ -75,3 +75,322 @@ Rectangle make_dart_rectangle(r) =>
|
|||
js.JsNative.getProperty(r, 'top'),
|
||||
js.JsNative.getProperty(r, 'width'),
|
||||
js.JsNative.getProperty(r, 'height'));
|
||||
|
||||
// Converts a flat Dart map into a JavaScript object with properties this is
|
||||
// is the Dartium only version it uses dart:js.
|
||||
// TODO(alanknight): This could probably be unified with the dart2js conversions
|
||||
// code in html_common and be more general.
|
||||
convertDartToNative_Dictionary(Map dict) {
|
||||
if (dict == null) return null;
|
||||
var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object'));
|
||||
dict.forEach((String key, value) {
|
||||
if (value is List) {
|
||||
var jsArray = new js.JsArray();
|
||||
value.forEach((elem) {
|
||||
jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
|
||||
});
|
||||
jsObject[key] = jsArray;
|
||||
} else {
|
||||
jsObject[key] = value;
|
||||
}
|
||||
});
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Conversion function place holder (currently not used in dart2js or dartium).
|
||||
List convertDartToNative_StringArray(List<String> input) => input;
|
||||
|
||||
// Converts a Dart list into a JsArray. For the Dartium version only.
|
||||
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
|
||||
|
||||
/// Find the underlying JS object for a dart:html Dart object.
|
||||
unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);
|
||||
|
||||
// Flag to disable JS interop asserts. Setting to false will speed up the
|
||||
// wrap_jso calls.
|
||||
bool interop_checks = false;
|
||||
|
||||
/// Wrap a JS object with an instance of the matching dart:html class. Used only in Dartium.
|
||||
wrap_jso(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
// if we have a wrapper return the Dart instance.
|
||||
if (wrapper != null) {
|
||||
var customElementClass = getCustomElementType(wrapper.blink_jsObject);
|
||||
if (wrapper.runtimeType != customElementClass && customElementClass != null) {
|
||||
if (wrapper.runtimeType == HtmlElement && !wrapper.isBadUpgrade) {
|
||||
// We're a Dart instance if it's HtmlElement and we have a customElement
|
||||
// class then we need to upgrade.
|
||||
if (customElementClass != null) {
|
||||
var dartClass_instance;
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
// Try the most general type conversions on it.
|
||||
// TODO(alanknight): We may be able to do better. This maintains identity,
|
||||
// which is useful, but expensive. And if we nest something that only
|
||||
// this conversion handles, how does that work? e.g. a list of maps of elements.
|
||||
var converted = convertNativeToDart_SerializedScriptValue(jsObject);
|
||||
if (!identical(converted, jsObject)) {
|
||||
return converted;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var dartClass_instance;
|
||||
var customElementClass = null;
|
||||
var extendsTag = "";
|
||||
var custom = getCustomElementEntry(jsObject);
|
||||
if (custom != null) {
|
||||
customElementClass = custom['type'];
|
||||
extendsTag = custom['extends'];
|
||||
}
|
||||
|
||||
// Custom Element to upgrade.
|
||||
// Only allow custome elements to be created in the html or svg default
|
||||
// namespace.
|
||||
var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' ||
|
||||
jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg';
|
||||
if (customElementClass != null && extendsTag == "" && defaultNS) {
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
} else {
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func == null) {
|
||||
if (jsTypeName == 'auto-binding') {
|
||||
func = getHtmlCreateFunction("HTMLTemplateElement");
|
||||
} else if (jsObject.toString() == "[object HTMLElement]") {
|
||||
// One last ditch effort could be a JS custom element.
|
||||
func = getHtmlCreateFunction("HTMLElement");
|
||||
}
|
||||
}
|
||||
if (func != null) {
|
||||
dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jacobr): cache that this is not a dart:html JS class.
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type, add the JsObject as an expando
|
||||
* on the Dart class and return the created Dart class.
|
||||
*/
|
||||
wrap_jso_no_SerializedScriptvalue(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// TODO(alanknight): With upgraded custom elements this causes a failure because
|
||||
// we need a new wrapper after the type changes. We could possibly invalidate this
|
||||
// if the constructor name didn't match?
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
if (wrapper != null) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func != null) {
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
return dartClass_instance;
|
||||
}
|
||||
return jsObject;
|
||||
} catch(e, stacktrace){
|
||||
if (interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type that is the JS type being
|
||||
* extended using JS interop createCallback (we need the base type of the
|
||||
* custom element) not the Dart created constructor.
|
||||
*/
|
||||
wrap_jso_custom_element(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Find out what object we're extending.
|
||||
var objectName = jsObject.toString();
|
||||
// Expect to see something like '[object HTMLElement]'.
|
||||
if (!objectName.startsWith('[object ')) {
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var extendsClass = objectName.substring(8, objectName.length - 1);
|
||||
var func = getHtmlCreateFunction(extendsClass);
|
||||
if (interop_checks)
|
||||
debug_or_assert("func != null name = ${extendsClass}", func != null);
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
|
||||
// Problem?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
getCustomElementEntry(element) {
|
||||
var hasAttribute = false;
|
||||
|
||||
var jsObject;
|
||||
var tag = "";
|
||||
var runtimeType = element.runtimeType;
|
||||
if (runtimeType == HtmlElement) {
|
||||
tag = element.localName;
|
||||
} else if (runtimeType == TemplateElement) {
|
||||
// Data binding with a Dart class.
|
||||
tag = element.attributes['is'];
|
||||
} else if (runtimeType == js.JsObjectImpl) {
|
||||
// It's a Polymer core element (written in JS).
|
||||
// Make sure it's an element anything else we can ignore.
|
||||
if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
|
||||
if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
|
||||
hasAttribute = true;
|
||||
// It's data binding use the is attribute.
|
||||
tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
|
||||
} else {
|
||||
// It's a custom element we want the local name.
|
||||
tag = element['localName'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
|
||||
}
|
||||
|
||||
var entry = _knownCustomElements[tag];
|
||||
if (entry != null) {
|
||||
// If there's an 'is' attribute then check if the extends tag registered
|
||||
// matches the tag if so then return the entry that's registered for this
|
||||
// extendsTag or if there's no 'is' tag then return the entry found.
|
||||
if ((hasAttribute && entry['extends'] == tag) || !hasAttribute) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// List of known tagName to DartClass for custom elements, used for upgrade.
|
||||
var _knownCustomElements = new Map<String, Map<Type, String>>();
|
||||
|
||||
void addCustomElementType(String tagName, Type dartClass, [String extendTag]) {
|
||||
_knownCustomElements[tagName] =
|
||||
{'type': dartClass, 'extends': extendTag != null ? extendTag : "" };
|
||||
}
|
||||
|
||||
Type getCustomElementType(object) {
|
||||
var entry = getCustomElementEntry(object);
|
||||
if (entry != null) {
|
||||
return entry['type'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a JsArray and will call wrap_jso on its entries.
|
||||
*/
|
||||
class DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
|
||||
DartHtmlWrappingList(this.blink_jsObject);
|
||||
|
||||
final js.JsArray blink_jsObject;
|
||||
|
||||
operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
|
||||
|
||||
operator []=(int index, value) => blink_jsObject[index] = value;
|
||||
|
||||
int get length => blink_jsObject.length;
|
||||
int set length(int newLength) => blink_jsObject.length = newLength;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'dart:collection';
|
|||
import 'dart:html';
|
||||
import 'dart:js' as js;
|
||||
import 'dart:_internal' show WhereIterable;
|
||||
import 'dart:nativewrappers';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:web_gl' as gl;
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ import 'dart:nativewrappers';
|
|||
import 'dart:math' as math;
|
||||
import 'dart:mirrors' as mirrors;
|
||||
import 'dart:html' as html;
|
||||
import 'dart:html_common' as html_common;
|
||||
import 'dart:indexed_db' as indexed_db;
|
||||
import 'dart:typed_data';
|
||||
|
||||
|
@ -700,7 +701,7 @@ JsObject get context {
|
|||
}
|
||||
|
||||
_maybeWrap(o) {
|
||||
var wrapped = html.wrap_jso_no_SerializedScriptvalue(o);
|
||||
var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o);
|
||||
if (identical(wrapped, o)) return o;
|
||||
return (wrapped is html.Blob
|
||||
|| wrapped is html.Event
|
||||
|
@ -819,7 +820,7 @@ class JsObject extends NativeFieldWrapperClass2 {
|
|||
|
||||
static JsObject _jsify(object) native "JsObject_jsify";
|
||||
|
||||
static JsObject _fromBrowserObject(object) => html.unwrap_jso(object);
|
||||
static JsObject _fromBrowserObject(object) => html_common.unwrap_jso(object);
|
||||
|
||||
/**
|
||||
* Returns the value associated with [property] from the proxied JavaScript
|
||||
|
@ -858,7 +859,7 @@ class JsObject extends NativeFieldWrapperClass2 {
|
|||
operator ==(other) {
|
||||
var is_JsObject = other is JsObject;
|
||||
if (!is_JsObject) {
|
||||
other = html.unwrap_jso(other);
|
||||
other = html_common.unwrap_jso(other);
|
||||
is_JsObject = other is JsObject;
|
||||
}
|
||||
return is_JsObject && _identityEquality(this, other);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
library wrapping_collection_test;
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:html_common';
|
||||
import 'dart:js' as js;
|
||||
import 'package:unittest/unittest.dart';
|
||||
import 'package:unittest/html_config.dart';
|
||||
|
|
|
@ -53,16 +53,16 @@ class _VMElementUpgrader implements ElementUpgrader {
|
|||
|
||||
// Element to extend is the real tag.
|
||||
tag = element.localName;
|
||||
} else if (tag != null && element.localName != tag) {
|
||||
} else if (tag != null && element.localName != tag) {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected native Html or Svg element to extend.');
|
||||
} else if (tag == null) {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObjectImpl.');
|
||||
}
|
||||
|
||||
// Remember Dart class to tagName for any upgrading done in wrap_jso.
|
||||
_addCustomElementType(tag, _type, _extendsTag);
|
||||
addCustomElementType(tag, _type, _extendsTag);
|
||||
|
||||
return createCustomUpgrader(_type, jsObject);
|
||||
return _createCustomUpgrader(_type, jsObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -352,71 +352,14 @@ Function _getSvgFunction(String key) {
|
|||
********** **********
|
||||
******************************************************************************/
|
||||
|
||||
// List of known tagName to DartClass for custom elements, used for upgrade.
|
||||
var _knownCustomElements = new Map<String, Map<Type, String>>();
|
||||
|
||||
void _addCustomElementType(String tagName, Type dartClass, [String extendTag]) {
|
||||
_knownCustomElements[tagName] =
|
||||
{'type': dartClass, 'extends': extendTag != null ? extendTag : "" };
|
||||
}
|
||||
|
||||
Type _getCustomElementType(object) {
|
||||
var entry = _getCustomElementEntry(object);
|
||||
if (entry != null) {
|
||||
return entry['type'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String _getCustomElementExtends(object) {
|
||||
var entry = _getCustomElementEntry(object);
|
||||
var entry = getCustomElementEntry(object);
|
||||
if (entry != null) {
|
||||
return entry['extends'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_getCustomElementEntry(element) {
|
||||
var hasAttribute = false;
|
||||
|
||||
var jsObject;
|
||||
var tag = "";
|
||||
var runtimeType = element.runtimeType;
|
||||
if (runtimeType == HtmlElement) {
|
||||
tag = element.localName;
|
||||
} else if (runtimeType == TemplateElement) {
|
||||
// Data binding with a Dart class.
|
||||
tag = element.attributes['is'];
|
||||
} else if (runtimeType == js.JsObjectImpl) {
|
||||
// It's a Polymer core element (written in JS).
|
||||
// Make sure it's an element anything else we can ignore.
|
||||
if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
|
||||
if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
|
||||
hasAttribute = true;
|
||||
// It's data binding use the is attribute.
|
||||
tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
|
||||
} else {
|
||||
// It's a custom element we want the local name.
|
||||
tag = element['localName'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
|
||||
}
|
||||
|
||||
var entry = _knownCustomElements[tag];
|
||||
if (entry != null) {
|
||||
// If there's an 'is' attribute then check if the extends tag registered
|
||||
// matches the tag if so then return the entry that's registered for this
|
||||
// extendsTag or if there's no 'is' tag then return the entry found.
|
||||
if ((hasAttribute && entry['extends'] == tag) || !hasAttribute) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return the tag name or is attribute of the custom element or data binding.
|
||||
String _getCustomElementName(element) {
|
||||
var jsObject;
|
||||
|
@ -455,242 +398,14 @@ class DartHtmlDomObject {
|
|||
|
||||
}
|
||||
|
||||
// Flag to disable JS interop asserts. Setting to false will speed up the
|
||||
// wrap_jso calls.
|
||||
bool __interop_checks = false;
|
||||
|
||||
/** Expando for JsObject, used by every Dart class associated with a Javascript
|
||||
* class (e.g., DOM, WebAudio, etc.).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the JsObject associated with a Dart class [dartClass_instance].
|
||||
*/
|
||||
unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type, add the JsObject as an expando
|
||||
* on the Dart class and return the created Dart class.
|
||||
*/
|
||||
wrap_jso(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
// if we have a wrapper return the Dart instance.
|
||||
if (wrapper != null) {
|
||||
var customElementClass = _getCustomElementType(wrapper.blink_jsObject);
|
||||
if (wrapper.runtimeType != customElementClass && customElementClass != null) {
|
||||
if (wrapper.runtimeType == HtmlElement && !wrapper._isBadUpgrade) {
|
||||
// We're a Dart instance if it's HtmlElement and we have a customElement
|
||||
// class then we need to upgrade.
|
||||
if (customElementClass != null) {
|
||||
var dartClass_instance;
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new _DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
// Try the most general type conversions on it.
|
||||
// TODO(alanknight): We may be able to do better. This maintains identity,
|
||||
// which is useful, but expensive. And if we nest something that only
|
||||
// this conversion handles, how does that work? e.g. a list of maps of elements.
|
||||
var converted = convertNativeToDart_SerializedScriptValue(jsObject);
|
||||
if (!identical(converted, jsObject)) {
|
||||
return converted;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var dartClass_instance;
|
||||
var customElementClass = null;
|
||||
var extendsTag = "";
|
||||
var custom = _getCustomElementEntry(jsObject);
|
||||
if (custom != null) {
|
||||
customElementClass = custom['type'];
|
||||
extendsTag = custom['extends'];
|
||||
}
|
||||
|
||||
// Custom Element to upgrade.
|
||||
// Only allow custome elements to be created in the html or svg default
|
||||
// namespace.
|
||||
var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' ||
|
||||
jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg';
|
||||
if (customElementClass != null && extendsTag == "" && defaultNS) {
|
||||
try {
|
||||
dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
|
||||
} finally {
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
} else {
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func == null) {
|
||||
if (jsTypeName == 'auto-binding') {
|
||||
func = getHtmlCreateFunction("HTMLTemplateElement");
|
||||
} else if (jsObject.toString() == "[object HTMLElement]") {
|
||||
// One last ditch effort could be a JS custom element.
|
||||
func = getHtmlCreateFunction("HTMLElement");
|
||||
}
|
||||
}
|
||||
if (func != null) {
|
||||
dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jacobr): cache that this is not a dart:html JS class.
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type, add the JsObject as an expando
|
||||
* on the Dart class and return the created Dart class.
|
||||
*/
|
||||
wrap_jso_no_SerializedScriptvalue(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject || jsObject == null) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
// or it's a simple type.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// TODO(alanknight): With upgraded custom elements this causes a failure because
|
||||
// we need a new wrapper after the type changes. We could possibly invalidate this
|
||||
// if the constructor name didn't match?
|
||||
var wrapper = js.getDartHtmlWrapperFor(jsObject);
|
||||
if (wrapper != null) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (jsObject is js.JsArray) {
|
||||
var wrappingList = new _DartHtmlWrappingList(jsObject);
|
||||
js.setDartHtmlWrapperFor(jsObject, wrappingList);
|
||||
return wrappingList;
|
||||
}
|
||||
|
||||
var constructor = js.JsNative.getProperty(jsObject, 'constructor');
|
||||
if (constructor == null) {
|
||||
// Perfectly valid case for JavaScript objects where __proto__ has
|
||||
// intentionally been set to null.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
|
||||
if (jsTypeName is! String || jsTypeName.length == 0) {
|
||||
// Not an html type.
|
||||
js.setDartHtmlWrapperFor(jsObject, jsObject);
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var func = getHtmlCreateFunction(jsTypeName);
|
||||
if (func != null) {
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
|
||||
return dartClass_instance;
|
||||
}
|
||||
return jsObject;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Dart class that maps to the JS Type that is the JS type being
|
||||
* extended using JS interop createCallback (we need the base type of the
|
||||
* custom element) not the Dart created constructor.
|
||||
*/
|
||||
wrap_jso_custom_element(jsObject) {
|
||||
try {
|
||||
if (jsObject is! js.JsObject) {
|
||||
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Find out what object we're extending.
|
||||
var objectName = jsObject.toString();
|
||||
// Expect to see something like '[object HTMLElement]'.
|
||||
if (!objectName.startsWith('[object ')) {
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
var extendsClass = objectName.substring(8, objectName.length - 1);
|
||||
var func = getHtmlCreateFunction(extendsClass);
|
||||
if (__interop_checks)
|
||||
debug_or_assert("func != null name = ${extendsClass}", func != null);
|
||||
var dartClass_instance = func();
|
||||
dartClass_instance.blink_jsObject = jsObject;
|
||||
return dartClass_instance;
|
||||
} catch(e, stacktrace){
|
||||
if (__interop_checks) {
|
||||
if (e is DebugAssertException)
|
||||
window.console.log("${e.message}\n ${stacktrace}");
|
||||
else
|
||||
window.console.log("${stacktrace}");
|
||||
}
|
||||
|
||||
// Problem?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade a Dart HtmlElement to the user's Dart custom element class.
|
||||
/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
|
||||
_upgradeHtmlElement(dartInstance) {
|
||||
// Only try upgrading HtmlElement (Dart class) if there is a failure then
|
||||
// don't try it again - one failure is enough.
|
||||
if (dartInstance.runtimeType == HtmlElement && !dartInstance._isBadUpgrade) {
|
||||
if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
|
||||
// Must be exactly HtmlElement not something derived from it.
|
||||
|
||||
var customElementClass = _getCustomElementType(dartInstance);
|
||||
var customElementClass = getCustomElementType(dartInstance);
|
||||
|
||||
// Custom Element to upgrade.
|
||||
if (customElementClass != null) {
|
||||
|
@ -746,53 +461,10 @@ Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Converts a flat Dart map into a JavaScript object with properties this is
|
||||
// is the Dartium only version it uses dart:js.
|
||||
// TODO(alanknight): This could probably be unified with the dart2js conversions
|
||||
// code in html_common and be more general.
|
||||
convertDartToNative_Dictionary(Map dict) {
|
||||
if (dict == null) return null;
|
||||
var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object'));
|
||||
dict.forEach((String key, value) {
|
||||
if (value is List) {
|
||||
var jsArray = new js.JsArray();
|
||||
value.forEach((elem) {
|
||||
jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
|
||||
});
|
||||
jsObject[key] = jsArray;
|
||||
} else {
|
||||
jsObject[key] = value;
|
||||
}
|
||||
});
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
// Converts a Dart list into a JsArray. For the Dartium version only.
|
||||
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
|
||||
|
||||
// Conversion function place holder (currently not used in dart2js or dartium).
|
||||
List convertDartToNative_StringArray(List<String> input) => input;
|
||||
|
||||
/**
|
||||
* Wraps a JsArray and will call wrap_jso on its entries.
|
||||
*/
|
||||
class _DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
|
||||
_DartHtmlWrappingList(this.blink_jsObject);
|
||||
|
||||
final js.JsArray blink_jsObject;
|
||||
|
||||
operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
|
||||
|
||||
operator []=(int index, value) => blink_jsObject[index] = value;
|
||||
|
||||
int get length => blink_jsObject.length;
|
||||
int set length(int newLength) => blink_jsObject.length = newLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the JS HTMLElement to the Dart class. Used by Dart's Polymer.
|
||||
*/
|
||||
createCustomUpgrader(Type customElementClass, $this) {
|
||||
_createCustomUpgrader(Type customElementClass, $this) {
|
||||
var dartClass;
|
||||
try {
|
||||
dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
|
||||
|
@ -812,11 +484,6 @@ createCustomUpgrader(Type customElementClass, $this) {
|
|||
$else
|
||||
class DartHtmlDomObject extends NativeFieldWrapperClass2 {}
|
||||
|
||||
unwrap_jso(dartClass_instance) => dartClass_instance;
|
||||
wrap_jso(jsObject) => jsObject;
|
||||
convertDartToNative_Dictionary(Map dict) => dict;
|
||||
List convertDartToNative_StringArray(List<String> input) => input;
|
||||
convertDartToNative_List(List input) => input;
|
||||
createCustomUpgrader(Type customElementClass, $this) => $this;
|
||||
_createCustomUpgrader(Type customElementClass, $this) => $this;
|
||||
|
||||
$endif
|
||||
|
|
|
@ -394,7 +394,7 @@ $else
|
|||
var nativeElement = document.createElement(extendsTag);
|
||||
|
||||
// Trying to extend a native element is it the Dart class consistent with the
|
||||
// extendsTag?
|
||||
// extendsTag?
|
||||
if (nativeElement.runtimeType != customClassType.reflectedType) {
|
||||
var nativeElementClassMirror = reflectClass(nativeElement.runtimeType);
|
||||
var customClassNativeElement = MirrorSystem.getName(customClassType.simpleName);
|
||||
|
@ -422,7 +422,7 @@ $else
|
|||
var elemProto = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), "create", [js.JsNative.getProperty(baseElement, 'prototype')]);
|
||||
|
||||
// Remember for any upgrading done in wrap_jso.
|
||||
_addCustomElementType(tag, customElementClass, extendsTag);
|
||||
addCustomElementType(tag, customElementClass, extendsTag);
|
||||
|
||||
// TODO(terry): Hack to stop recursion re-creating custom element when the
|
||||
// created() constructor of the custom element does e.g.,
|
||||
|
|
|
@ -8,10 +8,17 @@ part of $LIBRARYNAME;
|
|||
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
|
||||
$!MEMBERS
|
||||
$if DARTIUM
|
||||
// Flags to only try upgrading once if there's a failure don't try upgrading
|
||||
// Flags to only try upgrading once. If there's a failure don't try upgrading
|
||||
// anymore.
|
||||
bool _badUpgradeOccurred = false;
|
||||
bool get _isBadUpgrade => _badUpgradeOccurred;
|
||||
|
||||
/// Required for SDK Infrastructure. Internal use only.
|
||||
///
|
||||
/// Did this encounter a failure attempting to upgrade to
|
||||
/// a custom element.
|
||||
@Deprecated("Required for SDK Infrastructure. Internal use only.")
|
||||
bool get isBadUpgrade => _badUpgradeOccurred;
|
||||
|
||||
void _badUpgrade() { _badUpgradeOccurred = true; }
|
||||
$endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue