Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: sdk/lib/_internal/lib/js_helper.dart

Issue 221663005: Load deferred chunks in the right order. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/lib/async_patch.dart ('k') | sdk/lib/async/deferred_load.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:collection'; 7 import 'dart:collection';
8 import 'dart:_isolate_helper' show 8 import 'dart:_isolate_helper' show
9 IsolateNatives, 9 IsolateNatives,
10 leaveJsAsync, 10 leaveJsAsync,
(...skipping 3205 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 * DOM isolates. This happens when multiple programs are loaded in the same 3216 * DOM isolates. This happens when multiple programs are loaded in the same
3217 * JavaScript context (i.e. page). The name is based on [name] but with an 3217 * JavaScript context (i.e. page). The name is based on [name] but with an
3218 * additional part that is unique for each isolate. 3218 * additional part that is unique for each isolate.
3219 * 3219 *
3220 * The form of the name is '___dart_$name_$id'. 3220 * The form of the name is '___dart_$name_$id'.
3221 */ 3221 */
3222 String getIsolateAffinityTag(String name) { 3222 String getIsolateAffinityTag(String name) {
3223 return JS('String', 'init.getIsolateTag(#)', name); 3223 return JS('String', 'init.getIsolateTag(#)', name);
3224 } 3224 }
3225 3225
3226 typedef Future<bool> LoadLibraryFunctionType(); 3226 typedef Future<Null> LoadLibraryFunctionType();
3227 3227
3228 LoadLibraryFunctionType _loadLibraryWrapper(String loadId) { 3228 LoadLibraryFunctionType _loadLibraryWrapper(String loadId) {
3229 return () => loadDeferredLibrary(loadId); 3229 return () => loadDeferredLibrary(loadId);
3230 } 3230 }
3231 3231
3232 final Map<String, Future<bool>> _loadedLibraries = <String, Future<bool>>{}; 3232 final Map<String, Future<Null>> _loadedLibraries = <String, Future<Null>>{};
3233 3233
3234 Future<bool> loadDeferredLibrary(String loadId, [String uri]) { 3234 Future<bool> loadDeferredLibrary(String loadId, [String uri]) {
3235 List hunkNames = new List(); 3235
3236 if (JS('bool', '\$.libraries_to_load[#] === undefined', loadId)) { 3236 List<List<String>> hunkLists = JS('JSExtendableArray|Null',
3237 return new Future(() => false); 3237 '\$.libraries_to_load[#]', loadId);
3238 } 3238 if (hunkLists == null) return new Future.value(null);
3239 for (int index = 0; 3239
3240 index < JS('int', '\$.libraries_to_load[#].length', loadId); 3240 return Future.forEach(hunkLists, (hunkNames) {
3241 ++index) { 3241 Iterable<Future<Null>> allLoads =
3242 hunkNames.add(JS('String', '\$.libraries_to_load[#][#]', 3242 hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
3243 loadId, index)); 3243 return Future.wait(allLoads).then((_) => null);
3244 }
3245 Iterable<Future<bool>> allLoads =
3246 hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
3247 return Future.wait(allLoads).then((results) {
3248 return results.any((x) => x);
3249 }); 3244 });
3250 } 3245 }
3251 3246
3252 Future<bool> _loadHunk(String hunkName, String uri) { 3247 Future<Null> _loadHunk(String hunkName, String uri) {
3253 // TODO(ahe): Validate libraryName. Kasper points out that you want 3248 // TODO(ahe): Validate libraryName. Kasper points out that you want
3254 // to be able to experiment with the effect of toggling @DeferLoad, 3249 // to be able to experiment with the effect of toggling @DeferLoad,
3255 // so perhaps we should silently ignore "bad" library names. 3250 // so perhaps we should silently ignore "bad" library names.
3256 Future<bool> future = _loadedLibraries[hunkName]; 3251 Future<Null> future = _loadedLibraries[hunkName];
3257 if (future != null) { 3252 if (future != null) {
3258 return future.then((_) => false); 3253 return future.then((_) => null);
3259 } 3254 }
3260 3255
3261 if (uri == null) { 3256 if (uri == null) {
3262 uri = IsolateNatives.thisScript; 3257 uri = IsolateNatives.thisScript;
3263 } 3258 }
3264 int index = uri.lastIndexOf('/'); 3259 int index = uri.lastIndexOf('/');
3265 uri = '${uri.substring(0, index + 1)}$hunkName'; 3260 uri = '${uri.substring(0, index + 1)}$hunkName';
3266 3261
3267 if (Primitives.isJsshell || Primitives.isD8) { 3262 if (Primitives.isJsshell || Primitives.isD8) {
3268 // TODO(ahe): Move this code to a JavaScript command helper script that is 3263 // TODO(ahe): Move this code to a JavaScript command helper script that is
3269 // not included in generated output. 3264 // not included in generated output.
3270 return _loadedLibraries[hunkName] = new Future<bool>(() { 3265 return _loadedLibraries[hunkName] = new Future<Null>(() {
3271 try { 3266 try {
3272 // Create a new function to avoid getting access to current function 3267 // Create a new function to avoid getting access to current function
3273 // context. 3268 // context.
3274 JS('void', '(new Function(#))()', 'load("$uri")'); 3269 JS('void', '(new Function(#))()', 'load("$uri")');
3275 } catch (error, stackTrace) { 3270 } catch (error, stackTrace) {
3276 throw new DeferredLoadException("Loading $uri failed."); 3271 throw new DeferredLoadException("Loading $uri failed.");
3277 } 3272 }
3278 return true; 3273 return null;
3279 }); 3274 });
3280 } else if (isWorker()) { 3275 } else if (isWorker()) {
3281 // We are in a web worker. Load the code with an XMLHttpRequest. 3276 // We are in a web worker. Load the code with an XMLHttpRequest.
3282 return _loadedLibraries[hunkName] = new Future<bool>(() { 3277 return _loadedLibraries[hunkName] = new Future<Null>(() {
3283 Completer completer = new Completer<bool>(); 3278 Completer completer = new Completer<Null>();
3284 enterJsAsync(); 3279 enterJsAsync();
3285 Future<bool> leavingFuture = completer.future.whenComplete(() { 3280 Future<Null> leavingFuture = completer.future.whenComplete(() {
3286 leaveJsAsync(); 3281 leaveJsAsync();
3287 }); 3282 });
3288 3283
3289 int index = uri.lastIndexOf('/'); 3284 int index = uri.lastIndexOf('/');
3290 uri = '${uri.substring(0, index + 1)}$hunkName'; 3285 uri = '${uri.substring(0, index + 1)}$hunkName';
3291 var xhr = JS('dynamic', 'new XMLHttpRequest()'); 3286 var xhr = JS('dynamic', 'new XMLHttpRequest()');
3292 JS('void', '#.open("GET", #)', xhr, uri); 3287 JS('void', '#.open("GET", #)', xhr, uri);
3293 JS('void', '#.addEventListener("load", #, false)', 3288 JS('void', '#.addEventListener("load", #, false)',
3294 xhr, convertDartClosureToJS((event) { 3289 xhr, convertDartClosureToJS((event) {
3295 if (JS('int', '#.status', xhr) != 200) { 3290 if (JS('int', '#.status', xhr) != 200) {
3296 completer.completeError( 3291 completer.completeError(
3297 new DeferredLoadException("Loading $uri failed.")); 3292 new DeferredLoadException("Loading $uri failed."));
3298 return; 3293 return;
3299 } 3294 }
3300 String code = JS('String', '#.responseText', xhr); 3295 String code = JS('String', '#.responseText', xhr);
3301 try { 3296 try {
3302 // Create a new function to avoid getting access to current function 3297 // Create a new function to avoid getting access to current function
3303 // context. 3298 // context.
3304 JS('void', '(new Function(#))()', code); 3299 JS('void', '(new Function(#))()', code);
3305 } catch (error, stackTrace) { 3300 } catch (error, stackTrace) {
3306 completer.completeError( 3301 completer.completeError(
3307 new DeferredLoadException("Evaluating $uri failed.")); 3302 new DeferredLoadException("Evaluating $uri failed."));
3308 return; 3303 return;
3309 } 3304 }
3310 completer.complete(true); 3305 completer.complete(null);
3311 }, 1)); 3306 }, 1));
3312 3307
3313 var fail = convertDartClosureToJS((event) { 3308 var fail = convertDartClosureToJS((event) {
3314 new DeferredLoadException("Loading $uri failed."); 3309 new DeferredLoadException("Loading $uri failed.");
3315 }, 1); 3310 }, 1);
3316 JS('void', '#.addEventListener("error", #, false)', xhr, fail); 3311 JS('void', '#.addEventListener("error", #, false)', xhr, fail);
3317 JS('void', '#.addEventListener("abort", #, false)', xhr, fail); 3312 JS('void', '#.addEventListener("abort", #, false)', xhr, fail);
3318 3313
3319 JS('void', '#.send()', xhr); 3314 JS('void', '#.send()', xhr);
3320 return leavingFuture; 3315 return leavingFuture;
3321 }); 3316 });
3322 } 3317 }
3323 // We are in a dom-context. 3318 // We are in a dom-context.
3324 return _loadedLibraries[hunkName] = new Future<bool>(() { 3319 return _loadedLibraries[hunkName] = new Future<Null>(() {
3325 Completer completer = new Completer<bool>(); 3320 Completer completer = new Completer<Null>();
3326 // Inject a script tag. 3321 // Inject a script tag.
3327 var script = JS('', 'document.createElement("script")'); 3322 var script = JS('', 'document.createElement("script")');
3328 JS('', '#.type = "text/javascript"', script); 3323 JS('', '#.type = "text/javascript"', script);
3329 JS('', '#.src = #', script, uri); 3324 JS('', '#.src = #', script, uri);
3330 JS('', '#.addEventListener("load", #, false)', 3325 JS('', '#.addEventListener("load", #, false)',
3331 script, convertDartClosureToJS((event) { 3326 script, convertDartClosureToJS((event) {
3332 completer.complete(true); 3327 completer.complete(null);
3333 }, 1)); 3328 }, 1));
3334 JS('', '#.addEventListener("error", #, false)', 3329 JS('', '#.addEventListener("error", #, false)',
3335 script, convertDartClosureToJS((event) { 3330 script, convertDartClosureToJS((event) {
3336 completer.completeError( 3331 completer.completeError(
3337 new DeferredLoadException("Loading $uri failed.")); 3332 new DeferredLoadException("Loading $uri failed."));
3338 }, 1)); 3333 }, 1));
3339 JS('', 'document.body.appendChild(#)', script); 3334 JS('', 'document.body.appendChild(#)', script);
3340 3335
3341 return completer.future; 3336 return completer.future;
3342 }); 3337 });
3343 } 3338 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/lib/async_patch.dart ('k') | sdk/lib/async/deferred_load.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698