This is a snapshot of an early working draft and has therefore been superseded by the HTML standard.

This document will not be further updated.

HTML 5

Call For Comments — 27 October 2007

4.6. Offline Web applications

4.6.1. Introduction

...

4.6.2. Application caches

An application cache is a collection of resources. An application cache is identified by the URI of a resource manifest which is used to populate the cache.

Application caches are versioned, and there can be different instances of caches for the same manifest URI, each having a different version. A cache is newer than another if it was created after the other (in other words, caches in a group have a chronological order).

Each group of application caches for the same manifest URI have a common update status, which is one of the following: idle, checking, downloading.

A browsing context can be associated with an application cache. A child browsing context is always associated with the same browsing context as its parent browsing context, if any. A top-level browsing context is associated with the application cache appropriate for its active document. (A browsing context's associated cache thus can change during session history traversal.)

A Document initially has no appropriate cache, but steps in the parser and in the navigation sections cause cache selection to occur early in the page load process.

An application cache consists of:

Multiple application caches can contain the same resource, e.g. if their manifests all reference that resource. If the user agent is to select an application cache from a list of caches that contain a resource, that the user agent must use the application cache that the user most likely wants to see the resource from, taking into account the following:

4.6.3. The cache manifest syntax

4.6.3.1. Writing cache manifests

Manifests must be served using the text/cache-manifest MIME type. All resources served using the text/cache-manifest MIME type must follow the syntax of application cache manifests, as described in this section.

An application cache manifest is a text file, whose text is encoded using UTF-8. Data in application cache manifests is line-based. Newlines must be represented by U+000A LINE FEED (LF) characters, U+000D CARRIAGE RETURN (CR) characters, or U+000D CARRIAGE RETURN (CR) U+000A LINE FEED (LF) pairs.

This is a willful double violation of RFC2046.

The first line of an application cache manifest must consist of the string "CACHE", a single U+0020 SPACE character, the string "MANIFEST", and zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters. If any other text is found on the first line, the user agent will ignore the entire file. The first line may optionally be preceded by a U+FEFF BYTE ORDER MARK (BOM) character.

Subsequent lines, if any, must all be one of the following:

A blank line

Blank lines must consist of zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters only.

A comment

Comment lines must consist of zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, followed by a single U+0023 NUMBER SIGN (#) character, followed by zero or more characters other than U+000A LINE FEED (LF) and U+000D CARRIAGE RETURN (CR) characters.

Comments must be on a line on their own. If they were to be included on a line with a URI, the "#" would be mistaken for part of a fragment identifier.

A section header

Section headers change the current section. There are three possible section headers:

CACHE:
Switches to the explicit section.
FALLBACK:
Switches to the fallback section.
NETWORK:
Switches to the online whitelist section.

Section header lines must consist of zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, followed by one of the names above (including the U+003A COLON (:) character) followed by zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters.

Ironically, by default, the current section is the explicit section.

Data for the current section

The format that data lines must take depends on the current section.

When the current section is the explicit section or the online whitelist section, data lines must consist of zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, a valid URI reference or IRI reference, and then zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters. [RFC3986] [RFC3987]

When the current section is the fallback section, data lines must consist of zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, a valid URI reference or IRI reference, one or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, another valid URI reference or IRI reference, and then zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters. [RFC3986] [RFC3987]

Manifests may contain sections more than once. Sections may be empty.

URIs that are to be fallback pages associated with opportunistic caching namespaces, and those namespaces themselves, must be given in fallback sections, with the namespace being the first URI of the data line, and the corresponding fallback page being the second URI. All the other pages to be cached must be listed in explicit sections.

Opportunistic caching namespaces must have the same scheme/host/port as the manifest itself.

An opportunistic caching namespace must not be listed more than once.

URIs that the user agent is to put into the online whitelist must all be specified in online whitelist sections. (This is needed for any URI that the page is intending to use to communicate back to the server.)

URIs in the online whitelist section must not also be listed in explicit section, and must not be listed as fallback entries in the fallback section. (URIs in the online whitelist section may match opportunistic caching namespaces, however.)

Relative URIs must be given relative to the manifest's own URI.

URIs in manifests must not have fragment identifiers.

4.6.3.2. Parsing cache manifests

When a user agent is to parse a manifest, it means that the user agent must run the following steps:

  1. The user agent must decode the bytestream corresponding with the manifest to be parsed, treating it as UTF-8. Bytes or sequences of bytes that are not valid UTF-8 sequences must be interpreted as a U+FFFD REPLACEMENT CHARACTER. All U+0000 NULL characters must be replaced by U+FFFD REPLACEMENT CHARACTERs.

  2. Let explicit URIs be an initially empty list of explicit entries.

  3. Let fallback URIs be an initially empty mapping of opportunistic caching namespaces to fallback entries.

  4. Let online whitelist URIs be an initially empty list of URIs for a online whitelist.

  5. Let input be the decoded text of the manifest's bytestream.

  6. Let position be a pointer into input, initially pointing at the first character.

  7. If position is pointing at a U+FEFF BYTE ORDER MARK (BOM) character, then advance position to the next character.

  8. If the characters starting from position are "CACHE", followed by a U+0020 SPACE character, followed by "MANIFEST", then advance position to the next character after those. Otherwise, this isn't a cache manifest; abort this algorithm with a failure while checking for the magic signature.

  9. Collect a sequence of characters that are U+0020 SPACE or U+0009 CHARACTER TABULATION (tab) characters.

  10. If position is not past the end of input and the character at position is neither a U+000A LINE FEED (LF) characters nor a U+000D CARRIAGE RETURN (CR) character, then this isn't a cache manifest; abort this algorithm with a failure while checking for the magic signature.

  11. This is a cache manifest. The algorithm cannot fail beyond this point (though bogus lines can get ignored).

  12. Let mode be "explicit".

  13. Start of line: If position is past the end of input, then jump to the last step. Otherwise, collect a sequence of characters that are U+000A LINE FEED (LF), U+000D CARRIAGE RETURN (CR), U+0020 SPACE, or U+0009 CHARACTER TABULATION (tab) characters.

  14. Now, collect a sequence of characters that are not U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) characters, and let the result be line.

  15. If the first character in line is a U+0023 NUMBER SIGN (#) character, then jump back to the step labelled "start of line".

  16. Drop any trailing U+0020 SPACE, or U+0009 CHARACTER TABULATION (tab) characters at the end of line.

  17. If line equals "CACHE:" (the word "CACHE" followed by a U+003A COLON (:) character), then set mode to "explicit" and jump back to the step labelled "start of line".

  18. If line equals "FALLBACK:" (the word "FALLBACK" followed by a U+003A COLON (:) character), then set mode to "fallback" and jump back to the step labelled "start of line".

  19. If line equals "NETWORK:" (the word "NETWORK" followed by a U+003A COLON (:) character), then set mode to "online whitelist" and jump back to the step labelled "start of line".

  20. This is either a data line or it is syntactically incorrect.

    If mode is "explicit"

    If line is not a syntactically valid URI reference or IRI reference, then jump back to the step labelled "start of line".

    Otherwise, resolve the URI reference or IRI reference to an absolute URI or IRI, and drop the fragment identifier, if any.

    Now, if the resource's URI has a different <scheme> component than the manifest's URI, then jump back to the step labelled "start of line".

    Otherwise, add this URI to the explicit URIs.

    If mode is "fallback"

    If line does not contain at least one U+0020 SPACE or U+0009 CHARACTER TABULATION (tab) character, then jump back to the step labelled "start of line".

    Otherwise, let everything before the first U+0020 SPACE or U+0009 CHARACTER TABULATION (tab) character in line be part one, and let everything after the first U+0020 SPACE or U+0009 CHARACTER TABULATION (tab) character in line be part two.

    Strip any leading U+0020 SPACE or U+0009 CHARACTER TABULATION (tab) characters in part two.

    If part one and part two are not both syntactically valid URI or IRI references, then jump back to the step labelled "start of line".

    Resolve the URI or IRI references in part one and part two to absolute URIs or IRIs.

    If the absolute URI or IRI corresponding to part one is already in the fallback URIs mapping as an opportunistic caching namespace, then jump back to the step labelled "start of line".

    If the absolute URI or IRI corresponding to part one does not have the same scheme/host/port as the manifest's URI, then jump back to the step labelled "start of line".

    If the absolute URI or IRI corresponding to part two has a different <scheme> component than the manifest's URI, then jump back to the step labelled "start of line".

    Otherwise, add the absolute URI or IRI corresponding to part one to the fallback URIs mapping as an opportunistic caching namespace, mapped to the absolute URI corresponding to part two as the fallback entry.

    If mode is "online whitelist"

    If line is not a syntactically valid URI reference or IRI reference, then jump back to the step labelled "start of line".

    Otherwise, resolve the URI reference or IRI reference to an absolute URI or IRI, and drop the fragment identifier, if any.

    Now, if the resource's URI has a different <scheme> component than the manifest's URI, then jump back to the step labelled "start of line".

    Otherwise, add this URI to the online whitelist URIs.

  21. Jump back to the step labelled "start of line". (That step jumps to the next, and last, step when the end of the file is reached.)

  22. Return the explicit URIs list, the fallback URIs mapping, and the online whitelist URIs.

Relative URI references and IRI references resolved to absolute URIs or IRIs in the above algorithm must use the manifest's URI as the Base URI from the Retrieval URI for the purposes reference resolution as defined by RFC 3986. [RFC3986]

If a resource is listed in both the online whitelist and in the explicit section, then that resource will be downloaded and cached, but when the page tries to use this resource, the user agent will ignore the cached copy and attempt to fetch the file from the network. Indeed, the cached copy will only be used if it is opened from a top-level browsing context.

4.6.4. Updating an application cache

When the user agent is required (by other parts of this specification) to start the application cache update process, the user agent must run the following steps:

the event stuff needs to be more consistent -- something about showing every step of the ui or no steps or something; and we need to deal with showing ui for browsing contexts that open when an update is already in progress, and we may need to give applications control over the ui the first time they cache themselves (right now the original cache is done without notifications to the browsing contexts)

  1. Let manifest URI be the URI of the manifest of the cache to be updated.

  2. Let cache group be the group of application caches identified by manifest URI.

  3. Let cache be the most recently updated application cache identified by manifest URI (that is, the newest version found in cache group).

  4. If the status of the cache group is either checking or downloading, then abort these steps, as an update is already in progress for them. Otherwise, set the status of this group of caches to checking. This entire step must be performed as one atomic operation so as to avoid race conditions.

  5. If there is already a resource with the URI of manifest URI in cache, and that resource is categorised as a manifest, then this is an upgrade attempt. Otherwise, this is a cache attempt.

    If this is a cache attempt, then cache is forcibly the only application cache in cache group, and it hasn't ever been populated from its manifest (i.e. this update is an attempt to download the application for the first time). It also can't have any browsing contexts associated with it.

  6. Fire a simple event called checking at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that the user agent is checking for the availability of updates.

  7. Fetch the resource from manifest URI, and let manifest be that resource.

    If the resource is labelled with the MIME type text/cache-manifest, parse manifest according to the rules for parsing manifests, obtaining a list of explicit entries, fallback entries and the opportunistic caching namespaces that map to them, and entries for the online whitelist.

  8. If the previous step fails (e.g. the server returns a 4xx or 5xx response or equivalent, or there is a DNS error, or the connection times out, or the parser for manifests fails when checking the magic signature), or if the resource is labelled with a MIME type other than text/cache-manifest, then run these substeps:

    1. Fire a simple event called error at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that the user agent failed to save the application for offline use.

    2. If this is a cache attempt, then discard cache and abort the update process, optionally alerting the user to the failure.

    3. Otherwise, jump to the last step in the overall set of steps of the update process.

  9. If this is an upgrade attempt and the newly downloaded manifest is byte-for-byte identical to the manifest found in cache, or if the server reported it as "304 Not Modified" or equivalent, then fire a simple event called noupdate at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that the application is up to date. Then, jump to the last step of the update process.

  10. Set the status of cache group to downloading.

  11. Fire a simple event called downloading at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that a new version is being downloaded.

  12. If this is an upgrade attempt, then let new cache be a newly created application cache identified by manifest URI, being a new version in cache group. Otherwise, let new cache and cache be the same version of the application cache.

  13. Let file list be an empty list of URIs with flags.

  14. Add all the URIs in the list of explicit entries obtained by parsing manifest to file list, each flagged with "explicit entry".

  15. Add all the URIs in the list of fallback entries obtained by parsing manifest to file list, each flagged with "fallback entry".

  16. If this is an upgrade attempt, then add all the URIs of opportunistically cached entries in cache that match the opportunistic caching namespaces obtained by parsing manifest to file list, each flagged with "opportunistic entry".

  17. If this is an upgrade attempt, then add all the URIs of implicit entries in cache to file list, each flagged with "implicit entry".

  18. If this is an upgrade attempt, then add all the URIs of dynamic entries in cache to file list, each flagged with "dynamic entry".

  19. If any URI is in file list more than once, then merge the entries into one entry for that URI, that entry having all the flags that the original entries had.

  20. For each URI in file list, run the following steps:

    1. Fire a simple event called progress at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that a file is being downloaded in preparation for updating the application.

    2. Fetch the resource. If this is an upgrade attempt, then use cache as an HTTP cache, and honour HTTP caching semantics (such as expiration, ETags, and so forth) with respect to that cache. User agents may also have other caches in place that are also honored.

    3. If the previous steps fails (e.g. the server returns a 4xx or 5xx response or equivalent, or there is a DNS error, or the connection times out), then run these substeps:

      1. Fire a simple event called error at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that the user agent failed to save the application for offline use.

      2. If this is a cache attempt, then discard cache and abort the update process, optionally alerting the user to the failure.

      3. Otherwise, jump to the last step in the overall set of steps of the update process.

    4. Otherwise, the fetching succeeded. Store the resource in the new cache.

    5. If the URI being processed was flagged as an "explicit entry" in file list, then categorise the entry as an explicit entry.

    6. If the URI being processed was flagged as a "fallback entry" in file list, then categorise the entry as a fallback entry.

    7. If the URI being processed was flagged as a "opportunistic entry" in file list, then categorise the entry as an opportunistically cached entry.

    8. If the URI being processed was flagged as an "implicit entry" in file list, then categorise the entry as a implicit entry.

    9. If the URI being processed was flagged as an "dynamic entry" in file list, then categorise the entry as a dynamic entry.

  21. Store manifest in new cache, if it's not there already, and categorise this entry (whether newly added or not) as the manifest.

  22. Store the list of opportunistic caching namespaces, and the URIs of the fallback entries that they map to, in the new cache.

  23. Store the URIs that form the new online whitelist in the new cache.

  24. If this is a cache attempt, then:

    Set the status of cache group to idle.

    Associate any Document objects that were flagged as candidates for this manifest URI's caches with cache.

    Fire a simple event called cached at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that the application has been cached and that they can now use it offline.

  25. Otherwise, this is an upgrade attempt:

    Set the status of cache group to idle.

    Fire a simple event called updateready at the ApplicationCache singleton of each top-level browsing context that is associated with a cache in cache group. The default action of this event should be the display of some sort of user interface indicating to the user that a new version is available and that they can activate it by reloading the page.

  26. Abort these steps. The following step is jumped to by various parts of the algorithm above when they have to cancel the update.

  27. Let the status of the group of caches to which cache belongs be idle. If appropriate, remove any user interface indicating that an update for this cache is in progress.

4.6.5. Processing model

The processing model of application caches for offline support in Web applications is part of the navigation model, but references the algorithms defined in this section.

A URI matches an opportunistic caching namespace if there exists an application cache whose manifest's URI has the same scheme/host/port as the URI in question, and if that application cache has an opportunistic caching namespace with a <path> component that exactly matches the start of the <path> component of the URI being examined. If multiple opportunistic caching namespaces match the same URI, the one with the longest <path> component is the one that matches. A URI looking for an opportunistic caching namespace can match more than one application cache at a time, but only matches one namespace in each cache.

If a manifest http://example.com/app1/manifest declares that http://example.com/resources/images should be opportunistically cached, and the user navigates to http://example.com/resources/images/cat.png, then the user agent will decide that the application cache identified by http://example.com/app1/manifest contains a namespace with a match for that URI.

When the application cache selection algorithm algorithm is invoked with a manifest URI, the user agent must run the first applicable set of steps from the following list:

If the resource is not being loaded as part of navigation of a top-level browsing context

As an optimisation, if the resource was loaded from an application cache, and the manifest URI of that cache doesn't match the manifest URI with which the algorithm was invoked, then the user agent should mark the entry in that application cache corresponding to the resource that was just loaded as being foreign.

Other than that, nothing special happens with respect to application caches.

If the resource being loaded was loaded from an application cache and the URI of that application cache's manifest is the same as the manifest URI with which the algorithm was invoked

Associate the Document with the cache from which it was loaded. Invoke the application cache update process.

If the resource being loaded was loaded from an application cache and the URI of that application cache's manifest is not the same as the manifest URI with which the algorithm was invoked

Mark the entry for this resource in the application cache from which it was loaded as foreign.

Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made as part of the initial load (changes can be avoided by ensuring that the step to update the session history with the new page is only ever completed after the application cache selection algorithm is run, though this is not required).

The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation.

User agents may notify the user of the inconsistency between the cache manifest and the resource's own metadata, to aid in application development.

If the resource being loaded was not loaded from an application cache, but it was loaded using HTTP GET or equivalent
  1. If the manifest URI does not have the same scheme/host/port as the resource's own URI, then invoke the application cache selection algorithm again, but without a manifest, and abort these steps.

  2. If there is already an application cache identified by this manifest URI, and that application cache contains a resource with the URI of the manifest, and that resource is categorised as a manifest, then: store the resource in the matching cache with the most up to date version, categorised as an implicit entry, associate the Document with that cache, invoke the application cache update process, and abort these steps.

  3. Flag the resource's Document as a candidate for this manifest URI's caches.

  4. If there is already an application cache identified by this manifest URI, then that application cache does not yet contain a resource with the URI of the manifest, or it does but that resource is not yet categorised as a manifest: store the resource in that cache, categorised as an implicit entry (replacing the file's previous contents if it was already in the cache, but not removing any other categories it might have), and abort these steps.

  5. Otherwise, there is no matching application cache: create a new application cache identified by this manifest URI, store the resource in that cache, categorised as an implicit entry, and then invoke the application cache update process.

Otherwise

Invoke the application cache selection algorithm again, but without a manifest.

When the application cache selection algorithm is invoked without a manifest, then: if the resource is being loaded as part of navigation of a top-level browsing context, and the resource was fetched from a particular application cache, then the user agent must associate the Document with that application cache and invoke the application cache update process for that cache; otherwise, nothing special happens with respect to application caches.

4.6.5.1. Changes to the networking model

When a browsing context is associated with an application cache, any and all resource loads must go through the following steps instead of immediately invoking the mechanisms appropriate to that resource's scheme:

  1. If the resource is not to be fetched using the HTTP GET mechanism or equivalent, then fetch the resource normally and abort these steps.

  2. If the resource's URI, ignoring its fragment identifier if any, is listed in the application cache's online whitelist, then fetch the resource normally and abort these steps.

  3. If the resource's URI is an implicit entry, the manifest, an explicit entry, a fallback entry, an opportunistically cached entry, or a dynamic entry in the application cache, then fetch the resource from the cache and abort these steps.

  4. If the resource's URI has the same scheme/host/port as the manifest's URI, and the start of the resource's URI's <path> component is exactly matched by the <path> component of an opportunistic caching namespace in the application cache, then:

    Fetch the resource normally. If this results 4xx or 5xx status codes or equivalent, or if there were network errors, then instead fetch, from the cache, the resource of the fallback entry corresponding to the namespace with the longest matching <path> component. Abort these steps.

  5. Fail the resource load.

The above algorithm ensures that resources that are not present in the manifest will always fail to load (at least, after the cache has been primed the first time), making the testing of offline applications simpler.

4.6.6. Application cache API

interface ApplicationCache {

  // update status
  const unsigned short UNCACHED = 0;
  const unsigned short IDLE = 1;
  const unsigned short CHECKING = 2;
  const unsigned short DOWNLOADING = 3;
  const unsigned short UPDATEREADY = 4;
  readonly attribute unsigned short status;

  // updates
  void update();
  void swapCache();

  // dynamic entries
  readonly attribute unsigned long length;
  DOMString item(in unsigned long index);
  void add(in DOMString uri);
  void remove(in DOMString uri);

  // events
           attribute EventListener onchecking;
           attribute EventListener onerror;
           attribute EventListener onnoupdate;
           attribute EventListener ondownloading;
           attribute EventListener onprogress;
           attribute EventListener onupdateready;
           attribute EventListener oncached;

};

Objects implementing the ApplicationCache interface must also implement the EventTarget interface.

There is a one-to-one mapping from Document objects to ApplicationCache objects. The applicationCache attribute on Window objects must return the ApplicationCache object associated with the active document of the Window's browsing context.

An ApplicationCache object might be associated with an application cache. When the Document object that the ApplicationCache object maps to is associated with an application cache, then that is the application cache with which the ApplicationCache object is associated. Otherwise, the ApplicationCache object is associated with the application cache that the Document object's browsing context is associated with, if any.

The status attribute, on getting, must return the current state of the application cache ApplicationCache object is associated with, if any. This must be the appropriate value from the following list:

UNCACHED (numeric value 0)

The ApplicationCache object is not associated with an application cache at this time.

IDLE (numeric value 1)

The ApplicationCache object is associated with an application cache whose group is in the idle update status, and that application cache is the newest cache in its group that contains a resource categorised as a manifest.

CHECKING (numeric value 2)

The ApplicationCache object is associated with an application cache whose group is in the checking update status.

DOWNLOADING (numeric value 3)

The ApplicationCache object is associated with an application cache whose group is in the downloading update status.

UPDATEREADY (numeric value 4)

The ApplicationCache object is associated with an application cache whose group is in the idle update status, but that application cache is not the newest cache in its group that contains a resource categorised as a manifest.

The length attribute must return the number of dynamic entries in the application cache with which the ApplicationCache object is associated, if any, and zero if the object is not associated with any application cache.

The dynamic entries in the application cache are ordered in the same order as they were added to the cache by the add() method, with the oldest entry being the zeroth entry, and the most recently added entry having the index length-1.

The item(index) method must return the dynamic entries with index index from the application cache, if one is associated with the ApplicationCache object. If the object is not associated with any application cache, or if the index argument is lower than zero or greater than length-1, the method must instead raise an INDEX_SIZE_ERR exception.

The add(uri) method must run the following steps:

  1. If the ApplicationCache object is not associated with any application cache, then raise an INVALID_STATE_ERR exception and abort these steps.

  2. If there is already a resource in in the application cache with which the ApplicationCache object is associated that has the address uri, then ensure that entry is categorised as a dynamic entry and return and abort these steps.

  3. If uri has a different <scheme> component than the manifest's URI, then raise a security exception.

  4. Return, but do not abort these steps.

  5. Fetch the resource referenced by uri.

  6. If this results 4xx or 5xx status codes or equivalent, or if there were network errors, then abort these steps.

  7. Wait for there to be no running scripts, or at least no running scripts that can reach an ApplicationCache object associated with the application cache with which this ApplicationCache object is associated.

    Add the fetched resource to the application cache and categorise it as a dynamic entry before letting any such scripts resume.

We can make the add() API more usable (i.e. make it possible to detect progress and distinguish success from errors without polling and timeouts) if we have the method return an object that is a target of Progress Events, much like the XMLHttpRequestEventTarget interface. This would also make this far more complex to spec and implement.

The remove(uri) method must remove the dynamic entry categorisation of any entry with the address uri in the application cache with which the ApplicationCache object is associated. If this removes the last categorisation of an entry in that cache, then the entry must be removed entirely (such that if it is re-added, it will be loaded from the network again). If the ApplicationCache object is not associated with any application cache, then the method must raise an INVALID_STATE_ERR exception instead.

If the update() method is invoked, the user agent must invoke the application cache update process, in the background, for the application cache with which the ApplicationCache object is associated. If there is no such application cache, then the method must raise an INVALID_STATE_ERR exception instead.

If the swapCache() method is invoked, the user agent must run the following steps:

  1. Let document be the Document with which the ApplicationCache object is associated.

  2. Check that document is associated with an application cache. If it is not, then raise an INVALID_STATE_ERR exception and abort these steps.

    This is not the same thing as the ApplicationCache object being itself associated with an application cache! In particular, the Document with which the ApplicationCache object is associated can only itself be associated with an application cache if it is in a top-level browsing context.

  3. Let cache be the application cache with which the ApplicationCache object is associated. (By definition, this is the same as the one that was found in the previous step.)

  4. Check that there is an application cache in the same group as cache which has an entry categorised as a manifest that has is newer than cache. If there is not, then raise an INVALID_STATE_ERR exception and abort these steps.

  5. Let new cache be the newest application cache in the same group as cache which has an entry categorised as a manifest.

  6. Unassociate document from cache and instead associate it with new cache.

The following are the event handler DOM attributes that must be supported by objects implementing the ApplicationCache interface:

onchecking

Must be invoked whenever an checking event is targeted at or bubbles through the ApplicationCache object.

onerror

Must be invoked whenever an error event is targeted at or bubbles through the ApplicationCache object.

onnoupdate

Must be invoked whenever an noupdate event is targeted at or bubbles through the ApplicationCache object.

ondownloading

Must be invoked whenever an downloading event is targeted at or bubbles through the ApplicationCache object.

onprogress

Must be invoked whenever an progress event is targeted at or bubbles through the ApplicationCache object.

onupdateready

Must be invoked whenever an updateready event is targeted at or bubbles through the ApplicationCache object.

oncached

Must be invoked whenever a cached event is targeted at or bubbles through the ApplicationCache object.

4.6.7. Browser state

The navigator.onLine attribute must return false if the user agent will not contact the network when the user follows links or when a script requests a remote page (or knows that such an attempt would fail), and must return true otherwise.

When the value that would be returned by the navigator.onLine attribute of the Window changes from true to false, the user agent must fire a simple event called offline at the body element.

On the other hand, when the value that would be returned by the navigator.onLine attribute of the Window changes from false to true, the user agent must fire a simple event called online at the body element.