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

Unified Diff: sdk/lib/js/dart2js/js_dart2js.dart

Issue 27514003: A few API changes: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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
« no previous file with comments | « no previous file | sdk/lib/js/dartium/js_dartium.dart » ('j') | sdk/lib/js/dartium/js_dartium.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/js/dart2js/js_dart2js.dart
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 3fb3756565b34dfb2a1e6c5adac3e58bf0f53d6a..213a444213765ad768853ced1f4d49e66d7afbf6 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -4,50 +4,17 @@
library dart.js;
+import 'dart:html' show Blob, ImageData, Node;
+import 'dart:collection' show HashMap;
+import 'dart:indexed_db' show KeyRange;
+import 'dart:typed_data' show TypedData;
+
import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
+import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject;
import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
final JsObject context = new JsObject._fromJs(Primitives.computeGlobalThis());
-JsObject jsify(dynamic data) => data == null ? null : new JsObject._json(data);
-
-class Callback implements Serializable<JsFunction> {
- final Function _f; // here to allow capture in closure
- final bool _withThis; // here to allow capture in closure
- dynamic _jsFunction;
-
- Callback._(this._f, this._withThis) {
- _jsFunction = JS('', r'''
-(function(){
- var f = #;
- return function(){
- return f(this, Array.prototype.slice.apply(arguments));
- };
-}).apply(this)''', convertDartClosureToJS(_call, 2));
- }
-
- factory Callback(Function f) => new Callback._(f, false);
- factory Callback.withThis(Function f) => new Callback._(f, true);
-
- _call(thisArg, List args) {
- final arguments = new List.from(args);
- if (_withThis) arguments.insert(0, thisArg);
- final dartArgs = arguments.map(_convertToDart).toList();
- return _convertToJS(Function.apply(_f, dartArgs));
- }
-
- JsFunction toJs() => new JsFunction._fromJs(_jsFunction);
-}
-
-/*
- * TODO(justinfagnani): add tests and make public when we remove Callback.
- *
- * Returns a [JsFunction] that captures its 'this' binding and calls [f]
- * with the value of this passed as the first argument.
- */
-JsFunction _captureThis(Function f) =>
- new JsFunction._fromJs(_convertDartFunction(f, captureThis: true));
-
_convertDartFunction(Function f, {bool captureThis: false}) {
return JS('',
'function(_call, f, captureThis) {'
@@ -67,18 +34,46 @@ _callDartFunction(callback, bool captureThis, self, List arguments) {
}
-class JsObject implements Serializable<JsObject> {
+class JsObject {
// The wrapped JS object.
final dynamic _jsObject;
JsObject._fromJs(this._jsObject) {
+ assert(_jsObject != null);
// Remember this proxy for the JS object
_getDartProxy(_jsObject, _DART_OBJECT_PROPERTY_NAME, (o) => this);
}
- // TODO(vsm): Type constructor as Serializable<JsFunction> when
- // dartbug.com/11854 is fixed.
- factory JsObject(constructor, [List arguments]) {
+ /**
+ * Expert use only:
+ *
+ * Use this constructor only if you wish to get access to JS properties
+ * attached to a browser host object such as a Node or Blob. This constructor
+ * will return a JsObject proxy on [object], even though the object would
+ * normally be returned as a native Dart object.
+ *
+ * An exception will be thrown if [object] is a primitive type or null.
+ */
+ factory JsObject.fromBrowserObject(Object object) {
+ if (object is num || object is String || object is bool || object == null) {
+ throw new ArgumentError(
+ "object cannot be a num, string, bool, or null");
+ }
+ return new JsObject._fromJs(_convertToJS(object));
+ }
+
+ /**
+ * Converts a json-like [data] to a JavaScript map or array and return a
+ * [JsObject] to it.
+ */
+ factory JsObject.jsify(Object object) {
+ if ((object is! Map) && (object is! Iterable)) {
+ throw new ArgumentError("object must be a Map or Iterable");
+ }
+ return new JsObject._fromJs(_convertDataTree(object));
+ }
+
+ factory JsObject(JsFunction constructor, [List arguments]) {
var constr = _convertToJS(constructor);
if (arguments == null) {
return new JsObject._fromJs(JS('', 'new #()', constr));
@@ -94,38 +89,50 @@ class JsObject implements Serializable<JsObject> {
var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
// Without this line, calling factoryFunction as a constructor throws
JS('String', 'String(#)', factoryFunction);
- return new JsObject._fromJs(JS('', 'new #()', factoryFunction));
+ // This could return an UnknownJavaScriptObject, or a native
+ // object for which there is an interceptor
+ var jsObj = JS('JavaScriptObject', 'new #()', factoryFunction);
+ return new JsObject._fromJs(jsObj);
}
- factory JsObject._json(data) => new JsObject._fromJs(_convertDataTree(data));
-
+ // TODO: handle cycles
static _convertDataTree(data) {
- if (data is Map) {
- final convertedData = JS('=Object', '{}');
- for (var key in data.keys) {
- JS('=Object', '#[#]=#', convertedData, key,
- _convertDataTree(data[key]));
+ var _convertedObjects = new HashMap.identity();
+
+ _convert(o) {
+ if (_convertedObjects.containsKey(o)) {
+ return _convertedObjects[o];
+ }
+ if (o is Map) {
+ final convertedMap = JS('=Object', '{}');
+ _convertedObjects[o] = convertedMap;
+ for (var key in o.keys) {
+ JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+ }
+ return convertedMap;
+ } else if (o is Iterable) {
+ var convertedList = [];
+ _convertedObjects[o] = convertedList;
+ convertedList.addAll(o.map(_convert));
+ return convertedList;
+ } else {
+ return _convertToJS(o);
}
- return convertedData;
- } else if (data is Iterable) {
- return data.map(_convertDataTree).toList();
- } else {
- return _convertToJS(data);
}
- }
- JsObject toJs() => this;
+ return _convert(data);
+ }
/**
* Returns the value associated with [key] from the proxied JavaScript
* object.
*
- * [key] must either be a [String] or [int].
+ * [key] must either be a [String] or [num].
*/
// TODO(justinfagnani): rename key/name to property
dynamic operator[](key) {
- if (key is! String && key is! int) {
- throw new ArgumentError("key is not a String or int");
+ if (key is! String && key is! num) {
+ throw new ArgumentError("key is not a String or num");
}
return _convertToDart(JS('', '#[#]', _jsObject, key));
}
@@ -134,11 +141,11 @@ class JsObject implements Serializable<JsObject> {
* Sets the value associated with [key] from the proxied JavaScript
* object.
*
- * [key] must either be a [String] or [int].
+ * [key] must either be a [String] or [num].
*/
operator[]=(key, value) {
- if (key is! String && key is! int) {
- throw new ArgumentError("key is not a String or int");
+ if (key is! String && key is! num) {
+ throw new ArgumentError("key is not a String or num");
}
JS('', '#[#]=#', _jsObject, key, _convertToJS(value));
}
@@ -149,21 +156,19 @@ class JsObject implements Serializable<JsObject> {
JS('bool', '# === #', _jsObject, other._jsObject);
bool hasProperty(name) {
- if (name is! String && name is! int) {
- throw new ArgumentError("name is not a String or int");
+ if (name is! String && name is! num) {
+ throw new ArgumentError("name is not a String or num");
}
return JS('bool', '# in #', name, _jsObject);
}
void deleteProperty(name) {
- if (name is! String && name is! int) {
- throw new ArgumentError("name is not a String or int");
+ if (name is! String && name is! num) {
+ throw new ArgumentError("name is not a String or num");
}
JS('bool', 'delete #[#]', _jsObject, name);
}
- // TODO(vsm): Type type as Serializable<JsFunction> when
- // dartbug.com/11854 is fixed.
bool instanceof(type) {
alexandre.ardhuin 2013/10/20 07:17:00 `type` should be JsFunction
return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
}
@@ -177,8 +182,8 @@ class JsObject implements Serializable<JsObject> {
}
dynamic callMethod(name, [List args]) {
- if (name is! String && name is! int) {
- throw new ArgumentError("name is not a String or int");
+ if (name is! String && name is! num) {
+ throw new ArgumentError("name is not a String or num");
}
return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, name,
_jsObject,
@@ -186,20 +191,25 @@ class JsObject implements Serializable<JsObject> {
}
}
-class JsFunction extends JsObject implements Serializable<JsFunction> {
+class JsFunction extends JsObject {
+
+ /**
+ * Returns a [JsFunction] that captures its 'this' binding and calls [f]
+ * with the value of this passed as the first argument.
+ */
+ factory JsFunction.withThis(Function f) {
+ var jsFunc = _convertDartFunction(f, captureThis: true);
+ return new JsFunction._fromJs(jsFunc);
+ }
JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
- dynamic apply(thisArg, [List args]) =>
+ dynamic apply(List args, { thisArg }) =>
_convertToDart(JS('', '#.apply(#, #)', _jsObject,
_convertToJS(thisArg),
args == null ? null : args.map(_convertToJS).toList()));
}
-abstract class Serializable<T> {
- T toJs();
-}
-
// property added to a Dart object referencing its JS-side DartObject proxy
const _DART_OBJECT_PROPERTY_NAME = r'_$dart_dartObject';
const _DART_CLOSURE_PROPERTY_NAME = r'_$dart_dartClosure';
@@ -224,12 +234,14 @@ bool _defineProperty(o, String name, value) {
dynamic _convertToJS(dynamic o) {
if (o == null) {
return null;
- } else if (o is String || o is num || o is bool) {
+ } else if (o is String || o is num || o is bool
+ || o is Blob || o is KeyRange || o is ImageData || o is Node
+ || o is TypedData) {
return o;
+ } else if (o is DateTime) {
+ return Primitives.lazyAsJsDate(o);
} else if (o is JsObject) {
return o._jsObject;
- } else if (o is Serializable) {
- return _convertToJS(o.toJs());
} else if (o is Function) {
return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
var jsFunction = _convertDartFunction(o);
@@ -260,6 +272,9 @@ Object _convertToDart(o) {
JS('bool', 'typeof # == "number"', o) ||
JS('bool', 'typeof # == "boolean"', o)) {
return o;
+ } else if (o is Blob || o is DateTime || o is KeyRange
+ || o is ImageData || o is Node || o is TypedData) {
+ return JS('Blob|DateTime|KeyRange|ImageData|Node|TypedData', '#', o);
} else if (JS('bool', 'typeof # == "function"', o)) {
return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
(o) => new JsFunction._fromJs(o));
« no previous file with comments | « no previous file | sdk/lib/js/dartium/js_dartium.dart » ('j') | sdk/lib/js/dartium/js_dartium.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698