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

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

Issue 201613006: Introduces the new syntax for deferred loading (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Ambigous elements are not top-level. Created 6 years, 9 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // Patch file for the dart:async library. 5 // Patch file for the dart:async library.
6 6
7 import 'dart:_js_helper' show Primitives, convertDartClosureToJS; 7 import 'dart:_js_helper' show
8 import 'dart:_isolate_helper' show 8 Primitives,
9 IsolateNatives, 9 convertDartClosureToJS,
10 TimerImpl, 10 loadDeferredLibrary;
11 leaveJsAsync, 11 import 'dart:_isolate_helper' show TimerImpl;
12 enterJsAsync,
13 isWorker;
14 12
15 import 'dart:_foreign_helper' show JS; 13 import 'dart:_foreign_helper' show JS;
16 14
17 patch Timer _createTimer(Duration duration, void callback()) { 15 patch Timer _createTimer(Duration duration, void callback()) {
18 int milliseconds = duration.inMilliseconds; 16 int milliseconds = duration.inMilliseconds;
19 if (milliseconds < 0) milliseconds = 0; 17 if (milliseconds < 0) milliseconds = 0;
20 return new TimerImpl(milliseconds, callback); 18 return new TimerImpl(milliseconds, callback);
21 } 19 }
22 20
23 patch Timer _createPeriodicTimer(Duration duration, 21 patch Timer _createPeriodicTimer(Duration duration,
24 void callback(Timer timer)) { 22 void callback(Timer timer)) {
25 int milliseconds = duration.inMilliseconds; 23 int milliseconds = duration.inMilliseconds;
26 if (milliseconds < 0) milliseconds = 0; 24 if (milliseconds < 0) milliseconds = 0;
27 return new TimerImpl.periodic(milliseconds, callback); 25 return new TimerImpl.periodic(milliseconds, callback);
28 } 26 }
29 27
30 patch class _AsyncRun { 28 patch class _AsyncRun {
31 patch static void _scheduleImmediate(void callback()) { 29 patch static void _scheduleImmediate(void callback()) {
32 // TODO(9002): don't use the Timer to enqueue the immediate callback. 30 // TODO(9002): don't use the Timer to enqueue the immediate callback.
33 _createTimer(Duration.ZERO, callback); 31 _createTimer(Duration.ZERO, callback);
34 } 32 }
35 } 33 }
36 34
37 patch class DeferredLibrary { 35 patch class DeferredLibrary {
38 patch Future<bool> load() { 36 patch Future<bool> load() {
39 List hunkNames = new List(); 37 return loadDeferredLibrary(libraryName, uri);
40 if (JS('bool', '\$.libraries_to_load[#] === undefined', libraryName)) {
41 return new Future(() => false);
42 }
43 for (int index = 0;
44 index < JS('int', '\$.libraries_to_load[#].length', libraryName);
45 ++index) {
46 hunkNames.add(JS('String', '\$.libraries_to_load[#][#]',
47 libraryName, index));
48 }
49 Iterable<Future<bool>> allLoads =
50 hunkNames.map((hunkName) => _load(hunkName, uri));
51 return Future.wait(allLoads).then((results) {
52 return results.any((x) => x);
53 });
54 } 38 }
55 } 39 }
56 40
57 // TODO(ahe): This should not only apply to this isolate.
58 final Map<String, Future<bool>> _loadedLibraries = <String, Future<bool>>{};
59
60 Future<bool> _load(String hunkName, String uri) {
61 // TODO(ahe): Validate libraryName. Kasper points out that you want
62 // to be able to experiment with the effect of toggling @DeferLoad,
63 // so perhaps we should silently ignore "bad" library names.
64 Future<bool> future = _loadedLibraries[hunkName];
65 if (future != null) {
66 return future.then((_) => false);
67 }
68
69 if (uri == null) {
70 uri = IsolateNatives.thisScript;
71 }
72 int index = uri.lastIndexOf('/');
73 uri = '${uri.substring(0, index + 1)}$hunkName';
74
75 if (Primitives.isJsshell || Primitives.isD8) {
76 // TODO(ahe): Move this code to a JavaScript command helper script that is
77 // not included in generated output.
78 return _loadedLibraries[hunkName] = new Future<bool>(() {
79 try {
80 // Create a new function to avoid getting access to current function
81 // context.
82 JS('void', '(new Function(#))()', 'load("$uri")');
83 } catch (error, stackTrace) {
84 throw new DeferredLoadException("Loading $uri failed.");
85 }
86 return true;
87 });
88 } else if (isWorker()) {
89 // We are in a web worker. Load the code with an XMLHttpRequest.
90 return _loadedLibraries[hunkName] = new Future<bool>(() {
91 Completer completer = new Completer<bool>();
92 enterJsAsync();
93 Future<bool> leavingFuture = completer.future.whenComplete(() {
94 leaveJsAsync();
95 });
96
97 int index = uri.lastIndexOf('/');
98 uri = '${uri.substring(0, index + 1)}$hunkName';
99 var xhr = JS('dynamic', 'new XMLHttpRequest()');
100 JS('void', '#.open("GET", #)', xhr, uri);
101 JS('void', '#.addEventListener("load", #, false)',
102 xhr, convertDartClosureToJS((event) {
103 if (JS('int', '#.status', xhr) != 200) {
104 completer.completeError(
105 new DeferredLoadException("Loading $uri failed."));
106 return;
107 }
108 String code = JS('String', '#.responseText', xhr);
109 try {
110 // Create a new function to avoid getting access to current function
111 // context.
112 JS('void', '(new Function(#))()', code);
113 } catch (error, stackTrace) {
114 completer.completeError(
115 new DeferredLoadException("Evaluating $uri failed."));
116 return;
117 }
118 completer.complete(true);
119 }, 1));
120
121 var fail = convertDartClosureToJS((event) {
122 new DeferredLoadException("Loading $uri failed.");
123 }, 1);
124 JS('void', '#.addEventListener("error", #, false)', xhr, fail);
125 JS('void', '#.addEventListener("abort", #, false)', xhr, fail);
126
127 JS('void', '#.send()', xhr);
128 return leavingFuture;
129 });
130 }
131 // We are in a dom-context.
132 return _loadedLibraries[hunkName] = new Future<bool>(() {
133 Completer completer = new Completer<bool>();
134 // Inject a script tag.
135 var script = JS('', 'document.createElement("script")');
136 JS('', '#.type = "text/javascript"', script);
137 JS('', '#.src = #', script, uri);
138 JS('', '#.addEventListener("load", #, false)',
139 script, convertDartClosureToJS((event) {
140 completer.complete(true);
141 }, 1));
142 JS('', '#.addEventListener("error", #, false)',
143 script, convertDartClosureToJS((event) {
144 completer.completeError(
145 new DeferredLoadException("Loading $uri failed."));
146 }, 1));
147 JS('', 'document.body.appendChild(#)', script);
148
149 return completer.future;
150 });
151 }
152
153 bool get _hasDocument => JS('String', 'typeof document') == 'object'; 41 bool get _hasDocument => JS('String', 'typeof document') == 'object';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698