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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 import 'dart:typed_data'; | 97 import 'dart:typed_data'; |
98 | 98 |
99 // Pretend we are always in checked mode as we aren't interested in users | 99 // Pretend we are always in checked mode as we aren't interested in users |
100 // running Dartium code outside of checked mode. | 100 // running Dartium code outside of checked mode. |
101 final bool CHECK_JS_INVOCATIONS = true; | 101 final bool CHECK_JS_INVOCATIONS = true; |
102 | 102 |
103 final _allowedMethods = new Map<Symbol, _DeclarationSet>(); | 103 final _allowedMethods = new Map<Symbol, _DeclarationSet>(); |
104 final _allowedGetters = new Map<Symbol, _DeclarationSet>(); | 104 final _allowedGetters = new Map<Symbol, _DeclarationSet>(); |
105 final _allowedSetters = new Map<Symbol, _DeclarationSet>(); | 105 final _allowedSetters = new Map<Symbol, _DeclarationSet>(); |
106 | 106 |
107 final _jsInterfaceTypes = new Set<Type>(); | 107 final _jsInterfaceTypes = new Set<mirrors.ClassMirror>(); |
108 Iterable<Type> get jsInterfaceTypes => _jsInterfaceTypes; | 108 Iterable<mirrors.ClassMirror> get jsInterfaceTypes => _jsInterfaceTypes; |
109 | 109 |
110 /// A collection of methods where all methods have the same name. | 110 /// A collection of methods where all methods have the same name. |
111 /// This class is intended to optimize whether a specific invocation is | 111 /// This class is intended to optimize whether a specific invocation is |
112 /// appropritate for at least some of the methods in the collection. | 112 /// appropritate for at least some of the methods in the collection. |
113 class _DeclarationSet { | 113 class _DeclarationSet { |
114 _DeclarationSet() : _members = <mirrors.DeclarationMirror>[]; | 114 _DeclarationSet() : _members = <mirrors.DeclarationMirror>[]; |
115 | 115 |
116 static bool _checkType(obj, mirrors.TypeMirror type) { | 116 static bool _checkType(obj, mirrors.TypeMirror type) { |
117 if (obj == null) return true; | 117 if (obj == null) return true; |
118 return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type); | 118 return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 /** | 206 /** |
207 * Temporary method that we hope to remove at some point. This method should | 207 * Temporary method that we hope to remove at some point. This method should |
208 * generally only be called by machine generated code. | 208 * generally only be called by machine generated code. |
209 */ | 209 */ |
210 void registerJsInterfaces([List<Type> classes]) { | 210 void registerJsInterfaces([List<Type> classes]) { |
211 // This method is now obsolete in Dartium. | 211 // This method is now obsolete in Dartium. |
212 } | 212 } |
213 | 213 |
214 void _registerJsInterfaces(List<Type> classes) { | 214 void _registerJsInterfaces(List<Type> classes) { |
215 for (Type type in classes) { | 215 for (Type type in classes) { |
216 if (!_jsInterfaceTypes.add(type)) continue; // Already registered. | |
217 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); | 216 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); |
218 typeMirror.declarations.forEach((symbol, declaration) { | 217 typeMirror.declarations.forEach((symbol, declaration) { |
219 if (declaration is mirrors.MethodMirror || | 218 if (declaration is mirrors.MethodMirror || |
220 declaration is mirrors.VariableMirror && !declaration.isStatic) { | 219 declaration is mirrors.VariableMirror && !declaration.isStatic) { |
221 bool treatAsGetter = false; | 220 bool treatAsGetter = false; |
222 bool treatAsSetter = false; | 221 bool treatAsSetter = false; |
223 if (declaration is mirrors.VariableMirror) { | 222 if (declaration is mirrors.VariableMirror) { |
224 treatAsGetter = true; | 223 treatAsGetter = true; |
225 if (!declaration.isConst && !declaration.isFinal) { | 224 if (!declaration.isConst && !declaration.isFinal) { |
226 treatAsSetter = true; | 225 treatAsSetter = true; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 var name = annotation.reflectee.name; | 266 var name = annotation.reflectee.name; |
268 return name != null ? name : ""; | 267 return name != null ? name : ""; |
269 } catch (e) { | 268 } catch (e) { |
270 } | 269 } |
271 } | 270 } |
272 } | 271 } |
273 } | 272 } |
274 return null; | 273 return null; |
275 } | 274 } |
276 | 275 |
276 bool _isAnonymousClass(mirrors.ClassMirror mirror) { | |
277 for (var annotation in mirror.metadata) { | |
278 if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "_Anonymous" ) { | |
279 mirrors.LibraryMirror library = annotation.type.owner; | |
280 var uri = library.uri; | |
281 // make sure the annotation is from package://js | |
282 if (uri.scheme == 'package' && uri.path == 'js/js.dart') { | |
283 return true; | |
284 } | |
285 } | |
286 } | |
287 return false; | |
288 } | |
289 | |
277 bool _hasJsName(mirrors.DeclarationMirror mirror) => | 290 bool _hasJsName(mirrors.DeclarationMirror mirror) => |
278 _getJsName(mirror) != null; | 291 _getJsName(mirror) != null; |
279 | 292 |
280 | 293 |
281 _getJsMemberName(mirrors.DeclarationMirror mirror) { | 294 _getJsMemberName(mirrors.DeclarationMirror mirror) { |
282 var name = _getJsName(mirror); | 295 var name = _getJsName(mirror); |
283 return name == null || name.isEmpty ? _getDeclarationName(mirror) : | 296 return name == null || name.isEmpty ? _getDeclarationName(mirror) : |
284 name; | 297 name; |
285 } | 298 } |
286 | 299 |
287 // TODO(jacobr): handle setters correctyl. | 300 // TODO(jacobr): handle setters correctyl. |
288 String _getDeclarationName(mirrors.DeclarationMirror declaration) { | 301 String _getDeclarationName(mirrors.DeclarationMirror declaration) { |
289 var name = mirrors.MirrorSystem.getName(declaration.simpleName); | 302 var name = mirrors.MirrorSystem.getName(declaration.simpleName); |
290 if (declaration is mirrors.MethodMirror && declaration.isSetter) { | 303 if (declaration is mirrors.MethodMirror && declaration.isSetter) { |
291 assert(name.endsWith("=")); | 304 assert(name.endsWith("=")); |
292 name = name.substring(0, name.length - 1); | 305 name = name.substring(0, name.length - 1); |
293 } | 306 } |
294 return name; | 307 return name; |
295 } | 308 } |
296 | 309 |
297 final _JS_LIBRARY_PREFIX = "js_library"; | 310 final _JS_LIBRARY_PREFIX = "js_library"; |
298 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; | 311 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST"; |
299 | 312 |
300 String _accessJsPath(String path) => | 313 String _accessJsPath(String path) => |
301 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('' )}"; | 314 "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('' )}"; |
302 | 315 |
303 @Deprecated("Internal Use Only") | 316 @Deprecated("Internal Use Only") |
304 void addMemberHelper(mirrors.MethodMirror declaration, String path, StringBuffer sb, {bool isStatic: false, String memberName}) { | 317 void addMemberHelper(mirrors.MethodMirror declaration, String path, StringBuffer sb, {bool isStatic: false, String memberName}) { |
305 var jsName = _getJsMemberName(declaration); | 318 if (!declaration.isConstructor) { |
306 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; | 319 var jsName = _getJsMemberName(declaration); |
320 path = (path != null && path.isNotEmpty) ? "${path}.${jsName}" : jsName; | |
321 } | |
307 var name = memberName != null ? memberName : _getDeclarationName(declaration); | 322 var name = memberName != null ? memberName : _getDeclarationName(declaration); |
308 if (declaration.isConstructor) { | 323 if (declaration.isConstructor) { |
309 sb.write("factory"); | 324 sb.write("factory"); |
310 } else if (isStatic) { | 325 } else if (isStatic) { |
311 sb.write("static"); | 326 sb.write("static"); |
312 } else { | 327 } else { |
313 sb.write("patch"); | 328 sb.write("patch"); |
314 } | 329 } |
315 sb.write(" "); | 330 sb.write(" "); |
316 if (declaration.isGetter) { | 331 if (declaration.isGetter) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 | 370 |
356 if (hasOptional) { | 371 if (hasOptional) { |
357 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); | 372 sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()"); |
358 } | 373 } |
359 sb.write(");"); | 374 sb.write(");"); |
360 } | 375 } |
361 sb.write("\n"); | 376 sb.write("\n"); |
362 } | 377 } |
363 | 378 |
364 // TODO(jacobr): make this check more robust. | 379 // TODO(jacobr): make this check more robust. |
365 bool _isExternal(mirrors.MethodMirror mirror) => | 380 bool _isExternal(mirrors.Mirror mirror) { |
366 mirror.source != null && mirror.source.startsWith("external "); | 381 /* |
382 var source = mirror.source; | |
383 return source != null && source.startsWith("external "); | |
384 */ | |
385 return mirror.isExternal; | |
386 } | |
367 | 387 |
368 List<String> _generateExternalMethods() { | 388 List<String> _generateExternalMethods() { |
369 var staticCodegen = <String>[]; | 389 var staticCodegen = <String>[]; |
370 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { | 390 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { |
371 var sb = new StringBuffer(); | 391 var sb = new StringBuffer(); |
372 String jsLibraryName = _getJsName(library); | 392 String jsLibraryName = _getJsName(library); |
373 library.declarations.forEach((name, declaration) { | 393 library.declarations.forEach((name, declaration) { |
374 if (declaration is mirrors.MethodMirror) { | 394 if (declaration is mirrors.MethodMirror) { |
375 if (_isExternal(declaration) && (_hasJsName(declaration) || jsLibraryNam e != null)) { | 395 if ((_hasJsName(declaration) || jsLibraryName != null) && _isExternal(de claration)) { |
376 addMemberHelper(declaration, jsLibraryName, sb); | 396 addMemberHelper(declaration, jsLibraryName, sb); |
377 } | 397 } |
378 } else if (declaration is mirrors.ClassMirror) { | 398 } else if (declaration is mirrors.ClassMirror) { |
379 mirrors.ClassMirror clazz = declaration; | 399 mirrors.ClassMirror clazz = declaration; |
380 if (_hasJsName(clazz)) { | 400 if (_hasJsName(clazz)) { |
381 // TODO(jacobr): verify class implements JavaScriptObject. | 401 // TODO(jacobr): verify class implements JavaScriptObject. |
382 assert(clazz.hasReflectedType); | |
383 jsInterfaceTypes.add(clazz.reflectedType); | |
384 String jsClassName = _getJsMemberName(clazz); | 402 String jsClassName = _getJsMemberName(clazz); |
385 var className = mirrors.MirrorSystem.getName(clazz.simpleName); | 403 var className = mirrors.MirrorSystem.getName(clazz.simpleName); |
386 var sbPatch = new StringBuffer(); | 404 var sbPatch = new StringBuffer(); |
405 jsInterfaceTypes.add(clazz); | |
387 clazz.declarations.forEach((name, declaration) { | 406 clazz.declarations.forEach((name, declaration) { |
388 if (declaration is! mirrors.MethodMirror || !_isExternal(declaration )) return; | 407 if (declaration is! mirrors.MethodMirror || !_isExternal(declaration )) return; |
389 if (declaration.isFactoryConstructor) { | 408 if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) { |
390 sbPatch.write(" factory ${className}({"); | 409 sbPatch.write(" factory ${className}({"); |
391 int i = 0; | 410 int i = 0; |
392 var args = <String>[]; | 411 var args = <String>[]; |
412 for (var p in declaration.parameters) { | |
413 args.add(mirrors.MirrorSystem.getName(p.simpleName)); | |
414 i++; | |
415 } | |
416 sbPatch | |
417 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) | |
418 ..write("}) {\n" | |
419 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); | |
420 i = 0; | |
421 for (var p in declaration.parameters) { | |
422 assert(p.isNamed); // XXX throw | |
423 var name = args[i]; | |
424 var jsName = mirrors.MirrorSystem.getName(p.simpleName); | |
425 // XXX apply name conversion rules. | |
426 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); | |
427 i++; | |
428 } | |
429 | |
430 sbPatch.write(" return ret;\n" | |
431 " }\n"); | |
432 } else if (declaration.isConstructor || declaration.isFactoryConstru ctor) { | |
433 sbPatch.write(" "); | |
434 addMemberHelper(declaration, | |
435 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | |
436 sbPatch, | |
437 isStatic: true, | |
438 memberName: className); | |
439 } | |
440 }); | |
441 | |
442 clazz.staticMembers.forEach((memberName, member) { | |
443 if (_isExternal(member)) { | |
444 sbPatch.write(" "); | |
445 addMemberHelper(member, | |
446 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | |
447 sbPatch, | |
448 isStatic: true); | |
449 } | |
450 }); | |
451 var typeVariablesClause = ''; | |
452 if (!clazz.typeVariables.isEmpty) { | |
453 typeVariablesClause = '<${clazz.typeVariables.map((m) => mirrors.Mir rorSystem.getName(m.simpleName)).join(',')}>'; | |
454 } | |
455 if (sbPatch.isNotEmpty) { | |
456 sb.write(""" | |
457 patch class $className$typeVariablesClause { | |
458 $sbPatch | |
459 } | |
460 """); | |
461 } | |
462 } | |
463 } | |
464 }); | |
465 if (sb.isNotEmpty) { | |
466 staticCodegen | |
467 ..add(uri.toString()) | |
468 ..add("${uri}_js_interop_patch.dart") | |
469 ..add(""" | |
470 import 'dart:js' as ${_JS_LIBRARY_PREFIX}; | |
471 | |
472 /** | |
473 * Placeholder object for cases where we need to determine exactly how many | |
474 * args were passed to a function. | |
475 */ | |
476 const ${_UNDEFINED_VAR} = const Object(); | |
477 | |
478 ${sb} | |
479 """); | |
480 } | |
481 }); | |
482 | |
483 return staticCodegen; | |
484 } | |
485 | |
486 List<String> _generateExternalMethods2() { | |
487 var staticCodegen = <String>[]; | |
488 mirrors.currentMirrorSystem().libraries.forEach((uri, library) { | |
489 var sb = new StringBuffer(); | |
490 String jsLibraryName = _getJsName(library); | |
491 library.declarations.forEach((name, declaration) { | |
492 var isExternal = _isExternal(declaration); | |
493 if (declaration is mirrors.MethodMirror) { | |
494 if (isExternal && (_hasJsName(declaration) || jsLibraryName != null)) { | |
495 addMemberHelper(declaration, jsLibraryName, sb); | |
496 } | |
497 } else if (declaration is mirrors.ClassMirror) { | |
498 mirrors.ClassMirror clazz = declaration; | |
499 if (_hasJsName(clazz)) { | |
500 // TODO(jacobr): verify class implements JavaScriptObject. | |
501 String jsClassName = _getJsMemberName(clazz); | |
502 var className = mirrors.MirrorSystem.getName(clazz.simpleName); | |
503 var sbPatch = new StringBuffer(); | |
504 jsInterfaceTypes.add(clazz); | |
505 clazz.declarations.forEach((name, declaration) { | |
506 if (declaration is! mirrors.MethodMirror || !declaration.isAbstract || !isExternal) return; | |
507 if (_hasLiteralAnnotation(declaration) && declaration.isFactoryConst ructor) { | |
508 sbPatch.write(" factory ${className}({"); | |
509 int i = 0; | |
510 var args = <String>[]; | |
393 for (var p in declaration.parameters) { | 511 for (var p in declaration.parameters) { |
394 assert(p.isNamed); // XXX throw | 512 assert(p.isNamed); // XXX throw |
395 args.add(mirrors.MirrorSystem.getName(p.simpleName)); | 513 args.add(mirrors.MirrorSystem.getName(p.simpleName)); |
396 i++; | 514 i++; |
397 } | 515 } |
398 sbPatch | 516 sbPatch |
399 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) | 517 ..write(args.map((name) => '$name:${_UNDEFINED_VAR}').join(", ") ) |
400 ..write("}) {\n" | 518 ..write("}) {\n" |
401 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); | 519 " var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify( {});\n"); |
402 i = 0; | 520 i = 0; |
403 for (var p in declaration.parameters) { | 521 for (var p in declaration.parameters) { |
404 assert(p.isNamed); // XXX throw | 522 assert(p.isNamed); // XXX throw |
405 var name = args[i]; | 523 var name = args[i]; |
406 var jsName = mirrors.MirrorSystem.getName(p.simpleName); | 524 var jsName = mirrors.MirrorSystem.getName(p.simpleName); |
407 // XXX apply name conversion rules. | 525 // XXX apply name conversion rules. |
408 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); | 526 sbPatch.write(" if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n"); |
409 i++; | 527 i++; |
410 } | 528 } |
411 | 529 |
412 sbPatch.write(" return ret;\n" | 530 sbPatch.write(" return ret;\n" |
413 " }\n"); | 531 " }\n"); |
414 } else if (declaration.isConstructor) { | 532 } else if (declaration.isConstructor || declaration.isFactoryConstru ctor) { |
415 sbPatch.write(" "); | 533 sbPatch.write(" "); |
416 addMemberHelper(declaration, | 534 addMemberHelper(declaration, |
417 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}" : "", | 535 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, |
418 sbPatch, | 536 sbPatch, |
419 isStatic: true, | 537 isStatic: true, |
420 memberName: className); | 538 memberName: className); |
421 } | 539 } |
422 }); | 540 }); |
423 | 541 |
424 clazz.staticMembers.forEach((memberName, member) { | 542 clazz.staticMembers.forEach((memberName, member) { |
425 if (_isExternal(member)) { | 543 if (_isExternal(member)) { |
426 sbPatch.write(" "); | 544 sbPatch.write(" "); |
427 addMemberHelper(member, | 545 addMemberHelper(member, |
428 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, | 546 (jsLibraryName != null && jsLibraryName.isNotEmpty) ? "${jsLib raryName}.${jsClassName}" : jsClassName, |
429 sbPatch, | 547 sbPatch, |
430 isStatic: true); | 548 isStatic: true); |
431 } | 549 } |
432 }); | 550 }); |
551 var typeVariablesClause = ''; | |
552 if (!clazz.typeVariables.isEmpty) { | |
553 typeVariablesClause = '<${clazz.typeVariables.map((m) => mirrors.Mir rorSystem.getName(m.simpleName)).join(',')}>'; | |
554 } | |
433 if (sbPatch.isNotEmpty) { | 555 if (sbPatch.isNotEmpty) { |
434 sb.write(""" | 556 sb.write(""" |
435 patch class $className { | 557 patch class $className$typeVariablesClause { |
436 $sbPatch | 558 $sbPatch |
437 } | 559 } |
438 """); | 560 """); |
439 } | 561 } |
440 } | 562 } |
441 } | 563 } |
442 }); | 564 }); |
443 if (sb.isNotEmpty) { | 565 if (sb.isNotEmpty) { |
444 staticCodegen | 566 staticCodegen |
445 ..add(uri.toString()) | 567 ..add(uri.toString()) |
(...skipping 23 matching lines...) Expand all Loading... | |
469 List<String> _generateInteropPatchFiles() { | 591 List<String> _generateInteropPatchFiles() { |
470 var ret = _generateExternalMethods(); | 592 var ret = _generateExternalMethods(); |
471 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); | 593 var libraryPrefixes = new Map<mirrors.LibraryMirror, String>(); |
472 var prefixNames = new Set<String>(); | 594 var prefixNames = new Set<String>(); |
473 var sb = new StringBuffer(); | 595 var sb = new StringBuffer(); |
474 | 596 |
475 var implements = <String>[]; | 597 var implements = <String>[]; |
476 var implementsArray = <String>[]; | 598 var implementsArray = <String>[]; |
477 var listMirror = mirrors.reflectType(List); | 599 var listMirror = mirrors.reflectType(List); |
478 | 600 |
479 for (var type in jsInterfaceTypes) { | 601 for (var typeMirror in jsInterfaceTypes) { |
480 mirrors.ClassMirror typeMirror = mirrors.reflectType(type); | |
481 mirrors.LibraryMirror libraryMirror = typeMirror.owner; | 602 mirrors.LibraryMirror libraryMirror = typeMirror.owner; |
482 var prefixName; | 603 var prefixName; |
483 if (libraryPrefixes.containsKey(libraryMirror)) { | 604 if (libraryPrefixes.containsKey(libraryMirror)) { |
484 prefixName = libraryPrefixes[libraryMirror]; | 605 prefixName = libraryPrefixes[libraryMirror]; |
485 } else { | 606 } else { |
486 var basePrefixName = | 607 var basePrefixName = |
487 mirrors.MirrorSystem.getName(libraryMirror.simpleName); | 608 mirrors.MirrorSystem.getName(libraryMirror.simpleName); |
488 basePrefixName = basePrefixName.replaceAll('.', '_'); | 609 basePrefixName = basePrefixName.replaceAll('.', '_'); |
489 if (basePrefixName.isEmpty) basePrefixName = "lib"; | 610 if (basePrefixName.isEmpty) basePrefixName = "lib"; |
490 prefixName = basePrefixName; | 611 prefixName = basePrefixName; |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 object._dartHtmlWrapper = wrapper; | 851 object._dartHtmlWrapper = wrapper; |
731 } | 852 } |
732 | 853 |
733 /** | 854 /** |
734 * Used by callMethod to get the JS object for each argument passed if the | 855 * Used by callMethod to get the JS object for each argument passed if the |
735 * argument is a Dart class instance that delegates to a DOM object. See | 856 * argument is a Dart class instance that delegates to a DOM object. See |
736 * wrap_jso defined in dart:html. | 857 * wrap_jso defined in dart:html. |
737 */ | 858 */ |
738 @Deprecated("Internal Use Only") | 859 @Deprecated("Internal Use Only") |
739 unwrap_jso(dartClass_instance) { | 860 unwrap_jso(dartClass_instance) { |
740 if (dartClass_instance is html.DartHtmlDomObject) | 861 if (dartClass_instance is html.DartHtmlDomObject && dartClass_instance is! JsO bject) |
Alan Knight
2015/10/30 00:38:58
There's a way it can be both?
Jacob
2015/10/30 00:41:24
yep... and not just by accident.
@JS
class MyPoly
| |
741 return dartClass_instance.blink_jsObject; | 862 return dartClass_instance.blink_jsObject; |
742 else | 863 else |
743 return dartClass_instance; | 864 return dartClass_instance; |
744 } | 865 } |
745 | 866 |
746 /** | 867 /** |
747 * Proxies a JavaScript object to Dart. | 868 * Proxies a JavaScript object to Dart. |
748 * | 869 * |
749 * The properties of the JavaScript object are accessible via the `[]` and | 870 * The properties of the JavaScript object are accessible via the `[]` and |
750 * `[]=` operators. Methods are callable via [callMethod]. | 871 * `[]=` operators. Methods are callable via [callMethod]. |
751 */ | 872 */ |
752 class JsObject extends NativeFieldWrapperClass2 { | 873 class JsObject extends NativeFieldWrapperClass2 { |
753 JsObject.internal(); | 874 JsObject.internal(); |
754 | 875 |
755 /** | 876 /** |
756 * If this JsObject is wrapped, e.g. DOM objects, then we can save the | 877 * If this JsObject is wrapped, e.g. DOM objects, then we can save the |
757 * wrapper here and preserve its identity. | 878 * wrapper here and preserve its identity. |
758 */ | 879 */ |
759 var _dartHtmlWrapper; | 880 var _dartHtmlWrapper; |
760 | 881 |
761 /** | 882 /** |
762 * Constructs a new JavaScript object from [constructor] and returns a proxy | 883 * Constructs a new JavaScript object from [constructor] and returns a proxy |
763 * to it. | 884 * to it. |
764 */ | 885 */ |
765 factory JsObject(JsFunction constructor, [List arguments]) { | 886 factory JsObject(JsFunction constructor, [List arguments]) { |
766 try { | 887 try { |
767 return _create(constructor, arguments); | 888 return html_common.unwrap_jso(_create(constructor, arguments)); |
768 } catch (e) { | 889 } catch (e) { |
769 // Re-throw any errors (returned as a string) as a DomException. | 890 // Re-throw any errors (returned as a string) as a DomException. |
770 throw new html.DomException.jsInterop(e); | 891 throw new html.DomException.jsInterop(e); |
771 } | 892 } |
772 } | 893 } |
773 | 894 |
774 static JsObject _create( | 895 static JsObject _create( |
775 JsFunction constructor, arguments) native "JsObject_constructorCallback"; | 896 JsFunction constructor, arguments) native "JsObject_constructorCallback"; |
776 | 897 |
777 _buildArgs(Invocation invocation) { | 898 _buildArgs(Invocation invocation) { |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1197 return f; | 1318 return f; |
1198 } else { | 1319 } else { |
1199 var ret = _interopCaptureThisExpando[f]; | 1320 var ret = _interopCaptureThisExpando[f]; |
1200 if (ret == null) { | 1321 if (ret == null) { |
1201 ret = new JsFunction.withThis(f); | 1322 ret = new JsFunction.withThis(f); |
1202 _interopCaptureThisExpando[f] = ret; | 1323 _interopCaptureThisExpando[f] = ret; |
1203 } | 1324 } |
1204 return ret; | 1325 return ret; |
1205 } | 1326 } |
1206 } | 1327 } |
OLD | NEW |