Index: sdk/lib/js/dartium/js_dartium.dart |
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart |
index 2c4ccd30880727f13dad0bb36f048efcf980c0ee..610ec2242e04977813e966f1a47a3ab9c7e686fe 100644 |
--- a/sdk/lib/js/dartium/js_dartium.dart |
+++ b/sdk/lib/js/dartium/js_dartium.dart |
@@ -92,6 +92,7 @@ import 'dart:nativewrappers'; |
import 'dart:math' as math; |
import 'dart:mirrors' as mirrors; |
import 'dart:html' as html; |
+import 'dart:_blink' as _blink; |
import 'dart:html_common' as html_common; |
import 'dart:indexed_db' as indexed_db; |
import 'dart:typed_data'; |
@@ -120,7 +121,7 @@ _buildArgs(Invocation invocation) { |
varArgs[mirrors.MirrorSystem.getName(symbol)] = val; |
}); |
return invocation.positionalArguments.toList() |
- ..add(maybeWrapTypedInterop(new JsObject.jsify(varArgs))); |
+ ..add(JsNative.jsify(varArgs)); |
} |
} |
@@ -401,12 +402,21 @@ String _accessJsPathHelper(Iterable<String> parts) { |
return sb.toString(); |
} |
+// TODO(jacobr): remove these helpers and add JsNative.setPropertyDotted, |
+// getPropertyDotted, and callMethodDotted helpers that would be simpler |
+// and more efficient. |
String _accessJsPathSetter(String path) { |
var parts = path.split("."); |
return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1)) |
}, '${parts.last}', v)"; |
} |
+String _accessJsPathCallMethodHelper(String path) { |
+ var parts = path.split("."); |
+ return "${_JS_LIBRARY_PREFIX}.JsNative.callMethod(${_accessJsPathHelper(parts.getRange(0, parts.length - 1)) |
+ }, '${parts.last}',"; |
+} |
+ |
@Deprecated("Internal Use Only") |
void addMemberHelper( |
mirrors.MethodMirror declaration, String path, StringBuffer sb, |
@@ -426,11 +436,11 @@ void addMemberHelper( |
sb.write(" "); |
if (declaration.isGetter) { |
sb.write( |
- "get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});"); |
+ "get $name => ${_accessJsPath(path)};"); |
} else if (declaration.isSetter) { |
sb.write("set $name(v) {\n" |
" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n" |
- " return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});\n" |
+ " return ${_accessJsPathSetter(path)};\n" |
"}\n"); |
} else { |
sb.write("$name("); |
@@ -463,19 +473,19 @@ void addMemberHelper( |
for (var arg in args) { |
sb.write(" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($arg);\n"); |
} |
- sb.write(" return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop("); |
+ sb.write(" return "); |
if (declaration.isConstructor) { |
- sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject("); |
+ sb.write("${_JS_LIBRARY_PREFIX}.JsNative.callConstructor("); |
+ sb..write(_accessJsPath(path))..write(","); |
+ } else { |
+ sb.write(_accessJsPathCallMethodHelper(path)); |
} |
- sb |
- ..write(_accessJsPath(path)) |
- ..write(declaration.isConstructor ? "," : ".apply(") |
- ..write("[${args.join(",")}]"); |
+ sb.write("[${args.join(",")}]"); |
if (hasOptional) { |
sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); |
} |
- sb.write("));"); |
+ sb.write(");"); |
sb.write("}\n"); |
} |
sb.write("\n"); |
@@ -562,7 +572,7 @@ _generateLibraryCodegen(uri, library, staticCodegen) { |
..write('}'); |
} |
sbPatch.write(") {\n" |
- " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});\n"); |
+ " var ret = ${_JS_LIBRARY_PREFIX}.JsNative.newObject();\n"); |
i = 0; |
for (var p in declaration.parameters) { |
assert(p.isNamed); // TODO(jacobr): throw. |
@@ -571,14 +581,14 @@ _generateLibraryCodegen(uri, library, staticCodegen) { |
mirrors.MirrorSystem.getName(p.simpleName)); |
sbPatch.write(" if($name != ${_UNDEFINED_VAR}) {\n" |
" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n" |
- " ret['$jsName'] = $name;\n" |
+ " ${_JS_LIBRARY_PREFIX}.JsNative.setProperty(ret, '$jsName', $name);\n" |
" }\n"); |
i++; |
} |
sbPatch.write( |
- " return new ${_JS_LIBRARY_PREFIX}.JSObject.create(ret);\n" |
- " }\n"); |
+ " return ret;" |
+ "}\n"); |
} else if (declaration.isConstructor || |
declaration.isFactoryConstructor) { |
sbPatch.write(" "); |
@@ -607,8 +617,7 @@ _generateLibraryCodegen(uri, library, staticCodegen) { |
}); |
} |
if (isDom) { |
- sbPatch.write(" factory ${className}._internalWrap() => " |
- "new ${classNameImpl}.internal_();\n"); |
+ sbPatch.write(" static Type get instanceRuntimeType => ${classNameImpl};\n"); |
} |
if (sbPatch.isNotEmpty) { |
var typeVariablesClause = ''; |
@@ -757,27 +766,15 @@ abstract class JSObjectInterfacesDom $implementsClauseDom { |
} |
patch class JSObject { |
- factory JSObject.create(JsObject jsObject) { |
- var ret = new JSObjectImpl.internal()..blink_jsObject = jsObject; |
- jsObject._dartHtmlWrapper = ret; |
- return ret; |
- } |
+ static Type get instanceRuntimeType => JSObjectImpl; |
} |
patch class JSFunction { |
- factory JSFunction.create(JsObject jsObject) { |
- var ret = new JSFunctionImpl.internal()..blink_jsObject = jsObject; |
- jsObject._dartHtmlWrapper = ret; |
- return ret; |
- } |
+ static Type get instanceRuntimeType => JSFunctionImpl; |
} |
patch class JSArray { |
- factory JSArray.create(JsObject jsObject) { |
- var ret = new JSArrayImpl.internal()..blink_jsObject = jsObject; |
- jsObject._dartHtmlWrapper = ret; |
- return ret; |
- } |
+ static Type get instanceRuntimeType => JSArrayImpl; |
} |
_registerAllJsInterfaces() { |
@@ -959,49 +956,44 @@ JsObject get context { |
return _cachedContext; |
} |
-@Deprecated("Internal Use Only") |
-maybeWrapTypedInterop(o) => html_common.wrap_jso_no_SerializedScriptvalue(o); |
- |
-_maybeWrap(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 || |
- wrapped is indexed_db.KeyRange || |
- wrapped is html.ImageData || |
- wrapped is html.Node || |
- wrapped is TypedData || |
- wrapped is html.Window) ? wrapped : o; |
-} |
- |
-/** |
- * Get the dart wrapper object for object. Top-level so we |
- * we can access it from other libraries without it being |
- * a public instance field on JsObject. |
- */ |
-@Deprecated("Internal Use Only") |
-getDartHtmlWrapperFor(JsObject object) => object._dartHtmlWrapper; |
- |
-/** |
- * Set the dart wrapper object for object. Top-level so we |
- * we can access it from other libraries without it being |
- * a public instance field on JsObject. |
- */ |
-@Deprecated("Internal Use Only") |
-void setDartHtmlWrapperFor(JsObject object, wrapper) { |
- object._dartHtmlWrapper = wrapper; |
+_lookupType(o, bool isCrossFrame, bool isElement) { |
+ try { |
+ var type = html_common.lookupType(o, isElement); |
+ var typeMirror = mirrors.reflectType(type); |
+ var legacyInteropConvertToNative = typeMirror.isSubtypeOf(mirrors.reflectType(html.Blob)) || |
+ typeMirror.isSubtypeOf(mirrors.reflectType(html.Event)) || |
+ typeMirror.isSubtypeOf(mirrors.reflectType(indexed_db.KeyRange)) || |
+ typeMirror.isSubtypeOf(mirrors.reflectType(html.ImageData)) || |
+ typeMirror.isSubtypeOf(mirrors.reflectType(html.Node)) || |
+// TypedData is removed from this list as it is converted directly |
+// rather than flowing through the interceptor code path. |
+// typeMirror.isSubtypeOf(mirrors.reflectType(typed_data.TypedData)) || |
+ typeMirror.isSubtypeOf(mirrors.reflectType(html.Window)); |
+ if (isCrossFrame && !typeMirror.isSubtypeOf(mirrors.reflectType(html.Window))) { |
+ // TODO(jacobr): evaluate using the true cross frame Window class, etc. |
+ // as well as triggering that legacy JS Interop returns raw JsObject |
+ // instances. |
+ legacyInteropConvertToNative = false; |
+ } |
+ return [type, legacyInteropConvertToNative]; |
+ } catch (e) { } |
+ return [JSObject.instanceRuntimeType, false]; |
} |
/** |
- * Used by callMethod to get the JS object for each argument passed if the |
- * argument is a Dart class instance that delegates to a DOM object. See |
- * wrap_jso defined in dart:html. |
+ * Base class for both the legacy JsObject class and the modern JSObject class. |
+ * This allows the JsNative utility class tobehave identically whether it is |
+ * called on a JsObject or a JSObject. |
*/ |
-@Deprecated("Internal Use Only") |
-unwrap_jso(dartClass_instance) { |
- if (dartClass_instance is JSObject && |
- dartClass_instance is! JsObject) return dartClass_instance.blink_jsObject; |
- else return dartClass_instance; |
+class _JSObjectBase extends NativeFieldWrapperClass2 { |
+ String _toString() native "JSObject_toString"; |
+ _callMethod(String name, List args) native "JSObject_callMethod"; |
+ _operator_getter(String property) native "JSObject_[]"; |
+ _operator_setter(String property, value) native "JSObject_[]="; |
+ bool _hasProperty(String property) native "JsObject_hasProperty"; |
+ bool _instanceof(/*JsFunction|JSFunction*/ type) native "JsObject_instanceof"; |
+ |
+ int get hashCode native "JSObject_hashCode"; |
} |
/** |
@@ -1010,22 +1002,16 @@ unwrap_jso(dartClass_instance) { |
* The properties of the JavaScript object are accessible via the `[]` and |
* `[]=` operators. Methods are callable via [callMethod]. |
*/ |
-class JsObject extends NativeFieldWrapperClass2 { |
+class JsObject extends _JSObjectBase { |
JsObject.internal(); |
/** |
- * If this JsObject is wrapped, e.g. DOM objects, then we can save the |
- * wrapper here and preserve its identity. |
- */ |
- var _dartHtmlWrapper; |
- |
- /** |
* Constructs a new JavaScript object from [constructor] and returns a proxy |
* to it. |
*/ |
factory JsObject(JsFunction constructor, [List arguments]) { |
try { |
- return html_common.unwrap_jso(_create(constructor, arguments)); |
+ return _create(constructor, arguments); |
} catch (e) { |
// Re-throw any errors (returned as a string) as a DomException. |
throw new html.DomException.jsInterop(e); |
@@ -1050,6 +1036,7 @@ class JsObject extends NativeFieldWrapperClass2 { |
if (object is num || object is String || object is bool || object == null) { |
throw new ArgumentError("object cannot be a num, string, bool, or null"); |
} |
+ if (object is JsObject) return object; |
return _fromBrowserObject(object); |
} |
@@ -1071,7 +1058,7 @@ class JsObject extends NativeFieldWrapperClass2 { |
static JsObject _jsify(object) native "JsObject_jsify"; |
- static JsObject _fromBrowserObject(object) => html_common.unwrap_jso(object); |
+ static JsObject _fromBrowserObject(object) native "JsObject_fromBrowserObject"; |
/** |
* Returns the value associated with [property] from the proxied JavaScript |
@@ -1081,14 +1068,14 @@ class JsObject extends NativeFieldWrapperClass2 { |
*/ |
operator [](property) { |
try { |
- return _maybeWrap(_operator_getter(property)); |
+ return _operator_getterLegacy(property); |
} catch (e) { |
// Re-throw any errors (returned as a string) as a DomException. |
throw new html.DomException.jsInterop(e); |
} |
} |
- _operator_getter(property) native "JsObject_[]"; |
+ _operator_getterLegacy(property) native "JsObject_[]Legacy"; |
/** |
* Sets the value associated with [property] on the proxied JavaScript |
@@ -1098,27 +1085,23 @@ class JsObject extends NativeFieldWrapperClass2 { |
*/ |
operator []=(property, value) { |
try { |
- _operator_setter(property, value); |
+ _operator_setterLegacy(property, value); |
} catch (e) { |
// Re-throw any errors (returned as a string) as a DomException. |
throw new html.DomException.jsInterop(e); |
} |
} |
- _operator_setter(property, value) native "JsObject_[]="; |
+ _operator_setterLegacy(property, value) native "JsObject_[]=Legacy"; |
int get hashCode native "JsObject_hashCode"; |
operator ==(other) { |
- var is_JsObject = other is JsObject; |
- if (!is_JsObject) { |
- other = html_common.unwrap_jso(other); |
- is_JsObject = other is JsObject; |
- } |
- return is_JsObject && _identityEquality(this, other); |
+ if (other is! JsObject && other is! JSObject) return false; |
+ return _identityEquality(this, other); |
} |
- static bool _identityEquality(JsObject a, JsObject b) |
+ static bool _identityEquality(a, b) |
native "JsObject_identityEquality"; |
/** |
@@ -1127,7 +1110,7 @@ class JsObject extends NativeFieldWrapperClass2 { |
* |
* This is the equivalent of the `in` operator in JavaScript. |
*/ |
- bool hasProperty(String property) native "JsObject_hasProperty"; |
+ bool hasProperty(String property) => _hasProperty(property); |
/** |
* Removes [property] from the JavaScript object. |
@@ -1141,7 +1124,7 @@ class JsObject extends NativeFieldWrapperClass2 { |
* |
* This is the equivalent of the `instanceof` operator in JavaScript. |
*/ |
- bool instanceof(JsFunction type) native "JsObject_instanceof"; |
+ bool instanceof(JsFunction type) => _instanceof(type); |
/** |
* Returns the result of the JavaScript objects `toString` method. |
@@ -1164,7 +1147,7 @@ class JsObject extends NativeFieldWrapperClass2 { |
*/ |
callMethod(String method, [List args]) { |
try { |
- return _maybeWrap(_callMethod(method, args)); |
+ return _callMethodLegacy(method, args); |
} catch (e) { |
if (hasProperty(method)) { |
// Return a DomException if DOM call returned an error. |
@@ -1175,19 +1158,26 @@ class JsObject extends NativeFieldWrapperClass2 { |
} |
} |
- _callMethod(String name, List args) native "JsObject_callMethod"; |
+ _callMethodLegacy(String name, List args) native "JsObject_callMethodLegacy"; |
} |
+ |
/// Base class for all JS objects used through dart:html and typed JS interop. |
@Deprecated("Internal Use Only") |
-class JSObject { |
+class JSObject extends _JSObjectBase { |
JSObject.internal() {} |
- external factory JSObject.create(JsObject jsObject); |
- |
- @Deprecated("Internal Use Only") |
- JsObject blink_jsObject; |
+ external static Type get instanceRuntimeType; |
- String toString() => blink_jsObject.toString(); |
+ /** |
+ * Returns the result of the JavaScript objects `toString` method. |
+ */ |
+ String toString() { |
+ try { |
+ return _toString(); |
+ } catch (e) { |
+ return super.toString(); |
+ } |
+ } |
noSuchMethod(Invocation invocation) { |
throwError() { |
@@ -1204,7 +1194,7 @@ class JSObject { |
!_allowedMethods.containsKey(invocation.memberName)) { |
throwError(); |
} |
- var ret = maybeWrapTypedInterop(blink_jsObject._operator_getter(name)); |
+ var ret = _operator_getter(name); |
if (matches != null) return ret; |
if (ret is Function || |
(ret is JsFunction /* shouldn't be needed in the future*/) && |
@@ -1213,7 +1203,7 @@ class JSObject { |
throwError(); |
} else { |
// TODO(jacobr): should we throw if the JavaScript object doesn't have the property? |
- return maybeWrapTypedInterop(blink_jsObject._operator_getter(name)); |
+ return _operator_getter(name); |
} |
} else if (invocation.isSetter) { |
if (CHECK_JS_INVOCATIONS) { |
@@ -1223,8 +1213,7 @@ class JSObject { |
} |
assert(name.endsWith("=")); |
name = name.substring(0, name.length - 1); |
- return maybeWrapTypedInterop(blink_jsObject._operator_setter( |
- name, invocation.positionalArguments.first)); |
+ return _operator_setter(name, invocation.positionalArguments.first); |
} else { |
// TODO(jacobr): also allow calling getters that look like functions. |
var matches; |
@@ -1233,8 +1222,7 @@ class JSObject { |
if (matches == null || |
!matches.checkInvocation(invocation)) throwError(); |
} |
- var ret = maybeWrapTypedInterop( |
- blink_jsObject._callMethod(name, _buildArgs(invocation))); |
+ var ret = _callMethod(name, _buildArgs(invocation)); |
if (CHECK_JS_INVOCATIONS) { |
if (!matches._checkReturnType(ret)) { |
html.window.console.error("Return value for method: ${name} is " |
@@ -1250,21 +1238,56 @@ class JSObject { |
@Deprecated("Internal Use Only") |
class JSArray extends JSObject with ListMixin { |
JSArray.internal() : super.internal(); |
- external factory JSArray.create(JsObject jsObject); |
- operator [](int index) => |
- maybeWrapTypedInterop(JsNative.getArrayIndex(blink_jsObject, index)); |
+ external static Type get instanceRuntimeType; |
+ |
+ // Reuse JsArray_length as length behavior is unchanged. |
+ int get length native "JsArray_length"; |
+ |
+ set length(int length) { |
+ _operator_setter('length', length); |
+ } |
+ |
+ _checkIndex(int index, {bool insert: false}) { |
+ int length = insert ? this.length + 1 : this.length; |
+ if (index is int && (index < 0 || index >= length)) { |
+ throw new RangeError.range(index, 0, length); |
+ } |
+ } |
+ |
+ _checkRange(int start, int end) { |
+ int cachedLength = this.length; |
+ if (start < 0 || start > cachedLength) { |
+ throw new RangeError.range(start, 0, cachedLength); |
+ } |
+ if (end < start || end > cachedLength) { |
+ throw new RangeError.range(end, start, cachedLength); |
+ } |
+ } |
- operator []=(int index, value) => blink_jsObject[index] = value; |
+ _indexed_getter(int index) native "JSArray_indexed_getter"; |
+ _indexed_setter(int index, o) native "JSArray_indexed_setter"; |
+ |
+ // Methods required by ListMixin |
+ |
+ operator [](index) { |
+ if (index is int) { |
+ _checkIndex(index); |
+ } |
+ |
+ return _indexed_getter(index); |
+ } |
- int get length => blink_jsObject.length; |
- set length(int newLength) => blink_jsObject.length = newLength; |
+ void operator []=(int index, value) { |
+ _checkIndex(index); |
+ _indexed_setter(index, value); |
+ } |
} |
@Deprecated("Internal Use Only") |
class JSFunction extends JSObject implements Function { |
JSFunction.internal() : super.internal(); |
- external factory JSFunction.create(JsObject jsObject); |
+ external static Type get instanceRuntimeType; |
call( |
[a1 = _UNDEFINED, |
@@ -1277,48 +1300,49 @@ class JSFunction extends JSObject implements Function { |
a8 = _UNDEFINED, |
a9 = _UNDEFINED, |
a10 = _UNDEFINED]) { |
- return maybeWrapTypedInterop(blink_jsObject |
- .apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]))); |
+ return _apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); |
} |
noSuchMethod(Invocation invocation) { |
if (invocation.isMethod && invocation.memberName == #call) { |
- return maybeWrapTypedInterop( |
- blink_jsObject.apply(_buildArgs(invocation))); |
+ return _apply(_buildArgs(invocation)); |
} |
return super.noSuchMethod(invocation); |
} |
+ |
+ dynamic _apply(List args, {thisArg}) native "JSFunction_apply"; |
+ |
+ static JSFunction _createWithThis(Function f) native "JSFunction_createWithThis"; |
+ static JSFunction _create(Function f) native "JSFunction_create"; |
} |
// JavaScript interop methods that do not automatically wrap to dart:html types. |
// Warning: this API is not exposed to dart:js. |
+// TODO(jacobr): rename to JSNative and make at least part of this API public. |
@Deprecated("Internal Use Only") |
class JsNative { |
- static getProperty(o, name) { |
- o = unwrap_jso(o); |
- return o != null ? o._operator_getter(name) : null; |
- } |
+ static JSObject jsify(object) native "JSObject_jsify"; |
+ static JSObject newObject() native "JSObject_newObject"; |
+ static JSArray newArray() native "JSObject_newArray"; |
- static setProperty(o, name, value) { |
- return unwrap_jso(o)._operator_setter(name, value); |
- } |
- |
- static callMethod(o, String method, List args) { |
- return unwrap_jso(o)._callMethod(method, args); |
- } |
+ static hasProperty(_JSObjectBase o, name) => o._hasProperty(name); |
+ static getProperty(_JSObjectBase o, name) => o._operator_getter(name); |
+ static setProperty(_JSObjectBase o, name, value) => o._operator_setter(name, value); |
+ static callMethod(_JSObjectBase o, String method, List args) => o._callMethod(method, args); |
+ static instanceof(_JSObjectBase o, /*JsFunction|JSFunction*/ type) => o._instanceof(type); |
+ static callConstructor0(_JSObjectBase constructor) native "JSNative_callConstructor0"; |
+ static callConstructor(_JSObjectBase constructor, List args) native "JSNative_callConstructor"; |
- static getArrayIndex(JsArray array, int index) { |
- array._checkIndex(index); |
- return getProperty(array, index); |
- } |
+ static toTypedObject(JsObject o) native "JSNative_toTypedObject"; |
/** |
* Same behavior as new JsFunction.withThis except that JavaScript "this" is not |
* wrapped. |
*/ |
- static JsFunction withThis(Function f) native "JsFunction_withThisNoWrap"; |
+ static JSFunction withThis(Function f) native "JsFunction_withThisNoWrap"; |
} |
+ |
/** |
* Proxies a JavaScript Function object. |
*/ |
@@ -1336,7 +1360,7 @@ class JsFunction extends JsObject { |
* supplied it is the value of `this` for the invocation. |
*/ |
dynamic apply(List args, {thisArg}) => |
- _maybeWrap(_apply(args, thisArg: thisArg)); |
+ _apply(args, thisArg: thisArg); |
dynamic _apply(List args, {thisArg}) native "JsFunction_apply"; |
@@ -1488,15 +1512,6 @@ void argsSafeForTypedInterop(Iterable args) { |
} |
} |
-List _stripAndWrapArgs(Iterable args) { |
- var ret = []; |
- for (var arg in args) { |
- if (arg == _UNDEFINED) break; |
- ret.add(maybeWrapTypedInterop(arg)); |
- } |
- return ret; |
-} |
- |
/** |
* Returns a method that can be called with an arbitrary number (for n less |
* than 11) of arguments without violating Dart type checks. |
@@ -1515,90 +1530,6 @@ Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) => ( |
jsFunction._applyDebuggerOnly( |
_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); |
-/// This helper is purely a hack so we can reuse JsFunction.withThis even when |
-/// we don't care about passing JS "this". In an ideal world we would implement |
-/// helpers in C++ that directly implement allowInterop and |
-/// allowInteropCaptureThis. |
-class _CreateDartFunctionForInteropIgnoreThis implements Function { |
- Function _fn; |
- |
- _CreateDartFunctionForInteropIgnoreThis(this._fn); |
- |
- call( |
- [ignoredThis = _UNDEFINED, |
- a1 = _UNDEFINED, |
- a2 = _UNDEFINED, |
- a3 = _UNDEFINED, |
- a4 = _UNDEFINED, |
- a5 = _UNDEFINED, |
- a6 = _UNDEFINED, |
- a7 = _UNDEFINED, |
- a8 = _UNDEFINED, |
- a9 = _UNDEFINED, |
- a10 = _UNDEFINED]) { |
- var ret = Function.apply( |
- _fn, _stripAndWrapArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); |
- safeForTypedInterop(ret); |
- return ret; |
- } |
- |
- noSuchMethod(Invocation invocation) { |
- if (invocation.isMethod && invocation.memberName == #call) { |
- // Named arguments not yet supported. |
- if (invocation.namedArguments.isNotEmpty) return; |
- var ret = Function.apply( |
- _fn, _stripAndWrapArgs(invocation.positionalArguments.skip(1))); |
- // TODO(jacobr): it would be nice to check that the return value is safe |
- // for interop but we don't want to break existing addEventListener users. |
- // safeForTypedInterop(ret); |
- safeForTypedInterop(ret); |
- return ret; |
- } |
- return super.noSuchMethod(invocation); |
- } |
-} |
- |
-/// See comment for [_CreateDartFunctionForInteropIgnoreThis]. |
-/// This Function exists purely because JsObject doesn't have the DOM type |
-/// conversion semantics we want for JS typed interop. |
-class _CreateDartFunctionForInterop implements Function { |
- Function _fn; |
- |
- _CreateDartFunctionForInterop(this._fn); |
- |
- call( |
- [a1 = _UNDEFINED, |
- a2 = _UNDEFINED, |
- a3 = _UNDEFINED, |
- a4 = _UNDEFINED, |
- a5 = _UNDEFINED, |
- a6 = _UNDEFINED, |
- a7 = _UNDEFINED, |
- a8 = _UNDEFINED, |
- a9 = _UNDEFINED, |
- a10 = _UNDEFINED]) { |
- var ret = Function.apply( |
- _fn, _stripAndWrapArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); |
- safeForTypedInterop(ret); |
- return ret; |
- } |
- |
- noSuchMethod(Invocation invocation) { |
- if (invocation.isMethod && invocation.memberName == #call) { |
- // Named arguments not yet supported. |
- if (invocation.namedArguments.isNotEmpty) return; |
- var ret = Function.apply( |
- _fn, _stripAndWrapArgs(invocation.positionalArguments)); |
- safeForTypedInterop(ret); |
- return ret; |
- } |
- return super.noSuchMethod(invocation); |
- } |
-} |
- |
-/// Cached JSFunction associated with the Dart Function. |
-Expando<JSFunction> _interopExpando = new Expando<JSFunction>(); |
- |
/// Returns a wrapper around function [f] that can be called from JavaScript |
/// using the package:js Dart-JavaScript interop. |
/// |
@@ -1615,14 +1546,7 @@ JSFunction allowInterop(Function f) { |
// The function is already a JSFunction... no need to do anything. |
return f; |
} else { |
- var ret = _interopExpando[f]; |
- if (ret == null) { |
- // TODO(jacobr): we could optimize this. |
- ret = new JSFunction.create(new JsFunction.withThis( |
- new _CreateDartFunctionForInteropIgnoreThis(f))); |
- _interopExpando[f] = ret; |
- } |
- return ret; |
+ return JSFunction._create(f); |
} |
} |
@@ -1646,10 +1570,11 @@ JSFunction allowInteropCaptureThis(Function f) { |
var ret = _interopCaptureThisExpando[f]; |
if (ret == null) { |
// TODO(jacobr): we could optimize this. |
- ret = new JSFunction.create( |
- new JsFunction.withThis(new _CreateDartFunctionForInterop(f))); |
+ ret = JSFunction._createWithThis(f); |
_interopCaptureThisExpando[f] = ret; |
} |
return ret; |
} |
} |
+ |
+debugPrint(_) {} |