Copyright © 2006-2009 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document describes event types that can be used for monitoring the progress of an operation taking place. It is primarily intended for contexts such as data transfer operations specified by XMLHttpRequest [XHR], or Media Access Events [MAE].
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document is an editor's draft specification of the ProgressEvent events from the Web Applications Working Group, a successor to the Web API group, part of the Rich Web Client Activity. It defines events which can be used to monitor a process and provide feedback to a user, particularly for network-based events. This editor's draft does not imply any consensus of or endorsement by any member of the working group, and may contain minor or major errors.
This version is published following comments on the last formal draft in
October 2008, and subsequent Editor's drafts. All comments are welcome and
should be sent to the new Working Group list at public-webapps@w3.org with the marker
[progress] in the subject line. All messages received at this
address are viewable in a public archive
(Please note that the WebAPIs group list was used until mid 2008, so some old
messages are archived there
instead). At the time of publication the editor believes that issue-79
href="http://www.w3.org/2008/webapps/track/issues/105" has been resolved, but
that ISSUE-105 (what is counted by the
total/loaded attributes) is still unresolved.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
The terms must, should, may, must not, should not, are used in this document in accordance with [RFC2119]. A conformant implementation of this specification meets all relevant requirements identified by the use of these terms.
All sections of this document are normative, except examples, which are informative, and any section that begins with a statement identifying it as informative.
There are three classes of conformance to this specification:
ProgressEvent eventsThe following events are defined in this specification:
| Name | Description | How often? | When? |
|---|---|---|---|
loadstart |
The operation has begun | once | Must be dispatched first |
progress |
The operation is in progress | zero or more | May be dispatched zero or more times after a
loadstart event, before any error,
abort or load event is dispatched |
stalled |
The operation has temporarily stopped proceeding | zero or more | May be dispatched zero or more times after a
loadstart event, before any error,
abort or load event is dispatched |
suspend |
The operation has been temporarily halted by the user agent (e.g. as the result of a user action) | zero or more | May be dispatched zero or more times after a
loadstart event, before any error,
abort or load event is dispatched |
error |
The operation failed to complete, e.g. as a result of a network error | never or once | Exactly one of these must be dispatched |
abort |
The operation was cancelled, e.g. as a result of user interaction | never or once | |
load |
The operation successfuly completed | never or once | |
loadend |
The operation has finished | once | This must be fired after the operation has completed (i.e. following
error, abort or load events) |
ISSUE-105: How do we
track (if at all) progress other than in bytes, e.g. for a series of
transactions? Overload total/loaded and (optionally)
add some flag or attribute to track what is being counted, mint new events, or
what? Proposed resolution is to add the loadedItems and
totalItems attributes now found in the draft.
ISSUE-107: For
multiple-object transactions, should end-state events (load,
error, abort, loadend) fire for each
object, or only at the completion of the entire transaction?
User agents must ensure that these events trigger event listeners
attached on Element nodes for the relevant event and on the
capture and target phases.
No default action is defined in this specification for these events. Specifications may define default actions. Specifications should define whether events bubble or are cancelable. User Agents must implement the events as defined by any such specification.
For a Specification which has not defined whether these events bubble or are cancelable, User agents must implement these events such that by default the events do not bubble, and are not cancelable.
Specifications should use the events defined in this specification in preference to other events (e.g. in a different namespace, or with a different name) that offer the same functionality.
These events are in "no namespace", that is for the purposes of namespaced systems they use the null namespace. (For further information on namespaces, see "Namespaces in XML" [XMLNames]). Any events which have another namespace are not defined by this specification.
Two kinds of initialisation methods are provided: one (initProgressEventNS) in which the namespace is
required and must be null, and one (initProgressEvent) which assigns the
null namespace automatically. This specification does not
recommend use of one method over the other, and authors of specifications using
progress events may choose whichever method suits them better for any given
usage, or allow both.
loadstart event when
a relevant operation has begun. progress events while a network operation is taking
place.stalled
events if the operation has not proceeded. User Agents should
dispatch, and applications may listen for, a new
progress event as a notification that the operation is
proceeding again. suspend
events if the operation has been temporarily interrupted, e.g. due to some
user action. User Agents should dispatch, and applications
may listen for a new progress event as a notification
that the operation is proceeding again. error event, if the failure to complete was due to
an error (such as a timeout, or network error), or an abort
event if the operation was deliberately cancelled (e.g. by user interaction
or through a script call).load event. loadend event.In short, conforming user agents must fire at least one
loadstart event, followed by zero or more progress
events, followed by one event which may be any of error,
abort or load, according to the outcome of the
operation, and finally a loadend event must be fired. As noted in
Section 3, conforming specifications must maintain these constraints.
Where this specification repeats information from the DOM Level 3 Events specification [D3E], the repeated information in this section is informative. In the case of any conflict between the specifications the DOM Level 3 Events specification is normative.
Note: To create an instance of the
ProgressEvent interface, use the
DocumentEvent.createEvent("ProgressEvent") method call.
interface ProgressEvent : events::Event {
readonly attribute boolean lengthComputable;
readonly attribute unsigned long long loaded;
readonly attribute unsigned long long total;
readonly attribute unsigned long long loadedItems;
readonly attribute unsigned long long totalItems;
void initProgressEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in boolean lengthComputableArg,
in unsigned long long loadedArg,
in unsigned long long totalArg,
[Optional] in unsigned long loadedItemsArg,
in unsigned long totalItemsArg);
void initProgressEventNS(in DOMString namespaceURI,
in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in boolean lengthComputableArg,
in unsigned long long loadedArg,
in unsigned long long totalArg,
[Optional] in unsigned long loadedItemsArg,
in unsigned long totalItemsArg);
};
lengthComputableloadedItems attribute is present, then this
value refers to the amount loaded for item in the list
corresponding the to the value of the loadedItems
attribute.loadedBecause HTTP headers can include the users password, sometimes in clear text, a site that knows the size of the default headers for a given implementation can determine the size of the users password, which has the potential to assist in cracking it. Therefore the amount of content transferred should not be available from a HEAD request.For more details on HTTP see [RFC2616].
loadedItems attribute is present, then this
value refers to the amount loaded for item in the list
corresponding the to the value of the loadedItems
attribute.describes the state where of 34 items to be downloaded, the 20th ( item[19], where the first is item[0] ) has loaded 1024 of 8192 total bytes.
totalloaded attribute, conformant specifications
must define whether headers and overhead from the
transaction are included in calculating this value. Where there is
a content-encoding or transfer-encoding this value refers to the
number of bytes to be transferred, i.e. with the relevant encodings
applied. Where a specification has not defined this, conformant
user agents should exclude headers and similar
overhead.loadedItems attribute is present, then this
value refers to the amount loaded for item in the list
corresponding the to the value of the loadedItems
attribute.loadedItemstotalItemsEvent.initEventNS(), where the value of the namespace
parameter is specified as null [D3E].
load or
loadend this specification does not define
the resulting event. Refer to the
Event.initEvent() method [D3E] for further description of this
parameter.Event.bubbles. This parameter
overrides the intrinsic bubbling behavior of the event
and determines whether the event created will
bubbleEvent.cancelable. This
parameter overrides the intrinsic cancel behavior of
the event and determines whether the event created is
cancelableEvent.initEventNS() [D3E]. Except
as described below, parameters are the same as for initProgressEvent.
Note that initProgressEvent('progress', true, true, true, size,
bigsize) and initProgressEvent('progress', true, true, true, size,
bigsize, 0, 1) are equivalent (an event describing the progress of a
transaction involving a single option), but initProgressEvent('progress',
true, true, true, size, bigsize, 0, 0) is not equivalent to these, since
it describes the first object in a transaction with an unknown total number of
distinct objects.
A progress event occurs when the user agent makes progress in some data transfer operation, such as loading a resource from the web via XMLHttpRequest [XHR]. Conforming specifications which use progress events must define the targets on which progress events are dispatched.
Either by reference or by direct inclusion, conforming specifications
must maintain and must not contradict the requirements for
and definition of the events as described in the section The ProgressEvent
events, including such characteristics as the relative order of firing. As
noted in that section, specifications may define additional characteristics
subject to this restriction.
This example is informative.
FooAPI has a sendAndRetrieve() method, which sends some content
via a predefined SMTP server and retrieves some other content via HTTP HEAD
from a URI given as a parameter. It specifies two event targets
send and receive. Progress events as specified in the
[ProgressEvent] events specification may be fired [firing] on these targets for
the send and receive phases respectively.
If any progress events are dispatched, then at least one start
event, one progress or, if the rate of transfer falls below 10
bytes / second, one stalled event per second, one of
error, abort, or load and one
loadend event must be dispatched on each target.
For the send phase, the total attribute of the progress events
measures the size of the RFC822 message body. For the receive phase, the
total attribute specifies the size of the content to be returned
in the HTTP HEAD operation. If the rate of transfer falls below 1kb / second
one stalled event per second may be fired for as long as
the rate remains below 1kb/second. If no bytes are transferred for 4 seconds an
error event followed by a loadend event must
be fired and the transfer terminated.
References:
Firing a Progress event means to dispatch an event [D3E]
at a given target. This event must have the name progress, must be
in the null namespace (or have no namespace) and must use the
ProgressEvent interface. It must also meet the requirements described in
section 2 The
ProgressEvent events, including values for the
type, total, and loaded attributes. If
the specification calling for the event to be fired has defined its bubbling
and cancelability, then it must follow those requirements, otherwise (as
described in section 2), it must not bubble and must not be cancelable. There
is only a default action if it has been defined by the specification calling
for the events to be fired.
Scripts may use progress events in order to provide feedback on operations performed by an application.
This example is informative and does not necessarily illustrate best practice.
In this example, the application uses the information in progress events emitted as an image loads in order to fill a progress bar as it receives progress events. Where the size of a download is unknown or there has been no progress yet there is simply a block moving back and forth within the progress bar to indicate that there is still some kind of activity.
<?xml version="1.1" ?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400">
<script type="application/ecmascript"><![CDATA[
var xlinkNS = "http://www.w3.org/1999/xlink"
function showImage(imageHref) {
var image = document.getElementById('myImage');
image.setAttributeNS(xlinkNS, "href", imageHref);
image.addEventListener("progress",imageLoadProgress,false);
image.addEventListener("load",imageLoadComplete,false);
image.addEventListener("error",imageLoadComplete,false);
image.addEventListener("abort",imageLoadComplete,false);
}
function imageLoadProgress(evt) {
if (evt.lengthComputable && evt.total != 0) { // size is known, not zero
var progressBar = document.getElementById('progressBar');
progressBar.setAttribute("width", 100*evt.loaded/evt.total);
var loadAnimation = document.getElementById('loadAnimation');
loadAnimation.endElement();
} else { // we don't know the size and we need not to divide by zero
var progressBar = document.getElementById('progressBar');
progressBar.setAttribute("width", 20);
var loadAnimation = document.getElementById('loadAnimation');
loadAnimation.beginElement();
}
}
function imageLoadComplete(evt) {
var progressBar = document.getElementById('progressBar');
progressBar.setAttribute("width", 100);
var loadAnimation = document.getElementById('loadAnimation');
loadAnimation.endElement();
}
]]></script>
<image id="myImage" xlink:href="imageA.png" y="15" width="400" height="300"/>
<g id="button" onclick="showImage('imageB.png')">
<rect width="120"
height="30" y="350" id="button" fill="#aaa"/>
<text x="20" y="370" font-size="15">Change Image</text>
</g>
<animate id="loadAnimation" xlink:href="#progressBar" attributeName="x"
by="80" dur="1s" begin="button.click" repeatCount="indefinite"/>
<g id="meter" opacity="0">
<set attributeName="opacity" to=".7" begin="button.click" end="myImage.load"/>
<rect width="101" fill="none" stroke="black" height="5"
x="5" y="5" stroke-width="1"/>
<rect id="progressBar" fill="#444" height="4" x="5.5" y="5.5"/>
</g>
</svg>
Download example 2 (requires SVG support)
This example is informative and does not necessarily illustrate best practice.
In this example, the application creates an XMLHttpRequest [XHR], in an HTML5 [HTML5] document and checks whether it makes progress. (Note that this relies on draft specifications and may need to change)
<!DOCTYPE html>
<html>
<head>
<title>Using Progress Events</title>
<script>
var theTransfer = new XMLHttpRequest();
//start up the request properly...
theTransfer.addEventListener("progress",updateProgress,false);
theTransfer.addEventListener("load",worky,false);
theTransfer.addEventListener("error",failToWorky,false);
theTransfer.addEventListener("abort",whatForYouDoThat,false);
theTransfer.open()
function updateProgress(evt) {
var progressCount = document.getElementById('progressCount');
progressCount.child[0].data = evt.loaded;
if (evt.lengthComputable && evt.total != 0) { // show progress
var totalCount = document.getElementById('total');
totalCount.child[0].data = evt.total;
} else { // we don't know the size
var totalCount = document.getElementById('totalCount');
totalCount.setAttribute("irrelevant", "irrelevant");
}
}
function worky(evt) {
alert("Yuk! Modal dialog! But the transfer completed ;) ");
}
function failToWorky(evt) {
alert("Oh! The horror! The transfer failed!!1");
}
function whatForYouDoThat(evt) {
alert("Hey! User control is not relevant here...");
}
</script>
</head>
<body>
<p id="theProgress">So far, I have loaded
<span id="progressCount">0</span> bytes
<span id="totalCount">of the total transfer of
<span id="total">the total</span></span></p>
</body>
</html>
progress element
proposed by WHAT-WGThe editor would like to thank the SVG working group for producing the draft
[SVGD] that this was initially based on. The WHATWG's
proposed progress element [WPE] and the
documentation for Internet Explorer's onProgress implementation
[IEoP] were also useful as initial references for this
specification. In addition, the following individuals' comments have been
invaluable in preparing this draft:
Robin Berjon, Jean-Yves Bitterlich, Marcos Caceres, Suresh Chitturi, Alex Danilo, Erik Dahlström, Jean-Claude Duford, Andrew Emmons, João Eiras, Gorm Eriksen, Kartikaya Gupta, Ian Hickson, David Håsäther, Björn Höhrmann, Philip Jägenstedt, Anne van Kesteren, Travis Leithead, Aaron Leventhal, Jim Ley, Chris Lilley, Cameron McCormack, Olli Pettay, Simon Pieters, Michael Antony Puls, Nandini Ramani, Robert Sayre, Alan Schepers, Doug Schepers, Rich Schwerdtfeger, Lisa Seeman, Andrew Shellshear, Ellen Siegel, Andy Sledd, Garrett Smith, Maciej Stachowiak, Boris Zbarsky, Gottfried Zimmermann
The editor apologises to anyone who has inadvertently been left off this list, and welcomes corrections.
long to
long long where they hadn't been updated yet - ISSUE-37loadend event.long to
long long.progress
events.Element nodeslengthComputable back to IDL definitions toolengthComputable backtotal and
loadedpreload and postload event
types, added uploadprogresslengthComputable attributetotal as zero if it is unknownVarious editorial changes and corrections and modifications to the examples are made from draft to draft. These are generally not noted in the change history.