| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..282e5fab99098b7cb81972ec4e952dc82d8d1362
|
| --- /dev/null
|
| +++ b/sdk/lib/js/dart2js/js_dart2js.dart
|
| @@ -0,0 +1,197 @@
|
| +// 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
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library dart.js;
|
| +
|
| +import 'dart:_foreign_helper' show JS;
|
| +import 'dart:_js_helper' show convertDartClosureToJS;
|
| +
|
| +JsObject get context {
|
| + return new JsObject._fromJs(JS('=Object', 'window'));
|
| +}
|
| +
|
| +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('=Object', 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);
|
| +}
|
| +
|
| +class JsObject implements Serializable<JsObject> {
|
| + final dynamic _jsObject;
|
| +
|
| + JsObject._fromJs(this._jsObject);
|
| +
|
| + factory JsObject(Serializable<JsFunction> constructor, [List arguments]) {
|
| + final constr = _convertToJS(constructor);
|
| + if (arguments == null) {
|
| + return new JsObject._fromJs(JS('=Object', 'new #()', constr));
|
| + }
|
| + final args = arguments.map(_convertToJS).toList();
|
| + switch (args.length) {
|
| + case 0:
|
| + return new JsObject._fromJs(JS('=Object', 'new #()', constr));
|
| + case 1:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#)', constr, args[0]));
|
| + case 2:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#)', constr, args[0],
|
| + args[1]));
|
| + case 3:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#)', constr,
|
| + args[0], args[1], args[2]));
|
| + case 4:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#)', constr,
|
| + args[0], args[1], args[2], args[3]));
|
| + case 5:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#)', constr,
|
| + args[0], args[1], args[2], args[3], args[4]));
|
| + case 6:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#,#)', constr,
|
| + args[0], args[1], args[2], args[3], args[4], args[5]));
|
| + case 7:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#,#,#)',
|
| + constr, args[0], args[1], args[2], args[3], args[4], args[5],
|
| + args[6]));
|
| + case 8:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#,#,#,#)',
|
| + constr, args[0], args[1], args[2], args[3], args[4], args[5],
|
| + args[6], args[7]));
|
| + case 9:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#,#,#,#,#)',
|
| + constr, args[0], args[1], args[2], args[3], args[4], args[5],
|
| + args[6], args[7], args[8]));
|
| + case 10:
|
| + return new JsObject._fromJs(JS('=Object', 'new #(#,#,#,#,#,#,#,#,#,#)',
|
| + constr, args[0], args[1], args[2], args[3], args[4], args[5],
|
| + args[6], args[7], args[8], args[9]));
|
| + }
|
| + return new JsObject._fromJs(JS('=Object', r'''(function(){
|
| +var Type = function(){};
|
| +Type.prototype = #.prototype;
|
| +var instance = new Type();
|
| +ret = #.apply(instance, #);
|
| +ret = Object(ret) === ret ? ret : instance;
|
| +return ret;
|
| +})()''', constr, constr, args));
|
| + }
|
| +
|
| + factory JsObject._json(data) => new JsObject._fromJs(_convertDataTree(data));
|
| +
|
| + static _convertDataTree(data) {
|
| + if (data is Map) {
|
| + final convertedData = JS('=Object', '{}');
|
| + for (var key in data.keys) {
|
| + JS('=Object', '#[#]=#', convertedData, key,
|
| + _convertDataTree(data[key]));
|
| + }
|
| + return convertedData;
|
| + } else if (data is Iterable) {
|
| + return data.map(_convertDataTree).toList();
|
| + } else {
|
| + return _convertToJS(data);
|
| + }
|
| + }
|
| +
|
| + JsObject toJs() => this;
|
| +
|
| + operator[](key) =>
|
| + _convertToDart(JS('=Object', '#[#]', _convertToJS(this), key));
|
| + operator[]=(key, value) => JS('void', '#[#]=#', _convertToJS(this), key,
|
| + _convertToJS(value));
|
| +
|
| + int get hashCode => 0;
|
| +
|
| + operator==(other) => other is JsObject &&
|
| + JS('bool', '# === #', _convertToJS(this), _convertToJS(other));
|
| +
|
| + bool hasProperty(String property) => JS('bool', '# in #', property,
|
| + _convertToJS(this));
|
| +
|
| + void deleteProperty(String name) {
|
| + JS('void', 'delete #[#]', _convertToJS(this), name);
|
| + }
|
| +
|
| + bool instanceof(Serializable<JsFunction> type) =>
|
| + JS('bool', '# instanceof #', _convertToJS(this), _convertToJS(type));
|
| +
|
| + String toString() {
|
| + try {
|
| + return JS('String', '#.toString()', _convertToJS(this));
|
| + } catch(e) {
|
| + return super.toString();
|
| + }
|
| + }
|
| +
|
| + callMethod(String name, [List args]) =>
|
| + _convertToDart(JS('=Object', '#[#].apply(#, #)', _convertToJS(this), name,
|
| + _convertToJS(this),
|
| + args == null ? null : args.map(_convertToJS).toList()));
|
| +}
|
| +
|
| +class JsFunction extends JsObject implements Serializable<JsFunction> {
|
| + JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
|
| + apply(thisArg, [List args]) =>
|
| + _convertToDart(JS('=Object', '#.apply(#, #)', _convertToJS(this),
|
| + _convertToJS(thisArg),
|
| + args == null ? null : args.map(_convertToJS).toList()));
|
| +}
|
| +
|
| +abstract class Serializable<T> {
|
| + T toJs();
|
| +}
|
| +
|
| +dynamic _convertToJS(dynamic o) {
|
| + if (o == null) {
|
| + return null;
|
| + } else if (o is String || o is num || o is bool) {
|
| + return o;
|
| + } else if (o is JsObject) {
|
| + return o._jsObject;
|
| + } else if (o is Serializable) {
|
| + return _convertToJS(o.toJs());
|
| + } else if (o is Function) {
|
| + return _convertToJS(new Callback(o));
|
| + } else {
|
| + return JS('=Object', 'new DartProxy(#)', o);
|
| + }
|
| +}
|
| +
|
| +dynamic _convertToDart(dynamic o) {
|
| + if (JS('bool', '# == null', o)) {
|
| + return null;
|
| + } else if (JS('bool', 'typeof # == "string" || # instanceof String', o, o) ||
|
| + JS('bool', 'typeof # == "number" || # instanceof Number', o, o) ||
|
| + JS('bool', 'typeof # == "boolean" || # instanceof Boolean', o, o)) {
|
| + return o;
|
| + } else if (JS('bool', '# instanceof Function', o)) {
|
| + return new JsFunction._fromJs(JS('=Object', '#', o));
|
| + } else if (JS('bool', '# instanceof DartProxy', o)) {
|
| + return JS('var', '#.o', o);
|
| + } else {
|
| + return new JsObject._fromJs(JS('=Object', '#', o));
|
| + }
|
| +}
|
|
|