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

Side by Side Diff: tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate

Issue 2120063002: Revert zone tasks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « tools/dom/templates/html/impl/impl_Window.darttemplate ('k') | no next file » | 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) 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 part of $LIBRARYNAME; 5 part of $LIBRARYNAME;
6 6
7 /**
8 * A task specification for HTTP requests.
9 *
10 * This specification is not available when an HTTP request is sent through
11 * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification].
12 *
13 * A task created from this specification is a `Future<HttpRequest>`.
14 *
15 * *Experimental*. This class may disappear without notice.
16 */
17 class HttpRequestTaskSpecification extends TaskSpecification {
18 /// The URL of the request.
19 final String url;
20
21 /// The HTTP request method.
22 ///
23 /// By default (when `null`) this is a `"GET"` request. Alternatively, the
24 /// method can be `"POST"`, `"PUT"`, `"DELETE"`, etc.
25 final String method;
26
27 /// Whether the request should send credentials. Credentials are only useful
28 /// for cross-origin requests.
29 ///
30 /// See [HttpRequest.request] for more information.
31 final bool withCredentials;
32
33 /// The desired response format.
34 ///
35 /// Supported types are:
36 /// - `""`: (same as `"text"`),
37 /// - `"arraybuffer"`,
38 /// - `"blob"`,
39 /// - `"document"`,
40 /// - `"json"`,
41 /// - `"text"`
42 ///
43 /// When no value is provided (when equal to `null`) defaults to `""`.
44 final String responseType;
45
46 /// The desired MIME type.
47 ///
48 /// This overrides the default MIME type which is set up to transfer textual
49 /// data.
50 final String mimeType;
51
52 /// The request headers that should be sent with the request.
53 final Map<String, String> requestHeaders;
54
55 /// The data that is sent with the request.
56 ///
57 /// When data is provided (the value is not `null`), it must be a
58 /// [ByteBuffer], [Blob], [Document], [String], or [FormData].
59 final dynamic sendData;
60
61 /// The function that is invoked on progress updates. This function is
62 /// registered as an event listener on the created [HttpRequest] object, and
63 /// thus has its own task. Further invocations of the progress function do
64 /// *not* use the HTTP request task as task object.
65 ///
66 /// Creating an HTTP request automatically registers the on-progress listener.
67 final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress;
68
69 HttpRequestTaskSpecification(this.url,
70 {String this.method, bool this.withCredentials, String this.responseType,
71 String this.mimeType, Map<String, String> this.requestHeaders,
72 this.sendData,
73 void this.onProgress(ProgressEvent e)});
74
75 String get name => "dart.html.http-request";
76 bool get isOneShot => true;
77 }
78
79 /**
80 * A task specification for HTTP requests that are initiated through a direct
81 * invocation of [HttpRequest.send].
82 *
83 * This specification serves as signal to zones that an HTTP request has been
84 * initiated. The created task is the [request] object itself, and
85 * no callback is ever executed in this task.
86 *
87 * Note that event listeners on the HTTP request are also registered in the
88 * zone (although with their own task creations), and that a zone can thus
89 * detect when the HTTP request returns.
90 *
91 * HTTP requests that are initiated through `request` methods don't use
92 * this class but use [HttpRequestTaskSpecification].
93 *
94 * *Experimental*. This class may disappear without notice.
95 */
96 class HttpRequestSendTaskSpecification extends TaskSpecification {
97 final HttpRequest request;
98 final dynamic sendData;
99
100 HttpRequestSendTaskSpecification(this.request, this.sendData);
101
102 String get name => "dart.html.http-request-send";
103
104 /**
105 * No callback is ever executed in an HTTP request send task.
106 */
107 bool get isOneShot => false;
108 }
109
110 /** 7 /**
111 * A client-side XHR request for getting data from a URL, 8 * A client-side XHR request for getting data from a URL,
112 * formally known as XMLHttpRequest. 9 * formally known as XMLHttpRequest.
113 * 10 *
114 * HttpRequest can be used to obtain data from HTTP and FTP protocols, 11 * HttpRequest can be used to obtain data from HTTP and FTP protocols,
115 * and is useful for AJAX-style page updates. 12 * and is useful for AJAX-style page updates.
116 * 13 *
117 * The simplest way to get the contents of a text file, such as a 14 * The simplest way to get the contents of a text file, such as a
118 * JSON-formatted file, is with [getString]. 15 * JSON-formatted file, is with [getString].
119 * For example, the following code gets the contents of a JSON file 16 * For example, the following code gets the contents of a JSON file
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 * with appropriate permissions in their manifest. Requests to file:// URIs 183 * with appropriate permissions in their manifest. Requests to file:// URIs
287 * will also never fail- the Future will always complete successfully, even 184 * will also never fail- the Future will always complete successfully, even
288 * when the file cannot be found. 185 * when the file cannot be found.
289 * 186 *
290 * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access _authentication). 187 * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access _authentication).
291 */ 188 */
292 static Future<HttpRequest> request(String url, 189 static Future<HttpRequest> request(String url,
293 {String method, bool withCredentials, String responseType, 190 {String method, bool withCredentials, String responseType,
294 String mimeType, Map<String, String> requestHeaders, sendData, 191 String mimeType, Map<String, String> requestHeaders, sendData,
295 void onProgress(ProgressEvent e)}) { 192 void onProgress(ProgressEvent e)}) {
296 var spec = new HttpRequestTaskSpecification(
297 url, method: method,
298 withCredentials: withCredentials,
299 responseType: responseType,
300 mimeType: mimeType,
301 requestHeaders: requestHeaders,
302 sendData: sendData,
303 onProgress: onProgress);
304
305 if (identical(Zone.current, Zone.ROOT)) {
306 return _createHttpRequestTask(spec, null);
307 }
308 return Zone.current.createTask(_createHttpRequestTask, spec);
309 }
310
311 static Future<HttpRequest> _createHttpRequestTask(
312 HttpRequestTaskSpecification spec, Zone zone) {
313 String url = spec.url;
314 String method = spec.method;
315 bool withCredentials = spec.withCredentials;
316 String responseType = spec.responseType;
317 String mimeType = spec.mimeType;
318 Map<String, String> requestHeaders = spec.requestHeaders;
319 var sendData = spec.sendData;
320 var onProgress = spec.onProgress;
321
322 var completer = new Completer<HttpRequest>(); 193 var completer = new Completer<HttpRequest>();
323 var task = completer.future;
324 194
325 var xhr = new HttpRequest(); 195 var xhr = new HttpRequest();
326 if (method == null) { 196 if (method == null) {
327 method = 'GET'; 197 method = 'GET';
328 } 198 }
329 xhr.open(method, url, async: true); 199 xhr.open(method, url, async: true);
330 200
331 if (withCredentials != null) { 201 if (withCredentials != null) {
332 xhr.withCredentials = withCredentials; 202 xhr.withCredentials = withCredentials;
333 } 203 }
(...skipping 19 matching lines...) Expand all
353 xhr.onLoad.listen((e) { 223 xhr.onLoad.listen((e) {
354 var accepted = xhr.status >= 200 && xhr.status < 300; 224 var accepted = xhr.status >= 200 && xhr.status < 300;
355 var fileUri = xhr.status == 0; // file:// URIs have status of 0. 225 var fileUri = xhr.status == 0; // file:// URIs have status of 0.
356 var notModified = xhr.status == 304; 226 var notModified = xhr.status == 304;
357 // Redirect status is specified up to 307, but others have been used in 227 // Redirect status is specified up to 307, but others have been used in
358 // practice. Notably Google Drive uses 308 Resume Incomplete for 228 // practice. Notably Google Drive uses 308 Resume Incomplete for
359 // resumable uploads, and it's also been used as a redirect. The 229 // resumable uploads, and it's also been used as a redirect. The
360 // redirect case will be handled by the browser before it gets to us, 230 // redirect case will be handled by the browser before it gets to us,
361 // so if we see it we should pass it through to the user. 231 // so if we see it we should pass it through to the user.
362 var unknownRedirect = xhr.status > 307 && xhr.status < 400; 232 var unknownRedirect = xhr.status > 307 && xhr.status < 400;
363 233
364 var isSuccessful = accepted || fileUri || notModified || unknownRedirect; 234 if (accepted || fileUri || notModified || unknownRedirect) {
365
366 if (zone == null && isSuccessful) {
367 completer.complete(xhr); 235 completer.complete(xhr);
368 } else if (zone == null) { 236 } else {
369 completer.completeError(e); 237 completer.completeError(e);
370 } else if (isSuccessful) {
371 zone.runTask((task, value) {
372 completer.complete(value);
373 }, task, xhr);
374 } else {
375 zone.runTask((task, error) {
376 completer.completeError(error);
377 }, task, e);
378 } 238 }
379 }); 239 });
380 240
381 if (zone == null) { 241 xhr.onError.listen(completer.completeError);
382 xhr.onError.listen(completer.completeError); 242
243 if (sendData != null) {
244 xhr.send(sendData);
383 } else { 245 } else {
384 xhr.onError.listen((error) { 246 xhr.send();
385 zone.runTask((task, error) {
386 completer.completeError(error);
387 }, task, error);
388 });
389 } 247 }
390 248
391 if (sendData != null) { 249 return completer.future;
392 // TODO(floitsch): should we go through 'send()' and have nested tasks?
393 xhr._send(sendData);
394 } else {
395 xhr._send();
396 }
397
398 return task;
399 } 250 }
400 251
401 /** 252 /**
402 * Checks to see if the Progress event is supported on the current platform. 253 * Checks to see if the Progress event is supported on the current platform.
403 */ 254 */
404 static bool get supportsProgressEvent { 255 static bool get supportsProgressEvent {
405 $if DART2JS 256 $if DART2JS
406 var xhr = new HttpRequest(); 257 var xhr = new HttpRequest();
407 return JS('bool', '("onprogress" in #)', xhr); 258 return JS('bool', '("onprogress" in #)', xhr);
408 $else 259 $else
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 * cross-origin support is not required then [request] should be used instead. 309 * cross-origin support is not required then [request] should be used instead.
459 */ 310 */
460 @Experimental() 311 @Experimental()
461 static Future<String> requestCrossOrigin(String url, 312 static Future<String> requestCrossOrigin(String url,
462 {String method, String sendData}) { 313 {String method, String sendData}) {
463 if (supportsCrossOrigin) { 314 if (supportsCrossOrigin) {
464 return request(url, method: method, sendData: sendData).then((xhr) { 315 return request(url, method: method, sendData: sendData).then((xhr) {
465 return xhr.responseText; 316 return xhr.responseText;
466 }); 317 });
467 } 318 }
468 // TODO(floitsch): the following code doesn't go through task zones.
469 // Since 'XDomainRequest' is an IE9 feature we should probably just remove
470 // it.
471 $if DART2JS 319 $if DART2JS
472 var completer = new Completer<String>(); 320 var completer = new Completer<String>();
473 if (method == null) { 321 if (method == null) {
474 method = 'GET'; 322 method = 'GET';
475 } 323 }
476 var xhr = JS('var', 'new XDomainRequest()'); 324 var xhr = JS('var', 'new XDomainRequest()');
477 JS('', '#.open(#, #)', xhr, method, url); 325 JS('', '#.open(#, #)', xhr, method, url);
478 JS('', '#.onload = #', xhr, convertDartClosureToJS((e) { 326 JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
479 var response = JS('String', '#.responseText', xhr); 327 var response = JS('String', '#.responseText', xhr);
480 completer.complete(response); 328 completer.complete(response);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 * 389 *
542 * By default the request is done asyncronously, with no user or password 390 * By default the request is done asyncronously, with no user or password
543 * authentication information. If `async` is false, the request will be send 391 * authentication information. If `async` is false, the request will be send
544 * synchronously. 392 * synchronously.
545 * 393 *
546 * Calling `open` again on a currently active request is equivalent to 394 * Calling `open` again on a currently active request is equivalent to
547 * calling `abort`. 395 * calling `abort`.
548 * 396 *
549 * Note: Most simple HTTP requests can be accomplished using the [getString], 397 * Note: Most simple HTTP requests can be accomplished using the [getString],
550 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this 398 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
551 * `open` method is intended only for more complex HTTP requests where 399 * `open` method is intended only for more complext HTTP requests where
552 * finer-grained control is needed. 400 * finer-grained control is needed.
553 */ 401 */
554 @DomName('XMLHttpRequest.open') 402 @DomName('XMLHttpRequest.open')
555 @DocsEditable() 403 @DocsEditable()
556 $if JSINTEROP 404 $if JSINTEROP
557 void open(String method, String url, {bool async, String user, String password }) { 405 void open(String method, String url, {bool async, String user, String password }) {
558 if (async == null && user == null && password == null) { 406 if (async == null && user == null && password == null) {
559 _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url); 407 _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url);
560 } else { 408 } else {
561 _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, as ync, user, password); 409 _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, as ync, user, password);
562 } 410 }
563 } 411 }
564 $else 412 $else
565 void open(String method, String url, {bool async, String user, String password }) native; 413 void open(String method, String url, {bool async, String user, String password }) native;
566 $endif 414 $endif
567 415
568 /**
569 * Sends the request with any given `data`.
570 *
571 * Note: Most simple HTTP requests can be accomplished using the [getString],
572 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
573 * `send` method is intended only for more complex HTTP requests where
574 * finer-grained control is needed.
575 *
576 * ## Other resources
577 *
578 * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHtt pRequest#send%28%29)
579 * from MDN.
580 */
581 @DomName('XMLHttpRequest.send')
582 @DocsEditable()
583 void send([body_OR_data]) {
584 if (identical(Zone.current, Zone.ROOT)) {
585 _send(body_OR_data);
586 } else {
587 Zone.current.createTask(_createHttpRequestSendTask,
588 new HttpRequestSendTaskSpecification(this, body_OR_data));
589 }
590 }
591
592 static HttpRequest _createHttpRequestSendTask(
593 HttpRequestSendTaskSpecification spec, Zone zone) {
594 spec.request._send(spec.sendData);
595 return spec.request;
596 }
597
598 $!MEMBERS 416 $!MEMBERS
599 } 417 }
OLDNEW
« no previous file with comments | « tools/dom/templates/html/impl/impl_Window.darttemplate ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698