OLD | NEW |
---|---|
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:_isolate_helper' show TimerImpl; | 7 import 'dart:_isolate_helper' show TimerImpl; |
8 import 'dart:_foreign_helper' show JS; | |
8 | 9 |
9 patch class Timer { | 10 patch class Timer { |
10 patch factory Timer(int milliseconds, void callback(Timer timer)) { | 11 patch factory Timer(int milliseconds, void callback(Timer timer)) { |
11 return new TimerImpl(milliseconds, callback); | 12 return new TimerImpl(milliseconds, callback); |
12 } | 13 } |
13 | 14 |
14 /** | 15 /** |
15 * Creates a new repeating timer. The [callback] is invoked every | 16 * Creates a new repeating timer. The [callback] is invoked every |
16 * [milliseconds] millisecond until cancelled. | 17 * [milliseconds] millisecond until cancelled. |
17 */ | 18 */ |
18 patch factory Timer.repeating(int milliseconds, void callback(Timer timer)) { | 19 patch factory Timer.repeating(int milliseconds, void callback(Timer timer)) { |
19 return new TimerImpl.repeating(milliseconds, callback); | 20 return new TimerImpl.repeating(milliseconds, callback); |
20 } | 21 } |
21 } | 22 } |
23 | |
24 // TODO(ahe): This should not only apply to this isolate. | |
25 final _loadedLibraries = <String, Completer<bool>>{}; | |
26 | |
27 patch Future<bool> load(String libraryName, {String uri}) { | |
kasperl
2013/02/05 08:30:53
How should this behave if the specified library na
| |
28 // TODO(ahe): Validate libraryName. | |
29 Completer completer = new Completer<bool>(); | |
30 Future<bool> future = _loadedLibraries[libraryName]; | |
31 if (future != null) { | |
32 future.then((_) { completer.complete(false); }); | |
33 return completer.future; | |
34 } | |
35 _loadedLibraries[libraryName] = completer.future; | |
36 | |
37 if (uri == null) { | |
38 uri = _currentScriptUri; | |
39 int index = JS('int', '#.lastIndexOf("/")', uri); | |
40 uri = JS('String', '#.substring(0, # + 1) + #', uri, index, "part.js"); | |
41 } | |
42 | |
43 if (JS('String', 'typeof document') == 'object') { | |
kasperl
2013/02/05 08:30:53
Use _hasDocument?
ahe
2013/02/05 13:54:22
Done.
| |
44 // Inject a script tag. | |
45 var script = JS('', 'document.createElement("script")'); | |
46 JS('', '#.type = "text/javascript"', script); | |
47 JS('', '#.async = "async"', script); | |
48 JS('', '#.src = #', script, uri); | |
49 var onLoad = | |
50 JS('', '#.bind(null, #)', Primitives.onDeferredLibraryLoad(), completer); | |
kasperl
2013/02/05 08:30:53
4 space indent.
ahe
2013/02/05 13:54:22
Done.
| |
51 JS('', '#.addEventListener("load", #, false)', script, onLoad); | |
52 JS('', 'document.body.appendChild(#)', script); | |
53 } else if (JS('String', 'typeof read') == 'function') { | |
kasperl
2013/02/05 08:30:53
Not sure I understand this. If the function 'read'
ahe
2013/02/05 13:54:22
It's a mistake. I got the name wrong first :-)
| |
54 new Timer(0, (_) { | |
55 JS('void', 'load(#)', uri); | |
56 completer.complete(true); | |
57 }); | |
58 } else { | |
59 throw new UnsupportedError('load not supported'); | |
60 } | |
61 return completer.future; | |
62 } | |
63 | |
64 bool get _hasDocument => JS('String', 'typeof document') == 'object'; | |
65 | |
66 /// Returns the URI of the current script (as a string). | |
67 // TODO(ahe): Share with IsolateNatives.computeThisScript. | |
68 String get _currentScriptUri() { | |
69 // TODO(ahe): The following works in Firefox during loading of the | |
70 // script, and is being considered for the standard. | |
71 // if (_hasDocument) { | |
72 // var currentScript = JS('', 'document.currentScript'); | |
73 // if (JS('String', 'typeof #', currentScript) == 'object') { | |
74 // return JS('String', '#.src', currentScript); | |
75 // } | |
76 // } | |
77 | |
78 var stack = JS('String|Null', 'throw new Error().stack'); | |
kasperl
2013/02/05 08:30:53
Why doesn't this throw an uncaught exception? Did
ahe
2013/02/05 13:54:22
Yes. This was caught by my tests, but after having
| |
79 if (stack == null) { | |
80 // According to Internet Explorer documentation, the stack | |
81 // property is not set until the exception is thrown. | |
82 stack = JS('String', | |
83 'function() {try{throw new Error()}catch(e){return e.stack}}'); | |
84 } | |
85 var pattern, matches; | |
86 | |
87 // This pattern matches V8, Chrome, and Internet Explorer stack | |
88 // traces that look like this: | |
89 // Error | |
90 // at methodName (URI:LINE:COLUMN) | |
91 pattern = JS('', r'new RegExp("^ *at (.*):[0-9]*:[0-9]*$", "m")'); | |
92 | |
93 matches = JS('', '#.match(#)', stack, pattern); | |
94 if (matches != null) return matches[1]; | |
95 | |
96 // This pattern matches Firefox stack traces that look like this: | |
97 // methodName@URI:LINE | |
98 pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")'); | |
99 | |
100 matches = JS('', '#.match(#)', stack, pattern); | |
101 if (matches != null) return matches[1]; | |
102 | |
103 throw new UnsupportedError('Cannot extract URI from "$stack"'); | |
104 } | |
OLD | NEW |