| 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 library _js_helper; | 5 library _js_helper; |
| 6 | 6 |
| 7 import 'dart:_async_await_error_codes' as async_error_codes; | 7 import 'dart:_async_await_error_codes' as async_error_codes; |
| 8 | 8 |
| 9 import 'dart:_js_embedded_names' show | 9 import 'dart:_js_embedded_names' show |
| 10 JsGetName, | 10 JsGetName, |
| (...skipping 3433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3444 JS('void', '#(#)', initializer, hashes[i]); | 3444 JS('void', '#(#)', initializer, hashes[i]); |
| 3445 } | 3445 } |
| 3446 bool updated = _loadedLibraries.add(loadId); | 3446 bool updated = _loadedLibraries.add(loadId); |
| 3447 if (updated && deferredLoadHook != null) { | 3447 if (updated && deferredLoadHook != null) { |
| 3448 deferredLoadHook(); | 3448 deferredLoadHook(); |
| 3449 } | 3449 } |
| 3450 }); | 3450 }); |
| 3451 } | 3451 } |
| 3452 | 3452 |
| 3453 Future<Null> _loadHunk(String hunkName) { | 3453 Future<Null> _loadHunk(String hunkName) { |
| 3454 // TODO(ahe): Validate libraryName. Kasper points out that you want | |
| 3455 // to be able to experiment with the effect of toggling @DeferLoad, | |
| 3456 // so perhaps we should silently ignore "bad" library names. | |
| 3457 Future<Null> future = _loadingLibraries[hunkName]; | 3454 Future<Null> future = _loadingLibraries[hunkName]; |
| 3458 if (future != null) { | 3455 if (future != null) { |
| 3459 return future.then((_) => null); | 3456 return future.then((_) => null); |
| 3460 } | 3457 } |
| 3461 | 3458 |
| 3462 String uri = IsolateNatives.thisScript; | 3459 String uri = IsolateNatives.thisScript; |
| 3463 | 3460 |
| 3464 int index = uri.lastIndexOf('/'); | 3461 int index = uri.lastIndexOf('/'); |
| 3465 uri = '${uri.substring(0, index + 1)}$hunkName'; | 3462 uri = '${uri.substring(0, index + 1)}$hunkName'; |
| 3466 | 3463 |
| 3467 if (Primitives.isJsshell || Primitives.isD8) { | 3464 var deferredLibraryLoader = JS('', 'self.dartDeferredLibraryLoader'); |
| 3468 // TODO(ahe): Move this code to a JavaScript command helper script that is | 3465 Completer<Null> completer = new Completer<Null>(); |
| 3469 // not included in generated output. | 3466 |
| 3470 return _loadingLibraries[hunkName] = new Future<Null>(() { | 3467 void success() { |
| 3468 completer.complete(null); |
| 3469 } |
| 3470 |
| 3471 void failure([error, StackTrace stackTrace]) { |
| 3472 _loadingLibraries[hunkName] = null; |
| 3473 completer.completeError( |
| 3474 new DeferredLoadException("Loading $uri failed: $error"), |
| 3475 stackTrace); |
| 3476 } |
| 3477 |
| 3478 var jsSuccess = convertDartClosureToJS(success, 0); |
| 3479 var jsFailure = convertDartClosureToJS((error) { |
| 3480 failure(unwrapException(error), getTraceFromException(error)); |
| 3481 }, 1); |
| 3482 |
| 3483 if (JS('bool', 'typeof # === "function"', deferredLibraryLoader)) { |
| 3484 try { |
| 3485 JS('void', '#(#, #, #)', deferredLibraryLoader, uri, |
| 3486 jsSuccess, jsFailure); |
| 3487 } catch (error, stackTrace) { |
| 3488 failure(error, stackTrace); |
| 3489 } |
| 3490 } else if (isWorker()) { |
| 3491 // We are in a web worker. Load the code with an XMLHttpRequest. |
| 3492 enterJsAsync(); |
| 3493 Future<Null> leavingFuture = completer.future.whenComplete(() { |
| 3494 leaveJsAsync(); |
| 3495 }); |
| 3496 |
| 3497 int index = uri.lastIndexOf('/'); |
| 3498 uri = '${uri.substring(0, index + 1)}$hunkName'; |
| 3499 var xhr = JS('dynamic', 'new XMLHttpRequest()'); |
| 3500 JS('void', '#.open("GET", #)', xhr, uri); |
| 3501 JS('void', '#.addEventListener("load", #, false)', |
| 3502 xhr, convertDartClosureToJS((event) { |
| 3503 if (JS('int', '#.status', xhr) != 200) { |
| 3504 failure(""); |
| 3505 } |
| 3506 String code = JS('String', '#.responseText', xhr); |
| 3471 try { | 3507 try { |
| 3472 // Create a new function to avoid getting access to current function | 3508 // Create a new function to avoid getting access to current function |
| 3473 // context. | 3509 // context. |
| 3474 JS('void', '(new Function(#))()', 'load("$uri")'); | 3510 JS('void', '(new Function(#))()', code); |
| 3511 success(); |
| 3475 } catch (error, stackTrace) { | 3512 } catch (error, stackTrace) { |
| 3476 _loadingLibraries[hunkName] = null; | 3513 failure(error, stackTrace); |
| 3477 throw new DeferredLoadException("Loading $uri failed."); | |
| 3478 } | 3514 } |
| 3479 return null; | 3515 }, 1)); |
| 3480 }); | |
| 3481 } else if (isWorker()) { | |
| 3482 // We are in a web worker. Load the code with an XMLHttpRequest. | |
| 3483 return _loadingLibraries[hunkName] = new Future<Null>(() { | |
| 3484 Completer completer = new Completer<Null>(); | |
| 3485 enterJsAsync(); | |
| 3486 Future<Null> leavingFuture = completer.future.whenComplete(() { | |
| 3487 leaveJsAsync(); | |
| 3488 }); | |
| 3489 | 3516 |
| 3490 int index = uri.lastIndexOf('/'); | 3517 JS('void', '#.addEventListener("error", #, false)', xhr, failure); |
| 3491 uri = '${uri.substring(0, index + 1)}$hunkName'; | 3518 JS('void', '#.addEventListener("abort", #, false)', xhr, failure); |
| 3492 var xhr = JS('dynamic', 'new XMLHttpRequest()'); | 3519 JS('void', '#.send()', xhr); |
| 3493 JS('void', '#.open("GET", #)', xhr, uri); | 3520 } else { |
| 3494 JS('void', '#.addEventListener("load", #, false)', | 3521 // We are in a dom-context. |
| 3495 xhr, convertDartClosureToJS((event) { | |
| 3496 if (JS('int', '#.status', xhr) != 200) { | |
| 3497 _loadingLibraries[hunkName] = null; | |
| 3498 completer.completeError( | |
| 3499 new DeferredLoadException("Loading $uri failed.")); | |
| 3500 return; | |
| 3501 } | |
| 3502 String code = JS('String', '#.responseText', xhr); | |
| 3503 try { | |
| 3504 // Create a new function to avoid getting access to current function | |
| 3505 // context. | |
| 3506 JS('void', '(new Function(#))()', code); | |
| 3507 } catch (error, stackTrace) { | |
| 3508 _loadingLibraries[hunkName] = null; | |
| 3509 completer.completeError( | |
| 3510 new DeferredLoadException("Evaluating $uri failed.")); | |
| 3511 return; | |
| 3512 } | |
| 3513 completer.complete(null); | |
| 3514 }, 1)); | |
| 3515 | |
| 3516 var fail = convertDartClosureToJS((event) { | |
| 3517 _loadingLibraries[hunkName] = null; | |
| 3518 new DeferredLoadException("Loading $uri failed."); | |
| 3519 }, 1); | |
| 3520 JS('void', '#.addEventListener("error", #, false)', xhr, fail); | |
| 3521 JS('void', '#.addEventListener("abort", #, false)', xhr, fail); | |
| 3522 | |
| 3523 JS('void', '#.send()', xhr); | |
| 3524 return leavingFuture; | |
| 3525 }); | |
| 3526 } | |
| 3527 // We are in a dom-context. | |
| 3528 return _loadingLibraries[hunkName] = new Future<Null>(() { | |
| 3529 Completer completer = new Completer<Null>(); | |
| 3530 // Inject a script tag. | 3522 // Inject a script tag. |
| 3531 var script = JS('', 'document.createElement("script")'); | 3523 var script = JS('', 'document.createElement("script")'); |
| 3532 JS('', '#.type = "text/javascript"', script); | 3524 JS('', '#.type = "text/javascript"', script); |
| 3533 JS('', '#.src = #', script, uri); | 3525 JS('', '#.src = #', script, uri); |
| 3534 JS('', '#.addEventListener("load", #, false)', | 3526 JS('', '#.addEventListener("load", #, false)', script, jsSuccess); |
| 3535 script, convertDartClosureToJS((event) { | 3527 JS('', '#.addEventListener("error", #, false)', script, jsFailure); |
| 3536 completer.complete(null); | |
| 3537 }, 1)); | |
| 3538 JS('', '#.addEventListener("error", #, false)', | |
| 3539 script, convertDartClosureToJS((event) { | |
| 3540 _loadingLibraries[hunkName] = null; | |
| 3541 completer.completeError( | |
| 3542 new DeferredLoadException("Loading $uri failed.")); | |
| 3543 }, 1)); | |
| 3544 JS('', 'document.body.appendChild(#)', script); | 3528 JS('', 'document.body.appendChild(#)', script); |
| 3545 | 3529 } |
| 3546 return completer.future; | 3530 _loadingLibraries[hunkName] = completer.future; |
| 3547 }); | 3531 return completer.future; |
| 3548 } | 3532 } |
| 3549 | 3533 |
| 3550 class MainError extends Error implements NoSuchMethodError { | 3534 class MainError extends Error implements NoSuchMethodError { |
| 3551 final String _message; | 3535 final String _message; |
| 3552 | 3536 |
| 3553 MainError(this._message); | 3537 MainError(this._message); |
| 3554 | 3538 |
| 3555 String toString() => 'NoSuchMethodError: $_message'; | 3539 String toString() => 'NoSuchMethodError: $_message'; |
| 3556 } | 3540 } |
| 3557 | 3541 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3879 // This is a function that will return a helper function that does the | 3863 // This is a function that will return a helper function that does the |
| 3880 // iteration of the sync*. | 3864 // iteration of the sync*. |
| 3881 // | 3865 // |
| 3882 // Each invocation should give a body with fresh state. | 3866 // Each invocation should give a body with fresh state. |
| 3883 final dynamic /* js function */ _outerHelper; | 3867 final dynamic /* js function */ _outerHelper; |
| 3884 | 3868 |
| 3885 SyncStarIterable(this._outerHelper); | 3869 SyncStarIterable(this._outerHelper); |
| 3886 | 3870 |
| 3887 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3871 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
| 3888 } | 3872 } |
| OLD | NEW |