HTML 5

Draft Recommendation — 2 December 2008

5.7 Offline Web applications

5.7.1 Introduction

This section is non-normative.

...

5.7.2 Application caches

An application cache is a collection of resources. An application cache is identified by the absolute URL 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 URL, 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 URL has a common update status, which is one of the following: idle, checking, downloading.

Each group of application caches for the same manifest URL also has a common lifecycle status, which is one of the following: new, mature, obsolete. A relevant application cache is an application cache whose lifecycle status is mature.

A browsing context is associated with the application cache appropriate for its active document, if any. 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. A browsing context's associated cache can also change during session history traversal.

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 relevant application 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:

5.7.3 The cache manifest syntax

5.7.3.1 A sample manifest

This section is non-normative.

This example manifest requires two images and a style sheet to be cached and whitelists a CGI script.

CACHE MANIFEST
# the above line is required

# this is a comment
# there can be as many of these anywhere in the file
# they are all ignored
  # comments can have spaces before them
  # but most be alone on the line

# blank lines are ignored too

# these are files that need to be cached they can either be listed
# first, or a "CACHE:" header could be put before them, as is done
# lower down.
images/sound-icon.png
images/background.png
# note that each file has to be put on its own line

# here is a file for the online whitelist -- it isn't cached, and 
# references to this file will bypass the cache, always hitting the
# network (or trying to, if the user is offline).
NETWORK:
comm.cgi

# here is another set of files to cache, this time just the CSS file.
CACHE:
style/default.css
5.7.3.2 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. [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. The first line may optionally be preceded by a U+FEFF BYTE ORDER MARK (BOM) character. If any other text is found on the first line, the user agent will ignore the entire file.

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 URL, 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 URL identifying a resource other than the manifest itself, and then zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters.

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 URL identifying a resource other than the manifest itself, one or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters, another valid URL identifying a resource other than the manifest itself, and then zero or more U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters.

The URLs in data lines can't be empty strings, since those would be relative URLs to the manifest itself. Such lines would be confused with blank or invalid lines, anyway.

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

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

Fallback namespaces and fallback entries must have the same origin as the manifest itself.

A fallback namespace must not be listed more than once.

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

Relative URLs must be given relative to the manifest's own URL.

URLs in manifests must not have fragment identifiers (i.e. the U+0023 NUMBER SIGN character isn't allowed in URLs in manifests).

5.7.3.3 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 byte stream 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.

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

  3. Let fallback URLs be an initially empty mapping of fallback namespaces to fallback entries.

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

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

  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. Drop any trailing U+0020 SPACE and U+0009 CHARACTER TABULATION (tab) characters at the end of line.

  16. If line is the empty string, then jump back to the step labeled "start of line".

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

  18. 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 labeled "start of line".

  19. 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 labeled "start of line".

  20. 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 labeled "start of line".

  21. If line ends with a U+003A COLON (:) character, then set mode to "unknown" and jump back to the step labeled "start of line".

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

  23. Let position be a pointer into line, initially pointing at the start of the string.

  24. Let tokens be a list of strings, initially empty.

  25. While position doesn't point past the end of line:

    1. Let current token be an empty string.

    2. While position doesn't point past the end of line and the character at position is neither a U+0020 SPACE nor a U+0009 CHARACTER TABULATION (tab) character, add the character at position to current token and advance position to the next character in input.

    3. Add current token to the tokens list.

    4. While position doesn't point past the end of line and the character at position is either a U+0020 SPACE or a U+0009 CHARACTER TABULATION (tab) character, advance position to the next character in input.

  26. Process tokens as follows:

    If mode is "explicit"

    Resolve the first item in tokens; ignore the rest.

    If this fails, then jump back to the step labeled "start of line".

    If the resulting absolute URL has a different <scheme> component than the manifest's URL (compared in an ASCII case-insensitive manner), then jump back to the step labeled "start of line".

    Drop the <fragment> component of the resulting absolute URL, if it has one.

    Add the resulting absolute URL to the explicit URLs.

    If mode is "fallback"

    Let part one be the first token in tokens, and let part two be the second token in tokens.

    Resolve part one and part two.

    If either fails, then jump back to the step labeled "start of line".

    If the absolute URL corresponding to either part one or part two does not have the same origin as the manifest's URL, then jump back to the step labeled "start of line".

    Drop any the <fragment> components of the resulting absolute URLs.

    If the absolute URL corresponding to part one is already in the fallback URLs mapping as a fallback namespace, then jump back to the step labeled "start of line".

    Otherwise, add the absolute URL corresponding to part one to the fallback URLs mapping as a fallback namespace, mapped to the absolute URL corresponding to part two as the fallback entry.

    If mode is "online whitelist"

    Resolve the first item in tokens; ignore the rest.

    If this fails, then jump back to the step labeled "start of line".

    If the resulting absolute URL has a different <scheme> component than the manifest's URL (compared in an ASCII case-insensitive manner), then jump back to the step labeled "start of line".

    Drop the <fragment> component of the resulting absolute URL, if it has one.

    Add the resulting absolute URL to the online whitelist URLs.

    If mode is "unknown"

    Do nothing. The line is ignored.

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

  28. Return the explicit URLs list, the fallback URLs mapping, and the online whitelist URLs.

If a resource is listed in the explicit section and matches an entry in the online whitelist, or if a resource matches both an entry in the fallback section and the online whitelist, the resource will taken from the cache, and the online whitelist entry will be ignored.

5.7.4 Updating an application cache

When the user agent is required (by other parts of this specification) to start the application cache update process for a manifest URL or for an application cache, potentially given a particular browsing context, and potentially given a new master resource, 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); also, we need to update this so all event firing uses queues

  1. Atomically, so as to avoid race conditions, perform the following substeps:

    1. Let manifest URL be the URL of the manifest to be updated, or of the manifest of the application cache to be updated, as appropriate.

    2. If these steps were invoked with a URL (as opposed to a specific cache), and there is no application cache identified by manifest URL whose lifecycle status is not obsolete, then create a new application cache identified with that URL and set the group's lifecycle status to new.

    3. If these steps were invoked with a new master resource, then flag the resource's Document as a candidate for this manifest URL's caches, so that it will be associated with an application cache identified by this manifest URL later, when such an application cache is ready.

    4. Let cache group be the group of application caches identified by manifest URL.

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

    6. If these steps were invoked with a browsing context, and the status of the cache group is checking or downloading, then fire a simple event called checking at the ApplicationCache singleton of that browsing context.

    7. If these steps were invoked with a browsing context, and the status of the cache group is downloading, then also fire a simple event called downloading at the ApplicationCache singleton of that browsing context.

    8. If the status of the cache group is either checking or downloading, then abort this instance of the update process, as an update is already in progress for them.

    9. Set the status of this group of caches to checking.

    The remainder of the steps run asychronously.

  2. If there is already a resource with the URL of manifest URL in cache, and that resource is categorized 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.

  3. Fire a simple event called checking at the ApplicationCache singleton of each browsing context whose active document 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.

    Again, if this is a cache attempt, then cache group has only one cache and it has no browsing contexts associated with it, so no events are dispatched due to this step or any of the other steps that fire events other than the final cached event.

  4. Fetch the resource from manifest URL, and let manifest be that resource.

    If the resource is labeled 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 fallback namespaces that map to them, and entries for the online whitelist.

  5. If the previous step fails due to a 404 or 410 response or equivalent, then run the cache removal steps

    If the previous step fails in some other way (e.g. the server returns another 4xx or 5xx response or equivalent, or there is a DNS error, or the connection times out, or the user cancels the download, or the parser for manifests fails when checking the magic signature), or if the server returned a redirect, or if the resource is labeled with a MIME type other than text/cache-manifest, then run the cache failure steps.

  6. 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 run these substeps:

    1. Fire a simple event called noupdate at the ApplicationCache singleton of each browsing context whose active document 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.

    2. If there are any pending downloads of master entries that are being stored in the cache, then wait for all of them to have completed. If any of these downloads fail (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 user cancels the download), then run the cache failure steps.

    3. 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. Abort the update process.

  7. Set the status of cache group to downloading.

  8. Fire a simple event called downloading at the ApplicationCache singleton of each browsing context whose active document 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.

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

  10. Let file list be an empty list of URLs with flags.

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

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

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

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

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

  16. For each URL in file list, run the following steps. These steps may be run in parallel for two or more of the URLs at a time.

    1. If the resource URL being processed was flagged as neither an "explicit entry" nor or a "fallback entry", then the user agent may skip this URL.

      This is intended to allow user agents to expire resources (other than those in the manifest itself) from the cache. Generally, implementors are urged to use an approach that expires lesser-used resources first.

    2. Fire a simple event called progress at the ApplicationCache singleton of each browsing context whose active document 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.

    3. Fetch the resource. If this is an upgrade attempt, then use cache as an HTTP cache, and honor 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.

      If the resource in question is already being downloaded for other reasons then the existing download process can be used for the purposes of this step, as defined by the fetching algorithm.

      An example of a resource that might already be being downloaded is a large image on a Web page that is being seen for the first time. The image would get downloaded to satisfy the img element on the page, as well as being listed in the cache manifest. According to the rules for fetching that image only need be downloaded once, and it can be used both for the cache and for the rendered Web page.

    4. 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 user cancels the download), or if the server returned a redirect, then run the first appropriate step from the following list:

      If the URL being processed was flagged as an "explicit entry" or a "fallback entry"

      Run the cache failure steps.

      Redirects are fatal because they are either indicative of a network problem (e.g. a captive portal); or would allow resources to be added to the cache under URLs that differ from any URL that the networking model will allow access to, leaving orphan entries; or would allow resources to be stored under URLs different than their true URLs. All of these situations are bad.

      If the error was a 404 or 410 HTTP response or equivalent

      Skip this resource. It is dropped from the cache.

      Otherwise

      Copy the resource and its metadata from cache, and act as if that was the fetched resource, ignoring the resource obtained from the network.

      User agents may warn the user of these errors as an aid to development.

      These rules make errors for resources listed in the manifest fatal, while making it possible for other resources to be removed from caches when they are removed from the server, without errors, and making non-manifest resources survive server-side errors.

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

    6. If the URL being processed was flagged as an "explicit entry" in file list, then categorize the entry as an explicit entry.

    7. If the URL being processed was flagged as a "fallback entry" in file list, then categorize the entry as a fallback entry.

    8. If the URL being processed was flagged as an "master entry" in file list, then categorize the entry as a master entry.

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

    10. As an optimization, if the resource is an HTML or XML file whose root element is an html element with a manifest attribute whose value doesn't match the manifest URL of the application cache being processed, then the user agent should mark the entry as being foreign.

  17. Store the list of fallback namespaces, and the URLs of the fallback entries that they map to, in new cache.

  18. Store the URLs that form the new online whitelist in new cache.

  19. Wait for all pending downloads of master entries that are being stored in the cache to have completed.

    For example, if the browsing context's active document isn't itself listed in the cache manifest, then it might still be being downloaded.

    If any of these downloads fail (e.g. the connection times out, or the user cancels the download), then run the cache failure steps.

  20. Fetch the resource from manifest URL again, and let second manifest be that resource.

  21. If the previous step failed for any reason, or if the fetching attempt involved a redirect, or if second manifest and manifest are not byte-for-byte identical, then schedule a rerun of the entire algorithm with the same parameters after a short delay, and run the cache failure steps.

  22. Otherwise, store manifest in new cache, if it's not there already, and categorize this entry (whether newly added or not) as the manifest.

  23. If this is a cache attempt, then:

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

    Fire a simple event called cached at the ApplicationCache singleton of each browsing context whose active document 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.

    Set the lifecycle status of cache group to mature.

    Set the update status of cache group to idle.

  24. Otherwise, this is an upgrade attempt:

    Fire a simple event called updateready at the ApplicationCache singleton of each browsing context whose active document 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.

    Set the status of cache group to idle.

The cache removal steps are as follows:

  1. If this is a cache attempt, then discard cache and abort the update process.

  2. Fire a simple event called obsolete at the ApplicationCache singleton of each browsing context whose active document 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 no longer available for offline use.

  3. Set the lifecycle status of cache group to obsolete.

  4. Let the update 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. Abort the update process.

The cache failure steps are as follows:

  1. Fire a simple event called error at the ApplicationCache singleton of each browsing context whose active document 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.

  3. Otherwise, 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. Abort the update process.

User agents may invoke the application cache update process, in the background, for any application cache, at any time (with no browsing context). This allows user agents to keep caches primed and to update caches even before the user visits a site.

5.7.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 URL matches a fallback namespace if there exists a relevant application cache whose manifest's URL has the same origin as the URL in question, and that has a fallback namespace that is a prefix match for the URL being examined. If multiple fallback namespaces match the same URL, the longest one is the one that matches. A URL looking for an fallback 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 is a fallback namespace, and the user navigates to HTTP://EXAMPLE.COM:80/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 URL.


When the application cache selection algorithm algorithm is invoked with a manifest URL, 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 browsing context

Do nothing.

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

Associate the Document with the cache from which it was loaded. Invoke the application cache update process for that cache and with the browsing context being navigated.

If the resource being loaded was loaded from an application cache and the URL of that application cache's manifest is not the same as the manifest URL 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 URL does not have the same origin as the resource's own URL, then invoke the application cache selection algorithm again, but without a manifest, and abort these steps.

  2. Otherwise, invoke the application cache update process for the given manifest URL, with the browsing context being navigated, and with the resource's Document as the new master resource.

Otherwise

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

When the application cache selection algorithm is invoked without a manifest, if the resource is being loaded as part of navigation of a 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, with that browsing context. Otherwise, nothing special happens.

5.7.5.1 Changes to the networking model

When a browsing context is associated with an application cache, any and all loads for resources in that browsing context other than those for child browsing contexts 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, or if it has a javascript: URL, then fetch the resource normally and abort these steps.

  2. If the resource's URL is an master entry, the manifest, an explicit entry, a fallback entry, or a dynamic entry in the application cache, then get the resource from the cache (instead of fetching it), and abort these steps.

  3. If the resource's URL has the same origin as the manifest's URL, and there is a fallback namespace in the application cache that is a prefix match for the resource's URL, then:

    Fetch the resource normally. If this results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent, or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry corresponding to the matched namespace. Abort these steps.

  4. If there is an entry in the application cache's online whitelist that has the same origin as the resource's URL and that is a prefix match for the resource's URL, then fetch the resource normally and 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.

5.7.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;
  const unsigned short OBSOLETE = 5;
  readonly attribute unsigned short status;

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

  // dynamic entries
  readonly attribute DOMStringList items;
  boolean hasItem(in DOMString url);
  void add(in DOMString url);
  void remove(in DOMString url);

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

};

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.

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 the mature lifecycle status and that application cache is the newest cache in its group.

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 and the mature lifecycle status but that application cache is not the newest cache in its group.

OBSOLETE (numeric value 5)

The ApplicationCache object is associated with an application cache whose group is in the obsolete lifecycle status.


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.

The items DOM attribute must return a new DOMStringList object. If the ApplicationCache object has an associated application cache with one or more dynamic entries, then the DOMStringList object's items must be the absolute URLs of the dynamic entries in that application cache, in order; otherwise, the object must have no entries.

The hasItem(url) 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. Resolve the url argument. If this fails, raise a SYNTAX_ERR exception and abort these steps.

  3. If there is already a resource in in the application cache with which the ApplicationCache object is associated that has the address url, and that entry is categorized as a dynamic entry, then return true.

  4. Otherwise, return false.

The add(url) 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. Resolve the url argument. If this fails, raise a SYNTAX_ERR exception and abort these steps.

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

  4. If url has a different <scheme> component than the manifest's URL, then raise a SECURITY_ERR exception.

  5. Return, but do not abort these steps.

  6. Fetch the resource referenced by url.

  7. If this results in a redirect, or a 4xx or 5xx status code or equivalent, or if there were network errors, or if the user canceled the download, then abort these steps.

  8. Add the fetched resource to the application cache and categorize it as a dynamic entry.

The remove(url) method must resolve the url argument and, if that is successful, remove the dynamic entry categorization of any entry whose address is the resulting absolute URL in the application cache with which the ApplicationCache object is associated. If this removes the last categorization 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.

Authors should bear in mind that multiple scripts could be simultaneously modifying the same application cache.


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, but with no browsing context. 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. If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache and abort these steps.

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

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

  7. 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.

onobsolete

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

5.7.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.