Optimize dartium dart:html bindings so real world application performance is acceptable. Improves dart:html performance by 2X-30X for microbenchmarks. Real world improvement is typically 2X-3X.

BUG=

Review URL: https://codereview.chromium.org/1832713002 .
This commit is contained in:
Jacob Richman 2016-03-29 18:32:52 -07:00
parent a91f758b86
commit c65854d2e4
63 changed files with 17710 additions and 22404 deletions

File diff suppressed because it is too large Load diff

View file

@ -123,9 +123,6 @@ Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
throw new UnimplementedError(); throw new UnimplementedError();
} }
/// Dartium functions that are a NOOP in dart2js.
unwrap_jso(dartClass_instance) => dartClass_instance;
wrap_jso(jsObject) => jsObject;
createCustomUpgrader(Type customElementClass, $this) => $this; createCustomUpgrader(Type customElementClass, $this) => $this;
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a

File diff suppressed because it is too large Load diff

View file

@ -91,9 +91,3 @@ Future convertNativePromiseToDartFuture(promise) {
var newPromise = JS('', '#.then(#)["catch"](#)', promise, then, error); var newPromise = JS('', '#.then(#)["catch"](#)', promise, then, error);
return completer.future; 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;

View file

@ -7,11 +7,11 @@ convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) =>
new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy); new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
class _StructuredCloneDartium extends _StructuredClone { class _StructuredCloneDartium extends _StructuredClone {
newJsMap() => new js.JsObject(js.context["Object"]); newJsMap() => js.JsNative.newObject();
putIntoMap(map, key, value) => map[key] = value; putIntoMap(map, key, value) => js.JsNative.setProperty(map, key, value);
// TODO(alanknight): Don't create two extra lists to get a fixed-length JS list. newJsList(length) => js.JsNative.newArray()..length = length;
newJsList(length) => new js.JsArray.from(new List(length)); cloneNotRequired(e) =>
cloneNotRequired(e) => e is js.JsObject; e is js.JSObject || e is TypedData || e is ByteBuffer;
} }
/// A version of _AcceptStructuredClone, but using a different algorithm /// A version of _AcceptStructuredClone, but using a different algorithm
@ -24,15 +24,14 @@ class _StructuredCloneDartium extends _StructuredClone {
class _AcceptStructuredCloneDartium { class _AcceptStructuredCloneDartium {
newDartList(length) => new List(length); newDartList(length) => new List(length);
// JsObjects won't be identical, but will be equal only if the underlying // As long as we stick to JSObject instead of intermingling legacy JsObject,
// Js entities are identical. // we can simply use identical.
bool identicalInJs(a, b) => bool identicalInJs(a, b) => identical(a, b);
(a is js.JsObject) ? a == b : identical(a, b);
void forEachJsField(jsObject, action) { void forEachJsField(jsObject, action) {
var keys = js.context["Object"].callMethod("keys", [jsObject]); var keys = js.JsNative.callMethod(_object, "keys", [jsObject]);
for (var key in keys) { for (var key in keys) {
action(key, jsObject[key]); action(key, js.JsNative.getProperty(jsObject, key));
} }
} }
@ -52,10 +51,7 @@ class _AcceptStructuredCloneDartium {
if (e is bool) return e; if (e is bool) return e;
if (e is num) return e; if (e is num) return e;
if (e is String) return e; if (e is String) return e;
if (e is DateTime) return e;
if (isJavaScriptDate(e)) {
return convertNativeToDart_DateTime(e);
}
if (isJavaScriptRegExp(e)) { if (isJavaScriptRegExp(e)) {
// TODO(sra). // TODO(sra).
@ -106,51 +102,60 @@ class _AcceptStructuredCloneDartium {
} }
} }
final _dateConstructor = js.context["Date"]; final _dateConstructor = js.JsNative.getProperty(window, "Date");
final _regexConstructor = js.context["RegExp"]; final _regexConstructor = js.JsNative.getProperty(window, "RegExp");
bool isJavaScriptDate(value) => value is js.JsObject && value.instanceof(_dateConstructor); bool isJavaScriptDate(value) => value is js.JSObject && js.JsNative.instanceof(value, _dateConstructor);
bool isJavaScriptRegExp(value) => value is js.JsObject && value.instanceof(_regexConstructor); bool isJavaScriptRegExp(value) => value is js.JSObject && js.JsNative.instanceof(value, _regexConstructor);
bool isJavaScriptArray(value) => value is js.JsArray; bool isJavaScriptArray(value) => value is js.JSArray;
final _object = js.context["Object"]; final _object = js.JsNative.getProperty(window, "Object");
final _getPrototypeOf = _object["getPrototypeOf"]; final _getPrototypeOf = js.JsNative.getProperty(_object, "getPrototypeOf");
_getProto(object) { _getProto(object) {
return _getPrototypeOf.apply([object]); return _getPrototypeOf(object);
} }
final _objectProto = js.context["Object"]["prototype"]; final _objectProto = js.JsNative.getProperty(_object, "prototype");
bool isJavaScriptSimpleObject(value) { bool isJavaScriptSimpleObject(value) {
if (value is! js.JsObject) return false; if (value is! js.JSObject) return false;
var proto = _getProto(value); var proto = _getProto(value);
return proto == _objectProto || proto == null; return proto == _objectProto || proto == null;
} }
// TODO(jacobr): this makes little sense unless we are doing something
// ambitious to make Dartium and Dart2Js interop well with each other.
bool isImmutableJavaScriptArray(value) => bool isImmutableJavaScriptArray(value) =>
isJavaScriptArray(value) && value["immutable$list"] != null; isJavaScriptArray(value) && js.JsNative.getProperty(value, "immutable$list") != null;
final _promiseConstructor = js.context['Promise']; final _promiseConstructor = js.JsNative.getProperty(window, 'Promise');
bool isJavaScriptPromise(value) => value is js.JsObject && value['constructor'] == _promiseConstructor; bool isJavaScriptPromise(value) => value is js.JSObject && identical(js.JsNative.getProperty(value, 'constructor'), _promiseConstructor);
Future convertNativePromiseToDartFuture(js.JsObject promise) { Future convertNativePromiseToDartFuture(js.JSObject promise) {
var completer = new Completer(); var completer = new Completer();
var newPromise = promise var newPromise = js.JsNative.callMethod(js.JsNative.callMethod(promise,
.callMethod("then", [(result) => completer.complete(result)]) "then", [js.allowInterop((result) => completer.complete(result))]),
.callMethod("catch", [(result) => completer.completeError(result)]); "catch", [js.allowInterop((result) => completer.completeError(result))]);
return completer.future; return completer.future;
} }
convertDartToNative_DateTime(DateTime date) { convertDartToNative_DateTime(DateTime date) {
return new js.JsObject(js.context["Date"], [date.millisecondsSinceEpoch]); return date;
} }
/// Creates a Dart Rectangle from a Javascript object with properties /// Creates a Dart Rectangle from a Javascript object with properties
/// left, top, width and height. Used internally in Dartium. /// left, top, width and height or a 4 element array of integers. Used internally in Dartium.
Rectangle make_dart_rectangle(r) => Rectangle make_dart_rectangle(r) {
r == null ? null : new Rectangle( if (r == null) return null;
js.JsNative.getProperty(r, 'left'), if (r is List) {
js.JsNative.getProperty(r, 'top'), return new Rectangle(r[0], r[1], r[2], r[3]);
js.JsNative.getProperty(r, 'width'), }
js.JsNative.getProperty(r, 'height'));
return new Rectangle(
js.JsNative.getProperty(r, 'left'),
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 // Converts a flat Dart map into a JavaScript object with properties this is
// is the Dartium only version it uses dart:js. // is the Dartium only version it uses dart:js.
@ -158,16 +163,16 @@ Rectangle make_dart_rectangle(r) =>
// code in html_common and be more general. // code in html_common and be more general.
convertDartToNative_Dictionary(Map dict) { convertDartToNative_Dictionary(Map dict) {
if (dict == null) return null; if (dict == null) return null;
var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object')); var jsObject = js.JsNative.newObject();
dict.forEach((String key, value) { dict.forEach((String key, value) {
if (value is List) { if (value is List) {
var jsArray = new js.JsArray(); var jsArray = js.JsNative.newArray();
value.forEach((elem) { value.forEach((elem) {
jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem); jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
}); });
jsObject[key] = jsArray; js.JsNative.setProperty(jsObject, key, jsArray);
} else { } else {
jsObject[key] = value; js.JsNative.setProperty(jsObject, key, value);
} }
}); });
return jsObject; return jsObject;
@ -196,8 +201,15 @@ class _ReturnedDictionary {
// Helper function to wrapped a returned dictionary from blink to a Dart looking // Helper function to wrapped a returned dictionary from blink to a Dart looking
// class. // class.
convertNativeDictionaryToDartDictionary(Map values) => convertNativeDictionaryToDartDictionary(values) {
values != null ? new _ReturnedDictionary(values) : null; if (values is! Map) {
// TODO(jacobr): wish wwe didn't have to do this.
values = convertNativeToDart_SerializedScriptValue(values);
}
return values != null ? new _ReturnedDictionary(values) : null;
}
convertNativeToDart_Dictionary(values) => convertNativeToDart_SerializedScriptValue(values);
// Conversion function place holder (currently not used in dart2js or dartium). // Conversion function place holder (currently not used in dart2js or dartium).
List convertDartToNative_StringArray(List<String> input) => input; List convertDartToNative_StringArray(List<String> input) => input;
@ -205,284 +217,59 @@ List convertDartToNative_StringArray(List<String> input) => input;
// Converts a Dart list into a JsArray. For the Dartium version only. // Converts a Dart list into a JsArray. For the Dartium version only.
convertDartToNative_List(List input) => new js.JsArray()..addAll(input); convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
/// Find the underlying JS object for a dart:html Dart object. // Incredibly slow implementation to lookup the runtime type for an object.
unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance); // Fortunately, performance doesn't matter much as the results are cached
// as long as the object being looked up has a valid prototype.
// Flag to disable JS interop asserts. Setting to false will speed up the // TODO(jacobr): we should track the # of lookups to ensure that things aren't
// wrap_jso calls. // going off the rails due to objects with null prototypes, etc.
bool interop_checks = false; // Note: unlike all other methods in this class, here we intentionally use
// the old JsObject types to bootstrap the new typed bindings.
/// Wrap a JS object with an instance of the matching dart:html class. Used only in Dartium. Type lookupType(js.JsObject jsObject, bool isElement) {
wrap_jso(jsObject) {
try { try {
if (jsObject is! js.JsObject || jsObject == null) { // TODO(jacobr): add static methods that return the runtime type of the patch
// JS Interop converted the object to a Dart class e.g., Uint8ClampedList. // class so that this code works as expected.
// or it's a simple type. if (jsObject is js.JsArray) {
return jsObject; return js.JSArray.instanceRuntimeType;
} }
if (jsObject is js.JsFunction) {
var wrapper = js.getDartHtmlWrapperFor(jsObject); return js.JSFunction.instanceRuntimeType;
// if we have a wrapper return the Dart instance. }
if (wrapper != null) {
return wrapper;
}
if (jsObject is js.JsArray) {
wrapper = new js.JSArray.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
}
if (jsObject is js.JsFunction) {
wrapper = new js.JSFunction.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
}
// 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'); var constructor = js.JsNative.getProperty(jsObject, 'constructor');
if (constructor == null) { if (constructor == null) {
// Perfectly valid case for JavaScript objects where __proto__ has // Perfectly valid case for JavaScript objects where __proto__ has
// intentionally been set to null. // intentionally been set to null.
js.setDartHtmlWrapperFor(jsObject, new js.JSObject.create(jsObject)); // We should track and warn about this case as peformance will be poor.
return jsObject; return js.JSObject.instanceRuntimeType;
} }
var jsTypeName = js.JsNative.getProperty(constructor, 'name'); var jsTypeName = js.JsNative.getProperty(constructor, 'name');
if (jsTypeName is! String || jsTypeName.length == 0) { if (jsTypeName is! String || jsTypeName.length == 0) {
// Not an html type. // Not an html type.
wrapper = new js.JSObject.create(jsObject); return js.JSObject.instanceRuntimeType;
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
} }
var dartClass_instance; var dartClass_instance;
var customElementClass = null; var customElementClass = null;
var extendsTag = ""; var extendsTag = "";
var custom = getCustomElementEntry(jsObject);
if (custom != null) {
customElementClass = custom['type'];
extendsTag = custom['extends'];
}
// Only allow custom elements to be created in the html or svg default Type type = getHtmlCreateType(jsTypeName);
// namespace. if (type != null) return type;
var func;
var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' || // Start walking the prototype chain looking for a JS class.
jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg'; var prototype = js.JsNative.getProperty(jsObject, '__proto__');
if (customElementClass != null && extendsTag == "" && defaultNS) { while (prototype != null) {
// The customElementClass is known but we can't create the real class so // We're a Dart class that's pointing to a JS class.
// create the HtmlElement and it will get upgraded when registerElement's var constructor = js.JsNative.getProperty(prototype, 'constructor');
// createdCallback is called. if (constructor != null) {
func = getHtmlCreateFunction('HTMLElement'); jsTypeName = js.JsNative.getProperty(constructor, 'name');
} else { type = getHtmlCreateType(jsTypeName);
func = getHtmlCreateFunction(jsTypeName); if (type != null) return type;
if (func == null) {
// Start walking the prototype chain looking for a JS class.
var prototype = jsObject['__proto__'];
var keepWalking = true;
while (keepWalking && prototype.hasProperty('__proto__')) {
prototype = prototype['__proto__'];
if (prototype != null && prototype is Element &&
prototype.blink_jsObject != null) {
// We're a Dart class that's pointing to a JS class.
var blinkJso = prototype.blink_jsObject;
jsTypeName = blinkJso['constructor']['name'];
func = getHtmlCreateFunction(jsTypeName);
keepWalking = func == null;
}
}
} }
prototype = js.JsNative.getProperty(prototype, '__proto__');
} }
// Can we construct a Dart class?
if (func != null) {
dartClass_instance = func();
// Wrap our Dart instance in both directions.
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) { } catch (e, stacktrace) {
if (interop_checks) { if (e is DebugAssertException) print("${e.message}\n ${stacktrace}");
if (e is DebugAssertException) window.console else print("${stacktrace}");
.log("${e.message}\n ${stacktrace}");
else window.console.log("${stacktrace}");
}
} }
return js.JSObject.instanceRuntimeType;
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) {
wrapper = new js.JSArray.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
}
if (jsObject is js.JsFunction) {
wrapper = new js.JSFunction.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
}
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, new js.JSObject.create(jsObject));
return jsObject;
}
var jsTypeName = js.JsNative.getProperty(constructor, 'name');
if (jsTypeName is! String || jsTypeName.length == 0) {
// Not an html type.
wrapper = new js.JSObject.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
}
var func = getHtmlCreateFunction(jsTypeName);
if (func != null) {
var dartClass_instance = func();
dartClass_instance.blink_jsObject = jsObject;
js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
return dartClass_instance;
}
wrapper = new js.JSObject.create(jsObject);
js.setDartHtmlWrapperFor(jsObject, wrapper);
return wrapper;
} 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.JsObject) {
// 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/JsObject.');
}
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;
} }

View file

@ -110,37 +110,83 @@ class _KeyRangeFactoryProvider {
// FIXME: Can we make this private? // FIXME: Can we make this private?
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
final indexed_dbBlinkMap = { final indexed_dbBlinkMap = {
'IDBCursor': () => Cursor, 'IDBCursor': () => Cursor.instanceRuntimeType,
'IDBCursorWithValue': () => CursorWithValue, 'IDBCursorWithValue': () => CursorWithValue.instanceRuntimeType,
'IDBDatabase': () => Database, 'IDBDatabase': () => Database.instanceRuntimeType,
'IDBFactory': () => IdbFactory, 'IDBFactory': () => IdbFactory.instanceRuntimeType,
'IDBIndex': () => Index, 'IDBIndex': () => Index.instanceRuntimeType,
'IDBKeyRange': () => KeyRange, 'IDBKeyRange': () => KeyRange.instanceRuntimeType,
'IDBObjectStore': () => ObjectStore, 'IDBObjectStore': () => ObjectStore.instanceRuntimeType,
'IDBOpenDBRequest': () => OpenDBRequest, 'IDBOpenDBRequest': () => OpenDBRequest.instanceRuntimeType,
'IDBRequest': () => Request, 'IDBRequest': () => Request.instanceRuntimeType,
'IDBTransaction': () => Transaction, 'IDBTransaction': () => Transaction.instanceRuntimeType,
'IDBVersionChangeEvent': () => VersionChangeEvent, 'IDBVersionChangeEvent': () => VersionChangeEvent.instanceRuntimeType,
}; };
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final indexed_dbBlinkFunctionMap = {
'IDBCursor': () => Cursor.internalCreateCursor,
'IDBCursorWithValue': () => CursorWithValue.internalCreateCursorWithValue,
'IDBDatabase': () => Database.internalCreateDatabase,
'IDBFactory': () => IdbFactory.internalCreateIdbFactory,
'IDBIndex': () => Index.internalCreateIndex,
'IDBKeyRange': () => KeyRange.internalCreateKeyRange,
'IDBObjectStore': () => ObjectStore.internalCreateObjectStore,
'IDBOpenDBRequest': () => OpenDBRequest.internalCreateOpenDBRequest,
'IDBRequest': () => Request.internalCreateRequest,
'IDBTransaction': () => Transaction.internalCreateTransaction,
'IDBVersionChangeEvent': () => VersionChangeEvent.internalCreateVersionChangeEvent,
}; //
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // Per http://www.w3.org/TR/IndexedDB/#key-construct
//
// "A value is said to be a valid key if it is one of the following types: Array
// JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
// [WEBIDL]. However Arrays are only valid keys if every item in the array is
// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
// the Array doesn't directly or indirectly contain itself. Any non-numeric
// properties are ignored, and thus does not affect whether the Array is a valid
// key. Additionally, if the value is of type float, it is only a valid key if
// it is not NaN, and if the value is of type Date it is only a valid key if its
// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."
// What is required is to ensure that an Lists in the key are actually
// JavaScript arrays, and any Dates are JavaScript Dates.
/**
* Converts a native IDBKey into a Dart object.
*
* May return the original input. May mutate the original input (but will be
* idempotent if mutation occurs). It is assumed that this conversion happens
* on native IDBKeys on all paths that return IDBKeys from native DOM calls.
*
* If necessary, JavaScript Dates are converted into Dart Dates.
*/
_convertNativeToDart_IDBKey(nativeKey) {
containsDate(object) {
if (object is DateTime) return true;
if (object is List) {
for (int i = 0; i < object.length; i++) {
if (containsDate(object[i])) return true;
}
}
return false; // number, string.
}
if (nativeKey is DateTime) {
throw new UnimplementedError('Key containing DateTime');
}
// TODO: Cache conversion somewhere?
return nativeKey;
}
/**
* Converts a Dart object into a valid IDBKey.
*
* May return the original input. Does not mutate input.
*
* If necessary, [dartKey] may be copied to ensure all lists are converted into
* JavaScript Arrays and Dart Dates into JavaScript Dates.
*/
_convertDartToNative_IDBKey(dartKey) {
// TODO: Implement.
return dartKey;
}
/// May modify original. If so, action is idempotent.
_convertNativeToDart_IDBAny(object) {
return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
}// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
@ -169,62 +215,54 @@ class Cursor extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory Cursor._() { throw new UnsupportedError("Not supported"); } factory Cursor._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static Cursor internalCreateCursor() {
return new Cursor._internalWrap();
}
factory Cursor._internalWrap() { @Deprecated("Internal Use Only")
return new Cursor.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Cursor.internal_() { } Cursor.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('IDBCursor.direction') @DomName('IDBCursor.direction')
@DocsEditable() @DocsEditable()
String get direction => _blink.BlinkIDBCursor.instance.direction_Getter_(unwrap_jso(this)); String get direction => _blink.BlinkIDBCursor.instance.direction_Getter_(this);
@DomName('IDBCursor.key') @DomName('IDBCursor.key')
@DocsEditable() @DocsEditable()
Object get key => wrap_jso(_blink.BlinkIDBCursor.instance.key_Getter_(unwrap_jso(this))); Object get key => (_blink.BlinkIDBCursor.instance.key_Getter_(this));
@DomName('IDBCursor.primaryKey') @DomName('IDBCursor.primaryKey')
@DocsEditable() @DocsEditable()
Object get primaryKey => wrap_jso(_blink.BlinkIDBCursor.instance.primaryKey_Getter_(unwrap_jso(this))); Object get primaryKey => (_blink.BlinkIDBCursor.instance.primaryKey_Getter_(this));
@DomName('IDBCursor.source') @DomName('IDBCursor.source')
@DocsEditable() @DocsEditable()
Object get source => wrap_jso(_blink.BlinkIDBCursor.instance.source_Getter_(unwrap_jso(this))); Object get source => (_blink.BlinkIDBCursor.instance.source_Getter_(this));
@DomName('IDBCursor.advance') @DomName('IDBCursor.advance')
@DocsEditable() @DocsEditable()
void advance(int count) => _blink.BlinkIDBCursor.instance.advance_Callback_1_(unwrap_jso(this), count); void advance(int count) => _blink.BlinkIDBCursor.instance.advance_Callback_1_(this, count);
@DomName('IDBCursor.continuePrimaryKey') @DomName('IDBCursor.continuePrimaryKey')
@DocsEditable() @DocsEditable()
@Experimental() // untriaged @Experimental() // untriaged
void continuePrimaryKey(Object key, Object primaryKey) => _blink.BlinkIDBCursor.instance.continuePrimaryKey_Callback_2_(unwrap_jso(this), key, primaryKey); void continuePrimaryKey(Object key, Object primaryKey) => _blink.BlinkIDBCursor.instance.continuePrimaryKey_Callback_2_(this, key, primaryKey);
@DomName('IDBCursor.delete') @DomName('IDBCursor.delete')
@DocsEditable() @DocsEditable()
Request _delete() => wrap_jso(_blink.BlinkIDBCursor.instance.delete_Callback_0_(unwrap_jso(this))); Request _delete() => _blink.BlinkIDBCursor.instance.delete_Callback_0_(this);
void next([Object key]) { void next([Object key]) {
if (key != null) { if (key != null) {
_blink.BlinkIDBCursor.instance.continue_Callback_1_(unwrap_jso(this), key); _blink.BlinkIDBCursor.instance.continue_Callback_1_(this, key);
return; return;
} }
_blink.BlinkIDBCursor.instance.continue_Callback_0_(unwrap_jso(this)); _blink.BlinkIDBCursor.instance.continue_Callback_0_(this);
return; return;
} }
@DomName('IDBCursor.update') @DomName('IDBCursor.update')
@DocsEditable() @DocsEditable()
Request _update(Object value) => wrap_jso(_blink.BlinkIDBCursor.instance.update_Callback_1_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(value))); Request _update(Object value) => _blink.BlinkIDBCursor.instance.update_Callback_1_(this, convertDartToNative_SerializedScriptValue(value));
} }
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@ -243,11 +281,7 @@ class CursorWithValue extends Cursor {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static CursorWithValue internalCreateCursorWithValue() { external static Type get instanceRuntimeType;
return new CursorWithValue._internalWrap();
}
external factory CursorWithValue._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
CursorWithValue.internal_() : super.internal_(); CursorWithValue.internal_() : super.internal_();
@ -255,7 +289,7 @@ class CursorWithValue extends Cursor {
@DomName('IDBCursorWithValue.value') @DomName('IDBCursorWithValue.value')
@DocsEditable() @DocsEditable()
Object get value => wrap_jso(_blink.BlinkIDBCursorWithValue.instance.value_Getter_(unwrap_jso(this))); Object get value => _convertNativeToDart_IDBAny(_blink.BlinkIDBCursorWithValue.instance.value_Getter_(this));
} }
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
@ -298,14 +332,14 @@ class Database extends EventTarget {
if (storeName_OR_storeNames == null) { if (storeName_OR_storeNames == null) {
throw new ArgumentError("stores may not be null in transaction"); throw new ArgumentError("stores may not be null in transaction");
} else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) { } else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) {
names = unwrap_jso(storeName_OR_storeNames); names = storeName_OR_storeNames;
} else if (storeName_OR_storeNames is List<String>) { } else if (storeName_OR_storeNames is List<String>) {
names = convertDartToNative_List(storeName_OR_storeNames); names = convertDartToNative_List(storeName_OR_storeNames);
} else { } else {
throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames"); throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames");
} }
return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), names, mode)); return _blink.BlinkIDBDatabase.instance.transaction_Callback_2_(this, names, mode);
} }
Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode); Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode);
@ -359,11 +393,7 @@ class Database extends EventTarget {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static Database internalCreateDatabase() { external static Type get instanceRuntimeType;
return new Database._internalWrap();
}
external factory Database._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Database.internal_() : super.internal_(); Database.internal_() : super.internal_();
@ -371,30 +401,30 @@ class Database extends EventTarget {
@DomName('IDBDatabase.name') @DomName('IDBDatabase.name')
@DocsEditable() @DocsEditable()
String get name => _blink.BlinkIDBDatabase.instance.name_Getter_(unwrap_jso(this)); String get name => _blink.BlinkIDBDatabase.instance.name_Getter_(this);
@DomName('IDBDatabase.objectStoreNames') @DomName('IDBDatabase.objectStoreNames')
@DocsEditable() @DocsEditable()
List<String> get objectStoreNames => wrap_jso(_blink.BlinkIDBDatabase.instance.objectStoreNames_Getter_(unwrap_jso(this))); List<String> get objectStoreNames => _blink.BlinkIDBDatabase.instance.objectStoreNames_Getter_(this);
@DomName('IDBDatabase.version') @DomName('IDBDatabase.version')
@DocsEditable() @DocsEditable()
Object get version => wrap_jso(_blink.BlinkIDBDatabase.instance.version_Getter_(unwrap_jso(this))); Object get version => (_blink.BlinkIDBDatabase.instance.version_Getter_(this));
@DomName('IDBDatabase.close') @DomName('IDBDatabase.close')
@DocsEditable() @DocsEditable()
void close() => _blink.BlinkIDBDatabase.instance.close_Callback_0_(unwrap_jso(this)); void close() => _blink.BlinkIDBDatabase.instance.close_Callback_0_(this);
ObjectStore _createObjectStore(String name, [Map options]) { ObjectStore _createObjectStore(String name, [Map options]) {
if (options != null) { if (options != null) {
return wrap_jso(_blink.BlinkIDBDatabase.instance.createObjectStore_Callback_2_(unwrap_jso(this), name, convertDartToNative_Dictionary(options))); return _blink.BlinkIDBDatabase.instance.createObjectStore_Callback_2_(this, name, convertDartToNative_Dictionary(options));
} }
return wrap_jso(_blink.BlinkIDBDatabase.instance.createObjectStore_Callback_1_(unwrap_jso(this), name)); return _blink.BlinkIDBDatabase.instance.createObjectStore_Callback_1_(this, name);
} }
@DomName('IDBDatabase.deleteObjectStore') @DomName('IDBDatabase.deleteObjectStore')
@DocsEditable() @DocsEditable()
void deleteObjectStore(String name) => _blink.BlinkIDBDatabase.instance.deleteObjectStore_Callback_1_(unwrap_jso(this), name); void deleteObjectStore(String name) => _blink.BlinkIDBDatabase.instance.deleteObjectStore_Callback_1_(this, name);
/// Stream of `abort` events handled by this [Database]. /// Stream of `abort` events handled by this [Database].
@DomName('IDBDatabase.onabort') @DomName('IDBDatabase.onabort')
@ -508,34 +538,26 @@ class IdbFactory extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory IdbFactory._() { throw new UnsupportedError("Not supported"); } factory IdbFactory._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static IdbFactory internalCreateIdbFactory() {
return new IdbFactory._internalWrap();
}
factory IdbFactory._internalWrap() { @Deprecated("Internal Use Only")
return new IdbFactory.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
IdbFactory.internal_() { } IdbFactory.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('IDBFactory.cmp') @DomName('IDBFactory.cmp')
@DocsEditable() @DocsEditable()
int cmp(Object first, Object second) => _blink.BlinkIDBFactory.instance.cmp_Callback_2_(unwrap_jso(this), first, second); int cmp(Object first, Object second) => _blink.BlinkIDBFactory.instance.cmp_Callback_2_(this, first, second);
@DomName('IDBFactory.deleteDatabase') @DomName('IDBFactory.deleteDatabase')
@DocsEditable() @DocsEditable()
OpenDBRequest _deleteDatabase(String name) => wrap_jso(_blink.BlinkIDBFactory.instance.deleteDatabase_Callback_1_(unwrap_jso(this), name)); OpenDBRequest _deleteDatabase(String name) => _blink.BlinkIDBFactory.instance.deleteDatabase_Callback_1_(this, name);
OpenDBRequest _open(String name, [int version]) { OpenDBRequest _open(String name, [int version]) {
if (version != null) { if (version != null) {
return wrap_jso(_blink.BlinkIDBFactory.instance.open_Callback_2_(unwrap_jso(this), name, version)); return _blink.BlinkIDBFactory.instance.open_Callback_2_(this, name, version);
} }
return wrap_jso(_blink.BlinkIDBFactory.instance.open_Callback_1_(unwrap_jso(this), name)); return _blink.BlinkIDBFactory.instance.open_Callback_1_(this, name);
} }
@DomName('IDBFactory.webkitGetDatabaseNames') @DomName('IDBFactory.webkitGetDatabaseNames')
@ -543,7 +565,7 @@ class IdbFactory extends DartHtmlDomObject {
@SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI) @SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental() @Experimental()
Request _webkitGetDatabaseNames() => wrap_jso(_blink.BlinkIDBFactory.instance.webkitGetDatabaseNames_Callback_0_(unwrap_jso(this))); Request _webkitGetDatabaseNames() => _blink.BlinkIDBFactory.instance.webkitGetDatabaseNames_Callback_0_(this);
} }
@ -661,79 +683,71 @@ class Index extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory Index._() { throw new UnsupportedError("Not supported"); } factory Index._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static Index internalCreateIndex() {
return new Index._internalWrap();
}
factory Index._internalWrap() { @Deprecated("Internal Use Only")
return new Index.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Index.internal_() { } Index.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('IDBIndex.keyPath') @DomName('IDBIndex.keyPath')
@DocsEditable() @DocsEditable()
Object get keyPath => wrap_jso(_blink.BlinkIDBIndex.instance.keyPath_Getter_(unwrap_jso(this))); Object get keyPath => (_blink.BlinkIDBIndex.instance.keyPath_Getter_(this));
@DomName('IDBIndex.multiEntry') @DomName('IDBIndex.multiEntry')
@DocsEditable() @DocsEditable()
bool get multiEntry => _blink.BlinkIDBIndex.instance.multiEntry_Getter_(unwrap_jso(this)); bool get multiEntry => _blink.BlinkIDBIndex.instance.multiEntry_Getter_(this);
@DomName('IDBIndex.name') @DomName('IDBIndex.name')
@DocsEditable() @DocsEditable()
String get name => _blink.BlinkIDBIndex.instance.name_Getter_(unwrap_jso(this)); String get name => _blink.BlinkIDBIndex.instance.name_Getter_(this);
@DomName('IDBIndex.objectStore') @DomName('IDBIndex.objectStore')
@DocsEditable() @DocsEditable()
ObjectStore get objectStore => wrap_jso(_blink.BlinkIDBIndex.instance.objectStore_Getter_(unwrap_jso(this))); ObjectStore get objectStore => _blink.BlinkIDBIndex.instance.objectStore_Getter_(this);
@DomName('IDBIndex.unique') @DomName('IDBIndex.unique')
@DocsEditable() @DocsEditable()
bool get unique => _blink.BlinkIDBIndex.instance.unique_Getter_(unwrap_jso(this)); bool get unique => _blink.BlinkIDBIndex.instance.unique_Getter_(this);
@DomName('IDBIndex.count') @DomName('IDBIndex.count')
@DocsEditable() @DocsEditable()
Request _count(Object key) => wrap_jso(_blink.BlinkIDBIndex.instance.count_Callback_1_(unwrap_jso(this), key)); Request _count(Object key) => _blink.BlinkIDBIndex.instance.count_Callback_1_(this, key);
@DomName('IDBIndex.get') @DomName('IDBIndex.get')
@DocsEditable() @DocsEditable()
Request _get(Object key) => wrap_jso(_blink.BlinkIDBIndex.instance.get_Callback_1_(unwrap_jso(this), key)); Request _get(Object key) => _blink.BlinkIDBIndex.instance.get_Callback_1_(this, key);
Request getAll(Object range, [int maxCount]) { Request getAll(Object range, [int maxCount]) {
if (maxCount != null) { if (maxCount != null) {
return wrap_jso(_blink.BlinkIDBIndex.instance.getAll_Callback_2_(unwrap_jso(this), range, maxCount)); return _blink.BlinkIDBIndex.instance.getAll_Callback_2_(this, range, maxCount);
} }
return wrap_jso(_blink.BlinkIDBIndex.instance.getAll_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBIndex.instance.getAll_Callback_1_(this, range);
} }
Request getAllKeys(Object range, [int maxCount]) { Request getAllKeys(Object range, [int maxCount]) {
if (maxCount != null) { if (maxCount != null) {
return wrap_jso(_blink.BlinkIDBIndex.instance.getAllKeys_Callback_2_(unwrap_jso(this), range, maxCount)); return _blink.BlinkIDBIndex.instance.getAllKeys_Callback_2_(this, range, maxCount);
} }
return wrap_jso(_blink.BlinkIDBIndex.instance.getAllKeys_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBIndex.instance.getAllKeys_Callback_1_(this, range);
} }
@DomName('IDBIndex.getKey') @DomName('IDBIndex.getKey')
@DocsEditable() @DocsEditable()
Request _getKey(Object key) => wrap_jso(_blink.BlinkIDBIndex.instance.getKey_Callback_1_(unwrap_jso(this), key)); Request _getKey(Object key) => _blink.BlinkIDBIndex.instance.getKey_Callback_1_(this, key);
Request _openCursor(Object range, [String direction]) { Request _openCursor(Object range, [String direction]) {
if (direction != null) { if (direction != null) {
return wrap_jso(_blink.BlinkIDBIndex.instance.openCursor_Callback_2_(unwrap_jso(this), range, direction)); return _blink.BlinkIDBIndex.instance.openCursor_Callback_2_(this, range, direction);
} }
return wrap_jso(_blink.BlinkIDBIndex.instance.openCursor_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBIndex.instance.openCursor_Callback_1_(this, range);
} }
Request _openKeyCursor(Object range, [String direction]) { Request _openKeyCursor(Object range, [String direction]) {
if (direction != null) { if (direction != null) {
return wrap_jso(_blink.BlinkIDBIndex.instance.openKeyCursor_Callback_2_(unwrap_jso(this), range, direction)); return _blink.BlinkIDBIndex.instance.openKeyCursor_Callback_2_(this, range, direction);
} }
return wrap_jso(_blink.BlinkIDBIndex.instance.openKeyCursor_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBIndex.instance.openKeyCursor_Callback_1_(this, range);
} }
} }
@ -766,64 +780,56 @@ class KeyRange extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory KeyRange._() { throw new UnsupportedError("Not supported"); } factory KeyRange._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static KeyRange internalCreateKeyRange() {
return new KeyRange._internalWrap();
}
factory KeyRange._internalWrap() { @Deprecated("Internal Use Only")
return new KeyRange.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
KeyRange.internal_() { } KeyRange.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('IDBKeyRange.lower') @DomName('IDBKeyRange.lower')
@DocsEditable() @DocsEditable()
Object get lower => wrap_jso(_blink.BlinkIDBKeyRange.instance.lower_Getter_(unwrap_jso(this))); Object get lower => (_blink.BlinkIDBKeyRange.instance.lower_Getter_(this));
@DomName('IDBKeyRange.lowerOpen') @DomName('IDBKeyRange.lowerOpen')
@DocsEditable() @DocsEditable()
bool get lowerOpen => _blink.BlinkIDBKeyRange.instance.lowerOpen_Getter_(unwrap_jso(this)); bool get lowerOpen => _blink.BlinkIDBKeyRange.instance.lowerOpen_Getter_(this);
@DomName('IDBKeyRange.upper') @DomName('IDBKeyRange.upper')
@DocsEditable() @DocsEditable()
Object get upper => wrap_jso(_blink.BlinkIDBKeyRange.instance.upper_Getter_(unwrap_jso(this))); Object get upper => (_blink.BlinkIDBKeyRange.instance.upper_Getter_(this));
@DomName('IDBKeyRange.upperOpen') @DomName('IDBKeyRange.upperOpen')
@DocsEditable() @DocsEditable()
bool get upperOpen => _blink.BlinkIDBKeyRange.instance.upperOpen_Getter_(unwrap_jso(this)); bool get upperOpen => _blink.BlinkIDBKeyRange.instance.upperOpen_Getter_(this);
static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) { static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) {
if (upperOpen != null) { if (upperOpen != null) {
return wrap_jso(_blink.BlinkIDBKeyRange.instance.bound_Callback_4_(lower, upper, lowerOpen, upperOpen)); return _blink.BlinkIDBKeyRange.instance.bound_Callback_4_(lower, upper, lowerOpen, upperOpen);
} }
if (lowerOpen != null) { if (lowerOpen != null) {
return wrap_jso(_blink.BlinkIDBKeyRange.instance.bound_Callback_3_(lower, upper, lowerOpen)); return _blink.BlinkIDBKeyRange.instance.bound_Callback_3_(lower, upper, lowerOpen);
} }
return wrap_jso(_blink.BlinkIDBKeyRange.instance.bound_Callback_2_(lower, upper)); return _blink.BlinkIDBKeyRange.instance.bound_Callback_2_(lower, upper);
} }
static KeyRange lowerBound_(Object bound, [bool open]) { static KeyRange lowerBound_(Object bound, [bool open]) {
if (open != null) { if (open != null) {
return wrap_jso(_blink.BlinkIDBKeyRange.instance.lowerBound_Callback_2_(bound, open)); return _blink.BlinkIDBKeyRange.instance.lowerBound_Callback_2_(bound, open);
} }
return wrap_jso(_blink.BlinkIDBKeyRange.instance.lowerBound_Callback_1_(bound)); return _blink.BlinkIDBKeyRange.instance.lowerBound_Callback_1_(bound);
} }
@DomName('IDBKeyRange.only_') @DomName('IDBKeyRange.only_')
@DocsEditable() @DocsEditable()
@Experimental() // non-standard @Experimental() // non-standard
static KeyRange only_(Object value) => wrap_jso(_blink.BlinkIDBKeyRange.instance.only_Callback_1_(value)); static KeyRange only_(Object value) => _blink.BlinkIDBKeyRange.instance.only_Callback_1_(value);
static KeyRange upperBound_(Object bound, [bool open]) { static KeyRange upperBound_(Object bound, [bool open]) {
if (open != null) { if (open != null) {
return wrap_jso(_blink.BlinkIDBKeyRange.instance.upperBound_Callback_2_(bound, open)); return _blink.BlinkIDBKeyRange.instance.upperBound_Callback_2_(bound, open);
} }
return wrap_jso(_blink.BlinkIDBKeyRange.instance.upperBound_Callback_1_(bound)); return _blink.BlinkIDBKeyRange.instance.upperBound_Callback_1_(bound);
} }
} }
@ -965,112 +971,104 @@ class ObjectStore extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory ObjectStore._() { throw new UnsupportedError("Not supported"); } factory ObjectStore._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static ObjectStore internalCreateObjectStore() {
return new ObjectStore._internalWrap();
}
factory ObjectStore._internalWrap() { @Deprecated("Internal Use Only")
return new ObjectStore.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
ObjectStore.internal_() { } ObjectStore.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('IDBObjectStore.autoIncrement') @DomName('IDBObjectStore.autoIncrement')
@DocsEditable() @DocsEditable()
bool get autoIncrement => _blink.BlinkIDBObjectStore.instance.autoIncrement_Getter_(unwrap_jso(this)); bool get autoIncrement => _blink.BlinkIDBObjectStore.instance.autoIncrement_Getter_(this);
@DomName('IDBObjectStore.indexNames') @DomName('IDBObjectStore.indexNames')
@DocsEditable() @DocsEditable()
List<String> get indexNames => wrap_jso(_blink.BlinkIDBObjectStore.instance.indexNames_Getter_(unwrap_jso(this))); List<String> get indexNames => _blink.BlinkIDBObjectStore.instance.indexNames_Getter_(this);
@DomName('IDBObjectStore.keyPath') @DomName('IDBObjectStore.keyPath')
@DocsEditable() @DocsEditable()
Object get keyPath => wrap_jso(_blink.BlinkIDBObjectStore.instance.keyPath_Getter_(unwrap_jso(this))); Object get keyPath => (_blink.BlinkIDBObjectStore.instance.keyPath_Getter_(this));
@DomName('IDBObjectStore.name') @DomName('IDBObjectStore.name')
@DocsEditable() @DocsEditable()
String get name => _blink.BlinkIDBObjectStore.instance.name_Getter_(unwrap_jso(this)); String get name => _blink.BlinkIDBObjectStore.instance.name_Getter_(this);
@DomName('IDBObjectStore.transaction') @DomName('IDBObjectStore.transaction')
@DocsEditable() @DocsEditable()
Transaction get transaction => wrap_jso(_blink.BlinkIDBObjectStore.instance.transaction_Getter_(unwrap_jso(this))); Transaction get transaction => _blink.BlinkIDBObjectStore.instance.transaction_Getter_(this);
Request _add(Object value, [Object key]) { Request _add(Object value, [Object key]) {
if (key != null) { if (key != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.add_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(value), convertDartToNative_SerializedScriptValue(key))); return _blink.BlinkIDBObjectStore.instance.add_Callback_2_(this, convertDartToNative_SerializedScriptValue(value), convertDartToNative_SerializedScriptValue(key));
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.add_Callback_1_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(value))); return _blink.BlinkIDBObjectStore.instance.add_Callback_1_(this, convertDartToNative_SerializedScriptValue(value));
} }
@DomName('IDBObjectStore.clear') @DomName('IDBObjectStore.clear')
@DocsEditable() @DocsEditable()
Request _clear() => wrap_jso(_blink.BlinkIDBObjectStore.instance.clear_Callback_0_(unwrap_jso(this))); Request _clear() => _blink.BlinkIDBObjectStore.instance.clear_Callback_0_(this);
@DomName('IDBObjectStore.count') @DomName('IDBObjectStore.count')
@DocsEditable() @DocsEditable()
Request _count(Object key) => wrap_jso(_blink.BlinkIDBObjectStore.instance.count_Callback_1_(unwrap_jso(this), key)); Request _count(Object key) => _blink.BlinkIDBObjectStore.instance.count_Callback_1_(this, key);
Index _createIndex(String name, Object keyPath, [Map options]) { Index _createIndex(String name, Object keyPath, [Map options]) {
if (options != null) { if (options != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.createIndex_Callback_3_(unwrap_jso(this), name, keyPath, convertDartToNative_Dictionary(options))); return _blink.BlinkIDBObjectStore.instance.createIndex_Callback_3_(this, name, keyPath, convertDartToNative_Dictionary(options));
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.createIndex_Callback_2_(unwrap_jso(this), name, keyPath)); return _blink.BlinkIDBObjectStore.instance.createIndex_Callback_2_(this, name, keyPath);
} }
@DomName('IDBObjectStore.delete') @DomName('IDBObjectStore.delete')
@DocsEditable() @DocsEditable()
Request _delete(Object key) => wrap_jso(_blink.BlinkIDBObjectStore.instance.delete_Callback_1_(unwrap_jso(this), key)); Request _delete(Object key) => _blink.BlinkIDBObjectStore.instance.delete_Callback_1_(this, key);
@DomName('IDBObjectStore.deleteIndex') @DomName('IDBObjectStore.deleteIndex')
@DocsEditable() @DocsEditable()
void deleteIndex(String name) => _blink.BlinkIDBObjectStore.instance.deleteIndex_Callback_1_(unwrap_jso(this), name); void deleteIndex(String name) => _blink.BlinkIDBObjectStore.instance.deleteIndex_Callback_1_(this, name);
@DomName('IDBObjectStore.get') @DomName('IDBObjectStore.get')
@DocsEditable() @DocsEditable()
Request _get(Object key) => wrap_jso(_blink.BlinkIDBObjectStore.instance.get_Callback_1_(unwrap_jso(this), key)); Request _get(Object key) => _blink.BlinkIDBObjectStore.instance.get_Callback_1_(this, key);
Request getAll(Object range, [int maxCount]) { Request getAll(Object range, [int maxCount]) {
if (maxCount != null) { if (maxCount != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.getAll_Callback_2_(unwrap_jso(this), range, maxCount)); return _blink.BlinkIDBObjectStore.instance.getAll_Callback_2_(this, range, maxCount);
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.getAll_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBObjectStore.instance.getAll_Callback_1_(this, range);
} }
Request getAllKeys(Object range, [int maxCount]) { Request getAllKeys(Object range, [int maxCount]) {
if (maxCount != null) { if (maxCount != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.getAllKeys_Callback_2_(unwrap_jso(this), range, maxCount)); return _blink.BlinkIDBObjectStore.instance.getAllKeys_Callback_2_(this, range, maxCount);
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.getAllKeys_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBObjectStore.instance.getAllKeys_Callback_1_(this, range);
} }
@DomName('IDBObjectStore.index') @DomName('IDBObjectStore.index')
@DocsEditable() @DocsEditable()
Index index(String name) => wrap_jso(_blink.BlinkIDBObjectStore.instance.index_Callback_1_(unwrap_jso(this), name)); Index index(String name) => _blink.BlinkIDBObjectStore.instance.index_Callback_1_(this, name);
Request _openCursor(Object range, [String direction]) { Request _openCursor(Object range, [String direction]) {
if (direction != null) { if (direction != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.openCursor_Callback_2_(unwrap_jso(this), range, direction)); return _blink.BlinkIDBObjectStore.instance.openCursor_Callback_2_(this, range, direction);
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.openCursor_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBObjectStore.instance.openCursor_Callback_1_(this, range);
} }
Request openKeyCursor(Object range, [String direction]) { Request openKeyCursor(Object range, [String direction]) {
if (direction != null) { if (direction != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.openKeyCursor_Callback_2_(unwrap_jso(this), range, direction)); return _blink.BlinkIDBObjectStore.instance.openKeyCursor_Callback_2_(this, range, direction);
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.openKeyCursor_Callback_1_(unwrap_jso(this), range)); return _blink.BlinkIDBObjectStore.instance.openKeyCursor_Callback_1_(this, range);
} }
Request _put(Object value, [Object key]) { Request _put(Object value, [Object key]) {
if (key != null) { if (key != null) {
return wrap_jso(_blink.BlinkIDBObjectStore.instance.put_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(value), convertDartToNative_SerializedScriptValue(key))); return _blink.BlinkIDBObjectStore.instance.put_Callback_2_(this, convertDartToNative_SerializedScriptValue(value), convertDartToNative_SerializedScriptValue(key));
} }
return wrap_jso(_blink.BlinkIDBObjectStore.instance.put_Callback_1_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(value))); return _blink.BlinkIDBObjectStore.instance.put_Callback_1_(this, convertDartToNative_SerializedScriptValue(value));
} }
@ -1137,11 +1135,7 @@ class OpenDBRequest extends Request {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static OpenDBRequest internalCreateOpenDBRequest() { external static Type get instanceRuntimeType;
return new OpenDBRequest._internalWrap();
}
external factory OpenDBRequest._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
OpenDBRequest.internal_() : super.internal_(); OpenDBRequest.internal_() : super.internal_();
@ -1194,11 +1188,7 @@ class Request extends EventTarget {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static Request internalCreateRequest() { external static Type get instanceRuntimeType;
return new Request._internalWrap();
}
external factory Request._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Request.internal_() : super.internal_(); Request.internal_() : super.internal_();
@ -1206,23 +1196,23 @@ class Request extends EventTarget {
@DomName('IDBRequest.error') @DomName('IDBRequest.error')
@DocsEditable() @DocsEditable()
DomError get error => wrap_jso(_blink.BlinkIDBRequest.instance.error_Getter_(unwrap_jso(this))); DomError get error => _blink.BlinkIDBRequest.instance.error_Getter_(this);
@DomName('IDBRequest.readyState') @DomName('IDBRequest.readyState')
@DocsEditable() @DocsEditable()
String get readyState => _blink.BlinkIDBRequest.instance.readyState_Getter_(unwrap_jso(this)); String get readyState => _blink.BlinkIDBRequest.instance.readyState_Getter_(this);
@DomName('IDBRequest.result') @DomName('IDBRequest.result')
@DocsEditable() @DocsEditable()
Object get result => wrap_jso(_blink.BlinkIDBRequest.instance.result_Getter_(unwrap_jso(this))); Object get result => _convertNativeToDart_IDBAny(_blink.BlinkIDBRequest.instance.result_Getter_(this));
@DomName('IDBRequest.source') @DomName('IDBRequest.source')
@DocsEditable() @DocsEditable()
Object get source => wrap_jso(_blink.BlinkIDBRequest.instance.source_Getter_(unwrap_jso(this))); Object get source => (_blink.BlinkIDBRequest.instance.source_Getter_(this));
@DomName('IDBRequest.transaction') @DomName('IDBRequest.transaction')
@DocsEditable() @DocsEditable()
Transaction get transaction => wrap_jso(_blink.BlinkIDBRequest.instance.transaction_Getter_(unwrap_jso(this))); Transaction get transaction => _blink.BlinkIDBRequest.instance.transaction_Getter_(this);
/// Stream of `error` events handled by this [Request]. /// Stream of `error` events handled by this [Request].
@DomName('IDBRequest.onerror') @DomName('IDBRequest.onerror')
@ -1307,11 +1297,7 @@ class Transaction extends EventTarget {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static Transaction internalCreateTransaction() { external static Type get instanceRuntimeType;
return new Transaction._internalWrap();
}
external factory Transaction._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Transaction.internal_() : super.internal_(); Transaction.internal_() : super.internal_();
@ -1319,28 +1305,28 @@ class Transaction extends EventTarget {
@DomName('IDBTransaction.db') @DomName('IDBTransaction.db')
@DocsEditable() @DocsEditable()
Database get db => wrap_jso(_blink.BlinkIDBTransaction.instance.db_Getter_(unwrap_jso(this))); Database get db => _blink.BlinkIDBTransaction.instance.db_Getter_(this);
@DomName('IDBTransaction.error') @DomName('IDBTransaction.error')
@DocsEditable() @DocsEditable()
DomError get error => wrap_jso(_blink.BlinkIDBTransaction.instance.error_Getter_(unwrap_jso(this))); DomError get error => _blink.BlinkIDBTransaction.instance.error_Getter_(this);
@DomName('IDBTransaction.mode') @DomName('IDBTransaction.mode')
@DocsEditable() @DocsEditable()
String get mode => _blink.BlinkIDBTransaction.instance.mode_Getter_(unwrap_jso(this)); String get mode => _blink.BlinkIDBTransaction.instance.mode_Getter_(this);
@DomName('IDBTransaction.objectStoreNames') @DomName('IDBTransaction.objectStoreNames')
@DocsEditable() @DocsEditable()
@Experimental() // untriaged @Experimental() // untriaged
List<String> get objectStoreNames => wrap_jso(_blink.BlinkIDBTransaction.instance.objectStoreNames_Getter_(unwrap_jso(this))); List<String> get objectStoreNames => _blink.BlinkIDBTransaction.instance.objectStoreNames_Getter_(this);
@DomName('IDBTransaction.abort') @DomName('IDBTransaction.abort')
@DocsEditable() @DocsEditable()
void abort() => _blink.BlinkIDBTransaction.instance.abort_Callback_0_(unwrap_jso(this)); void abort() => _blink.BlinkIDBTransaction.instance.abort_Callback_0_(this);
@DomName('IDBTransaction.objectStore') @DomName('IDBTransaction.objectStore')
@DocsEditable() @DocsEditable()
ObjectStore objectStore(String name) => wrap_jso(_blink.BlinkIDBTransaction.instance.objectStore_Callback_1_(unwrap_jso(this), name)); ObjectStore objectStore(String name) => _blink.BlinkIDBTransaction.instance.objectStore_Callback_1_(this, name);
/// Stream of `abort` events handled by this [Transaction]. /// Stream of `abort` events handled by this [Transaction].
@DomName('IDBTransaction.onabort') @DomName('IDBTransaction.onabort')
@ -1377,18 +1363,14 @@ class VersionChangeEvent extends Event {
factory VersionChangeEvent(String type, [Map eventInitDict]) { factory VersionChangeEvent(String type, [Map eventInitDict]) {
if (eventInitDict != null) { if (eventInitDict != null) {
var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
return wrap_jso(_blink.BlinkIDBVersionChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1)); return _blink.BlinkIDBVersionChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1);
} }
return wrap_jso(_blink.BlinkIDBVersionChangeEvent.instance.constructorCallback_1_(type)); return _blink.BlinkIDBVersionChangeEvent.instance.constructorCallback_1_(type);
} }
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static VersionChangeEvent internalCreateVersionChangeEvent() { external static Type get instanceRuntimeType;
return new VersionChangeEvent._internalWrap();
}
external factory VersionChangeEvent._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
VersionChangeEvent.internal_() : super.internal_(); VersionChangeEvent.internal_() : super.internal_();
@ -1397,19 +1379,19 @@ class VersionChangeEvent extends Event {
@DomName('IDBVersionChangeEvent.dataLoss') @DomName('IDBVersionChangeEvent.dataLoss')
@DocsEditable() @DocsEditable()
@Experimental() // untriaged @Experimental() // untriaged
String get dataLoss => _blink.BlinkIDBVersionChangeEvent.instance.dataLoss_Getter_(unwrap_jso(this)); String get dataLoss => _blink.BlinkIDBVersionChangeEvent.instance.dataLoss_Getter_(this);
@DomName('IDBVersionChangeEvent.dataLossMessage') @DomName('IDBVersionChangeEvent.dataLossMessage')
@DocsEditable() @DocsEditable()
@Experimental() // untriaged @Experimental() // untriaged
String get dataLossMessage => _blink.BlinkIDBVersionChangeEvent.instance.dataLossMessage_Getter_(unwrap_jso(this)); String get dataLossMessage => _blink.BlinkIDBVersionChangeEvent.instance.dataLossMessage_Getter_(this);
@DomName('IDBVersionChangeEvent.newVersion') @DomName('IDBVersionChangeEvent.newVersion')
@DocsEditable() @DocsEditable()
int get newVersion => _blink.BlinkIDBVersionChangeEvent.instance.newVersion_Getter_(unwrap_jso(this)); int get newVersion => _blink.BlinkIDBVersionChangeEvent.instance.newVersion_Getter_(this);
@DomName('IDBVersionChangeEvent.oldVersion') @DomName('IDBVersionChangeEvent.oldVersion')
@DocsEditable() @DocsEditable()
int get oldVersion => _blink.BlinkIDBVersionChangeEvent.instance.oldVersion_Getter_(unwrap_jso(this)); int get oldVersion => _blink.BlinkIDBVersionChangeEvent.instance.oldVersion_Getter_(this);
} }

File diff suppressed because it is too large Load diff

View file

@ -92,6 +92,7 @@ import 'dart:nativewrappers';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:mirrors' as mirrors; import 'dart:mirrors' as mirrors;
import 'dart:html' as html; import 'dart:html' as html;
import 'dart:_blink' as _blink;
import 'dart:html_common' as html_common; import 'dart:html_common' as html_common;
import 'dart:indexed_db' as indexed_db; import 'dart:indexed_db' as indexed_db;
import 'dart:typed_data'; import 'dart:typed_data';
@ -120,7 +121,7 @@ _buildArgs(Invocation invocation) {
varArgs[mirrors.MirrorSystem.getName(symbol)] = val; varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
}); });
return invocation.positionalArguments.toList() 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(); 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) { String _accessJsPathSetter(String path) {
var parts = path.split("."); var parts = path.split(".");
return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1)) return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
}, '${parts.last}', v)"; }, '${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") @Deprecated("Internal Use Only")
void addMemberHelper( void addMemberHelper(
mirrors.MethodMirror declaration, String path, StringBuffer sb, mirrors.MethodMirror declaration, String path, StringBuffer sb,
@ -426,11 +436,11 @@ void addMemberHelper(
sb.write(" "); sb.write(" ");
if (declaration.isGetter) { if (declaration.isGetter) {
sb.write( sb.write(
"get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});"); "get $name => ${_accessJsPath(path)};");
} else if (declaration.isSetter) { } else if (declaration.isSetter) {
sb.write("set $name(v) {\n" sb.write("set $name(v) {\n"
" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n" " ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n"
" return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});\n" " return ${_accessJsPathSetter(path)};\n"
"}\n"); "}\n");
} else { } else {
sb.write("$name("); sb.write("$name(");
@ -463,19 +473,19 @@ void addMemberHelper(
for (var arg in args) { for (var arg in args) {
sb.write(" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($arg);\n"); sb.write(" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($arg);\n");
} }
sb.write(" return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop("); sb.write(" return ");
if (declaration.isConstructor) { 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 sb.write("[${args.join(",")}]");
..write(_accessJsPath(path))
..write(declaration.isConstructor ? "," : ".apply(")
..write("[${args.join(",")}]");
if (hasOptional) { if (hasOptional) {
sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()");
} }
sb.write("));"); sb.write(");");
sb.write("}\n"); sb.write("}\n");
} }
sb.write("\n"); sb.write("\n");
@ -562,7 +572,7 @@ _generateLibraryCodegen(uri, library, staticCodegen) {
..write('}'); ..write('}');
} }
sbPatch.write(") {\n" sbPatch.write(") {\n"
" var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});\n"); " var ret = ${_JS_LIBRARY_PREFIX}.JsNative.newObject();\n");
i = 0; i = 0;
for (var p in declaration.parameters) { for (var p in declaration.parameters) {
assert(p.isNamed); // TODO(jacobr): throw. assert(p.isNamed); // TODO(jacobr): throw.
@ -571,14 +581,14 @@ _generateLibraryCodegen(uri, library, staticCodegen) {
mirrors.MirrorSystem.getName(p.simpleName)); mirrors.MirrorSystem.getName(p.simpleName));
sbPatch.write(" if($name != ${_UNDEFINED_VAR}) {\n" sbPatch.write(" if($name != ${_UNDEFINED_VAR}) {\n"
" ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n" " ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n"
" ret['$jsName'] = $name;\n" " ${_JS_LIBRARY_PREFIX}.JsNative.setProperty(ret, '$jsName', $name);\n"
" }\n"); " }\n");
i++; i++;
} }
sbPatch.write( sbPatch.write(
" return new ${_JS_LIBRARY_PREFIX}.JSObject.create(ret);\n" " return ret;"
" }\n"); "}\n");
} else if (declaration.isConstructor || } else if (declaration.isConstructor ||
declaration.isFactoryConstructor) { declaration.isFactoryConstructor) {
sbPatch.write(" "); sbPatch.write(" ");
@ -607,8 +617,7 @@ _generateLibraryCodegen(uri, library, staticCodegen) {
}); });
} }
if (isDom) { if (isDom) {
sbPatch.write(" factory ${className}._internalWrap() => " sbPatch.write(" static Type get instanceRuntimeType => ${classNameImpl};\n");
"new ${classNameImpl}.internal_();\n");
} }
if (sbPatch.isNotEmpty) { if (sbPatch.isNotEmpty) {
var typeVariablesClause = ''; var typeVariablesClause = '';
@ -757,27 +766,15 @@ abstract class JSObjectInterfacesDom $implementsClauseDom {
} }
patch class JSObject { patch class JSObject {
factory JSObject.create(JsObject jsObject) { static Type get instanceRuntimeType => JSObjectImpl;
var ret = new JSObjectImpl.internal()..blink_jsObject = jsObject;
jsObject._dartHtmlWrapper = ret;
return ret;
}
} }
patch class JSFunction { patch class JSFunction {
factory JSFunction.create(JsObject jsObject) { static Type get instanceRuntimeType => JSFunctionImpl;
var ret = new JSFunctionImpl.internal()..blink_jsObject = jsObject;
jsObject._dartHtmlWrapper = ret;
return ret;
}
} }
patch class JSArray { patch class JSArray {
factory JSArray.create(JsObject jsObject) { static Type get instanceRuntimeType => JSArrayImpl;
var ret = new JSArrayImpl.internal()..blink_jsObject = jsObject;
jsObject._dartHtmlWrapper = ret;
return ret;
}
} }
_registerAllJsInterfaces() { _registerAllJsInterfaces() {
@ -959,49 +956,44 @@ JsObject get context {
return _cachedContext; return _cachedContext;
} }
@Deprecated("Internal Use Only") _lookupType(o, bool isCrossFrame, bool isElement) {
maybeWrapTypedInterop(o) => html_common.wrap_jso_no_SerializedScriptvalue(o); try {
var type = html_common.lookupType(o, isElement);
_maybeWrap(o) { var typeMirror = mirrors.reflectType(type);
var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o); var legacyInteropConvertToNative = typeMirror.isSubtypeOf(mirrors.reflectType(html.Blob)) ||
if (identical(wrapped, o)) return o; typeMirror.isSubtypeOf(mirrors.reflectType(html.Event)) ||
return (wrapped is html.Blob || typeMirror.isSubtypeOf(mirrors.reflectType(indexed_db.KeyRange)) ||
wrapped is html.Event || typeMirror.isSubtypeOf(mirrors.reflectType(html.ImageData)) ||
wrapped is indexed_db.KeyRange || typeMirror.isSubtypeOf(mirrors.reflectType(html.Node)) ||
wrapped is html.ImageData || // TypedData is removed from this list as it is converted directly
wrapped is html.Node || // rather than flowing through the interceptor code path.
wrapped is TypedData || // typeMirror.isSubtypeOf(mirrors.reflectType(typed_data.TypedData)) ||
wrapped is html.Window) ? wrapped : o; 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];
} }
/** /**
* Get the dart wrapper object for object. Top-level so we * Base class for both the legacy JsObject class and the modern JSObject class.
* we can access it from other libraries without it being * This allows the JsNative utility class tobehave identically whether it is
* a public instance field on JsObject. * called on a JsObject or a JSObject.
*/ */
@Deprecated("Internal Use Only") class _JSObjectBase extends NativeFieldWrapperClass2 {
getDartHtmlWrapperFor(JsObject object) => object._dartHtmlWrapper; 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";
* 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;
}
/**
* 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.
*/
@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;
} }
/** /**
@ -1010,22 +1002,16 @@ unwrap_jso(dartClass_instance) {
* The properties of the JavaScript object are accessible via the `[]` and * The properties of the JavaScript object are accessible via the `[]` and
* `[]=` operators. Methods are callable via [callMethod]. * `[]=` operators. Methods are callable via [callMethod].
*/ */
class JsObject extends NativeFieldWrapperClass2 { class JsObject extends _JSObjectBase {
JsObject.internal(); 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 * Constructs a new JavaScript object from [constructor] and returns a proxy
* to it. * to it.
*/ */
factory JsObject(JsFunction constructor, [List arguments]) { factory JsObject(JsFunction constructor, [List arguments]) {
try { try {
return html_common.unwrap_jso(_create(constructor, arguments)); return _create(constructor, arguments);
} catch (e) { } catch (e) {
// Re-throw any errors (returned as a string) as a DomException. // Re-throw any errors (returned as a string) as a DomException.
throw new html.DomException.jsInterop(e); 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) { if (object is num || object is String || object is bool || object == null) {
throw new ArgumentError("object cannot be a num, string, bool, or null"); throw new ArgumentError("object cannot be a num, string, bool, or null");
} }
if (object is JsObject) return object;
return _fromBrowserObject(object); return _fromBrowserObject(object);
} }
@ -1071,7 +1058,7 @@ class JsObject extends NativeFieldWrapperClass2 {
static JsObject _jsify(object) native "JsObject_jsify"; 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 * Returns the value associated with [property] from the proxied JavaScript
@ -1081,14 +1068,14 @@ class JsObject extends NativeFieldWrapperClass2 {
*/ */
operator [](property) { operator [](property) {
try { try {
return _maybeWrap(_operator_getter(property)); return _operator_getterLegacy(property);
} catch (e) { } catch (e) {
// Re-throw any errors (returned as a string) as a DomException. // Re-throw any errors (returned as a string) as a DomException.
throw new html.DomException.jsInterop(e); 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 * Sets the value associated with [property] on the proxied JavaScript
@ -1098,27 +1085,23 @@ class JsObject extends NativeFieldWrapperClass2 {
*/ */
operator []=(property, value) { operator []=(property, value) {
try { try {
_operator_setter(property, value); _operator_setterLegacy(property, value);
} catch (e) { } catch (e) {
// Re-throw any errors (returned as a string) as a DomException. // Re-throw any errors (returned as a string) as a DomException.
throw new html.DomException.jsInterop(e); 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"; int get hashCode native "JsObject_hashCode";
operator ==(other) { operator ==(other) {
var is_JsObject = other is JsObject; if (other is! JsObject && other is! JSObject) return false;
if (!is_JsObject) { return _identityEquality(this, other);
other = html_common.unwrap_jso(other);
is_JsObject = other is JsObject;
}
return is_JsObject && _identityEquality(this, other);
} }
static bool _identityEquality(JsObject a, JsObject b) static bool _identityEquality(a, b)
native "JsObject_identityEquality"; native "JsObject_identityEquality";
/** /**
@ -1127,7 +1110,7 @@ class JsObject extends NativeFieldWrapperClass2 {
* *
* This is the equivalent of the `in` operator in JavaScript. * 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. * Removes [property] from the JavaScript object.
@ -1141,7 +1124,7 @@ class JsObject extends NativeFieldWrapperClass2 {
* *
* This is the equivalent of the `instanceof` operator in JavaScript. * 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. * Returns the result of the JavaScript objects `toString` method.
@ -1164,7 +1147,7 @@ class JsObject extends NativeFieldWrapperClass2 {
*/ */
callMethod(String method, [List args]) { callMethod(String method, [List args]) {
try { try {
return _maybeWrap(_callMethod(method, args)); return _callMethodLegacy(method, args);
} catch (e) { } catch (e) {
if (hasProperty(method)) { if (hasProperty(method)) {
// Return a DomException if DOM call returned an error. // 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. /// Base class for all JS objects used through dart:html and typed JS interop.
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
class JSObject { class JSObject extends _JSObjectBase {
JSObject.internal() {} JSObject.internal() {}
external factory JSObject.create(JsObject jsObject); external static Type get instanceRuntimeType;
@Deprecated("Internal Use Only") /**
JsObject blink_jsObject; * Returns the result of the JavaScript objects `toString` method.
*/
String toString() => blink_jsObject.toString(); String toString() {
try {
return _toString();
} catch (e) {
return super.toString();
}
}
noSuchMethod(Invocation invocation) { noSuchMethod(Invocation invocation) {
throwError() { throwError() {
@ -1204,7 +1194,7 @@ class JSObject {
!_allowedMethods.containsKey(invocation.memberName)) { !_allowedMethods.containsKey(invocation.memberName)) {
throwError(); throwError();
} }
var ret = maybeWrapTypedInterop(blink_jsObject._operator_getter(name)); var ret = _operator_getter(name);
if (matches != null) return ret; if (matches != null) return ret;
if (ret is Function || if (ret is Function ||
(ret is JsFunction /* shouldn't be needed in the future*/) && (ret is JsFunction /* shouldn't be needed in the future*/) &&
@ -1213,7 +1203,7 @@ class JSObject {
throwError(); throwError();
} else { } else {
// TODO(jacobr): should we throw if the JavaScript object doesn't have the property? // 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) { } else if (invocation.isSetter) {
if (CHECK_JS_INVOCATIONS) { if (CHECK_JS_INVOCATIONS) {
@ -1223,8 +1213,7 @@ class JSObject {
} }
assert(name.endsWith("=")); assert(name.endsWith("="));
name = name.substring(0, name.length - 1); name = name.substring(0, name.length - 1);
return maybeWrapTypedInterop(blink_jsObject._operator_setter( return _operator_setter(name, invocation.positionalArguments.first);
name, invocation.positionalArguments.first));
} else { } else {
// TODO(jacobr): also allow calling getters that look like functions. // TODO(jacobr): also allow calling getters that look like functions.
var matches; var matches;
@ -1233,8 +1222,7 @@ class JSObject {
if (matches == null || if (matches == null ||
!matches.checkInvocation(invocation)) throwError(); !matches.checkInvocation(invocation)) throwError();
} }
var ret = maybeWrapTypedInterop( var ret = _callMethod(name, _buildArgs(invocation));
blink_jsObject._callMethod(name, _buildArgs(invocation)));
if (CHECK_JS_INVOCATIONS) { if (CHECK_JS_INVOCATIONS) {
if (!matches._checkReturnType(ret)) { if (!matches._checkReturnType(ret)) {
html.window.console.error("Return value for method: ${name} is " html.window.console.error("Return value for method: ${name} is "
@ -1250,21 +1238,56 @@ class JSObject {
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
class JSArray extends JSObject with ListMixin { class JSArray extends JSObject with ListMixin {
JSArray.internal() : super.internal(); JSArray.internal() : super.internal();
external factory JSArray.create(JsObject jsObject); external static Type get instanceRuntimeType;
operator [](int index) =>
maybeWrapTypedInterop(JsNative.getArrayIndex(blink_jsObject, index));
operator []=(int index, value) => blink_jsObject[index] = value; // Reuse JsArray_length as length behavior is unchanged.
int get length native "JsArray_length";
int get length => blink_jsObject.length; set length(int length) {
set length(int newLength) => blink_jsObject.length = newLength; _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);
}
}
_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);
}
void operator []=(int index, value) {
_checkIndex(index);
_indexed_setter(index, value);
}
} }
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
class JSFunction extends JSObject implements Function { class JSFunction extends JSObject implements Function {
JSFunction.internal() : super.internal(); JSFunction.internal() : super.internal();
external factory JSFunction.create(JsObject jsObject); external static Type get instanceRuntimeType;
call( call(
[a1 = _UNDEFINED, [a1 = _UNDEFINED,
@ -1277,48 +1300,49 @@ class JSFunction extends JSObject implements Function {
a8 = _UNDEFINED, a8 = _UNDEFINED,
a9 = _UNDEFINED, a9 = _UNDEFINED,
a10 = _UNDEFINED]) { a10 = _UNDEFINED]) {
return maybeWrapTypedInterop(blink_jsObject return _apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
.apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])));
} }
noSuchMethod(Invocation invocation) { noSuchMethod(Invocation invocation) {
if (invocation.isMethod && invocation.memberName == #call) { if (invocation.isMethod && invocation.memberName == #call) {
return maybeWrapTypedInterop( return _apply(_buildArgs(invocation));
blink_jsObject.apply(_buildArgs(invocation)));
} }
return super.noSuchMethod(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. // JavaScript interop methods that do not automatically wrap to dart:html types.
// Warning: this API is not exposed to dart:js. // 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") @Deprecated("Internal Use Only")
class JsNative { class JsNative {
static getProperty(o, name) { static JSObject jsify(object) native "JSObject_jsify";
o = unwrap_jso(o); static JSObject newObject() native "JSObject_newObject";
return o != null ? o._operator_getter(name) : null; static JSArray newArray() native "JSObject_newArray";
}
static setProperty(o, name, value) { static hasProperty(_JSObjectBase o, name) => o._hasProperty(name);
return unwrap_jso(o)._operator_setter(name, value); 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 callMethod(o, String method, List args) { static toTypedObject(JsObject o) native "JSNative_toTypedObject";
return unwrap_jso(o)._callMethod(method, args);
}
static getArrayIndex(JsArray array, int index) {
array._checkIndex(index);
return getProperty(array, index);
}
/** /**
* Same behavior as new JsFunction.withThis except that JavaScript "this" is not * Same behavior as new JsFunction.withThis except that JavaScript "this" is not
* wrapped. * wrapped.
*/ */
static JsFunction withThis(Function f) native "JsFunction_withThisNoWrap"; static JSFunction withThis(Function f) native "JsFunction_withThisNoWrap";
} }
/** /**
* Proxies a JavaScript Function object. * Proxies a JavaScript Function object.
*/ */
@ -1336,7 +1360,7 @@ class JsFunction extends JsObject {
* supplied it is the value of `this` for the invocation. * supplied it is the value of `this` for the invocation.
*/ */
dynamic apply(List args, {thisArg}) => dynamic apply(List args, {thisArg}) =>
_maybeWrap(_apply(args, thisArg: thisArg)); _apply(args, thisArg: thisArg);
dynamic _apply(List args, {thisArg}) native "JsFunction_apply"; 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 * Returns a method that can be called with an arbitrary number (for n less
* than 11) of arguments without violating Dart type checks. * than 11) of arguments without violating Dart type checks.
@ -1515,90 +1530,6 @@ Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) => (
jsFunction._applyDebuggerOnly( jsFunction._applyDebuggerOnly(
_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])); _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 /// Returns a wrapper around function [f] that can be called from JavaScript
/// using the package:js Dart-JavaScript interop. /// 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. // The function is already a JSFunction... no need to do anything.
return f; return f;
} else { } else {
var ret = _interopExpando[f]; return JSFunction._create(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;
} }
} }
@ -1646,10 +1570,11 @@ JSFunction allowInteropCaptureThis(Function f) {
var ret = _interopCaptureThisExpando[f]; var ret = _interopCaptureThisExpando[f];
if (ret == null) { if (ret == null) {
// TODO(jacobr): we could optimize this. // TODO(jacobr): we could optimize this.
ret = new JSFunction.create( ret = JSFunction._createWithThis(f);
new JsFunction.withThis(new _CreateDartFunctionForInterop(f)));
_interopCaptureThisExpando[f] = ret; _interopCaptureThisExpando[f] = ret;
} }
return ret; return ret;
} }
} }
debugPrint(_) {}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -29,22 +29,11 @@ import 'dart:js' as js;
// FIXME: Can we make this private? // FIXME: Can we make this private?
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
final web_sqlBlinkMap = { final web_sqlBlinkMap = {
'Database': () => SqlDatabase, 'Database': () => SqlDatabase.instanceRuntimeType,
'SQLError': () => SqlError, 'SQLError': () => SqlError.instanceRuntimeType,
'SQLResultSet': () => SqlResultSet, 'SQLResultSet': () => SqlResultSet.instanceRuntimeType,
'SQLResultSetRowList': () => SqlResultSetRowList, 'SQLResultSetRowList': () => SqlResultSetRowList.instanceRuntimeType,
'SQLTransaction': () => SqlTransaction, 'SQLTransaction': () => SqlTransaction.instanceRuntimeType,
};
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final web_sqlBlinkFunctionMap = {
'Database': () => SqlDatabase.internalCreateSqlDatabase,
'SQLError': () => SqlError.internalCreateSqlError,
'SQLResultSet': () => SqlResultSet.internalCreateSqlResultSet,
'SQLResultSetRowList': () => SqlResultSetRowList.internalCreateSqlResultSetRowList,
'SQLTransaction': () => SqlTransaction.internalCreateSqlTransaction,
}; };
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@ -109,68 +98,60 @@ class SqlDatabase extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory SqlDatabase._() { throw new UnsupportedError("Not supported"); } factory SqlDatabase._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static SqlDatabase internalCreateSqlDatabase() {
return new SqlDatabase._internalWrap();
}
factory SqlDatabase._internalWrap() { @Deprecated("Internal Use Only")
return new SqlDatabase.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
SqlDatabase.internal_() { } SqlDatabase.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
/// Checks if this type is supported on the current platform. /// Checks if this type is supported on the current platform.
static bool get supported => true; static bool get supported => true;
@DomName('Database.version') @DomName('Database.version')
@DocsEditable() @DocsEditable()
String get version => _blink.BlinkDatabase.instance.version_Getter_(unwrap_jso(this)); String get version => _blink.BlinkDatabase.instance.version_Getter_(this);
void changeVersion(String oldVersion, String newVersion, [SqlTransactionCallback callback, SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) { void changeVersion(String oldVersion, String newVersion, [SqlTransactionCallback callback, SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) {
if (successCallback != null) { if (successCallback != null) {
_blink.BlinkDatabase.instance.changeVersion_Callback_5_(unwrap_jso(this), oldVersion, newVersion, unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error))), unwrap_jso(() => successCallback())); _blink.BlinkDatabase.instance.changeVersion_Callback_5_(this, oldVersion, newVersion, callback, errorCallback, successCallback);
return; return;
} }
if (errorCallback != null) { if (errorCallback != null) {
_blink.BlinkDatabase.instance.changeVersion_Callback_4_(unwrap_jso(this), oldVersion, newVersion, unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error)))); _blink.BlinkDatabase.instance.changeVersion_Callback_4_(this, oldVersion, newVersion, callback, errorCallback);
return; return;
} }
if (callback != null) { if (callback != null) {
_blink.BlinkDatabase.instance.changeVersion_Callback_3_(unwrap_jso(this), oldVersion, newVersion, unwrap_jso((transaction) => callback(wrap_jso(transaction)))); _blink.BlinkDatabase.instance.changeVersion_Callback_3_(this, oldVersion, newVersion, callback);
return; return;
} }
_blink.BlinkDatabase.instance.changeVersion_Callback_2_(unwrap_jso(this), oldVersion, newVersion); _blink.BlinkDatabase.instance.changeVersion_Callback_2_(this, oldVersion, newVersion);
return; return;
} }
void readTransaction(SqlTransactionCallback callback, [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) { void readTransaction(SqlTransactionCallback callback, [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) {
if (successCallback != null) { if (successCallback != null) {
_blink.BlinkDatabase.instance.readTransaction_Callback_3_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error))), unwrap_jso(() => successCallback())); _blink.BlinkDatabase.instance.readTransaction_Callback_3_(this, callback, errorCallback, successCallback);
return; return;
} }
if (errorCallback != null) { if (errorCallback != null) {
_blink.BlinkDatabase.instance.readTransaction_Callback_2_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error)))); _blink.BlinkDatabase.instance.readTransaction_Callback_2_(this, callback, errorCallback);
return; return;
} }
_blink.BlinkDatabase.instance.readTransaction_Callback_1_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction)))); _blink.BlinkDatabase.instance.readTransaction_Callback_1_(this, callback);
return; return;
} }
void transaction(SqlTransactionCallback callback, [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) { void transaction(SqlTransactionCallback callback, [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) {
if (successCallback != null) { if (successCallback != null) {
_blink.BlinkDatabase.instance.transaction_Callback_3_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error))), unwrap_jso(() => successCallback())); _blink.BlinkDatabase.instance.transaction_Callback_3_(this, callback, errorCallback, successCallback);
return; return;
} }
if (errorCallback != null) { if (errorCallback != null) {
_blink.BlinkDatabase.instance.transaction_Callback_2_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction))), unwrap_jso((error) => errorCallback(wrap_jso(error)))); _blink.BlinkDatabase.instance.transaction_Callback_2_(this, callback, errorCallback);
return; return;
} }
_blink.BlinkDatabase.instance.transaction_Callback_1_(unwrap_jso(this), unwrap_jso((transaction) => callback(wrap_jso(transaction)))); _blink.BlinkDatabase.instance.transaction_Callback_1_(this, callback);
return; return;
} }
@ -190,21 +171,13 @@ class SqlError extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory SqlError._() { throw new UnsupportedError("Not supported"); } factory SqlError._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static SqlError internalCreateSqlError() {
return new SqlError._internalWrap();
}
factory SqlError._internalWrap() { @Deprecated("Internal Use Only")
return new SqlError.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
SqlError.internal_() { } SqlError.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('SQLError.CONSTRAINT_ERR') @DomName('SQLError.CONSTRAINT_ERR')
@DocsEditable() @DocsEditable()
static const int CONSTRAINT_ERR = 6; static const int CONSTRAINT_ERR = 6;
@ -239,11 +212,11 @@ class SqlError extends DartHtmlDomObject {
@DomName('SQLError.code') @DomName('SQLError.code')
@DocsEditable() @DocsEditable()
int get code => _blink.BlinkSQLError.instance.code_Getter_(unwrap_jso(this)); int get code => _blink.BlinkSQLError.instance.code_Getter_(this);
@DomName('SQLError.message') @DomName('SQLError.message')
@DocsEditable() @DocsEditable()
String get message => _blink.BlinkSQLError.instance.message_Getter_(unwrap_jso(this)); String get message => _blink.BlinkSQLError.instance.message_Getter_(this);
} }
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@ -261,32 +234,24 @@ class SqlResultSet extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory SqlResultSet._() { throw new UnsupportedError("Not supported"); } factory SqlResultSet._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static SqlResultSet internalCreateSqlResultSet() {
return new SqlResultSet._internalWrap();
}
factory SqlResultSet._internalWrap() { @Deprecated("Internal Use Only")
return new SqlResultSet.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
SqlResultSet.internal_() { } SqlResultSet.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('SQLResultSet.insertId') @DomName('SQLResultSet.insertId')
@DocsEditable() @DocsEditable()
int get insertId => _blink.BlinkSQLResultSet.instance.insertId_Getter_(unwrap_jso(this)); int get insertId => _blink.BlinkSQLResultSet.instance.insertId_Getter_(this);
@DomName('SQLResultSet.rows') @DomName('SQLResultSet.rows')
@DocsEditable() @DocsEditable()
SqlResultSetRowList get rows => wrap_jso(_blink.BlinkSQLResultSet.instance.rows_Getter_(unwrap_jso(this))); SqlResultSetRowList get rows => _blink.BlinkSQLResultSet.instance.rows_Getter_(this);
@DomName('SQLResultSet.rowsAffected') @DomName('SQLResultSet.rowsAffected')
@DocsEditable() @DocsEditable()
int get rowsAffected => _blink.BlinkSQLResultSet.instance.rowsAffected_Getter_(unwrap_jso(this)); int get rowsAffected => _blink.BlinkSQLResultSet.instance.rowsAffected_Getter_(this);
} }
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@ -304,32 +269,24 @@ class SqlResultSetRowList extends DartHtmlDomObject with ListMixin<Map>, Immutab
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory SqlResultSetRowList._() { throw new UnsupportedError("Not supported"); } factory SqlResultSetRowList._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static SqlResultSetRowList internalCreateSqlResultSetRowList() {
return new SqlResultSetRowList._internalWrap();
}
factory SqlResultSetRowList._internalWrap() { @Deprecated("Internal Use Only")
return new SqlResultSetRowList.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
SqlResultSetRowList.internal_() { } SqlResultSetRowList.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
@DomName('SQLResultSetRowList.length') @DomName('SQLResultSetRowList.length')
@DocsEditable() @DocsEditable()
int get length => _blink.BlinkSQLResultSetRowList.instance.length_Getter_(unwrap_jso(this)); int get length => _blink.BlinkSQLResultSetRowList.instance.length_Getter_(this);
Map operator[](int index) { Map operator[](int index) {
if (index < 0 || index >= length) if (index < 0 || index >= length)
throw new RangeError.index(index, this); throw new RangeError.index(index, this);
return wrap_jso(_blink.BlinkSQLResultSetRowList.instance.item_Callback_1_(unwrap_jso(this), index)); return _nativeIndexedGetter(index);
} }
Map _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkSQLResultSetRowList.instance.item_Callback_1_(unwrap_jso(this), index)); Map _nativeIndexedGetter(int index) => convertNativeToDart_Dictionary(_blink.BlinkSQLResultSetRowList.instance.item_Callback_1_(this, index));
void operator[]=(int index, Map value) { void operator[]=(int index, Map value) {
throw new UnsupportedError("Cannot assign element of immutable List."); throw new UnsupportedError("Cannot assign element of immutable List.");
@ -371,7 +328,7 @@ class SqlResultSetRowList extends DartHtmlDomObject with ListMixin<Map>, Immutab
@DomName('SQLResultSetRowList.item') @DomName('SQLResultSetRowList.item')
@DocsEditable() @DocsEditable()
Object item(int index) => wrap_jso(_blink.BlinkSQLResultSetRowList.instance.item_Callback_1_(unwrap_jso(this), index)); Object item(int index) => convertNativeToDart_Dictionary(_blink.BlinkSQLResultSetRowList.instance.item_Callback_1_(this, index));
} }
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@ -392,35 +349,27 @@ class SqlTransaction extends DartHtmlDomObject {
// To suppress missing implicit constructor warnings. // To suppress missing implicit constructor warnings.
factory SqlTransaction._() { throw new UnsupportedError("Not supported"); } factory SqlTransaction._() { throw new UnsupportedError("Not supported"); }
@Deprecated("Internal Use Only")
static SqlTransaction internalCreateSqlTransaction() {
return new SqlTransaction._internalWrap();
}
factory SqlTransaction._internalWrap() { @Deprecated("Internal Use Only")
return new SqlTransaction.internal_(); external static Type get instanceRuntimeType;
}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
SqlTransaction.internal_() { } SqlTransaction.internal_() { }
bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
int get hashCode => unwrap_jso(this).hashCode;
void executeSql(String sqlStatement, [List arguments, SqlStatementCallback callback, SqlStatementErrorCallback errorCallback]) { void executeSql(String sqlStatement, [List arguments, SqlStatementCallback callback, SqlStatementErrorCallback errorCallback]) {
if (errorCallback != null) { if (errorCallback != null) {
_blink.BlinkSQLTransaction.instance.executeSql_Callback_4_(unwrap_jso(this), sqlStatement, arguments, unwrap_jso((transaction, resultSet) => callback(wrap_jso(transaction), wrap_jso(resultSet))), unwrap_jso((transaction, error) => errorCallback(wrap_jso(transaction), wrap_jso(error)))); _blink.BlinkSQLTransaction.instance.executeSql_Callback_4_(this, sqlStatement, arguments, callback, errorCallback);
return; return;
} }
if (callback != null) { if (callback != null) {
_blink.BlinkSQLTransaction.instance.executeSql_Callback_3_(unwrap_jso(this), sqlStatement, arguments, unwrap_jso((transaction, resultSet) => callback(wrap_jso(transaction), wrap_jso(resultSet)))); _blink.BlinkSQLTransaction.instance.executeSql_Callback_3_(this, sqlStatement, arguments, callback);
return; return;
} }
if (arguments != null) { if (arguments != null) {
_blink.BlinkSQLTransaction.instance.executeSql_Callback_2_(unwrap_jso(this), sqlStatement, arguments); _blink.BlinkSQLTransaction.instance.executeSql_Callback_2_(this, sqlStatement, arguments);
return; return;
} }
_blink.BlinkSQLTransaction.instance.executeSql_Callback_1_(unwrap_jso(this), sqlStatement); _blink.BlinkSQLTransaction.instance.executeSql_Callback_1_(this, sqlStatement);
return; return;
} }

View file

@ -299,19 +299,6 @@ WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-obje
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning # Please triage this failure. WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning # Please triage this failure.
LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure. LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure.
# Missing concrete implementation of setter 'XPathNSResolver.blink_jsObject' and getter 'XPathNSResolver.blink_jsObject'
# TODO(terry): Dartium only because of implements instead of extends consider fixing by making blink_jsObject private
# with private wrap_jso and unwrap_jso in each library that delegates to the public wrap/unwrap_jso.
LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/attr-namespace_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/attr-namespace_t02: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/node-name-case-sensitivity_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/node-name-case-sensitivity_t02: StaticWarning # Please triage this failure.
LayoutTests/fast/xpath/py-dom-xpath/data_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/svg/getbbox_t01: StaticWarning # Please triage this failure.
# co19 roll to Sep 29 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0) # co19 roll to Sep 29 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
Language/Classes/Abstract_Instance_Members/invocation_t03: MissingStaticWarning # Please triage this failure. Language/Classes/Abstract_Instance_Members/invocation_t03: MissingStaticWarning # Please triage this failure.
Language/Classes/Abstract_Instance_Members/invocation_t04: MissingStaticWarning # Please triage this failure. Language/Classes/Abstract_Instance_Members/invocation_t04: MissingStaticWarning # Please triage this failure.

View file

@ -7,16 +7,11 @@ cross_frame_test: Skip # Test reloads itself. Issue 18558
[ $compiler == none && ($runtime == dartium || $runtime == drt) ] [ $compiler == none && ($runtime == dartium || $runtime == drt) ]
js_array_test: Skip # Dartium JSInterop failure
mirrors_js_typed_interop_test: Fail # Missing expected failure (Issue 25044) mirrors_js_typed_interop_test: Fail # Missing expected failure (Issue 25044)
js_typed_interop_side_cast_exp_test: Fail, OK # tests dart2js-specific behavior. js_typed_interop_side_cast_exp_test: Fail, OK # tests dart2js-specific behavior.
cross_domain_iframe_test: RuntimeError # Dartium JSInterop failure cross_domain_iframe_test: RuntimeError # Dartium JSInterop failure
indexeddb_2_test: Fail # Dartium JSInterop failure. Identity preservation on array deferred copy.
js_test/transferrables: RuntimeError # Dartium JSInterop failure
js_test/JsArray: RuntimeError # Dartium JSInterop failure
native_gc_test: Skip # Dartium JSInterop failure native_gc_test: Skip # Dartium JSInterop failure
transferables_test: RuntimeError # Dartium JSInterop failure
[ $compiler == none && ($runtime == drt || $runtime == dartium ) ] [ $compiler == none && ($runtime == drt || $runtime == dartium ) ]
worker_api_test: Fail # Issue 10223 worker_api_test: Fail # Issue 10223

View file

@ -511,8 +511,10 @@ main() {
expect(descriptor.value, equals("a")); expect(descriptor.value, equals("a"));
expect(descriptor.writable, isTrue); expect(descriptor.writable, isTrue);
expect(descriptor.enumerable, isTrue); // TODO(jacobr): commented out until https://github.com/dart-lang/sdk/issues/26128
expect(descriptor.configurable, isTrue); // is fixed.
// expect(descriptor.enumerable, isTrue);
// expect(descriptor.configurable, isTrue);
descriptor = getOwnPropertyDescriptor(list, "length"); descriptor = getOwnPropertyDescriptor(list, "length");
expect(descriptor.value, equals(2)); expect(descriptor.value, equals(2));

View file

@ -240,34 +240,31 @@ main() {
expect(identical(c1, c2), isTrue); expect(identical(c1, c2), isTrue);
}); });
/*
TODO(jacobr): enable this test when dartium supports maintaining proxy
equality.
test('identical JS objects should have identical proxies', () { test('identical JS objects should have identical proxies', () {
var o1 = new JsObject(context['Foo'], [1]); var o1 = new JsObject(context['Foo'], [1]);
context['f1'] = o1; context['f1'] = o1;
var o2 = context['f1']; var o2 = context['f1'];
expect(equals(o1, o2), isTrue); expect(identical(o1, o2), isTrue);
}); });
/*
TODO(jacobr): enable this test when dartium supports maintaining proxy
equality.
test('identical Dart objects should have identical proxies', () { test('identical Dart objects should have identical proxies', () {
var o1 = new TestDartObject(); var o1 = new TestDartObject();
expect(context.callMethod('identical', [o1, o1]), isTrue); expect(context.callMethod('identical', [o1, o1]), isTrue);
}); });
test('identical Dart functions should have identical proxies', () {
var f1 = () => print("I'm a Function!");
expect(context.callMethod('identical', [f1, f1]), isTrue);
});
*/ */
// TODO(jacobr): switch from equals to indentical when dartium supports test('identical Dart functions should have identical proxies', () {
// maintaining proxy equality. var f1 = allowInterop(() => print("I'm a Function!"));
test('identical JS functions should have equal proxies', () { expect(context.callMethod('identical', [f1, f1]), isTrue);
});
test('identical JS functions should have identical proxies', () {
var f1 = context['Object']; var f1 = context['Object'];
var f2 = context['Object']; var f2 = context['Object'];
expect(f1, equals(f2)); expect(identical(f1, f2), isTrue);
}); });
// TODO(justinfagnani): old tests duplicate checks above, remove // TODO(justinfagnani): old tests duplicate checks above, remove
@ -454,7 +451,7 @@ main() {
expect(context['razzle'].apply([]), equals(42)); expect(context['razzle'].apply([]), equals(42));
}); });
test('JsFunction.apply on a function that uses "this"', () { test('JsFunction.apply on a function that uses this', () {
var object = new Object(); var object = new Object();
expect(context['returnThis'].apply([], thisArg: object), same(object)); expect(context['returnThis'].apply([], thisArg: object), same(object));
}); });
@ -517,7 +514,7 @@ main() {
test('pass Array to JS', () { test('pass Array to JS', () {
context['a'] = [1, 2, 3]; context['a'] = [1, 2, 3];
expect(context.callMethod('isPropertyInstanceOf', expect(context.callMethod('isPropertyInstanceOf',
['a', context['Array']]), isFalse); ['a', context['Array']]), isTrue);
var a = context['a']; var a = context['a'];
expect(a, new isInstanceOf<List>()); expect(a, new isInstanceOf<List>());
expect(a, isNot(new isInstanceOf<JsArray>())); expect(a, isNot(new isInstanceOf<JsArray>()));

View file

@ -18,7 +18,7 @@ main() {
}); });
test("Access through dart:html", () { test("Access through dart:html", () {
var dartPerformance = wrap_jso(js.context['performance']); var dartPerformance = js.JsNative.toTypedObject(js.context['performance']);
var dartEntries = dartPerformance.getEntries(); var dartEntries = dartPerformance.getEntries();
dartEntries.forEach((x) { dartEntries.forEach((x) {
expect(x is PerformanceEntry, isTrue); expect(x is PerformanceEntry, isTrue);

View file

@ -9,7 +9,7 @@ execfile(os.path.join(path, 'src', 'dart', 'tools', 'deps', 'dartium.deps', 'DEP
vars.update({ vars.update({
"dartium_chromium_commit": "b16942297fc65fd478c6f46afd1c3aaecde77009", "dartium_chromium_commit": "b16942297fc65fd478c6f46afd1c3aaecde77009",
"dartium_webkit_commit": "140b0cde50780b4d76d33260d3154946ca55ee08", "dartium_webkit_commit": "5da3130867ba3d07759388e4e5166facf6cf8f94",
"chromium_base_revision": "338390", "chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and # We use mirrors of all github repos to guarantee reproducibility and

View file

@ -16927,12 +16927,24 @@
"blitFramebuffer": { "blitFramebuffer": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
"bufferByteData": {
"support_level": "untriaged"
},
"bufferData": { "bufferData": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
"bufferDataTyped": {
"support_level": "untriaged"
},
"bufferSubByteData": {
"support_level": "untriaged"
},
"bufferSubData": { "bufferSubData": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
"bufferSubDataTyped": {
"support_level": "untriaged"
},
"canvas": { "canvas": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
@ -17365,6 +17377,18 @@
"texImage2D": { "texImage2D": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
"texImage2DCanvas": {
"support_level": "untriaged"
},
"texImage2DImage": {
"support_level": "untriaged"
},
"texImage2DImageData": {
"support_level": "untriaged"
},
"texImage2DVideo": {
"support_level": "untriaged"
},
"texImage3D": { "texImage3D": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
@ -17383,6 +17407,18 @@
"texSubImage2D": { "texSubImage2D": {
"support_level": "untriaged" "support_level": "untriaged"
}, },
"texSubImage2DCanvas": {
"support_level": "untriaged"
},
"texSubImage2DImage": {
"support_level": "untriaged"
},
"texSubImage2DImageData": {
"support_level": "untriaged"
},
"texSubImage2DVideo": {
"support_level": "untriaged"
},
"texSubImage3D": { "texSubImage3D": {
"support_level": "untriaged" "support_level": "untriaged"
}, },

View file

@ -154,7 +154,7 @@ $endif
$if DARTIUM $if DARTIUM
bool _hasProperty(String propertyName) => bool _hasProperty(String propertyName) =>
$if JSINTEROP $if JSINTEROP
_blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(unwrap_jso(this), propertyName) != null; _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(this, propertyName);
$else $else
_blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName); _blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName);
$endif $endif

View file

@ -7,9 +7,85 @@
"""Generates sdk/lib/_blink/dartium/_blink_dartium.dart file.""" """Generates sdk/lib/_blink/dartium/_blink_dartium.dart file."""
import os import os
from sets import Set
from generator import AnalyzeOperation, AnalyzeConstructor from generator import AnalyzeOperation, AnalyzeConstructor
# This is list of all methods with native c++ implementations
# If performing a dartium merge, the best practice is to comment out this list,
# ensure everything runs, and then uncomment this list which might possibly
# introduce breaking changes due to changes to these method signatures.
_js_custom_members = Set([
'Document.createElement',
'Element.id',
'Element.tagName',
'Element.className',
'Element.setAttribute',
'Element.getAttribute',
# Consider adding this method so there is a fast path to access only
# element children.
# 'NonDocumentTypeChildNode.nextElementSibling',
'Node.appendChild', # actually not removed, just native implementation.
'Node.cloneNode',
'Node.insertBefore',
'Node.lastChild',
'Node.firstChild',
'Node.parentElement',
'Node.parentNode',
'Node.childNodes',
'Node.removeChild',
'Node.contains',
'Node.nextSibling',
'Node.previousSibling',
'ChildNode.remove',
'Document.createTextNode',
'Window.location',
'Location.href',
'Node.querySelector',
'HTMLElement.hidden',
'HTMLElement.style',
'Element.attributes',
'Window.innerWidth',
'NodeList.length',
'NodeList.item',
'ParentNode.children',
'ParentNode.firstElementChild',
'ParentNode.lastElementChild',
'Event.target',
'MouseEvent.clientY',
'MouseEvent.clientX',
'Node.nodeType',
'Node.textContent',
'HTMLCollection.length',
'HTMLCollection.item',
'Node.lastElementChild',
'Node.firstElementChild',
'HTMLElement_tabIndex',
'Element.clientWidth',
'Element.clientHeight',
'Document.body',
'Element.removeAttribute',
'Element.getBoundingClientRect',
'CSSStyleDeclaration.getPropertyValue',
'CSSStyleDeclaration.setProperty',
'CSSStyleDeclaration.__propertyQuery__',
# TODO(jacobr): consider implementing these methods as well as they show
# up in benchmarks for some sample applications.
#'Document.createEvent',
#'Document.initEvent',
#'EventTarget.dispatchEvent',
])
# Uncomment out this line to short circuited native methods and run all of
# dart:html through JS interop except for createElement which is slightly more
# tightly natively wired.
# _js_custom_members = Set([])
HEADER = """/* Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file HEADER = """/* Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
* for details. All rights reserved. Use of this source code is governed by a * for details. All rights reserved. Use of this source code is governed by a
* BSD-style license that can be found in the LICENSE file. * BSD-style license that can be found in the LICENSE file.
@ -50,13 +126,14 @@ class Blink_Utils {
static register(document, tag, customType, extendsTagName) native "Utils_register"; static register(document, tag, customType, extendsTagName) native "Utils_register";
static createElement(document, tagName) native "Utils_createElement"; // Defines an interceptor if there is an appropriate JavaScript prototype to define it on.
// In any case, returns a typed JS wrapper compatibile with dart:html and the new
static constructElement(element_type, jsObject) native "Utils_constructor_create"; // typed JS Interop.
static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
// This method will throw if the element isn't actually a real Element.
static initializeCustomElement(element) native "Utils_initializeCustomElement"; static initializeCustomElement(element) native "Utils_initializeCustomElement";
static changeElementWrapper(element, type) native "Utils_changeElementWrapper";
} }
class Blink_DOMWindowCrossFrame { class Blink_DOMWindowCrossFrame {
@ -106,9 +183,63 @@ class Blink_DOMStringMap {
} }
// Calls through JsNative but returns DomException instead of error strings. // Calls through JsNative but returns DomException instead of error strings.
class Stats {
Stats(this.name) {
counts = new Map<String, int>();
}
String name;
Map<String, int> counts;
clear() {
counts.clear();
}
track(String v) {
counts[v] = counts.putIfAbsent(v, ()=> 0) + 1;
}
toString() {
StringBuffer sb = new StringBuffer();
sb.write('================');
sb.write('$name ${counts.length}');
var keys = counts.keys.toList();
keys.sort((a,b) => counts[b].compareTo(counts[a]));
for (var key in keys) {
print("$key => ${counts[key]}");
}
sb.write('---------------');
sb.write('================');
return sb;
}
}
bool TRACK_STATS = true;
dumpStats() {
print("------------ STATS ----------------");
print(Blink_JsNative_DomException.getPropertyStats.toString());
print(Blink_JsNative_DomException.setPropertyStats.toString());
print(Blink_JsNative_DomException.callMethodStats.toString());
print(Blink_JsNative_DomException.constructorStats.toString());
print("-----------------------------------");
}
clearStats() {
Blink_JsNative_DomException.getPropertyStats.clear();
Blink_JsNative_DomException.setPropertyStats.clear();
Blink_JsNative_DomException.callMethodStats.clear();
Blink_JsNative_DomException.constructorStats.clear();
}
class Blink_JsNative_DomException { class Blink_JsNative_DomException {
static getProperty(js.JsObject o, name) { static var getPropertyStats = new Stats('get property');
static var setPropertyStats = new Stats('set property');
static var callMethodStats = new Stats('call method');
static var constructorStats = new Stats('constructor');
static var constructors = new Map<String, dynamic>();
static getProperty(o, String name) {
try { try {
if (TRACK_STATS) getPropertyStats.track(name);
return js.JsNative.getProperty(o, name); return js.JsNative.getProperty(o, name);
} catch (e) { } catch (e) {
// Re-throw any errors (returned as a string) as a DomException. // Re-throw any errors (returned as a string) as a DomException.
@ -116,8 +247,51 @@ class Blink_JsNative_DomException {
} }
} }
static callMethod(js.JsObject o, String method, List args) { static propertyQuery(o, String name) {
try { try {
if (TRACK_STATS) getPropertyStats.track('__propertyQuery__');
return js.JsNative.getProperty(o, name);
} catch (e) {
// Re-throw any errors (returned as a string) as a DomException.
throw new DomException.jsInterop(e);
}
}
static callConstructor0(String name) {
try {
if (TRACK_STATS) constructorStats.track(name);
var constructor = constructors.putIfAbsent(name, () => js.context[name]);
return js.JsNative.callConstructor0(constructor);
} catch (e) {
// Re-throw any errors (returned as a string) as a DomException.
throw new DomException.jsInterop(e);
}
}
static callConstructor(String name, List args) {
try {
if (TRACK_STATS) constructorStats.track(name);
var constructor = constructors.putIfAbsent(name, () => js.context[name]);
return js.JsNative.callConstructor(constructor, args);
} catch (e) {
// Re-throw any errors (returned as a string) as a DomException.
throw new DomException.jsInterop(e);
}
}
static setProperty(o, String name, value) {
try {
if (TRACK_STATS) setPropertyStats.track(name);
return js.JsNative.setProperty(o, name, value);
} catch (e) {
// Re-throw any errors (returned as a string) as a DomException.
throw new DomException.jsInterop(e);
}
}
static callMethod(o, String method, List args) {
try {
if (TRACK_STATS) callMethodStats.track(method);
return js.JsNative.callMethod(o, method, args); return js.JsNative.callMethod(o, method, args);
} catch (e) { } catch (e) {
// Re-throw any errors (returned as a string) as a DomException. // Re-throw any errors (returned as a string) as a DomException.
@ -137,38 +311,73 @@ CLASS_DEFINITION_EXTENDS = """class Blink%s extends Blink%s {
""" """
#(interface_name) #(interface_name)
CONSTRUCTOR_0 = ' constructorCallback_0_() => new js.JsObject(Blink_JsNative_DomException.getProperty(js.context, "%s"), []);\n\n'
#
CONSTRUCTOR_0 = [' constructorCallback_0_()',
' => Blink_JsNative_DomException.callConstructor0("%s");\n\n',
' native "Blink_Constructor_%s";\n\n']
#(argument_count, arguments, interface_name, arguments) #(argument_count, arguments, interface_name, arguments)
CONSTRUCTOR_ARGS = ' constructorCallback_%s_(%s) => new js.JsObject(Blink_JsNative_DomException.getProperty(js.context, "%s"), [%s]);\n\n' CONSTRUCTOR_ARGS = [' constructorCallback_%s_(%s)',
' => Blink_JsNative_DomException.callConstructor("%s", [%s]);\n\n',
' native "Blink_Constructor_Args_%s" /* %s */;\n\n']
#(attribute_name, attribute_name) #(attribute_name, attribute_name)
ATTRIBUTE_GETTER = ' %s_Getter_(mthis) => Blink_JsNative_DomException.getProperty(mthis, "%s");\n\n' ATTRIBUTE_GETTER = [' %s_Getter_(mthis)',
ATTRIBUTE_SETTER = ' %s_Setter_(mthis, __arg_0) => mthis["%s"] = __arg_0;\n\n' ' => Blink_JsNative_DomException.getProperty(mthis /* %s */, "%s");\n\n',
' native "Blink_Getter_%s_%s";\n\n'
]
ATTRIBUTE_SETTER = [' %s_Setter_(mthis, __arg_0)',
' => Blink_JsNative_DomException.setProperty(mthis /* %s */, "%s", __arg_0);\n\n',
' native "Blink_Setter_%s_%s";\n\n'
]
#(operation_name, operationName) #(operation_name, operationName)
OPERATION_0 = ' %s_Callback_0_(mthis) => Blink_JsNative_DomException.callMethod(mthis, "%s", []);\n\n' OPERATION_0 = [' %s_Callback_0_(mthis)',
' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", []);\n\n',
' native "Blink_Operation_0_%s_%s";\n\n'
]
# getter, setter, deleter and propertyQuery code # getter, setter, deleter and propertyQuery code
OPERATION_1 = ' $%s_Callback_1_(mthis, __arg_0) => Blink_JsNative_DomException.callMethod(mthis, "%s", [__arg_0]);\n\n' OPERATION_1 = [' $%s_Callback_1_(mthis, __arg_0)',
OPERATION_2 = ' $%s_Callback_2_(mthis, __arg_0, __arg_1) => Blink_JsNative_DomException.callMethod(mthis, "%s", [__arg_0, __arg_1]);\n\n' ' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [__arg_0]);\n\n',
OPERATION_PQ = ' $%s_Callback_1_(mthis, __arg_0) => mthis[__arg_0];\n\n' ' native "Blink_Operation_1_%s_%s";\n\n'
]
OPERATION_2 = [' $%s_Callback_2_(mthis, __arg_0, __arg_1)',
' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [__arg_0, __arg_1]);\n\n',
' native "Blink_Operation_2_%s_%s";\n\n']
OPERATION_PQ = [' $%s_Callback_1_(mthis, __arg_0)',
' => Blink_JsNative_DomException.propertyQuery(mthis, __arg_0); /* %s */ \n\n',
' native "Blink_Operation_PQ_%s";\n\n']
#(operation_name, argument_count, arguments, operation_name, arguments) #(operation_name, argument_count, arguments, operation_name, arguments)
ARGUMENT_NUM = "__arg_%s" ARGUMENT_NUM = "__arg_%s"
OPERATION_ARGS = ' %s_Callback_%s_(mthis, %s) => Blink_JsNative_DomException.callMethod(mthis, "%s", [%s]);\n\n' OPERATION_ARGS = [' %s_Callback_%s_(mthis, %s)',
' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [%s]);\n\n',
' native "Blink_Operation_%s_%s"; /* %s */\n\n']
# get class property to make static call. # get class property to make static call.
CLASS_STATIC = 'Blink_JsNative_DomException.getProperty(js.context, "%s")' CLASS_STATIC = 'Blink_JsNative_DomException.getProperty(js.context, "%s")'
# name, classname_getproperty, name # name, classname_getproperty, name
STATIC_ATTRIBUTE_GETTER = ' %s_Getter_() => Blink_JsNative_DomException.getProperty(%s, "%s");\n\n' STATIC_ATTRIBUTE_GETTER = [' %s_Getter_()',
' => Blink_JsNative_DomException.getProperty(%s /* %s */, "%s");\n\n',
' /* %s */ native "Blink_Static_getter_%s_%s"']
# name, classname_getproperty, name # name, classname_getproperty, name
STATIC_OPERATION_0 = ' %s_Callback_0_() => Blink_JsNative_DomException.callMethod(%s, "%s", []);\n\n' STATIC_OPERATION_0 = [' %s_Callback_0_()',
' => Blink_JsNative_DomException.callMethod(%s /* %s */, "%s", []);\n\n',
' /* %s */ native "Blink_Static_Operation_0_%s_%s']
# name, argsCount, args, classname_getproperty, name, args # name, argsCount, args, classname_getproperty, name, args
STATIC_OPERATION_ARGS = ' %s_Callback_%s_(%s) => Blink_JsNative_DomException.callMethod(%s, "%s", [%s]);\n\n' STATIC_OPERATION_ARGS = [' %s_Callback_%s_(%s)',
' => Blink_JsNative_DomException.callMethod(%s /* %s */, "%s", [%s]);\n\n',
' /* %s */ native "Blink_Static_Operations_%s_%s" /* %s */ \n\n']
CLASS_DEFINITION_END = """} CLASS_DEFINITION_END = """}
@ -197,6 +406,27 @@ constructor_renames = {
def rename_constructor(name): def rename_constructor(name):
return constructor_renames[name] if name in constructor_renames else name return constructor_renames[name] if name in constructor_renames else name
def _Find_Match(interface_id, member, member_prefix, candidates):
member_name = interface_id + '.' + member
if member_name in candidates:
return member_name
member_name = interface_id + '.' + member_prefix + member
if member_name in candidates:
return member_name
member_name = interface_id + '.*'
if member_name in candidates:
return member_name
def _Is_Native(interface, member):
return _Find_Match(interface, member, '', _js_custom_members)
def Select_Stub(template, is_native):
if is_native:
return template[0] + template[2]
else:
return template[0] + template[1]
def Generate_Blink(output_dir, database, type_registry): def Generate_Blink(output_dir, database, type_registry):
blink_filename = os.path.join(output_dir, '_blink_dartium.dart') blink_filename = os.path.join(output_dir, '_blink_dartium.dart')
blink_file = open(blink_filename, 'w') blink_file = open(blink_filename, 'w')
@ -226,7 +456,7 @@ def Generate_Blink(output_dir, database, type_registry):
_Emit_Blink_Constructors(blink_file, analyzed_constructors) _Emit_Blink_Constructors(blink_file, analyzed_constructors)
elif 'Constructor' in interface.ext_attrs: elif 'Constructor' in interface.ext_attrs:
# Zero parameter constructor. # Zero parameter constructor.
blink_file.write(CONSTRUCTOR_0 % rename_constructor(name)) blink_file.write(Select_Stub(CONSTRUCTOR_0, _Is_Native(name, 'constructor')) % rename_constructor(name))
_Process_Attributes(blink_file, interface, interface.attributes) _Process_Attributes(blink_file, interface, interface.attributes)
_Process_Operations(blink_file, interface, interface.operations) _Process_Operations(blink_file, interface, interface.operations)
@ -250,27 +480,29 @@ def _Emit_Blink_Constructors(blink_file, analyzed_constructors):
for callback_index in range(arg_min_count, arg_max_count): for callback_index in range(arg_min_count, arg_max_count):
if callback_index == 0: if callback_index == 0:
blink_file.write(CONSTRUCTOR_0 % (rename_constructor(name))) blink_file.write(Select_Stub(CONSTRUCTOR_0, _Is_Native(name, 'constructor')) % (rename_constructor(name)))
else: else:
arguments = [] arguments = []
for i in range(0, callback_index): for i in range(0, callback_index):
arguments.append(ARGUMENT_NUM % i) arguments.append(ARGUMENT_NUM % i)
argument_list = ', '.join(arguments) argument_list = ', '.join(arguments)
blink_file.write(CONSTRUCTOR_ARGS % (callback_index, argument_list, rename_constructor(name), argument_list)) blink_file.write(
Select_Stub(CONSTRUCTOR_ARGS, _Is_Native(name, 'constructor')) % (callback_index, argument_list, rename_constructor(name), argument_list))
def _Process_Attributes(blink_file, interface, attributes): def _Process_Attributes(blink_file, interface, attributes):
# Emit an interface's attributes and operations. # Emit an interface's attributes and operations.
for attribute in sorted(attributes, ConstantOutputOrder): for attribute in sorted(attributes, ConstantOutputOrder):
name = attribute.id name = attribute.id
is_native = _Is_Native(interface.id, name)
if attribute.is_read_only: if attribute.is_read_only:
if attribute.is_static: if attribute.is_static:
class_property = CLASS_STATIC % interface.id class_property = CLASS_STATIC % interface.id
blink_file.write(STATIC_ATTRIBUTE_GETTER % (name, class_property, name)) blink_file.write(Select_Stub(STATIC_ATTRIBUTE_GETTER, is_native) % (name, class_property, interface.id, name))
else: else:
blink_file.write(ATTRIBUTE_GETTER % (name, name)) blink_file.write(Select_Stub(ATTRIBUTE_GETTER, is_native) % (name, interface.id, name))
else: else:
blink_file.write(ATTRIBUTE_GETTER % (name, name)) blink_file.write(Select_Stub(ATTRIBUTE_GETTER, is_native) % (name, interface.id, name))
blink_file.write(ATTRIBUTE_SETTER % (name, name)) blink_file.write(Select_Stub(ATTRIBUTE_SETTER, is_native) % (name, interface.id, name))
def _Process_Operations(blink_file, interface, operations): def _Process_Operations(blink_file, interface, operations):
analyzeOperations = [] analyzeOperations = []
@ -292,6 +524,7 @@ def _Emit_Blink_Operation(blink_file, interface, analyzeOperations):
analyzed = AnalyzeOperation(interface, analyzeOperations) analyzed = AnalyzeOperation(interface, analyzeOperations)
(arg_min_count, arg_max_count) = generate_parameter_entries(analyzed.param_infos) (arg_min_count, arg_max_count) = generate_parameter_entries(analyzed.param_infos)
name = analyzed.js_name name = analyzed.js_name
is_native = _Is_Native(interface.id, name)
operation = analyzeOperations[0] operation = analyzeOperations[0]
if (name.startswith('__') and \ if (name.startswith('__') and \
@ -299,13 +532,13 @@ def _Emit_Blink_Operation(blink_file, interface, analyzeOperations):
'setter' in operation.specials or \ 'setter' in operation.specials or \
'deleter' in operation.specials)): 'deleter' in operation.specials)):
if name == '__propertyQuery__': if name == '__propertyQuery__':
blink_file.write(OPERATION_PQ % (name)) blink_file.write(Select_Stub(OPERATION_PQ, is_native) % (name, interface.id))
else: else:
arg_min_count = arg_max_count arg_min_count = arg_max_count
if arg_max_count == 2: if arg_max_count == 2:
blink_file.write(OPERATION_1 % (name, name)) blink_file.write(Select_Stub(OPERATION_1, is_native) % (name, interface.id, name))
elif arg_max_count == 3: elif arg_max_count == 3:
blink_file.write(OPERATION_2 % (name, name)) blink_file.write(Select_Stub(OPERATION_2, is_native) % (name, interface.id, name))
else: else:
print "FATAL ERROR: _blink emitter operator %s.%s" % (interface.id, name) print "FATAL ERROR: _blink emitter operator %s.%s" % (interface.id, name)
exit exit
@ -316,9 +549,9 @@ def _Emit_Blink_Operation(blink_file, interface, analyzeOperations):
if callback_index == 0: if callback_index == 0:
if operation.is_static: if operation.is_static:
class_property = CLASS_STATIC % interface.id class_property = CLASS_STATIC % interface.id
blink_file.write(STATIC_OPERATION_0 % (name, class_property, name)) blink_file.write(Select_Stub(STATIC_OPERATION_0, is_native) % (name, class_property, interface.id, name))
else: else:
blink_file.write(OPERATION_0 % (name, name)) blink_file.write(Select_Stub(OPERATION_0, is_native) % (name, interface.id, name))
else: else:
arguments = [] arguments = []
for i in range(0, callback_index): for i in range(0, callback_index):
@ -326,6 +559,6 @@ def _Emit_Blink_Operation(blink_file, interface, analyzeOperations):
argument_list = ', '.join(arguments) argument_list = ', '.join(arguments)
if operation.is_static: if operation.is_static:
class_property = CLASS_STATIC % interface.id class_property = CLASS_STATIC % interface.id
blink_file.write(STATIC_OPERATION_ARGS % (name, callback_index, argument_list, class_property, name, argument_list)) blink_file.write(Select_Stub(STATIC_OPERATION_ARGS, is_native) % (name, callback_index, argument_list, class_property, interface.id, name, argument_list))
else: else:
blink_file.write(OPERATION_ARGS % (name, callback_index, argument_list, name, argument_list)) blink_file.write(Select_Stub(OPERATION_ARGS, is_native) % (name, callback_index, argument_list, interface.id, name, argument_list))

View file

@ -543,29 +543,28 @@ class OperationInfo(object):
type_id = p.type_id type_id = p.type_id
# Unwrap the type to get the JsObject if Type is: # Unwrap the type to get the JsObject if Type is:
# #
# - known IDL type
# - type_id is None then it's probably a union type or overloaded # - type_id is None then it's probably a union type or overloaded
# it's a dynamic/any type # it's a dynamic/any type
# - type is Object # - type is Object
# #
# JsObject maybe stored in the Dart class.
if (wrap_unwrap_type_blink(type_id, type_registry)): if (wrap_unwrap_type_blink(type_id, type_registry)):
type_is_callback = self.isCallback(type_registry, type_id) type_is_callback = self.isCallback(type_registry, type_id)
if (dart_js_interop and type_id == 'EventListener' and if (dart_js_interop and type_id == 'EventListener' and
self.name in ['addEventListener', 'removeEventListener']): self.name in ['addEventListener', 'removeEventListener']):
# Events fired need use a JsFunction not a anonymous closure to # Events fired need use a JSFunction not a anonymous closure to
# insure the event can really be removed. # insure the event can really be removed.
parameters.append('unwrap_jso(js.allowInterop(%s))' % p.name) parameters.append('js.allowInterop(%s)' % p.name)
elif dart_js_interop and type_id == 'FontFaceSetForEachCallback': # These commented out cases don't actually generate any code.
# elif dart_js_interop and type_id == 'FontFaceSetForEachCallback':
# forEach is supported in the DOM for FontFaceSet as it iterates # forEach is supported in the DOM for FontFaceSet as it iterates
# over the Javascript Object the callback parameters are also # over the Javascript Object the callback parameters are also
# Javascript objects and must be wrapped. # Javascript objects and must be wrapped.
parameters.append('unwrap_jso((fontFace, fontFaceAgain, set) => %s(wrap_jso(fontFace), wrap_jso(fontFaceAgain), wrap_jso(set)))' % p.name) # parameters.append('(fontFace, fontFaceAgain, set) => %s(fontFace, fontFaceAgain, wrap_jso(set))' % p.name)
elif dart_js_interop and type_id == 'HeadersForEachCallback': # elif dart_js_interop and type_id == 'HeadersForEachCallback':
# forEach is supported in the DOM for Headers as it iterates # forEach is supported in the DOM for Headers as it iterates
# over the Javascript Object the callback parameters are also # over the Javascript Object the callback parameters are also
# Javascript objects and must be wrapped. # Javascript objects and must be wrapped.
parameters.append('unwrap_jso((String value, String key, map) => %s(value, key, wrap_jso(map)))' % p.name) # parameters.append('(String value, String key, map) => %s(value, key, wrap_jso(map))' % p.name)
elif dart_js_interop and type_is_callback and not(isRemoveOperation): elif dart_js_interop and type_is_callback and not(isRemoveOperation):
# Any remove operation that has a a callback doesn't need wrapping. # Any remove operation that has a a callback doesn't need wrapping.
# TODO(terry): Kind of hacky but handles all the cases we care about # TODO(terry): Kind of hacky but handles all the cases we care about
@ -579,15 +578,15 @@ class OperationInfo(object):
dart_type = type_registry.DartType(callback_arg.type.id) + ' ' dart_type = type_registry.DartType(callback_arg.type.id) + ' '
callback_args_decl.append('%s%s' % (dart_type, callback_arg.id)) callback_args_decl.append('%s%s' % (dart_type, callback_arg.id))
if wrap_unwrap_type_blink(callback_arg.type.id, type_registry): if wrap_unwrap_type_blink(callback_arg.type.id, type_registry):
callback_args_call.append('wrap_jso(%s)' % callback_arg.id) callback_args_call.append(callback_arg.id)
else: else:
callback_args_call.append(callback_arg.id) callback_args_call.append(callback_arg.id)
parameters.append('unwrap_jso((%s) => %s(%s))' % parameters.append('(%s) => %s(%s)' %
(", ".join(callback_args_decl), (", ".join(callback_args_decl),
p.name, p.name,
", ".join(callback_args_call))) ", ".join(callback_args_call)))
else: else:
parameters.append('unwrap_jso(%s)' % p.name) parameters.append(p.name)
else: else:
if dart_js_interop: if dart_js_interop:
conversion = backend._InputConversion(p.type_id, self.declared_name) conversion = backend._InputConversion(p.type_id, self.declared_name)
@ -1495,6 +1494,8 @@ def get_list_type(return_type):
# Get the list type NNNN inside of List<NNNN> # Get the list type NNNN inside of List<NNNN>
return return_type[5:-1] if isList(return_type) else return_type return return_type[5:-1] if isList(return_type) else return_type
# TODO(jacobr): remove these obsolete methods as we don't actually
# perform any wrapping.
def wrap_unwrap_list_blink(return_type, type_registry): def wrap_unwrap_list_blink(return_type, type_registry):
"""Return True if the type is the list type is a blink know """Return True if the type is the list type is a blink know
type e.g., List<Node>, List<FontFace>, etc.""" type e.g., List<Node>, List<FontFace>, etc."""
@ -1508,14 +1509,9 @@ def wrap_unwrap_type_blink(return_type, type_registry):
unwrap_jso""" unwrap_jso"""
if return_type and return_type.startswith('Html'): if return_type and return_type.startswith('Html'):
return_type = return_type.replace('Html', 'HTML', 1) return_type = return_type.replace('Html', 'HTML', 1)
return (type_registry.HasInterface(return_type) or not(return_type) or return (not(return_type) or
return_type == 'Object' or return_type == 'Object' or
return_type == 'dynamic' or return_type == 'dynamic')
return_type == 'Future' or
return_type == 'SqlDatabase' or # renamed to Database
return_type == 'HTMLElement' or
return_type == 'MutationObserver' or
(return_type.endswith('[]') and return_type != 'DOMString[]'))
def wrap_type_blink(return_type, type_registry): def wrap_type_blink(return_type, type_registry):
"""Returns True if the type is a blink type that requires wrap_jso but """Returns True if the type is a blink type that requires wrap_jso but

View file

@ -626,7 +626,7 @@ class HtmlDartGenerator(object):
(factory_params, converted_arguments) = self._ConvertArgumentTypes( (factory_params, converted_arguments) = self._ConvertArgumentTypes(
stmts_emitter, arguments, argument_count, constructor_info) stmts_emitter, arguments, argument_count, constructor_info)
args = ', '.join(converted_arguments) args = ', '.join(converted_arguments)
call_template = 'wrap_jso($FACTORY_NAME($FACTORY_PARAMS))' call_template = '$FACTORY_NAME($FACTORY_PARAMS)'
else: else:
qualified_name = emitter.Format( qualified_name = emitter.Format(
'$FACTORY.$NAME', '$FACTORY.$NAME',

View file

@ -586,7 +586,7 @@ class HtmlDartInterfaceGenerator(object):
class_modifiers = '' class_modifiers = ''
else: else:
# For Dartium w/ JsInterop these suppressed interfaces are needed to # For Dartium w/ JsInterop these suppressed interfaces are needed to
# instanciate the internal classes when wrap_jso is called for a JS object. # instanciate the internal classes.
if (self._renamer.ShouldSuppressInterface(self._interface) and if (self._renamer.ShouldSuppressInterface(self._interface) and
not(isinstance(self._backend, Dart2JSBackend)) and not(isinstance(self._backend, Dart2JSBackend)) and
self._options.dart_js_interop): self._options.dart_js_interop):
@ -600,21 +600,10 @@ class HtmlDartInterfaceGenerator(object):
class_name = self._interface_type_info.implementation_name() class_name = self._interface_type_info.implementation_name()
js_interop_equivalence_op = \
' bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);\n' \
+ ' int get hashCode => unwrap_jso(this).hashCode;\n'
# ClientRect overrides the equivalence operator.
if interface_name == 'ClientRect' or interface_name == 'DomRectReadOnly':
js_interop_equivalence_op = ''
js_interop_wrapper = ''' js_interop_wrapper = '''
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
static {0} internalCreate{0}() {{ external static Type get instanceRuntimeType;
return new {0}._internalWrap();
}}
external factory {0}._internalWrap();
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
{0}.internal_() : super.internal_(); {0}.internal_() : super.internal_();
@ -622,19 +611,13 @@ class HtmlDartInterfaceGenerator(object):
'''.format(class_name) '''.format(class_name)
if base_class == 'NativeFieldWrapperClass2' or base_class == 'DartHtmlDomObject': if base_class == 'NativeFieldWrapperClass2' or base_class == 'DartHtmlDomObject':
js_interop_wrapper = ''' js_interop_wrapper = '''
@Deprecated("Internal Use Only")
static {0} internalCreate{0}() {{
return new {0}._internalWrap();
}}
factory {0}._internalWrap() {{ @Deprecated("Internal Use Only")
return new {0}.internal_(); external static Type get instanceRuntimeType;
}}
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
{0}.internal_() {{ }} {0}.internal_() {{ }}
'''.format(class_name)
{1}'''.format(class_name, js_interop_equivalence_op)
# Change to use the synthesized class so we can construct with a mixin # Change to use the synthesized class so we can construct with a mixin
# classes prefixed with name of NativeFieldWrapperClass2 don't have a # classes prefixed with name of NativeFieldWrapperClass2 don't have a
# default constructor so classes with mixins can't be new'd. # default constructor so classes with mixins can't be new'd.
@ -1285,13 +1268,9 @@ class DartLibrary():
emitters = library_emitter.Emit( emitters = library_emitter.Emit(
self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) self._template, AUXILIARY_DIR=massage_path(auxiliary_dir))
if isinstance(emitters, tuple): if isinstance(emitters, tuple):
if self._dart_js_interop: imports_emitter, map_emitter = emitters
imports_emitter, map_emitter, function_emitter = emitters
else:
imports_emitter, map_emitter = emitters
function_emitter = None
else: else:
imports_emitter, map_emitter, function_emitter = emitters, None, None imports_emitter, map_emitter = emitters, None
for path in sorted(self._paths): for path in sorted(self._paths):
relpath = os.path.relpath(path, library_file_dir) relpath = os.path.relpath(path, library_file_dir)
@ -1304,26 +1283,10 @@ class DartLibrary():
items.sort() items.sort()
for (idl_name, dart_name) in items: for (idl_name, dart_name) in items:
map_emitter.Emit( map_emitter.Emit(
" '$IDL_NAME': () => $DART_NAME,\n", " '$IDL_NAME': () => $DART_NAME.instanceRuntimeType,\n",
IDL_NAME=idl_name, IDL_NAME=idl_name,
DART_NAME=dart_name) DART_NAME=dart_name)
# Emit the $!TYPE_FUNCTION_MAP
if function_emitter:
items = self._typeMap.items()
items.sort()
for (idl_name, dart_name) in items:
# DOMStringMap is in the abstract list but is used as a concrete class
# in Dartium.
if not IsPureInterface(idl_name):
# Handle classes that are concrete (abstract can't be instantiated).
function_emitter.Emit(
" '$IDL_NAME': () => $DART_NAME.internalCreate$DART_NAME,\n",
IDL_NAME=idl_name,
DART_NAME=dart_name)
if self._dart_path.endswith('html_dartium.dart'):
function_emitter.Emit(" 'polymer-element': () => HtmlElement.internalCreateHtmlElement,\n")
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -22,6 +22,8 @@ _url_utils = ['hash', 'host', 'hostname', 'origin',
'password', 'pathname', 'port', 'protocol', 'password', 'pathname', 'port', 'protocol',
'search', 'username'] 'search', 'username']
_promise_to_future = Conversion('convertNativePromiseToDartFuture', 'dynamic', 'Future')
def array_type(data_type): def array_type(data_type):
matched = re.match(r'([\w\d_\s]+)\[\]', data_type) matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
if not matched: if not matched:
@ -108,6 +110,16 @@ class DartiumBackend(HtmlDartGenerator):
def CustomJSMembers(self): def CustomJSMembers(self):
return {} return {}
def _OutputConversion(self, idl_type, member):
conversion = FindConversion(idl_type, 'get', self._interface.id, member)
# TODO(jacobr) handle promise consistently in dart2js and dartium.
if idl_type == 'Promise':
return _promise_to_future
if conversion:
if conversion.function_name in ('_convertNativeToDart_Window', '_convertNativeToDart_EventTarget', 'convertNativeToDart_DateTime', 'convertNativeToDart_ImageData'):
return None
return conversion
def _InputConversion(self, idl_type, member): def _InputConversion(self, idl_type, member):
return FindConversion(idl_type, 'set', self._interface.id, member) return FindConversion(idl_type, 'set', self._interface.id, member)
@ -250,7 +262,7 @@ class DartiumBackend(HtmlDartGenerator):
self._members_emitter.Emit( self._members_emitter.Emit(
'\n @DocsEditable()\n' '\n @DocsEditable()\n'
' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => ' ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => '
'wrap_jso($TOPLEVEL_NAME($OUTPARAMETERS));\n', '$TOPLEVEL_NAME($OUTPARAMETERS);\n',
INTERFACE_NAME=self._interface_type_info.interface_name(), INTERFACE_NAME=self._interface_type_info.interface_name(),
FACTORY_METHOD_NAME=factory_method_name, FACTORY_METHOD_NAME=factory_method_name,
PARAMETERS=typed_formals, PARAMETERS=typed_formals,
@ -272,7 +284,7 @@ class DartiumBackend(HtmlDartGenerator):
self._interface, self._interface.id, ' ') self._interface, self._interface.id, ' ')
self._members_emitter.Emit( self._members_emitter.Emit(
'\n $(ANNOTATIONS)factory $CTOR($PARAMS) => wrap_jso(_create($FACTORY_PARAMS));\n', '\n $(ANNOTATIONS)factory $CTOR($PARAMS) => _create($FACTORY_PARAMS);\n',
ANNOTATIONS=annotations, ANNOTATIONS=annotations,
CTOR=constructor_info._ConstructorFullName(self._DartType), CTOR=constructor_info._ConstructorFullName(self._DartType),
PARAMS=constructor_info.ParametersAsDeclaration(self._DartType), PARAMS=constructor_info.ParametersAsDeclaration(self._DartType),
@ -536,7 +548,7 @@ class DartiumBackend(HtmlDartGenerator):
# JsObject maybe stored in the Dart class. # JsObject maybe stored in the Dart class.
return_wrap_jso = wrap_return_type_blink(return_type, attr.type.id, self._type_registry) return_wrap_jso = wrap_return_type_blink(return_type, attr.type.id, self._type_registry)
wrap_unwrap_list.append(return_wrap_jso) # wrap_jso the returned object wrap_unwrap_list.append(return_wrap_jso) # wrap_jso the returned object
wrap_unwrap_list.append(self._dart_use_blink) # this must be unwrap_jso wrap_unwrap_list.append(self._dart_use_blink)
# This seems to have been replaced with Custom=Getter (see above), but # This seems to have been replaced with Custom=Getter (see above), but
# check to be sure we don't see the old syntax # check to be sure we don't see the old syntax
@ -545,10 +557,13 @@ class DartiumBackend(HtmlDartGenerator):
auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix) auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
native_entry = \ native_entry = \
self.DeriveNativeEntry(attr.id, 'Getter', None) self.DeriveNativeEntry(attr.id, 'Getter', None)
output_conversion = self._OutputConversion(attr.type.id, attr.id)
cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
dart_declaration, attr.is_static, return_type, parameters, dart_declaration, attr.is_static, return_type, parameters,
native_suffix, is_custom, auto_scope_setup, native_entry=native_entry, native_suffix, is_custom, auto_scope_setup, native_entry=native_entry,
wrap_unwrap_list=wrap_unwrap_list, dictionary_return=dictionary_returned) wrap_unwrap_list=wrap_unwrap_list, dictionary_return=dictionary_returned,
output_conversion=output_conversion)
if is_custom: if is_custom:
return return
@ -583,9 +598,7 @@ class DartiumBackend(HtmlDartGenerator):
# Is the setter value a DartClass (that has a JsObject) or the type is # Is the setter value a DartClass (that has a JsObject) or the type is
# None (it's a dynamic/any type) then unwrap_jso before passing to blink. # None (it's a dynamic/any type) then unwrap_jso before passing to blink.
parameters = ['unwrap_jso(value)' if (isinstance(type_info, InterfaceIDLTypeInfo) or parameters = ['value']
not(attr.type.id) or ptype == 'Object')
else 'value']
dart_declaration = 'set %s(%s value)' % (html_name, ptype) dart_declaration = 'set %s(%s value)' % (html_name, ptype)
is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
@ -651,6 +664,12 @@ class DartiumBackend(HtmlDartGenerator):
self._EmitExplicitIndexedGetter(dart_element_type) self._EmitExplicitIndexedGetter(dart_element_type)
else: else:
is_custom = any((op.id == 'item' and _IsCustom(op)) for op in self._interface.operations) is_custom = any((op.id == 'item' and _IsCustom(op)) for op in self._interface.operations)
output_conversion = self._OutputConversion(element_type, 'item')
conversion_name = ''
if output_conversion:
conversion_name = output_conversion.function_name
# First emit a toplevel function to do the native call # First emit a toplevel function to do the native call
# Calls to this are emitted elsewhere, # Calls to this are emitted elsewhere,
dart_native_name, resolver_string = \ dart_native_name, resolver_string = \
@ -663,40 +682,22 @@ class DartiumBackend(HtmlDartGenerator):
dart_native_name) dart_native_name)
type_info = self._TypeInfo(element_type) type_info = self._TypeInfo(element_type)
# Does nativeIndexGetter return a DartClass (JsObject) if so wrap_jso.
wrap_jso_start = ''
wrap_jso_end = ''
if (isinstance(type_info, InterfaceIDLTypeInfo) or
wrap_type_blink(type_info.narrow_dart_type(), self._type_registry)):
wrap_jso_start = 'wrap_jso('
wrap_jso_end = ')'
blinkNativeIndexed = """ blinkNativeIndexed = """
$TYPE operator[](int index) { $TYPE operator[](int index) {
if (index < 0 || index >= length) if (index < 0 || index >= length)
throw new RangeError.index(index, this); throw new RangeError.index(index, this);
return %s$(DART_NATIVE_NAME)(unwrap_jso(this), index)%s; return _nativeIndexedGetter(index);
} }
$TYPE _nativeIndexedGetter(int index) => %s$(DART_NATIVE_NAME)(unwrap_jso(this), index)%s; $TYPE _nativeIndexedGetter(int index) => $(CONVERSION_NAME)($(DART_NATIVE_NAME)(this, index));
""" % (wrap_jso_start, wrap_jso_end, wrap_jso_start, wrap_jso_end) """
# Wrap the type to store the JsObject if Type is: blinkNativeIndexedGetter = \
# ' $(DART_NATIVE_NAME)(this, index);\n'
# - known IDL type
# - type_id is None then it's probably a union type or overloaded
# it's a dynamic/any type
# - type is Object
#
# JsObject maybe stored in the Dart class.
if isinstance(type_info, InterfaceIDLTypeInfo) or not(type_info) or dart_element_type == 'Object':
blinkNativeIndexedGetter = \
' {0}$(DART_NATIVE_NAME)(unwrap_jso(this), index){1};\n'.format('wrap_jso(', ')')
else:
blinkNativeIndexedGetter = \
' $(DART_NATIVE_NAME)(unwrap_jso(this), index);\n'
self._members_emitter.Emit(blinkNativeIndexed, self._members_emitter.Emit(blinkNativeIndexed,
DART_NATIVE_NAME=dart_qualified_name, DART_NATIVE_NAME=dart_qualified_name,
TYPE=self.SecureOutputType(element_type), TYPE=self.SecureOutputType(element_type),
INTERFACE=self._interface.id) INTERFACE=self._interface.id,
CONVERSION_NAME=conversion_name)
if self._HasNativeIndexSetter(): if self._HasNativeIndexSetter():
self._EmitNativeIndexSetter(dart_element_type) self._EmitNativeIndexSetter(dart_element_type)
@ -798,6 +799,8 @@ class DartiumBackend(HtmlDartGenerator):
operation = info.operations[0] operation = info.operations[0]
output_conversion = self._OutputConversion(operation.type.id, operation.id)
dictionary_returned = False dictionary_returned = False
# Return type for dictionary is any (untyped). # Return type for dictionary is any (untyped).
if operation.type.id == 'Dictionary': if operation.type.id == 'Dictionary':
@ -821,20 +824,14 @@ class DartiumBackend(HtmlDartGenerator):
if self._dart_use_blink: if self._dart_use_blink:
# Wrap the type to store the JsObject if Type is: # Wrap the type to store the JsObject if Type is:
# #
# - known IDL type
# - type_id is None then it's probably a union type or overloaded
# it's a dynamic/any type # it's a dynamic/any type
# - type is Object # - type is Object
# #
# JsObject maybe stored in the Dart class. # JsObject maybe stored in the Dart class.
return_wrap_jso = wrap_return_type_blink(return_type, info.type_name, self._type_registry) return_wrap_jso = wrap_return_type_blink(return_type, info.type_name, self._type_registry)
return_type_info = self._type_registry.TypeInfo(info.type_name) return_type_info = self._type_registry.TypeInfo(info.type_name)
if (isinstance(return_type_info, SequenceIDLTypeInfo) and
not isinstance(return_type_info._item_info, PrimitiveIDLTypeInfo)):
return_wrap_jso = True
# wrap_jso the returned object # wrap_jso the returned object
wrap_unwrap_list.append(return_wrap_jso) wrap_unwrap_list.append(return_wrap_jso)
# The 'this' parameter must be unwrap_jso
wrap_unwrap_list.append(self._dart_use_blink) wrap_unwrap_list.append(self._dart_use_blink)
if info.callback_args: if info.callback_args:
@ -852,7 +849,8 @@ class DartiumBackend(HtmlDartGenerator):
native_suffix, is_custom, auto_scope_setup, native_suffix, is_custom, auto_scope_setup,
native_entry=native_entry, native_entry=native_entry,
wrap_unwrap_list=wrap_unwrap_list, wrap_unwrap_list=wrap_unwrap_list,
dictionary_return=dictionary_returned) dictionary_return=dictionary_returned,
output_conversion=output_conversion)
if not is_custom: if not is_custom:
self._GenerateOperationNativeCallback(operation, operation.arguments, cpp_callback_name, auto_scope_setup) self._GenerateOperationNativeCallback(operation, operation.arguments, cpp_callback_name, auto_scope_setup)
else: else:
@ -880,7 +878,7 @@ class DartiumBackend(HtmlDartGenerator):
base_name = '_%s_%s' % (operation.id, version) base_name = '_%s_%s' % (operation.id, version)
static = True static = True
if not operation.is_static: if not operation.is_static:
actuals = ['unwrap_jso(this)' if self._dart_use_blink else 'this'] + actuals actuals = ['this'] + actuals
formals = ['mthis'] + formals formals = ['mthis'] + formals
actuals_s = ", ".join(actuals) actuals_s = ", ".join(actuals)
formals_s = ", ".join(formals) formals_s = ", ".join(formals)
@ -892,10 +890,7 @@ class DartiumBackend(HtmlDartGenerator):
overload_name = \ overload_name = \
self.DeriveQualifiedBlinkName(self._interface.id, self.DeriveQualifiedBlinkName(self._interface.id,
overload_base_name) overload_base_name)
if return_wrap_jso: call_emitter.Emit('$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s)
call_emitter.Emit('wrap_jso($NAME($ARGS))', NAME=overload_name, ARGS=actuals_s)
else:
call_emitter.Emit('$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s)
auto_scope_setup = \ auto_scope_setup = \
self._GenerateAutoSetupScope(base_name, native_suffix) self._GenerateAutoSetupScope(base_name, native_suffix)
cpp_callback_name = self._GenerateNativeBinding( cpp_callback_name = self._GenerateNativeBinding(
@ -927,7 +922,7 @@ class DartiumBackend(HtmlDartGenerator):
def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
static, return_type, parameters, native_suffix, is_custom, static, return_type, parameters, native_suffix, is_custom,
auto_scope_setup=True, emit_metadata=True, emit_to_native=False, auto_scope_setup=True, emit_metadata=True, emit_to_native=False,
native_entry=None, wrap_unwrap_list=[], dictionary_return=False): native_entry=None, wrap_unwrap_list=[], dictionary_return=False, output_conversion=None):
metadata = [] metadata = []
if emit_metadata: if emit_metadata:
metadata = self._metadata.GetFormattedMetadata( metadata = self._metadata.GetFormattedMetadata(
@ -946,10 +941,7 @@ class DartiumBackend(HtmlDartGenerator):
if not static: if not static:
formals = ", ".join(['mthis'] + parameters) formals = ", ".join(['mthis'] + parameters)
if wrap_unwrap_list and wrap_unwrap_list[1]: actuals = ", ".join(['this'] + parameters)
actuals = ", ".join(['unwrap_jso(this)'] + parameters)
else:
actuals = ", ".join(['this'] + parameters)
else: else:
formals = ", ".join(parameters) formals = ", ".join(parameters)
actuals = ", ".join(parameters) actuals = ", ".join(parameters)
@ -969,11 +961,17 @@ class DartiumBackend(HtmlDartGenerator):
emit_template = ''' emit_template = '''
$METADATA$DART_DECLARATION => $DART_NAME($ACTUALS); $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);
''' '''
if wrap_unwrap_list and wrap_unwrap_list[0]: if output_conversion and not dictionary_return:
conversion_template = '''
$METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
'''
emit_template = conversion_template % output_conversion.function_name
elif wrap_unwrap_list and wrap_unwrap_list[0]:
if return_type == 'Rectangle': if return_type == 'Rectangle':
jso_util_method = 'make_dart_rectangle' jso_util_method = 'make_dart_rectangle'
elif wrap_unwrap_list[0]: elif wrap_unwrap_list[0]:
jso_util_method = 'wrap_jso' jso_util_method = ''
if dictionary_return: if dictionary_return:
emit_jso_template = ''' emit_jso_template = '''

View file

@ -29,40 +29,11 @@ class _VMElementUpgrader implements ElementUpgrader {
} }
Element upgrade(element) { Element upgrade(element) {
var jsObject; // Only exact type matches are supported- cannot be a subclass.
var tag; if (element.runtimeType != _nativeType) {
var isNativeElementExtension = false; throw new ArgumentError('element is not subclass of $_nativeType');
try {
tag = _getCustomElementName(element);
} catch (e) {
isNativeElementExtension = element.localName == _extendsTag;
} }
return _createCustomUpgrader(_type, element);
if (element.runtimeType == HtmlElement || element.runtimeType == TemplateElement) {
if (tag != _extendsTag) {
throw new UnsupportedError('$tag is not registered.');
}
jsObject = unwrap_jso(element);
} else if (element.runtimeType == js.JsObject) {
// It's a Polymer core element (written in JS).
jsObject = element;
} else if (isNativeElementExtension) {
// Extending a native element.
jsObject = element.blink_jsObject;
// Element to extend is the real tag.
tag = element.localName;
} 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/JsObject.');
}
// Remember Dart class to tagName for any upgrading done in wrap_jso.
addCustomElementType(tag, _type, _extendsTag);
return _createCustomUpgrader(_type, jsObject);
} }
} }

View file

@ -30,13 +30,7 @@ part of html;
@Experimental() @Experimental()
class KeyEvent extends _WrappedEvent implements KeyboardEvent { class KeyEvent extends _WrappedEvent implements KeyboardEvent {
/** Needed because KeyboardEvent is implements. /** Needed because KeyboardEvent is implements.
* TODO(terry): Consider making blink_jsObject private (add underscore) for
* all blink_jsObject. Then needed private wrap/unwrap_jso
* functions that delegate to a public wrap/unwrap_jso.
*/ */
@Deprecated("Internal Use Only")
js.JsObject blink_jsObject;
/** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */ /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
KeyboardEvent _parent; KeyboardEvent _parent;

View file

@ -6,15 +6,14 @@ part of dart.html;
/** /**
* Helper class to implement custom events which wrap DOM events. * Helper class to implement custom events which wrap DOM events.
* TODO(jacobr): consider using dart JsNative.$setInstanceInterceptor
* instead of using wrappers as that would allow passing these wrappers
* back through dispatchEvent unlike the current implementation.
* See https://github.com/dart-lang/sdk/issues/16869
*/ */
class _WrappedEvent implements Event { class _WrappedEvent implements Event {
/** Needed because KeyboardEvent is implements. /** Needed because KeyboardEvent is implements.
* TODO(terry): Consider making blink_jsObject private (add underscore) for
* all blink_jsObject. Then needed private wrap/unwrap_jso
* functions that delegate to a public wrap/unwrap_jso.
*/ */
js.JsObject blink_jsObject;
final Event wrapped; final Event wrapped;
/** The CSS selector involved with event delegation. */ /** The CSS selector involved with event delegation. */

View file

@ -124,8 +124,6 @@ class _Utils {
} }
} }
static maybeUnwrapJso(obj) => unwrap_jso(obj);
static List convertToList(List list) { static List convertToList(List list) {
// FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it. // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
final length = list.length; final length = list.length;
@ -189,15 +187,14 @@ class _Utils {
return element; return element;
} }
static window() => wrap_jso(js.context['window']);
static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(message); static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(message);
static void spawnDomHelper(Function f, int replyTo) => static void spawnDomHelper(Function f, int replyTo) =>
_blink.Blink_Utils.spawnDomHelper(f, replyTo); _blink.Blink_Utils.spawnDomHelper(f, replyTo);
// TODO(vsm): Make this API compatible with spawnUri. It should also // TODO(vsm): Make this API compatible with spawnUri. It should also
// return a Future<Isolate>. // return a Future<Isolate>.
static spawnDomUri(String uri) => wrap_jso(_blink.Blink_Utils.spawnDomUri(uri)); // TODO(jacobr): IS THIS RIGHT? I worry we have broken conversion from Promise to Future.
static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri);
// The following methods were added for debugger integration to make working // The following methods were added for debugger integration to make working
// with the Dart C mirrors API simpler. // with the Dart C mirrors API simpler.
@ -774,13 +771,13 @@ class _Utils {
return [ return [
"inspect", "inspect",
(o) { (o) {
host.callMethod("_inspect", [unwrap_jso(o)]); js.JsNative.callMethod(host, "_inspect", [o]);
return o; return o;
}, },
"dir", "dir",
window().console.dir, window.console.dir,
"dirxml", "dirxml",
window().console.dirxml window.console.dirxml
// FIXME: add copy method. // FIXME: add copy method.
]; ];
} }
@ -804,38 +801,34 @@ class _Utils {
} }
static void _register(Document document, String tag, Type customType, static void _register(Document document, String tag, Type customType,
String extendsTagName) => _blink.Blink_Utils.register(unwrap_jso(document), tag, customType, extendsTagName); String extendsTagName) => _blink.Blink_Utils.register(document, tag, customType, extendsTagName);
static Element createElement(Document document, String tagName) => static Element createElement(Document document, String tagName) =>
wrap_jso(_blink.Blink_Utils.createElement(unwrap_jso(document), tagName)); _blink.Blink_Utils.createElement(document, tagName);
static Element changeElementWrapper(HtmlElement element, Type type) =>
wrap_jso(_blink.Blink_Utils.changeElementWrapper(unwrap_jso(element), type));
} }
// TODO(jacobr): this seems busted. I believe we are actually
// giving users real windows for opener, parent, top, etc.
// Or worse, we are probaly returning a raw JSObject.
class _DOMWindowCrossFrame extends DartHtmlDomObject implements class _DOMWindowCrossFrame extends DartHtmlDomObject implements
WindowBase { WindowBase {
/** Needed because KeyboardEvent is implements.
* TODO(terry): Consider making blink_jsObject private (add underscore) for
* all blink_jsObject. Then needed private wrap/unwrap_jso
* functions that delegate to a public wrap/unwrap_jso.
*/
js.JsObject blink_jsObject;
_DOMWindowCrossFrame.internal(); _DOMWindowCrossFrame.internal();
static _createSafe(win) => _blink.Blink_Utils.setInstanceInterceptor(win, _DOMWindowCrossFrame);
// Fields. // Fields.
HistoryBase get history => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_history(unwrap_jso(this))); HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this);
LocationBase get location => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_location(unwrap_jso(this))); LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(this);
bool get closed => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_closed(unwrap_jso(this))); bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
WindowBase get opener => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_opener(unwrap_jso(this))); WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
WindowBase get parent => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_parent(unwrap_jso(this))); WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
WindowBase get top => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_top(unwrap_jso(this))); WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);
// Methods. // Methods.
void close() => _blink.Blink_DOMWindowCrossFrame.close(unwrap_jso(this)); void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) => void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
_blink.Blink_DOMWindowCrossFrame.postMessage(unwrap_jso(this), _blink.Blink_DOMWindowCrossFrame.postMessage(this,
convertDartToNative_SerializedScriptValue(message), targetOrigin, messagePorts); convertDartToNative_SerializedScriptValue(message), targetOrigin, messagePorts);
// Implementation support. // Implementation support.
@ -869,9 +862,9 @@ class _HistoryCrossFrame extends DartHtmlDomObject implements HistoryBase {
_HistoryCrossFrame.internal(); _HistoryCrossFrame.internal();
// Methods. // Methods.
void back() => _blink.Blink_HistoryCrossFrame.back(unwrap_jso(this)); void back() => _blink.Blink_HistoryCrossFrame.back(this);
void forward() => _blink.Blink_HistoryCrossFrame.forward(unwrap_jso(this)); void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
void go(int distance) => _blink.Blink_HistoryCrossFrame.go(unwrap_jso(this), distance); void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);
// Implementation support. // Implementation support.
String get typeName => "History"; String get typeName => "History";
@ -881,7 +874,7 @@ class _LocationCrossFrame extends DartHtmlDomObject implements LocationBase {
_LocationCrossFrame.internal(); _LocationCrossFrame.internal();
// Fields. // Fields.
set href(String h) => _blink.Blink_LocationCrossFrame.set_href(unwrap_jso(this), h); set href(String h) => _blink.Blink_LocationCrossFrame.set_href(this, h);
// Implementation support. // Implementation support.
String get typeName => "Location"; String get typeName => "Location";

View file

@ -150,7 +150,4 @@ Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
throw new UnimplementedError(); throw new UnimplementedError();
} }
/// Dartium functions that are a NOOP in dart2js.
unwrap_jso(dartClass_instance) => dartClass_instance;
wrap_jso(jsObject) => jsObject;
createCustomUpgrader(Type customElementClass, $this) => $this; createCustomUpgrader(Type customElementClass, $this) => $this;

View file

@ -37,7 +37,6 @@ import 'dart:_internal' hide Symbol;
import 'dart:html_common'; import 'dart:html_common';
import 'dart:indexed_db'; import 'dart:indexed_db';
import 'dart:indexed_db' show indexed_dbBlinkMap; import 'dart:indexed_db' show indexed_dbBlinkMap;
import 'dart:indexed_db' show indexed_dbBlinkFunctionMap;
import 'dart:isolate'; import 'dart:isolate';
import 'dart:js' as js; import 'dart:js' as js;
import "dart:convert"; import "dart:convert";
@ -49,17 +48,14 @@ import 'dart:nativewrappers';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:web_gl' as gl; import 'dart:web_gl' as gl;
import 'dart:web_gl' show web_glBlinkMap; import 'dart:web_gl' show web_glBlinkMap;
import 'dart:web_gl' show web_glBlinkFunctionMap;
import 'dart:web_sql'; import 'dart:web_sql';
// Not actually used, but imported since dart:html can generate these objects. // Not actually used, but imported since dart:html can generate these objects.
import 'dart:svg' as svg; import 'dart:svg' as svg;
import 'dart:svg' show svgBlinkMap; import 'dart:svg' show svgBlinkMap;
import 'dart:svg' show svgBlinkFunctionMap;
import 'dart:svg' show Matrix; import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement; import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio; import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show web_audioBlinkMap; import 'dart:web_audio' show web_audioBlinkMap;
import 'dart:web_audio' show web_audioBlinkFunctionMap;
import 'dart:_blink' as _blink; import 'dart:_blink' as _blink;
import 'dart:developer'; import 'dart:developer';
@ -118,7 +114,7 @@ Window get window {
} }
$if DARTIUM $if DARTIUM
$if JSINTEROP $if JSINTEROP
_window = wrap_jso(js.JsNative.getProperty(js.context, 'window')); _window = js.JsNative.toTypedObject(js.context);
$else $else
_window = _Utils.window(); _window = _Utils.window();
$endif $endif
@ -161,11 +157,19 @@ final htmlBlinkMap = {
'JsObject': () => js.JsObject, 'JsObject': () => js.JsObject,
'JsFunction': () => js.JsFunction, 'JsFunction': () => js.JsFunction,
'JsArray': () => js.JsArray, 'JsArray': () => js.JsArray,
// We have to call .instanceRuntimeType as these classes have a private
// implementation class defined dynamically at runtime via a patch file.
'JSObject': () => js.JSObject.instanceRuntimeType,
'JSFunction': () => js.JSFunction.instanceRuntimeType,
'JSArray': () => js.JSArray.instanceRuntimeType,
$!TYPE_MAP $!TYPE_MAP
}; };
// TODO(leafp): We may want to move this elsewhere if html becomes // TODO(leafp): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html. // a package to avoid dartium depending on pkg:html.
@Deprecated("Internal Use Only")
getHtmlCreateType(String key) => _getType(key);
Type _getType(String key) { Type _getType(String key) {
var result; var result;
@ -252,102 +256,15 @@ Type _getSvgType(String key) {
return null; return null;
} }
// TODO(jacobr): it would be nice to place this in a consistent place for dart2js and dartium.
_convertNativeToDart_XHR_Response(o) {
if (o is Document) {
return o;
}
return convertNativeToDart_SerializedScriptValue(o);
}
$if JSINTEROP $if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final htmlBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};
// TODO(terry): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
@Deprecated("Internal Use Only")
getHtmlCreateFunction(String key) {
var result;
// TODO(vsm): Add Cross Frame and JS types here as well.
// Check the html library.
result = _getHtmlFunction(key);
if (result != null) {
return result;
}
// Check the web gl library.
result = _getWebGlFunction(key);
if (result != null) {
return result;
}
// Check the indexed db library.
result = _getIndexDbFunction(key);
if (result != null) {
return result;
}
// Check the web audio library.
result = _getWebAudioFunction(key);
if (result != null) {
return result;
}
// Check the web sql library.
result = _getWebSqlFunction(key);
if (result != null) {
return result;
}
// Check the svg library.
result = _getSvgFunction(key);
if (result != null) {
return result;
}
return null;
}
Function _getHtmlFunction(String key) {
if (htmlBlinkFunctionMap.containsKey(key)) {
return htmlBlinkFunctionMap[key]();
}
return null;
}
Function _getWebGlFunction(String key) {
if (web_glBlinkFunctionMap.containsKey(key)) {
return web_glBlinkFunctionMap[key]();
}
return null;
}
Function _getIndexDbFunction(String key) {
if (indexed_dbBlinkFunctionMap.containsKey(key)) {
return indexed_dbBlinkFunctionMap[key]();
}
return null;
}
Function _getWebAudioFunction(String key) {
if (web_audioBlinkFunctionMap.containsKey(key)) {
return web_audioBlinkFunctionMap[key]();
}
return null;
}
Function _getWebSqlFunction(String key) {
if (web_sqlBlinkFunctionMap.containsKey(key)) {
return web_sqlBlinkFunctionMap[key]();
}
return null;
}
Function _getSvgFunction(String key) {
if (svgBlinkFunctionMap.containsKey(key)) {
return svgBlinkFunctionMap[key]();
}
return null;
}
/****************************************************************************** /******************************************************************************
********** ********** ********** **********
@ -368,22 +285,14 @@ String _getCustomElementName(element) {
var jsObject; var jsObject;
var tag = ""; var tag = "";
var runtimeType = element.runtimeType; var runtimeType = element.runtimeType;
if (runtimeType == HtmlElement) { if (runtimeType == TemplateElement) {
tag = element.localName;
} else if (runtimeType == TemplateElement) {
// Data binding with a Dart class. // Data binding with a Dart class.
tag = element.attributes['is']; tag = element.attributes['is'];
} else if (runtimeType == js.JsObject) { } else if (element is HtmlElement) {
// It's a Polymer core element (written in JS). tag = element.attributes['is'];
// Make sure it's an element anything else we can ignore. if (tag == null) {
if (element.hasProperty('nodeType') && element['nodeType'] == 1) { // It's a custom element we want the local name.
if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) { tag = element.localName;
// 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 { } else {
throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.'); throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.');
@ -412,12 +321,16 @@ debug_or_assert(message, expression) {
} }
} }
// TODO(jacobr): we shouldn't be generating this call in the dart:html
// bindings but we are.
_convertDartToNative_EventTarget(target) => target;
@Deprecated("Internal Use Only") @Deprecated("Internal Use Only")
Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) { Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
var result = new Map(); var result = new Map();
var keys = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), 'keys', [jsObject]); var keys = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), 'keys', [jsObject]);
for (var key in keys) { for (var key in keys) {
result[key] = wrap_jso(js.JsNative.getProperty(jsObject, key)); result[key] = js.JsNative.getProperty(jsObject, key);
} }
return result; return result;
} }
@ -426,25 +339,7 @@ Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
* Upgrade the JS HTMLElement to the Dart class. Used by Dart's Polymer. * Upgrade the JS HTMLElement to the Dart class. Used by Dart's Polymer.
*/ */
_createCustomUpgrader(Type customElementClass, $this) { _createCustomUpgrader(Type customElementClass, $this) {
var dartClass; return _blink.Blink_Utils.setInstanceInterceptor($this, customElementClass, customElement: true);
try {
dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
} catch (e) {
// Did the dartClass get allocated but the created failed? Otherwise, other
// components inside of this failed somewhere (could be JS custom element).
if (dartClass != null) {
// Yes, mark as didn't upgrade.
dartClass._badUpgrade();
}
throw e;
} finally {
// Need to remember the Dart class that was created for this custom so
// return it and setup the blink_jsObject to the $this that we'll be working
// with as we talk to blink.
js.setDartHtmlWrapperFor($this, dartClass);
}
return dartClass;
} }
$else $else

View file

@ -112,10 +112,66 @@ final indexed_dbBlinkMap = {
$!TYPE_MAP $!TYPE_MAP
}; };
$if JSINTEROP
// FIXME: Can we make this private? //
@Deprecated("Internal Use Only") // Per http://www.w3.org/TR/IndexedDB/#key-construct
final indexed_dbBlinkFunctionMap = { //
$!TYPE_FUNCTION_MAP // "A value is said to be a valid key if it is one of the following types: Array
}; // JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
$endif // [WEBIDL]. However Arrays are only valid keys if every item in the array is
// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
// the Array doesn't directly or indirectly contain itself. Any non-numeric
// properties are ignored, and thus does not affect whether the Array is a valid
// key. Additionally, if the value is of type float, it is only a valid key if
// it is not NaN, and if the value is of type Date it is only a valid key if its
// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."
// What is required is to ensure that an Lists in the key are actually
// JavaScript arrays, and any Dates are JavaScript Dates.
/**
* Converts a native IDBKey into a Dart object.
*
* May return the original input. May mutate the original input (but will be
* idempotent if mutation occurs). It is assumed that this conversion happens
* on native IDBKeys on all paths that return IDBKeys from native DOM calls.
*
* If necessary, JavaScript Dates are converted into Dart Dates.
*/
_convertNativeToDart_IDBKey(nativeKey) {
containsDate(object) {
if (object is DateTime) return true;
if (object is List) {
for (int i = 0; i < object.length; i++) {
if (containsDate(object[i])) return true;
}
}
return false; // number, string.
}
if (nativeKey is DateTime) {
throw new UnimplementedError('Key containing DateTime');
}
// TODO: Cache conversion somewhere?
return nativeKey;
}
/**
* Converts a Dart object into a valid IDBKey.
*
* May return the original input. Does not mutate input.
*
* If necessary, [dartKey] may be copied to ensure all lists are converted into
* JavaScript Arrays and Dart Dates into JavaScript Dates.
*/
_convertDartToNative_IDBKey(dartKey) {
// TODO: Implement.
return dartKey;
}
/// May modify original. If so, action is idempotent.
_convertNativeToDart_IDBAny(object) {
return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
}

View file

@ -28,11 +28,3 @@ $!GENERATED_DART_FILES
final svgBlinkMap = { final svgBlinkMap = {
$!TYPE_MAP $!TYPE_MAP
}; };
$if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final svgBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};
$endif

View file

@ -22,11 +22,3 @@ $!GENERATED_DART_FILES
final web_audioBlinkMap = { final web_audioBlinkMap = {
$!TYPE_MAP $!TYPE_MAP
}; };
$if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final web_audioBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};
$endif

View file

@ -24,11 +24,3 @@ $!GENERATED_DART_FILES
final web_glBlinkMap = { final web_glBlinkMap = {
$!TYPE_MAP $!TYPE_MAP
}; };
$if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final web_glBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};
$endif

View file

@ -30,11 +30,3 @@ $!GENERATED_DART_FILES
final web_sqlBlinkMap = { final web_sqlBlinkMap = {
$!TYPE_MAP $!TYPE_MAP
}; };
$if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final web_sqlBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};
$endif

View file

@ -31,15 +31,15 @@ $else
// TODO: any coercions on the elements of blobParts, e.g. coerce a typed // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
// array to ArrayBuffer if it is a total view. // array to ArrayBuffer if it is a total view.
var parts = convertDartToNative_List(blobParts.map(unwrap_jso).toList()); var parts = convertDartToNative_List(blobParts);
if (type == null && endings == null) { if (type == null && endings == null) {
return wrap_jso(_blink.BlinkBlob.instance.constructorCallback_1_(parts)); return _blink.BlinkBlob.instance.constructorCallback_1_(parts);
} }
var bag = {}; var bag = {};
if (type != null) bag['type'] = type; if (type != null) bag['type'] = type;
if (endings != null) bag['endings'] = endings; if (endings != null) bag['endings'] = endings;
return wrap_jso(_blink.BlinkBlob.instance.constructorCallback_2_(parts, return _blink.BlinkBlob.instance.constructorCallback_2_(parts,
convertDartToNative_Dictionary(bag))); convertDartToNative_Dictionary(bag));
} }
$endif $endif
$endif $endif

View file

@ -63,7 +63,7 @@ $endif
$if DARTIUM $if DARTIUM
bool _hasProperty(String propertyName) => bool _hasProperty(String propertyName) =>
$if JSINTEROP $if JSINTEROP
_blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(unwrap_jso(this), propertyName) != null; _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(this, propertyName);
$else $else
_blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName); _blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName);
$endif $endif

View file

@ -23,9 +23,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
// first-chance exceptions. Can expand this list in the future as needed. // first-chance exceptions. Can expand this list in the future as needed.
if (detail is List || detail is Map || detail is String || detail is num) { if (detail is List || detail is Map || detail is String || detail is num) {
try { try {
$if DART2JS
detail = convertDartToNative_SerializedScriptValue(detail); detail = convertDartToNative_SerializedScriptValue(detail);
$endif
e._initCustomEvent(type, canBubble, cancelable, detail); e._initCustomEvent(type, canBubble, cancelable, detail);
} catch(_) { } catch(_) {
e._initCustomEvent(type, canBubble, cancelable, null); e._initCustomEvent(type, canBubble, cancelable, null);
@ -34,11 +32,6 @@ $endif
e._initCustomEvent(type, canBubble, cancelable, null); e._initCustomEvent(type, canBubble, cancelable, null);
} }
$if DARTIUM
// Need for identity.
js.setDartHtmlWrapperFor(e.blink_jsObject, e);
$endif
return e; return e;
} }

View file

@ -15,7 +15,7 @@ $else
// TODO(alanknight): I think that all the __getter__ generators should just // TODO(alanknight): I think that all the __getter__ generators should just
// do property access, but that's major surgery. This one is a problem, so // do property access, but that's major surgery. This one is a problem, so
// just hard-code it for now. // just hard-code it for now.
return _blink.Blink_JsNative_DomException.getProperty(unwrap_jso(this), index); return _blink.Blink_JsNative_DomException.getProperty(this, index);
$endif $endif
} }

View file

@ -68,23 +68,9 @@ $if DART2JS
? _createElement_2(tagName) ? _createElement_2(tagName)
: _createElement(tagName, typeExtension); : _createElement(tagName, typeExtension);
$else $else
var newElement = (typeExtension == null) ? return (typeExtension == null) ?
_blink.BlinkDocument.instance.createElement_Callback_1_(unwrap_jso(this), tagName) : _blink.BlinkDocument.instance.createElement_Callback_1_(this, tagName) :
_blink.BlinkDocument.instance.createElement_Callback_2_(unwrap_jso(this), tagName, typeExtension); _blink.BlinkDocument.instance.createElement_Callback_2_(this, tagName, typeExtension);
var wrapped = js.getDartHtmlWrapperFor(newElement); // Here's our Dart class.
if (wrapped != null) {
wrapped.blink_jsObject = newElement;
} else {
wrapped = wrap_jso(newElement);
if (wrapped == null) {
wrapped = wrap_jso_custom_element(newElement);
} else {
js.setDartHtmlWrapperFor(wrapped.blink_jsObject, wrapped);
}
}
return wrapped;
$endif $endif
} }
@ -110,25 +96,9 @@ $if DART2JS
? _createElementNS_2(namespaceURI, qualifiedName) ? _createElementNS_2(namespaceURI, qualifiedName)
: _createElementNS(namespaceURI, qualifiedName, typeExtension); : _createElementNS(namespaceURI, qualifiedName, typeExtension);
$else $else
var newElement = (typeExtension == null) ? return (typeExtension == null) ?
_blink.BlinkDocument.instance.createElementNS_Callback_2_(unwrap_jso(this), namespaceURI, qualifiedName) : _blink.BlinkDocument.instance.createElementNS_Callback_2_(this, namespaceURI, qualifiedName) :
_blink.BlinkDocument.instance.createElementNS_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, typeExtension); _blink.BlinkDocument.instance.createElementNS_Callback_3_(this, namespaceURI, qualifiedName, typeExtension);
var wrapped;
wrapped = js.getDartHtmlWrapperFor(newElement); // Here's our Dart class.
if (wrapped != null) {
wrapped.blink_jsObject = newElement;
} else {
wrapped = wrap_jso(newElement);
if (wrapped == null) {
wrapped = wrap_jso_custom_element(newElement);
} else {
js.setDartHtmlWrapperFor(wrapped.blink_jsObject, wrapped); // Here's our Dart class.
}
}
return wrapped;
$endif $endif
} }

View file

@ -9,8 +9,8 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override this methods for Dartium _DocumentType can't be abstract. // Override this methods for Dartium _DocumentType can't be abstract.
Element get nextElementSibling => wrap_jso(_blink.BlinkDocumentType.instance.nextElementSibling_Getter_(unwrap_jso(this))); Element get nextElementSibling => _blink.BlinkDocumentType.instance.nextElementSibling_Getter_(this);
Element get previousElementSibling => wrap_jso(_blink.BlinkDocumentType.instance.previousElementSibling_Getter_(unwrap_jso(this))); Element get previousElementSibling => _blink.BlinkDocumentType.instance.previousElementSibling_Getter_(this);
$endif $endif
} }

View file

@ -380,7 +380,15 @@ $(ANNOTATIONS)$(NATIVESPEC)class $CLASSNAME$EXTENDS$IMPLEMENTS {
* } * }
* document.registerElement('x-custom', CustomElement); * document.registerElement('x-custom', CustomElement);
*/ */
$if DART2JS
Element.created() : super._created(); Element.created() : super._created();
$else
Element.created() : super._created() {
// Validate that this is a custom element & possibly perform additional
// initialization.
_blink.Blink_Utils.initializeCustomElement(this);
}
$endif
/** /**
* Creates the HTML element specified by the tag name. * Creates the HTML element specified by the tag name.
@ -1483,24 +1491,20 @@ $else
static var _htmlCollection = js.context["HTMLCollection"]; static var _htmlCollection = js.context["HTMLCollection"];
static var _nodeList = js.context["NodeList"]; static var _nodeList = js.context["NodeList"];
static const _evilAttributeNames =
const ['attributes', 'lastChild', 'children', 'childNodes'];
static bool _hasCorruptedAttributes(Element element) { static bool _hasCorruptedAttributes(Element element) {
var attributes = unwrap_jso(element)["attributes"]; // We have trusted access to children and to attributes of objects,
if (!attributes.instanceof(_namedNodeMap)) { // so we can inspect directly for attempts at DOM clobbering.
return true; var child = element.firstChild;
} while( child != null) {
var childNodes = unwrap_jso(element.childNodes); if (child is Element) {
var length = childNodes["length"]; for (var attributeName in ["id", "name"]) {
var lastChild = unwrap_jso(element.lastChild); var childAttribute = child.getAttribute(attributeName);
if (null != lastChild && if (_evilAttributeNames.contains(childAttribute)) return true;
lastChild != childNodes[length - 1]) { }}
return true; child = child.nextNode;
}
var children = unwrap_jso(element._children);
if (null != children) { // On Safari, children can apparently be null.
if (!children.instanceof(_htmlCollection) ||
children.instanceof(_nodeList)) {
return true;
}
} }
return false; return false;
} }
@ -1509,6 +1513,7 @@ $else
static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false; static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false;
$endif $endif
$if DART2JS
static String _safeTagName(element) { static String _safeTagName(element) {
String result = 'element tag unavailable'; String result = 'element tag unavailable';
try { try {
@ -1518,6 +1523,15 @@ $endif
} catch (e) {} } catch (e) {}
return result; return result;
} }
$else
static String _safeTagName(element) {
try {
// Safe as we plumb directly to a C++ native method.
return element.tagName;
} catch (e) {}
return 'element tag unavailable';
}
$endif
$if DART2JS $if DART2JS
@DomName('Element.offsetParent') @DomName('Element.offsetParent')
@ -1570,52 +1584,52 @@ $if DART2JS
$else $else
// Need to explicitly delegate because Element is no longer abstract for Dartium. // Need to explicitly delegate because Element is no longer abstract for Dartium.
bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(unwrap_jso(this)); bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(this);
void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso(this)); void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(this);
@DomName('Element.offsetParent') @DomName('Element.offsetParent')
@DocsEditable() @DocsEditable()
Element get offsetParent => wrap_jso(_blink.BlinkElement.instance.offsetParent_Getter_(unwrap_jso(this))); Element get offsetParent => _blink.BlinkElement.instance.offsetParent_Getter_(this);
@DomName('Element.offsetHeight') @DomName('Element.offsetHeight')
@DocsEditable() @DocsEditable()
int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwrap_jso(this)); int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(this);
@DomName('Element.offsetLeft') @DomName('Element.offsetLeft')
@DocsEditable() @DocsEditable()
int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_jso(this)); int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(this);
@DomName('Element.offsetTop') @DomName('Element.offsetTop')
@DocsEditable() @DocsEditable()
int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(unwrap_jso(this)); int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(this);
@DomName('Element.offsetWidth') @DomName('Element.offsetWidth')
@DocsEditable() @DocsEditable()
int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(unwrap_jso(this)); int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(this);
@DomName('Element.scrollHeight') @DomName('Element.scrollHeight')
@DocsEditable() @DocsEditable()
int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwrap_jso(this)).round(); int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(this).round();
@DomName('Element.scrollLeft') @DomName('Element.scrollLeft')
@DocsEditable() @DocsEditable()
int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_jso(this)).round(); int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(this).round();
@DomName('Element.scrollLeft') @DomName('Element.scrollLeft')
@DocsEditable() @DocsEditable()
set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(unwrap_jso(this), value.round()); set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(this, value.round());
@DomName('Element.scrollTop') @DomName('Element.scrollTop')
@DocsEditable() @DocsEditable()
int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso(this)).round(); int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(this).round();
@DomName('Element.scrollTop') @DomName('Element.scrollTop')
@DocsEditable() @DocsEditable()
set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(unwrap_jso(this), value.round()); set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(this, value.round());
@DomName('Element.scrollWidth') @DomName('Element.scrollWidth')
@DocsEditable() @DocsEditable()
int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap_jso(this)).round(); int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(this).round();
$endif $endif
$!MEMBERS $!MEMBERS

View file

@ -13,7 +13,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$if DART2JS $if DART2JS
var res = JS('Null|String|NativeByteBuffer', '#.result', this); var res = JS('Null|String|NativeByteBuffer', '#.result', this);
$else $else
var res = _blink.BlinkFileReader.instance.result_Getter_(unwrap_jso(this)); var res = _blink.BlinkFileReader.instance.result_Getter_(this);
$endif $endif
if (res is ByteBuffer) { if (res is ByteBuffer) {
return new Uint8List.view(res); return new Uint8List.view(res);

View file

@ -10,9 +10,9 @@ $!MEMBERS
$if JSINTEROP $if JSINTEROP
factory AudioElement([String src]) { factory AudioElement([String src]) {
if (src == null) if (src == null)
return wrap_jso(_blink.BlinkHTMLAudioElement.instance.constructorCallback_0_()); return _blink.BlinkHTMLAudioElement.instance.constructorCallback_0_();
else else
return wrap_jso(_blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src)); return _blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src);
} }
$else $else
factory AudioElement([String src]) => new AudioElement._(src); factory AudioElement([String src]) => new AudioElement._(src);

View file

@ -413,9 +413,6 @@ $else
} }
var elemProto = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), "create", [js.JsNative.getProperty(baseElement, 'prototype')]); 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);
// TODO(terry): Hack to stop recursion re-creating custom element when the // TODO(terry): Hack to stop recursion re-creating custom element when the
// created() constructor of the custom element does e.g., // created() constructor of the custom element does e.g.,
// //
@ -427,77 +424,42 @@ $else
// until stack overflow. // until stack overflow.
// //
// See https://github.com/dart-lang/sdk/issues/23666 // See https://github.com/dart-lang/sdk/issues/23666
int creating = 0; int creating = 0; // TODO(jacobr): I think I broke thise case. Will fix monday.
// If any JS code is hooked we want to call it too. // If any JS code is hooked we want to call it too.
var oldCreatedCallback = elemProto['createdCallback']; var oldCreatedCallback = js.JsNative.getProperty(elemProto, 'createdCallback');
var oldAttributeChangedCallback = elemProto['attributeChangedCallback']; var oldAttributeChangedCallback = js.JsNative.getProperty(elemProto, 'attributeChangedCallback');
var oldAttachedCallback = elemProto['attachedCallback']; var oldAttachedCallback = js.JsNative.getProperty(elemProto, 'attachedCallback');
var oldDetachedCallback = elemProto['detachedCallback']; var oldDetachedCallback = js.JsNative.getProperty(elemProto, 'detachedCallback');
// TODO(jacobr): warning:
elemProto['createdCallback'] = js.JsNative.withThis(($this) {
if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
creating++;
var dartClass;
try {
if (extendsTag != null) {
// If we're extending a native element then create that element.
// Then upgrade that element to the customElementClass through
// normal flow.
dartClass = document.createElement(extendsTag);
js.setDartHtmlWrapperFor($this, dartClass);
dartClass.blink_jsObject = $this;
}
// Upgrade to the CustomElement Dart class.
dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
} catch (e) {
// Got a problem make it an HtmlElement and rethrow the error.
dartClass = HtmlElement.internalCreateHtmlElement();
// We need to remember the JS object (because constructElement failed
// it normally sets up the blink_jsObject.
dartClass.blink_jsObject = $this;
// Mark to only try this once don't try upgrading from HtmlElement
// to the user's Dart class - we had a problem.
dartClass._badUpgrade();
throw e;
} finally {
// Need to remember the Dart class that was created for this custom so
// return it and setup the blink_jsObject to the $this that we'll be working
// with as we talk to blink.
js.setDartHtmlWrapperFor($this, dartClass);
creating--;
}
}
js.JsNative.setProperty(elemProto, 'createdCallback', js.allowInteropCaptureThis(($this) {
// The created callback has already been called by the very act of passing a JS
// custom element from JS to Dart.
if (oldCreatedCallback != null) if (oldCreatedCallback != null)
oldCreatedCallback.apply([], thisArg: unwrap_jso($this)); oldCreatedCallback.apply([], thisArg: $this);
}); }));
elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) { js.JsNative.setProperty(elemProto, 'attributeChangedCallback', js.allowInteropCaptureThis(($this, attrName, oldVal, newVal) {
$this.attributeChanged(attrName, oldVal, newVal); $this.attributeChanged(attrName, oldVal, newVal);
if (oldAttributeChangedCallback != null) if (oldAttributeChangedCallback != null)
oldAttributeChangedCallback.apply([], thisArg: unwrap_jso($this)); oldAttributeChangedCallback.apply([], thisArg: $this);
}); }));
elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) { js.JsNative.setProperty(elemProto, 'attachedCallback', js.allowInteropCaptureThis(($this) {
$this.attached(); $this.attached();
if (oldAttachedCallback != null) if (oldAttachedCallback != null)
oldAttachedCallback.apply([], thisArg: unwrap_jso($this)); oldAttachedCallback.apply([], thisArg: $this);
}); }));
elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) { js.JsNative.setProperty(elemProto, 'detachedCallback', js.allowInteropCaptureThis(($this) {
$this.detached(); $this.detached();
if (oldDetachedCallback != null) if (oldDetachedCallback != null)
oldDetachedCallback.apply([], thisArg: unwrap_jso($this)); oldDetachedCallback.apply([], thisArg: $this);
}); }));
// document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag}); // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag}); var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'document'), 'registerElement', [tag, jsMap]); _blink.Blink_Utils.defineInterceptorCustomElement(elemProto, customElementClass);
js.JsNative.callMethod(document, 'registerElement', [tag, jsMap]);
} }
$endif $endif
} }

View file

@ -7,18 +7,4 @@ part of $LIBRARYNAME;
@DocsEditable() @DocsEditable()
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
$!MEMBERS $!MEMBERS
$if DARTIUM
// Flags to only try upgrading once. If there's a failure don't try upgrading
// anymore.
bool _badUpgradeOccurred = false;
/// 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
} }

View file

@ -72,14 +72,14 @@ $else
if (storeName_OR_storeNames == null) { if (storeName_OR_storeNames == null) {
throw new ArgumentError("stores may not be null in transaction"); throw new ArgumentError("stores may not be null in transaction");
} else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) { } else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) {
names = unwrap_jso(storeName_OR_storeNames); names = storeName_OR_storeNames;
} else if (storeName_OR_storeNames is List<String>) { } else if (storeName_OR_storeNames is List<String>) {
names = convertDartToNative_List(storeName_OR_storeNames); names = convertDartToNative_List(storeName_OR_storeNames);
} else { } else {
throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames"); throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames");
} }
return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), names, mode)); return _blink.BlinkIDBDatabase.instance.transaction_Callback_2_(this, names, mode);
} }
Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode); Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode);

View file

@ -35,7 +35,7 @@ $if DARTIUM
@DomName('MessageEvent.data') @DomName('MessageEvent.data')
@DocsEditable() @DocsEditable()
dynamic get data => convertNativeToDart_SerializedScriptValue( dynamic get data => convertNativeToDart_SerializedScriptValue(
_blink.BlinkMessageEvent.instance.data_Getter_(unwrap_jso(this))); _blink.BlinkMessageEvent.instance.data_Getter_(this));
$else $else
// TODO(alanknight): This really should be generated by the // TODO(alanknight): This really should be generated by the

View file

@ -20,13 +20,7 @@ $endif
} }
$if DARTIUM $if DARTIUM
@DocsEditable() @DocsEditable()
$if JSINTEROP
static MutationObserver _create(callback) => wrap_jso(_blink.BlinkMutationObserver.instance.constructorCallback_1_((mutations, observer) {
callback(wrap_jso(mutations), wrap_jso(observer));
}));
$else
static MutationObserver _create(callback) => _blink.BlinkMutationObserver.instance.constructorCallback_1_(callback); static MutationObserver _create(callback) => _blink.BlinkMutationObserver.instance.constructorCallback_1_(callback);
$endif
$endif $endif
/** /**

View file

@ -200,14 +200,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$if DART2JS $if DART2JS
Node._created() : super._created(); Node._created() : super._created();
$else $else
Node._created() : super._created() { Node._created() : super._created();
// By this point blink_jsObject should be setup if it's not then we weren't
// called by the registerElement createdCallback - probably created() was
// called directly which is verboten.
if (this.blink_jsObject == null) {
throw new DomException.jsInterop("the created constructor cannot be called directly");
}
}
$endif $endif
/** /**
@ -304,7 +297,7 @@ $if DARTIUM
*/ */
@DomName('Node.childNodes') @DomName('Node.childNodes')
@DocsEditable() @DocsEditable()
List<Node> get childNodes => wrap_jso(_blink.BlinkNode.instance.childNodes_Getter_(unwrap_jso(this))); List<Node> get childNodes => _blink.BlinkNode.instance.childNodes_Getter_(this);
$else $else
/** /**
* A list of this node's children. * A list of this node's children.

View file

@ -9,11 +9,11 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _SVGCursorElement can't be abstract. // Override these methods for Dartium _SVGCursorElement can't be abstract.
StringList get requiredExtensions => wrap_jso(_blink.BlinkSVGCursorElement.instance.requiredExtensions_Getter_(unwrap_jso(this))); StringList get requiredExtensions => _blink.BlinkSVGCursorElement.instance.requiredExtensions_Getter_(this);
StringList get requiredFeatures => wrap_jso(_blink.BlinkSVGCursorElement.instance.requiredFeatures_Getter_(unwrap_jso(this))); StringList get requiredFeatures => _blink.BlinkSVGCursorElement.instance.requiredFeatures_Getter_(this);
StringList get systemLanguage => wrap_jso(_blink.BlinkSVGCursorElement.instance.systemLanguage_Getter_(unwrap_jso(this))); StringList get systemLanguage => _blink.BlinkSVGCursorElement.instance.systemLanguage_Getter_(this);
AnimatedString get href => wrap_jso(_blink.BlinkSVGCursorElement.instance.href_Getter_(unwrap_jso(this))); AnimatedString get href => _blink.BlinkSVGCursorElement.instance.href_Getter_(this);
bool hasExtension(String extension) => _blink.BlinkSVGCursorElement.instance.hasExtension_Callback_1_(unwrap_jso(this), extension); bool hasExtension(String extension) => _blink.BlinkSVGCursorElement.instance.hasExtension_Callback_1_(this, extension);
$endif $endif
} }

View file

@ -146,18 +146,8 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$if JSINTEROP $if JSINTEROP
set _svgClassName(AnimatedString value) => set _svgClassName(AnimatedString value) =>
_blink.BlinkSVGElement.instance.className_Setter_(unwrap_jso(this), unwrap_jso(value)); _blink.BlinkSVGElement.instance.className_Setter_(this, value);
String get className => _svgClassName.baseVal;
// Unbelievable hack. We can't create an SvgAnimatedString, but we can get
// the existing one and change its baseVal. Then we call the blink setter directly
// TODO(alanknight): Handle suppressing the SVGAnimated<*> better
set className(String s) {
var oldClass = _svgClassName;
oldClass.baseVal = s;
_svgClassName = oldClass;
}
$endif $endif
$!MEMBERS $!MEMBERS
} }

View file

@ -9,11 +9,11 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _SVGFEDropShadowElement can't be abstract. // Override these methods for Dartium _SVGFEDropShadowElement can't be abstract.
AnimatedLength get height => wrap_jso(_blink.BlinkSVGFEDropShadowElement.instance.height_Getter_(unwrap_jso(this))); AnimatedLength get height => _blink.BlinkSVGFEDropShadowElement.instance.height_Getter_(this);
AnimatedString get result => wrap_jso(_blink.BlinkSVGFEDropShadowElement.instance.result_Getter_(unwrap_jso(this))); AnimatedString get result => _blink.BlinkSVGFEDropShadowElement.instance.result_Getter_(this);
AnimatedLength get width => wrap_jso(_blink.BlinkSVGFEDropShadowElement.instance.width_Getter_(unwrap_jso(this))); AnimatedLength get width => _blink.BlinkSVGFEDropShadowElement.instance.width_Getter_(this);
AnimatedLength get x => wrap_jso(_blink.BlinkSVGFEDropShadowElement.instance.x_Getter_(unwrap_jso(this))); AnimatedLength get x => _blink.BlinkSVGFEDropShadowElement.instance.x_Getter_(this);
AnimatedLength get y => wrap_jso(_blink.BlinkSVGFEDropShadowElement.instance.y_Getter_(unwrap_jso(this))); AnimatedLength get y => _blink.BlinkSVGFEDropShadowElement.instance.y_Getter_(this);
$endif $endif
} }

View file

@ -9,7 +9,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _SVGGlyphRefElement can't be abstract. // Override these methods for Dartium _SVGGlyphRefElement can't be abstract.
AnimatedString get href => wrap_jso(_blink.BlinkSVGGlyphRefElement.instance.href_Getter_(unwrap_jso(this))); AnimatedString get href => _blink.BlinkSVGGlyphRefElement.instance.href_Getter_(this);
$endif $endif
} }

View file

@ -9,7 +9,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _SVGMPathElement can't be abstract. // Override these methods for Dartium _SVGMPathElement can't be abstract.
AnimatedString get href => wrap_jso(_blink.BlinkSVGMPathElement.instance.href_Getter_(unwrap_jso(this))); AnimatedString get href => _blink.BlinkSVGMPathElement.instance.href_Getter_(this);
$endif $endif
} }

View file

@ -17,7 +17,7 @@ $if DARTIUM
@DomName('ServiceWorkerMessageEvent.data') @DomName('ServiceWorkerMessageEvent.data')
@DocsEditable() @DocsEditable()
dynamic get data => convertNativeToDart_SerializedScriptValue( dynamic get data => convertNativeToDart_SerializedScriptValue(
_blink.BlinkMessageEvent.instance.data_Getter_(unwrap_jso(this))); _blink.BlinkMessageEvent.instance.data_Getter_(this));
$else $else
// TODO(alanknight): This really should be generated by the // TODO(alanknight): This really should be generated by the
// _OutputConversion in the systemnative.py script, but that doesn't // _OutputConversion in the systemnative.py script, but that doesn't

View file

@ -20,14 +20,14 @@ $if DART2JS
int get __radiusX => JS('num', '#.radiusX', this).round(); int get __radiusX => JS('num', '#.radiusX', this).round();
int get __radiusY => JS('num', '#.radiusY', this).round(); int get __radiusY => JS('num', '#.radiusY', this).round();
$else $else
int get __clientX => _blink.BlinkTouch.instance.clientX_Getter_(unwrap_jso(this)).round(); int get __clientX => _blink.BlinkTouch.instance.clientX_Getter_(this).round();
int get __clientY => _blink.BlinkTouch.instance.clientY_Getter_(unwrap_jso(this)).round(); int get __clientY => _blink.BlinkTouch.instance.clientY_Getter_(this).round();
int get __screenX => _blink.BlinkTouch.instance.screenX_Getter_(unwrap_jso(this)).round(); int get __screenX => _blink.BlinkTouch.instance.screenX_Getter_(this).round();
int get __screenY => _blink.BlinkTouch.instance.screenY_Getter_(unwrap_jso(this)).round(); int get __screenY => _blink.BlinkTouch.instance.screenY_Getter_(this).round();
int get __pageX => _blink.BlinkTouch.instance.pageX_Getter_(unwrap_jso(this)).round(); int get __pageX => _blink.BlinkTouch.instance.pageX_Getter_(this).round();
int get __pageY => _blink.BlinkTouch.instance.pageY_Getter_(unwrap_jso(this)).round(); int get __pageY => _blink.BlinkTouch.instance.pageY_Getter_(this).round();
int get __radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(unwrap_jso(this)).round(); int get __radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(this).round();
int get __radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(unwrap_jso(this)).round(); int get __radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(this).round();
$endif $endif
@DomName('Touch.clientX') @DomName('Touch.clientX')

View file

@ -44,7 +44,7 @@ $if DART2JS
type, convertDartToNative_Dictionary(options)); type, convertDartToNative_Dictionary(options));
$else $else
return wrap_jso(_blink.BlinkWheelEvent.instance.constructorCallback_2_(type, convertDartToNative_Dictionary(options))); return _blink.BlinkWheelEvent.instance.constructorCallback_2_(type, convertDartToNative_Dictionary(options));
$endif $endif
} }

View file

@ -297,19 +297,19 @@ $if DART2JS
$else $else
@DomName('Window.pageXOffset') @DomName('Window.pageXOffset')
@DocsEditable() @DocsEditable()
int get pageXOffset => _blink.BlinkWindow.instance.pageXOffset_Getter_(unwrap_jso(this)).round(); int get pageXOffset => _blink.BlinkWindow.instance.pageXOffset_Getter_(this).round();
@DomName('Window.pageYOffset') @DomName('Window.pageYOffset')
@DocsEditable() @DocsEditable()
int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(unwrap_jso(this)).round(); int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(this).round();
@DomName('Window.scrollX') @DomName('Window.scrollX')
@DocsEditable() @DocsEditable()
int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(unwrap_jso(this)).round(); int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(this).round();
@DomName('Window.scrollY') @DomName('Window.scrollY')
@DocsEditable() @DocsEditable()
int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(unwrap_jso(this)).round(); int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(this).round();
$endif $endif
} }

View file

@ -9,15 +9,15 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _WorkerLocation can't be abstract. // Override these methods for Dartium _WorkerLocation can't be abstract.
String get hash => _blink.BlinkWorkerLocation.instance.hash_Getter_(unwrap_jso(this)); String get hash => _blink.BlinkWorkerLocation.instance.hash_Getter_(this);
String get host => _blink.BlinkWorkerLocation.instance.host_Getter_(unwrap_jso(this)); String get host => _blink.BlinkWorkerLocation.instance.host_Getter_(this);
String get hostname => _blink.BlinkWorkerLocation.instance.hostname_Getter_(unwrap_jso(this)); String get hostname => _blink.BlinkWorkerLocation.instance.hostname_Getter_(this);
String get href => _blink.BlinkWorkerLocation.instance.href_Getter_(unwrap_jso(this)); String get href => _blink.BlinkWorkerLocation.instance.href_Getter_(this);
String get origin => _blink.BlinkWorkerLocation.instance.origin_Getter_(unwrap_jso(this)); String get origin => _blink.BlinkWorkerLocation.instance.origin_Getter_(this);
String get pathname => _blink.BlinkWorkerLocation.instance.pathname_Getter_(unwrap_jso(this)); String get pathname => _blink.BlinkWorkerLocation.instance.pathname_Getter_(this);
String get port => _blink.BlinkWorkerLocation.instance.port_Getter_(unwrap_jso(this)); String get port => _blink.BlinkWorkerLocation.instance.port_Getter_(this);
String get protocol => _blink.BlinkWorkerLocation.instance.protocol_Getter_(unwrap_jso(this)); String get protocol => _blink.BlinkWorkerLocation.instance.protocol_Getter_(this);
String get search => _blink.BlinkWorkerLocation.instance.search_Getter_(unwrap_jso(this)); String get search => _blink.BlinkWorkerLocation.instance.search_Getter_(this);
$endif $endif
} }

View file

@ -9,15 +9,15 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
$!MEMBERS $!MEMBERS
$if DARTIUM $if DARTIUM
// Override these methods for Dartium _WorkerNavigator can't be abstract. // Override these methods for Dartium _WorkerNavigator can't be abstract.
String get appCodeName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(unwrap_jso(this)); String get appCodeName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(this);
String get appName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(unwrap_jso(this)); String get appName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(this);
String get appVersion => _blink.BlinkWorkerNavigator.instance.appVersion_Getter_(unwrap_jso(this)); String get appVersion => _blink.BlinkWorkerNavigator.instance.appVersion_Getter_(this);
bool get dartEnabled => _blink.BlinkWorkerNavigator.instance.dartEnabled_Getter_(unwrap_jso(this)); bool get dartEnabled => _blink.BlinkWorkerNavigator.instance.dartEnabled_Getter_(this);
String get platform => _blink.BlinkWorkerNavigator.instance.platform_Getter_(unwrap_jso(this)); String get platform => _blink.BlinkWorkerNavigator.instance.platform_Getter_(this);
String get product => _blink.BlinkWorkerNavigator.instance.product_Getter_(unwrap_jso(this)); String get product => _blink.BlinkWorkerNavigator.instance.product_Getter_(this);
String get userAgent => _blink.BlinkWorkerNavigator.instance.userAgent_Getter_(unwrap_jso(this)); String get userAgent => _blink.BlinkWorkerNavigator.instance.userAgent_Getter_(this);
int get hardwareConcurrency => _blink.BlinkWorkerNavigator.instance.hardwareConcurrency_Getter_(unwrap_jso(this)); int get hardwareConcurrency => _blink.BlinkWorkerNavigator.instance.hardwareConcurrency_Getter_(this);
bool get onLine => _blink.BlinkWorkerNavigator.instance.onLine_Getter_(unwrap_jso(this)); bool get onLine => _blink.BlinkWorkerNavigator.instance.onLine_Getter_(this);
$endif $endif
} }

View file

@ -404,9 +404,9 @@ $endif
$if JSINTEROP $if JSINTEROP
void open(String method, String url, {bool async, String user, String password}) { void open(String method, String url, {bool async, String user, String password}) {
if (async == null && user == null && password == null) { if (async == null && user == null && password == null) {
_blink.BlinkXMLHttpRequest.instance.open_Callback_2_(unwrap_jso(this), method, url); _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url);
} else { } else {
_blink.BlinkXMLHttpRequest.instance.open_Callback_5_(unwrap_jso(this), method, url, async, user, password); _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, async, user, password);
} }
} }
$else $else