diff --git a/fetch.bs b/fetch.bs index 4d01e315b..490cfdf3d 100755 --- a/fetch.bs +++ b/fetch.bs @@ -114,6 +114,8 @@ urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
spec:dom; type:dfn; text:element +spec:dom; type:dfn; text:event; +spec:xhr; type:event; text:progress; spec:infra; type:dfn; text:implementation-defined@@ -8512,7 +8514,24 @@ otherwise false.
partial interface mixin WindowOrWorkerGlobalScope {
- [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
+ [NewObject] Promise<Response> fetch(RequestInfo input, optional FetchInit init = {});
+};
+
+dictionary FetchInit : RequestInit {
+ FetchMonitorCallback monitor;
+};
+
+callback FetchMonitorCallback = undefined (FetchMonitor monitor);
+
+[Exposed=(Window,Worker)]
+interface FetchMonitor : EventTarget {
+ readonly attribute double requestLoaded;
+ readonly attribute double responseLoaded;
+ readonly attribute double requestTotal;
+ readonly attribute double responseTotal;
+
+ attribute EventHandler onrequestprogress;
+ attribute EventHandler onresponseprogress;
};
@@ -8584,10 +8603,55 @@ method steps are:
https://github.com/whatwg/dom/issues/1031#issuecomment-1233206400 -->
+ Let monitor be null. + +
If init["{{FetchInit/monitor}}"] exists, then: + +
Let monitorCallback be init["{{FetchInit/monitor}}"]. + +
Set monitor to a {{FetchMonitor}}. + +
Set monitor's requestTotal to request's + body's length, if request's body + is non-null; otherwise 0. + +
Let args be « monitor ». + +
[=invoke|Invoke=] monitorCallback with args
+ and "rethrow". If this throws an exception, reject p with it
+ and return p.
+
Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +
If monitor is null, then return. + +
Increase monitor's requestLoaded by bytesLength. + +
If not roughly 50ms has passed since these steps were last invoked, then return. + +
Fire a progress event named
+ requestprogress at monitor with
+ monitor's requestLoaded and monitor's requestTotal.
+
Set controller to the result of calling fetch given - request and processResponse given response being - these steps: +
Let processRequestEndOfBody be these steps: + +
If monitor is null, then return. + +
Fire a progress event named requestprogress at
+ monitor with monitor's requestLoaded and
+ monitor's requestTotal.
+
Let processResponse given a response be these steps:
If locallyAborted is true, then abort these steps. @@ -8615,10 +8679,17 @@ method steps are:
Resolve p with responseObject.
Set controller to the result of calling fetch given + request with processResponse set to processResponse, + processRequestBodyChunkLength set to processRequestBodyChunkLength, + and processRequestEndOfBody set to processRequestEndOfBody. +
Return p.
+TEMPORARY requestprogress
+
To abort a fetch() call
with a promise, request, responseObject, and an error:
@@ -9132,6 +9203,125 @@ done only by navigations). The fetch controller is also used to
process the next manual redirect for requests with
redirect mode set to "manual".
+
+[Exposed=(Window,Worker)]
+interface ProgressEvent : Event {
+ constructor(DOMString type, optional ProgressEventInit eventInitDict = {});
+
+ readonly attribute boolean lengthComputable;
+ readonly attribute double loaded;
+ readonly attribute double total;
+};
+
+dictionary ProgressEventInit : EventInit {
+ boolean lengthComputable = false;
+ double loaded = 0;
+ double total = 0;
+};
+
+
+Events using the {{ProgressEvent}} interface indicate some kind of progression. + +
The
+lengthComputable,
+loaded, and
+total
+getter steps are to return the value they were initialized to.
+
+
+
To fire a progress event named e at +target, given transmitted and length, means to fire an event +named e at target, using {{ProgressEvent}}, with the {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +
This section is non-normative. + +
The suggested {{Event/type}} +attribute values for use with +events using the +{{ProgressEvent}} interface are summarized in the table below. +Specification editors are free to tune the details to their specific +scenarios, though are strongly encouraged to discuss their usage with the +WHATWG community to ensure input from people familiar with the subject. + +
| {{Event/type}} attribute value + | Description + | Times + | When + |
|---|---|---|---|
loadstart
+ | Progress has begun. + | Once. + | First. + |
progress
+ | In progress. + | Once or more. + | After loadstart has been
+ dispatched.
+ |
requestprogress
+ | In progress request. + | Once or more. + | After loadstart has been
+ dispatched.
+ |
error
+ | Progression failed. + | Zero or once (mutually exclusive). + | After the last progress has
+ been
+ dispatched.
+ |
abort
+ | Progression is terminated. + | ||
timeout
+ | Progression is terminated due to preset time expiring. + | ||
load
+ | Progression is successful. + | ||
loadend
+ | Progress has stopped. + | Once. + | After one of error, abort,
+ timeout or load has been
+ dispatched.
+ |
The error, abort, timeout, and
+load event types are mutually exclusive.
+
+
Throughout the web platform the error, abort,
+timeout and load event types have
+their {{Event/bubbles}} and {{Event/cancelable}}
+attributes initialized to false, so it is suggested that for consistency all
+events using the
+{{ProgressEvent}} interface do the same.
+
+
+
For cross-origin requests some kind of opt-in, e.g., the +CORS protocol, has to be used before events using the +{{ProgressEvent}} interface are +dispatched +as information (e.g., size) would be revealed that cannot be obtained +otherwise. +