OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 part of $LIBRARYNAME; | |
6 | |
7 $if DART2JS | |
8 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" { | |
9 $else | |
10 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { | |
11 $endif | |
12 | |
13 /** | |
14 * Executes a [callback] after the immediate execution stack has completed. | |
15 * | |
16 * This differs from using Timer.run(callback) | |
17 * because Timer will run in about 4-15 milliseconds, depending on browser, | |
18 * depending on load. [setImmediate], in contrast, makes browser-specific | |
19 * changes in behavior to attempt to run immediately after the current | |
20 * frame unwinds, causing the future to complete after all processing has | |
21 * completed for the current event, but before any subsequent events. | |
22 */ | |
23 void setImmediate(TimeoutHandler callback) { | |
24 _addMicrotaskCallback(callback); | |
25 } | |
26 /** | |
27 * Lookup a port by its [name]. Return null if no port is | |
28 * registered under [name]. | |
29 */ | |
30 SendPortSync lookupPort(String name) { | |
31 var port = | |
32 json.parse(document.documentElement.attributes['dart-port:$name']); | |
33 return _deserialize(port); | |
34 } | |
35 | |
36 /** | |
37 * Register a [port] on this window under the given [name]. This | |
38 * port may be retrieved by any isolate (or JavaScript script) | |
39 * running in this window. | |
40 */ | |
41 void registerPort(String name, var port) { | |
42 var serialized = _serialize(port); | |
43 document.documentElement.attributes['dart-port:$name'] = | |
44 json.stringify(serialized); | |
45 } | |
46 | |
47 /** | |
48 * Returns a Future that completes just before the window is about to repaint | |
49 * so the user can draw an animation frame | |
50 * | |
51 * If you need to later cancel this animation, use [requestAnimationFrame] | |
52 * instead. | |
53 * | |
54 * Note: The code that runs when the future completes should call | |
55 * [animationFrame] again for the animation to continue. | |
56 */ | |
57 Future<num> get animationFrame { | |
58 var completer = new Completer<int>(); | |
59 requestAnimationFrame(completer.complete); | |
60 return completer.future; | |
61 } | |
62 | |
63 $if DART2JS | |
64 Document get document => JS('Document', '#.document', this); | |
65 | |
66 WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name); | |
67 | |
68 WindowBase _open3(url, name, options) => | |
69 JS('Window', '#.open(#,#,#)', this, url, name, options); | |
70 | |
71 WindowBase open(String url, String name, [String options]) { | |
72 if (options == null) { | |
73 return _DOMWindowCrossFrame._createSafe(_open2(url, name)); | |
74 } else { | |
75 return _DOMWindowCrossFrame._createSafe(_open3(url, name, options)); | |
76 } | |
77 } | |
78 | |
79 // API level getter and setter for Location. | |
80 // TODO: The cross domain safe wrapper can be inserted here or folded into | |
81 // _LocationWrapper. | |
82 Location get location { | |
83 // Firefox work-around for Location. The Firefox location object cannot be | |
84 // made to behave like a Dart object so must be wrapped. | |
85 var result = _location; | |
86 if (_isDartLocation(result)) return result; // e.g. on Chrome. | |
87 if (null == _location_wrapper) { | |
88 _location_wrapper = new _LocationWrapper(result); | |
89 } | |
90 return _location_wrapper; | |
91 } | |
92 | |
93 // TODO: consider forcing users to do: window.location.assign('string'). | |
94 /** | |
95 * Sets the window's location, which causes the browser to navigate to the new | |
96 * location. [value] may be a Location object or a string. | |
97 */ | |
98 void set location(value) { | |
99 if (value is _LocationWrapper) { | |
100 _location = value._ptr; | |
101 } else { | |
102 _location = value; | |
103 } | |
104 } | |
105 | |
106 _LocationWrapper _location_wrapper; // Cached wrapped Location object. | |
107 | |
108 // Native getter and setter to access raw Location object. | |
109 dynamic get _location => JS('Location|=Object', '#.location', this); | |
110 void set _location(value) { | |
111 JS('void', '#.location = #', this, value); | |
112 } | |
113 // Prevent compiled from thinking 'location' property is available for a Dart | |
114 // member. | |
115 @JSName('location') | |
116 _protect_location() native; | |
117 | |
118 static _isDartLocation(thing) { | |
119 // On Firefox the code that implements 'is Location' fails to find the patch | |
120 // stub on Object.prototype and throws an exception. | |
121 try { | |
122 return thing is Location; | |
123 } catch (e) { | |
124 return false; | |
125 } | |
126 } | |
127 | |
128 /** | |
129 * Called to draw an animation frame and then request the window to repaint | |
130 * after [callback] has finished (creating the animation). | |
131 * | |
132 * Use this method only if you need to later call [cancelAnimationFrame]. If | |
133 * not, the preferred Dart idiom is to set animation frames by calling | |
134 * [animationFrame], which returns a Future. | |
135 * | |
136 * Returns a non-zero valued integer to represent the request id for this | |
137 * request. This value only needs to be saved if you intend to call | |
138 * [cancelAnimationFrame] so you can specify the particular animation to | |
139 * cancel. | |
140 * | |
141 * Note: The supplied [callback] needs to call [requestAnimationFrame] again | |
142 * for the animation to continue. | |
143 */ | |
144 @DomName('DOMWindow.requestAnimationFrame') | |
145 int requestAnimationFrame(RequestAnimationFrameCallback callback) { | |
146 _ensureRequestAnimationFrame(); | |
147 return _requestAnimationFrame(callback); | |
148 } | |
149 | |
150 void cancelAnimationFrame(id) { | |
151 _ensureRequestAnimationFrame(); | |
152 _cancelAnimationFrame(id); | |
153 } | |
154 | |
155 @JSName('requestAnimationFrame') | |
156 int _requestAnimationFrame(RequestAnimationFrameCallback callback) native; | |
157 | |
158 @JSName('cancelAnimationFrame') | |
159 void _cancelAnimationFrame(int id) native; | |
160 | |
161 _ensureRequestAnimationFrame() { | |
162 if (JS('bool', | |
163 '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this)) | |
164 return; | |
165 | |
166 JS('void', | |
167 r""" | |
168 (function($this) { | |
169 var vendors = ['ms', 'moz', 'webkit', 'o']; | |
170 for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) { | |
171 $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame']; | |
172 $this.cancelAnimationFrame = | |
173 $this[vendors[i]+'CancelAnimationFrame'] || | |
174 $this[vendors[i]+'CancelRequestAnimationFrame']; | |
175 } | |
176 if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return; | |
177 $this.requestAnimationFrame = function(callback) { | |
178 return window.setTimeout(function() { | |
179 callback(Date.now()); | |
180 }, 16 /* 16ms ~= 60fps */); | |
181 }; | |
182 $this.cancelAnimationFrame = function(id) { clearTimeout(id); } | |
183 })(#)""", | |
184 this); | |
185 } | |
186 | |
187 /** | |
188 * Gets an instance of the Indexed DB factory to being using Indexed DB. | |
189 * | |
190 * Use [IdbFactory.supported] to check if Indexed DB is supported on the | |
191 * current platform. | |
192 */ | |
193 @SupportedBrowser(SupportedBrowser.CHROME, '23.0') | |
194 @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0') | |
195 @SupportedBrowser(SupportedBrowser.IE, '10.0') | |
196 @Experimental | |
197 IdbFactory get indexedDB => | |
198 JS('IdbFactory', | |
199 '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB', | |
200 this, this, this); | |
201 | |
202 @DomName('Window.console') | |
203 Console get console => Console.safeConsole; | |
204 | |
205 /// Checks if _setImmediate is supported. | |
206 static bool get _supportsSetImmediate => | |
207 JS('bool', '!!(window.setImmediate)'); | |
208 | |
209 // Set immediate implementation for IE | |
210 void _setImmediate(void callback()) { | |
211 JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0)); | |
212 } | |
213 $else | |
214 /// Checks if _setImmediate is supported. | |
215 static bool get _supportsSetImmediate => false; | |
216 | |
217 /// Dartium stub for IE's setImmediate. | |
218 void _setImmediate(void callback()) { | |
219 throw new UnsupportedError('setImmediate is not supported'); | |
220 } | |
221 $endif | |
222 | |
223 $!MEMBERS | |
224 } | |
OLD | NEW |