OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Support for interoperating with JavaScript. | 6 * Support for interoperating with JavaScript. |
7 * | 7 * |
8 * This library provides access to JavaScript objects from Dart, allowing | 8 * This library provides access to JavaScript objects from Dart, allowing |
9 * Dart code to get and set properties, and call methods of JavaScript objects | 9 * Dart code to get and set properties, and call methods of JavaScript objects |
10 * and invoke JavaScript functions. The library takes care of converting | 10 * and invoke JavaScript functions. The library takes care of converting |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 * `a` and `b` defined: | 80 * `a` and `b` defined: |
81 * | 81 * |
82 * var jsMap = new JsObject.jsify({'a': 1, 'b': 2}); | 82 * var jsMap = new JsObject.jsify({'a': 1, 'b': 2}); |
83 * | 83 * |
84 * This expression creates a JavaScript array: | 84 * This expression creates a JavaScript array: |
85 * | 85 * |
86 * var jsArray = new JsObject.jsify([1, 2, 3]); | 86 * var jsArray = new JsObject.jsify([1, 2, 3]); |
87 */ | 87 */ |
88 library dart.js; | 88 library dart.js; |
89 | 89 |
90 import 'dart:async' show Zone; | |
90 import 'dart:html' show Blob, Event, ImageData, Node, Window; | 91 import 'dart:html' show Blob, Event, ImageData, Node, Window; |
91 import 'dart:collection' show HashMap, ListMixin; | 92 import 'dart:collection' show HashMap, ListMixin; |
92 import 'dart:indexed_db' show KeyRange; | 93 import 'dart:indexed_db' show KeyRange; |
93 import 'dart:typed_data' show TypedData; | 94 import 'dart:typed_data' show TypedData; |
94 | 95 |
95 import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS; | 96 import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS; |
96 import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject; | 97 import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject; |
97 import 'dart:_js_helper' show Primitives, convertDartClosureToJS, | 98 import 'dart:_js_helper' show Primitives, convertDartClosureToJS, |
98 getIsolateAffinityTag; | 99 getIsolateAffinityTag; |
99 | 100 |
100 final JsObject context = _wrapToDart(Primitives.computeGlobalThis()); | 101 final JsObject context = _wrapToDart(Primitives.computeGlobalThis()); |
101 | 102 |
102 _convertDartFunction(Function f, {bool captureThis: false}) { | 103 _convertDartFunction(Function f) { |
103 return JS('', | 104 return JS('', |
104 'function(_call, f, captureThis) {' | 105 'function(_call, f) {' |
105 'return function() {' | 106 'return function() {' |
106 'return _call(f, captureThis, this, ' | 107 'return _call(f, Array.prototype.slice.apply(arguments));' |
107 'Array.prototype.slice.apply(arguments));' | |
108 '}' | 108 '}' |
109 '}(#, #, #)', DART_CLOSURE_TO_JS(_callDartFunction), f, captureThis); | 109 '}(#, #)', DART_CLOSURE_TO_JS(_callDartFunction), _applyZoned(f)); |
110 } | 110 } |
111 | 111 |
112 _callDartFunction(callback, bool captureThis, self, List arguments) { | 112 _convertDartFunctionWithThis(Function f) { |
113 if (captureThis) { | 113 return JS('', |
114 arguments = [self]..addAll(arguments); | 114 'function(_call, f) {' |
115 } | 115 'return function() {' |
116 var dartArgs = new List.from(arguments.map(_convertToDart)); | 116 'var args = Array.prototype.slice.apply(arguments);' |
117 return _convertToJS(Function.apply(callback, dartArgs)); | 117 'args.unshift(this);' |
118 'return _call(f, args);' | |
119 '}' | |
120 '}(#, #)', DART_CLOSURE_TO_JS(_callDartFunction), _applyZoned(f)); | |
121 } | |
122 | |
123 _callDartFunction(f, List arguments) => f(arguments); | |
124 | |
125 _applyZoned(f) { | |
126 var callDart = (List arguments) { | |
127 var dartArgs = new List.from(arguments.map(_convertToDart)); | |
128 return _convertToJS(Function.apply(f, dartArgs)); | |
129 }; | |
130 if (Zone.current == Zone.ROOT) return callDart; | |
131 return Zone.current.bindUnaryCallback(callDart, runGuarded: true); | |
floitsch
2014/04/03 12:52:30
are you sure you want to run guarded?
Running guar
justinfagnani
2014/04/10 00:26:59
I'll assume that JS should have a chance to handle
| |
118 } | 132 } |
119 | 133 |
120 /** | 134 /** |
121 * Proxies a JavaScript object to Dart. | 135 * Proxies a JavaScript object to Dart. |
122 * | 136 * |
123 * The properties of the JavaScript object are accessible via the `[]` and | 137 * The properties of the JavaScript object are accessible via the `[]` and |
124 * `[]=` operators. Methods are callable via [callMethod]. | 138 * `[]=` operators. Methods are callable via [callMethod]. |
125 */ | 139 */ |
126 class JsObject { | 140 class JsObject { |
127 // The wrapped JS object. | 141 // The wrapped JS object. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 /** | 330 /** |
317 * Proxies a JavaScript Function object. | 331 * Proxies a JavaScript Function object. |
318 */ | 332 */ |
319 class JsFunction extends JsObject { | 333 class JsFunction extends JsObject { |
320 | 334 |
321 /** | 335 /** |
322 * Returns a [JsFunction] that captures its 'this' binding and calls [f] | 336 * Returns a [JsFunction] that captures its 'this' binding and calls [f] |
323 * with the value of this passed as the first argument. | 337 * with the value of this passed as the first argument. |
324 */ | 338 */ |
325 factory JsFunction.withThis(Function f) { | 339 factory JsFunction.withThis(Function f) { |
326 var jsFunc = _convertDartFunction(f, captureThis: true); | 340 var jsFunc = _convertDartFunctionWithThis(f); |
327 return new JsFunction._fromJs(jsFunc); | 341 return new JsFunction._fromJs(jsFunc); |
328 } | 342 } |
329 | 343 |
330 JsFunction._fromJs(jsObject) : super._fromJs(jsObject); | 344 JsFunction._fromJs(jsObject) : super._fromJs(jsObject); |
331 | 345 |
332 /** | 346 /** |
333 * Invokes the JavaScript function with arguments [args]. If [thisArg] is | 347 * Invokes the JavaScript function with arguments [args]. If [thisArg] is |
334 * supplied it is the value of `this` for the invocation. | 348 * supplied it is the value of `this` for the invocation. |
335 */ | 349 */ |
336 dynamic apply(List args, { thisArg }) => | 350 dynamic apply(List args, { thisArg }) => |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 // Dart in that context. The JS object will have a cached proxy | 578 // Dart in that context. The JS object will have a cached proxy |
565 // but it won't be a valid Dart object in this context. | 579 // but it won't be a valid Dart object in this context. |
566 // For now we throw away the cached proxy, but we should be able | 580 // For now we throw away the cached proxy, but we should be able |
567 // to cache proxies from multiple JS contexts and Dart isolates. | 581 // to cache proxies from multiple JS contexts and Dart isolates. |
568 if (dartProxy == null || !_isLocalObject(o)) { | 582 if (dartProxy == null || !_isLocalObject(o)) { |
569 dartProxy = createProxy(o); | 583 dartProxy = createProxy(o); |
570 _defineProperty(o, propertyName, dartProxy); | 584 _defineProperty(o, propertyName, dartProxy); |
571 } | 585 } |
572 return dartProxy; | 586 return dartProxy; |
573 } | 587 } |
OLD | NEW |