Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(479)

Unified Diff: sdk/lib/html/html_common/conversions_dartium.dart

Issue 3005913003: Revert: Removed Dartium SDK libs (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/html/html_common/conversions_dartium.dart
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
new file mode 100644
index 0000000000000000000000000000000000000000..892cc1e081347760e1055a57ea6b4650f0a3630c
--- /dev/null
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -0,0 +1,294 @@
+part of html_common;
+
+convertDartToNative_PrepareForStructuredClone(value) =>
+ new _StructuredCloneDartium()
+ .convertDartToNative_PrepareForStructuredClone(value);
+
+convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) =>
+ new _AcceptStructuredCloneDartium()
+ .convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
+
+class _StructuredCloneDartium extends _StructuredClone {
+ newJsMap() => js.JsNative.newObject();
+ putIntoMap(map, key, value) => js.JsNative.setProperty(map, key, value);
+ newJsList(length) => js.JsNative.newArray()..length = length;
+ cloneNotRequired(e) => e is js.JSObject || e is TypedData || e is ByteBuffer;
+}
+
+/// A version of _AcceptStructuredClone, but using a different algorithm
+/// so we can take advantage of an identity HashMap on Dartium without
+/// the bad side-effect of modifying the JS source objects if we do the same in
+/// dart2js.
+///
+/// This no longer inherits anything from _AcceptStructuredClone
+/// and is never used polymorphically with it, so it doesn't inherit.
+class _AcceptStructuredCloneDartium {
+ newDartList(length) => new List(length);
+
+ // As long as we stick to JSObject instead of intermingling legacy JsObject,
+ // we can simply use identical.
+ bool identicalInJs(a, b) => identical(a, b);
+
+ void forEachJsField(jsObject, action) {
+ var keys = js.JsNative.callMethod(_object, "keys", [jsObject]);
+ for (var key in keys) {
+ action(key, js.JsNative.getProperty(jsObject, key));
+ }
+ }
+
+ // Keep track of the clones, keyed by the original object. If we're
+ // not copying, these may be the same.
+ var clones = new HashMap.identity();
+ bool mustCopy = false;
+
+ Object findSlot(value) {
+ return clones.putIfAbsent(value, () => null);
+ }
+
+ writeSlot(original, x) {
+ clones[original] = x;
+ }
+
+ walk(e) {
+ if (e == null) return e;
+ if (e is bool) return e;
+ if (e is num) return e;
+ if (e is String) return e;
+ if (e is DateTime) return e;
+
+ if (isJavaScriptRegExp(e)) {
+ // TODO(sra).
+ throw new UnimplementedError('structured clone of RegExp');
+ }
+
+ if (isJavaScriptPromise(e)) {
+ return convertNativePromiseToDartFuture(e);
+ }
+
+ if (isJavaScriptSimpleObject(e)) {
+ // TODO(sra): If mustCopy is false, swizzle the prototype for one of a Map
+ // implementation that uses the properies as storage.
+ var copy = findSlot(e);
+ if (copy != null) return copy;
+ copy = {};
+
+ writeSlot(e, copy);
+ forEachJsField(e, (key, value) => copy[key] = walk(value));
+ return copy;
+ }
+
+ if (isJavaScriptArray(e)) {
+ var copy = findSlot(e);
+ if (copy != null) return copy;
+
+ int length = e.length;
+ // Since a JavaScript Array is an instance of Dart List, we can modify it
+ // in-place unless we must copy.
+ copy = mustCopy ? newDartList(length) : e;
+ writeSlot(e, copy);
+
+ for (int i = 0; i < length; i++) {
+ copy[i] = walk(e[i]);
+ }
+ return copy;
+ }
+
+ // Assume anything else is already a valid Dart object, either by having
+ // already been processed, or e.g. a clonable native class.
+ return e;
+ }
+
+ convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) {
+ this.mustCopy = mustCopy;
+ var copy = walk(object);
+ return copy;
+ }
+}
+
+final _dateConstructor = js.JsNative.getProperty(window, "Date");
+final _regexConstructor = js.JsNative.getProperty(window, "RegExp");
+
+bool isJavaScriptDate(value) =>
+ value is js.JSObject && js.JsNative.instanceof(value, _dateConstructor);
+bool isJavaScriptRegExp(value) =>
+ value is js.JSObject && js.JsNative.instanceof(value, _regexConstructor);
+bool isJavaScriptArray(value) => value is js.JSArray;
+
+final _object = js.JsNative.getProperty(window, "Object");
+final _getPrototypeOf = js.JsNative.getProperty(_object, "getPrototypeOf");
+_getProto(object) {
+ return _getPrototypeOf(object);
+}
+
+final _objectProto = js.JsNative.getProperty(_object, "prototype");
+
+bool isJavaScriptSimpleObject(value) {
+ if (value is! js.JSObject) return false;
+ var proto = _getProto(value);
+ 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) =>
+ isJavaScriptArray(value) &&
+ js.JsNative.getProperty(value, "immutable$list") != null;
+
+final _promiseConstructor = js.JsNative.getProperty(window, 'Promise');
+bool isJavaScriptPromise(value) =>
+ value is js.JSObject &&
+ identical(
+ js.JsNative.getProperty(value, 'constructor'), _promiseConstructor);
+
+Future convertNativePromiseToDartFuture(js.JSObject promise) {
+ var completer = new Completer();
+ var newPromise = js.JsNative.callMethod(
+ js.JsNative.callMethod(promise, "then",
+ [js.allowInterop((result) => completer.complete(result))]),
+ "catch",
+ [js.allowInterop((result) => completer.completeError(result))]);
+ return completer.future;
+}
+
+convertDartToNative_DateTime(DateTime date) {
+ return date;
+}
+
+/// Creates a Dart Rectangle from a Javascript object with properties
+/// left, top, width and height or a 4 element array of integers. Used internally in Dartium.
+Rectangle make_dart_rectangle(r) {
+ if (r == null) return null;
+ if (r is List) {
+ return new Rectangle(r[0], r[1], r[2], r[3]);
+ }
+
+ 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
+// is the Dartium only version it uses dart:js.
+// TODO(alanknight): This could probably be unified with the dart2js conversions
+// code in html_common and be more general.
+convertDartToNative_Dictionary(Map dict) {
+ if (dict == null) return null;
+ var jsObject = js.JsNative.newObject();
+ dict.forEach((String key, value) {
+ if (value is List) {
+ var jsArray = js.JsNative.newArray();
+ value.forEach((elem) {
+ jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem) : elem);
+ });
+ js.JsNative.setProperty(jsObject, key, jsArray);
+ } else {
+ js.JsNative.setProperty(jsObject, key, value);
+ }
+ });
+ return jsObject;
+}
+
+// Creates a Dart class to allow members of the Map to be fetched (as if getters exist).
+// TODO(terry): Need to use package:js but that's a problem in dart:html. Talk to
+// Jacob about how to do this properly using dart:js.
+class _ReturnedDictionary {
+ Map _values;
+
+ noSuchMethod(Invocation invocation) {
+ var key = MirrorSystem.getName(invocation.memberName);
+ if (invocation.isGetter) {
+ return _values[key];
+ } else if (invocation.isSetter && key.endsWith('=')) {
+ key = key.substring(0, key.length - 1);
+ _values[key] = invocation.positionalArguments[0];
+ }
+ }
+
+ Map get toMap => _values;
+
+ _ReturnedDictionary(Map value) : _values = value != null ? value : {};
+}
+
+// Helper function to wrapped a returned dictionary from blink to a Dart looking
+// class.
+convertNativeDictionaryToDartDictionary(values) {
+ 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).
+List convertDartToNative_StringArray(List<String> input) => input;
+
+// Converts a Dart list into a JsArray. For the Dartium version only.
+convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
+
+// Incredibly slow implementation to lookup the runtime type for an object.
+// Fortunately, performance doesn't matter much as the results are cached
+// as long as the object being looked up has a valid prototype.
+// TODO(jacobr): we should track the # of lookups to ensure that things aren't
+// going off the rails due to objects with null prototypes, etc.
+// Note: unlike all other methods in this class, here we intentionally use
+// the old JsObject types to bootstrap the new typed bindings.
+Type lookupType(js.JsObject jsObject, bool isElement) {
+ try {
+ // TODO(jacobr): add static methods that return the runtime type of the patch
+ // class so that this code works as expected.
+ if (jsObject is js.JsArray) {
+ return js.JSArray.instanceRuntimeType;
+ }
+ if (jsObject is js.JsFunction) {
+ return js.JSFunction.instanceRuntimeType;
+ }
+
+ var constructor = js.JsNative.getProperty(jsObject, 'constructor');
+ if (constructor == null) {
+ // Perfectly valid case for JavaScript objects where __proto__ has
+ // intentionally been set to null.
+ // We should track and warn about this case as peformance will be poor.
+ return js.JSObject.instanceRuntimeType;
+ }
+ var jsTypeName = js.JsNative.getProperty(constructor, 'name');
+ if (jsTypeName is! String || jsTypeName.length == 0) {
+ // Not an html type.
+ return js.JSObject.instanceRuntimeType;
+ }
+
+ var dartClass_instance;
+ var customElementClass = null;
+ var extendsTag = "";
+
+ Type type = getHtmlCreateType(jsTypeName);
+ if (type != null) return type;
+
+ // Start walking the prototype chain looking for a JS class.
+ var prototype = js.JsNative.getProperty(jsObject, '__proto__');
+ while (prototype != null) {
+ // We're a Dart class that's pointing to a JS class.
+ var constructor = js.JsNative.getProperty(prototype, 'constructor');
+ if (constructor != null) {
+ jsTypeName = js.JsNative.getProperty(constructor, 'name');
+ type = getHtmlCreateType(jsTypeName);
+ if (type != null) return type;
+ }
+ prototype = js.JsNative.getProperty(prototype, '__proto__');
+ }
+ } catch (e) {
+ // This case can happen for cross frame objects.
+ if (js.JsNative.hasProperty(e, "postMessage")) {
+ // assume this is a Window. To match Dart2JS, separate conversion code
+ // in dart:html will switch the wrapper to a cross frame window as
+ // required.
+ // TODO(jacobr): we could consider removing this code completely.
+ return Window.instanceRuntimeType;
+ }
+ }
+ return js.JSObject.instanceRuntimeType;
+}
« no previous file with comments | « sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart ('k') | sdk/lib/html/html_common/html_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698