| 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 JS('void', 'Object.defineProperty(#, #, { value: #})', o, name, value); | 464 JS('void', 'Object.defineProperty(#, #, { value: #})', o, name, value); |
| 465 return true; | 465 return true; |
| 466 } catch(e) { | 466 } catch(e) { |
| 467 // object is native and lies about being extensible | 467 // object is native and lies about being extensible |
| 468 // see https://bugzilla.mozilla.org/show_bug.cgi?id=775185 | 468 // see https://bugzilla.mozilla.org/show_bug.cgi?id=775185 |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 return false; | 471 return false; |
| 472 } | 472 } |
| 473 | 473 |
| 474 Object _getOwnProperty(o, String name) { |
| 475 if (JS('bool', 'Object.prototype.hasOwnProperty.call(#, #)', o, name)) { |
| 476 return JS('', '#[#]', o, name); |
| 477 } |
| 478 return null; |
| 479 } |
| 480 |
| 474 bool _isLocalObject(o) => JS('bool', '# instanceof Object', o); | 481 bool _isLocalObject(o) => JS('bool', '# instanceof Object', o); |
| 475 | 482 |
| 476 dynamic _convertToJS(dynamic o) { | 483 dynamic _convertToJS(dynamic o) { |
| 477 if (o == null) { | 484 if (o == null) { |
| 478 return null; | 485 return null; |
| 479 } else if (o is String || o is num || o is bool | 486 } else if (o is String || o is num || o is bool |
| 480 || o is Blob || o is Event || o is KeyRange || o is ImageData | 487 || o is Blob || o is Event || o is KeyRange || o is ImageData |
| 481 || o is Node || o is TypedData || o is Window) { | 488 || o is Node || o is TypedData || o is Window) { |
| 482 return o; | 489 return o; |
| 483 } else if (o is DateTime) { | 490 } else if (o is DateTime) { |
| 484 return Primitives.lazyAsJsDate(o); | 491 return Primitives.lazyAsJsDate(o); |
| 485 } else if (o is JsObject) { | 492 } else if (o is JsObject) { |
| 486 return o._jsObject; | 493 return o._jsObject; |
| 487 } else if (o is Function) { | 494 } else if (o is Function) { |
| 488 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) { | 495 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) { |
| 489 var jsFunction = _convertDartFunction(o); | 496 var jsFunction = _convertDartFunction(o); |
| 490 // set a property on the JS closure referencing the Dart closure | 497 // set a property on the JS closure referencing the Dart closure |
| 491 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o); | 498 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o); |
| 492 return jsFunction; | 499 return jsFunction; |
| 493 }); | 500 }); |
| 494 } else { | 501 } else { |
| 495 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME, | 502 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME, |
| 496 (o) => JS('', 'new DartObject(#)', o)); | 503 (o) => JS('', 'new DartObject(#)', o)); |
| 497 } | 504 } |
| 498 } | 505 } |
| 499 | 506 |
| 500 Object _getJsProxy(o, String propertyName, createProxy(o)) { | 507 Object _getJsProxy(o, String propertyName, createProxy(o)) { |
| 501 var jsProxy = JS('', '#[#]', o, propertyName); | 508 var jsProxy = _getOwnProperty(o, propertyName); |
| 502 if (jsProxy == null) { | 509 if (jsProxy == null) { |
| 503 jsProxy = createProxy(o); | 510 jsProxy = createProxy(o); |
| 504 _defineProperty(o, propertyName, jsProxy); | 511 _defineProperty(o, propertyName, jsProxy); |
| 505 } | 512 } |
| 506 return jsProxy; | 513 return jsProxy; |
| 507 } | 514 } |
| 508 | 515 |
| 509 // converts a Dart object to a reference to a native JS object | 516 // converts a Dart object to a reference to a native JS object |
| 510 // which might be a DartObject JS->Dart proxy | 517 // which might be a DartObject JS->Dart proxy |
| 511 Object _convertToDart(o) { | 518 Object _convertToDart(o) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 536 } else if (JS('bool', '# instanceof Array', o)) { | 543 } else if (JS('bool', '# instanceof Array', o)) { |
| 537 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, | 544 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, |
| 538 (o) => new JsArray._fromJs(o)); | 545 (o) => new JsArray._fromJs(o)); |
| 539 } else { | 546 } else { |
| 540 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, | 547 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, |
| 541 (o) => new JsObject._fromJs(o)); | 548 (o) => new JsObject._fromJs(o)); |
| 542 } | 549 } |
| 543 } | 550 } |
| 544 | 551 |
| 545 Object _getDartProxy(o, String propertyName, createProxy(o)) { | 552 Object _getDartProxy(o, String propertyName, createProxy(o)) { |
| 546 var dartProxy = JS('', '#[#]', o, propertyName); | 553 var dartProxy = _getOwnProperty(o, propertyName); |
| 547 // Temporary fix for dartbug.com/15193 | 554 // Temporary fix for dartbug.com/15193 |
| 548 // In some cases it's possible to see a JavaScript object that | 555 // In some cases it's possible to see a JavaScript object that |
| 549 // came from a different context and was previously proxied to | 556 // came from a different context and was previously proxied to |
| 550 // Dart in that context. The JS object will have a cached proxy | 557 // Dart in that context. The JS object will have a cached proxy |
| 551 // but it won't be a valid Dart object in this context. | 558 // but it won't be a valid Dart object in this context. |
| 552 // For now we throw away the cached proxy, but we should be able | 559 // For now we throw away the cached proxy, but we should be able |
| 553 // to cache proxies from multiple JS contexts and Dart isolates. | 560 // to cache proxies from multiple JS contexts and Dart isolates. |
| 554 if (dartProxy == null || !_isLocalObject(o)) { | 561 if (dartProxy == null || !_isLocalObject(o)) { |
| 555 dartProxy = createProxy(o); | 562 dartProxy = createProxy(o); |
| 556 _defineProperty(o, propertyName, dartProxy); | 563 _defineProperty(o, propertyName, dartProxy); |
| 557 } | 564 } |
| 558 return dartProxy; | 565 return dartProxy; |
| 559 } | 566 } |
| OLD | NEW |