| 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(_) {}
|
|
|