Chromium Code Reviews| Index: tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate |
| diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate |
| index 9ad00f61c2c2053f97c229ee85a0ffa0b1dd0b83..ba2fda06c6adad73ca3ca06543a34035964d2038 100644 |
| --- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate |
| +++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate |
| @@ -4,6 +4,109 @@ |
| part of $LIBRARYNAME; |
| +/** |
| + * A task specification for http requests. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
http -> HTTP
(lots more below).
floitsch
2016/07/02 01:53:55
Done.
|
| + * |
| + * This specification is not available when an http request is sent through |
| + * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification]. |
| + * |
| + * A task created by this specification is a `Future<HttpRequest>`. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
by -> from.
It's created by the `create` function
floitsch
2016/07/02 01:53:55
Done.
|
| + * |
| + * *Experimental*. This class may disappear without notice. |
| + */ |
| +class HttpRequestTaskSpecification extends TaskSpecification { |
| + /// The URL of the request. |
| + final String url; |
| + |
| + /// The method used to do the request. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
"method" here needs to be put in context. Maybe "r
floitsch
2016/07/02 01:53:55
changed to 'The HTTP request method.'
|
| + /// |
| + /// By default (when `null`) this is a `"GET"` request. Alternatively, the |
| + /// method can be `"POST"`, `"PUT"`, `"DELETE"`, etc. |
| + final String method; |
| + |
| + /// Whether the request should send credentials. Credentials are only useful |
| + /// for cross-origin requests. |
| + /// |
| + /// See [HttpRequest.request] for more information. |
| + final bool withCredentials; |
| + |
| + /// The desired response format. |
| + /// |
| + /// Supported types are: |
| + /// - `""`: (same as `"text"`), |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:30
It seems a little odd to have `""` be equal to `"t
floitsch
2016/07/02 01:53:55
not my choice. This is just documentation copied f
|
| + /// - `"arraybuffer"`, |
| + /// - `"blob"`, |
| + /// - `"document"`, |
| + /// - `"json"`, |
| + /// - `"text"` |
| + /// |
| + /// By default (when `null`) the desired format is `""`. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:30
This says that if the desired response format is n
floitsch
2016/07/02 01:53:55
Changed to: "When no value is provided (when equal
|
| + final String responseType; |
| + |
| + /// The desired mime type. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
mime -> MIME
I think "media type" or "content typ
floitsch
2016/07/02 01:53:55
I'm just copying/documenting the values from the `
|
| + /// |
| + /// This overrides the default mime-type which is set up to transfer textual |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:30
which is set up to transfer textual data -> which
Lasse Reichstein Nielsen
2016/07/01 12:41:30
no dash in "MIME type".
floitsch
2016/07/02 01:53:55
I even went into the spec, but couldn't find the M
floitsch
2016/07/02 01:53:55
Done.
|
| + /// data. |
| + final String mimeType; |
| + |
| + /// The request headers that should be sent with the request. |
| + final Map<String, String> requestHeaders; |
| + |
| + /// The data that is sent with the request. |
| + /// |
| + /// When provided (not `null`) must be a [ByteBuffer], |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
When data is provided (the value is not `null`), i
floitsch
2016/07/02 01:53:55
Done.
|
| + /// [Blob], [Document], [String], or [FormData]. |
| + final dynamic sendData; |
| + |
| + /// The function that is invoked on progress updates. This function is |
| + /// registered as an event listener on the created [HttpRequest] object, and |
| + /// thus has its own task. Further invocations of the progress function do |
| + /// *not* use the http-request task as task object. |
| + /// |
| + /// Creating an HTTP request automatically registers the on-progress listener. |
| + final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress; |
| + |
| + HttpRequestTaskSpecification(this.url, |
| + {String this.method, bool this.withCredentials, String this.responseType, |
| + String this.mimeType, Map<String, String> this.requestHeaders, |
| + this.sendData, |
| + void this.onProgress(ProgressEvent e)}); |
| + |
| + String get name => "dart.html.http-request"; |
| + bool get isOneShot => true; |
| +} |
| + |
| +/** |
| + * A task specification for http requests that are initiated through a direct |
| + * invocation of [HttpRequest.send]. |
| + * |
| + * This specification serves as signal to zones that an http request has been |
| + * initiated. The created task is the [request] object itself, and |
| + * no callback is ever executed in this task. |
|
Lasse Reichstein Nielsen
2016/07/01 12:41:29
Doesn't that make it a non-task? If a task is some
floitsch
2016/07/02 01:53:55
Somehow yes.
I added it:
- because it makes http-
|
| + * |
| + * Note that event listeners on the http request are also registered in the |
| + * zone (although with their own task creations), and that a zone can thus |
| + * detect when the http-request returns. |
| + * |
| + * HTTP requests that are initiated through `request` methods don't use |
| + * this class but use [HttpRequestTaskSpecification]. |
| + * |
| + * *Experimental*. This class may disappear without notice. |
| + */ |
| +class HttpRequestSendTaskSpecification extends TaskSpecification { |
| + final HttpRequest request; |
| + final dynamic sendData; |
| + |
| + HttpRequestSendTaskSpecification(this.request, this.sendData); |
| + |
| + String get name => "dart.html.http-request-send"; |
| + |
| + /** |
| + * No callback is ever executed in an http-request send task. |
| + */ |
| + bool get isOneShot => false; |
| +} |
| + |
| /** |
| * A client-side XHR request for getting data from a URL, |
| * formally known as XMLHttpRequest. |
| @@ -190,7 +293,34 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS |
| {String method, bool withCredentials, String responseType, |
| String mimeType, Map<String, String> requestHeaders, sendData, |
| void onProgress(ProgressEvent e)}) { |
| + var spec = new HttpRequestTaskSpecification( |
| + url, method: method, |
| + withCredentials: withCredentials, |
| + responseType: responseType, |
| + mimeType: mimeType, |
| + requestHeaders: requestHeaders, |
| + sendData: sendData, |
| + onProgress: onProgress); |
| + |
| + if (identical(Zone.current, Zone.ROOT)) { |
| + return _createHttpRequestTask(spec, null); |
| + } |
| + return Zone.current.createTask(_createHttpRequestTask, spec); |
| + } |
| + |
| + static Future<HttpRequest> _createHttpRequestTask( |
| + HttpRequestTaskSpecification spec, Zone zone) { |
| + String url = spec.url; |
| + String method = spec.method; |
| + bool withCredentials = spec.withCredentials; |
| + String responseType = spec.responseType; |
| + String mimeType = spec.mimeType; |
| + Map<String, String> requestHeaders = spec.requestHeaders; |
| + var sendData = spec.sendData; |
| + var onProgress = spec.onProgress; |
| + |
| var completer = new Completer<HttpRequest>(); |
| + var task = completer.future; |
| var xhr = new HttpRequest(); |
| if (method == null) { |
| @@ -230,23 +360,42 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS |
| // redirect case will be handled by the browser before it gets to us, |
| // so if we see it we should pass it through to the user. |
| var unknownRedirect = xhr.status > 307 && xhr.status < 400; |
| - |
| - if (accepted || fileUri || notModified || unknownRedirect) { |
| + |
| + var isSuccessful = accepted || fileUri || notModified || unknownRedirect; |
| + |
| + if (zone == null && isSuccessful) { |
| completer.complete(xhr); |
| - } else { |
| + } else if (zone == null) { |
| completer.completeError(e); |
| + } else if (isSuccessful) { |
| + zone.runTask((task, value) { |
| + completer.complete(value); |
| + }, task, xhr); |
| + } else { |
| + zone.runTask((task, error) { |
| + completer.completeError(error); |
| + }, task, e); |
| } |
| }); |
| - xhr.onError.listen(completer.completeError); |
| + if (zone == null) { |
| + xhr.onError.listen(completer.completeError); |
| + } else { |
| + xhr.onError.listen((error) { |
| + zone.runTask((task, error) { |
| + completer.completeError(error); |
| + }, task, error); |
| + }); |
| + } |
| if (sendData != null) { |
| - xhr.send(sendData); |
| + // TODO(floitsch): should we go through 'send()' and have nested tasks? |
| + xhr._send(sendData); |
| } else { |
| - xhr.send(); |
| + xhr._send(); |
| } |
| - return completer.future; |
| + return task; |
| } |
| /** |
| @@ -316,6 +465,9 @@ $endif |
| return xhr.responseText; |
| }); |
| } |
| + // TODO(floitsch): the following code doesn't go through task zones. |
| + // Since 'XDomainRequest' is an IE9 feature we should probably just remove |
| + // it. |
| $if DART2JS |
| var completer = new Completer<String>(); |
| if (method == null) { |
| @@ -396,7 +548,7 @@ $endif |
| * |
| * Note: Most simple HTTP requests can be accomplished using the [getString], |
| * [request], [requestCrossOrigin], or [postFormData] methods. Use of this |
| - * `open` method is intended only for more complext HTTP requests where |
| + * `open` method is intended only for more complex HTTP requests where |
| * finer-grained control is needed. |
| */ |
| @DomName('XMLHttpRequest.open') |
| @@ -413,5 +565,35 @@ $else |
| void open(String method, String url, {bool async, String user, String password}) native; |
| $endif |
| + /** |
| + * Sends the request with any given `data`. |
| + * |
| + * Note: Most simple HTTP requests can be accomplished using the [getString], |
| + * [request], [requestCrossOrigin], or [postFormData] methods. Use of this |
| + * `send` method is intended only for more complex HTTP requests where |
| + * finer-grained control is needed. |
| + * |
| + * ## Other resources |
| + * |
| + * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29) |
| + * from MDN. |
| + */ |
| + @DomName('XMLHttpRequest.send') |
| + @DocsEditable() |
| + void send([body_OR_data]) { |
| + if (identical(Zone.current, Zone.ROOT)) { |
| + _send(body_OR_data); |
| + } else { |
| + Zone.current.createTask(_createHttpRequestSendTask, |
| + new HttpRequestSendTaskSpecification(this, body_OR_data)); |
| + } |
| + } |
| + |
| + static HttpRequest _createHttpRequestSendTask( |
| + HttpRequestSendTaskSpecification spec, Zone zone) { |
| + spec.request._send(spec.sendData); |
| + return spec.request; |
| + } |
| + |
| $!MEMBERS |
| } |