| 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); |
| 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 // Dart in that context. The JS object will have a cached proxy | 587 // Dart in that context. The JS object will have a cached proxy |
| 574 // but it won't be a valid Dart object in this context. | 588 // but it won't be a valid Dart object in this context. |
| 575 // For now we throw away the cached proxy, but we should be able | 589 // For now we throw away the cached proxy, but we should be able |
| 576 // to cache proxies from multiple JS contexts and Dart isolates. | 590 // to cache proxies from multiple JS contexts and Dart isolates. |
| 577 if (dartProxy == null || !_isLocalObject(o)) { | 591 if (dartProxy == null || !_isLocalObject(o)) { |
| 578 dartProxy = createProxy(o); | 592 dartProxy = createProxy(o); |
| 579 _defineProperty(o, propertyName, dartProxy); | 593 _defineProperty(o, propertyName, dartProxy); |
| 580 } | 594 } |
| 581 return dartProxy; | 595 return dartProxy; |
| 582 } | 596 } |
| OLD | NEW |