-
Notifications
You must be signed in to change notification settings - Fork 320
Navigation preload #983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+581
−184
Merged
Navigation preload #983
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8fd436f
Rebasing on new, cleaner spec.
jakearchibald 4b34e0a
Fixing linking & formatting bugs
jakearchibald f8c4eab
Invalid state error is more consistent with the rest of the spec
jakearchibald a2c97de
Following review feeback
jakearchibald dba2f0a
Service workers mode
jakearchibald d284f4c
Reverting skip-sw-flag change
jakearchibald File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,6 +201,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
|
|
||
| A [=/service worker registration=] has one or more <dfn export id="dfn-service-worker-registration-task-queue">task queues</dfn> that back up the <a>tasks</a> from its <a>active worker</a>'s <a>event loop</a>'s corresponding [=/task queues=]. (The target task sources for this back up operation are the <a>handle fetch task source</a> and the <a>handle functional event task source</a>.) The user agent dumps the <a>active worker</a>'s <a>tasks</a> to the [=/service worker registration=]'s [=service worker registration/task queues=] when the <a>active worker</a> is <a lt="terminate service worker">terminated</a> and <a lt="queue a task">re-queues those tasks</a> to the <a>active worker</a>'s <a>event loop</a>'s corresponding [=/task queues=] when the <a>active worker</a> spins off. Unlike the [=/task queues=] owned by <a>event loops</a>, the [=/service worker registration=]'s [=service worker registration/task queues=] are not processed by any <a>event loops</a> in and of itself. | ||
|
|
||
| A [=/service worker registration=] has an associated <dfn export>{{NavigationPreloadManager}}</dfn> object. | ||
|
|
||
| A [=/service worker registration=] has an associated <dfn export>navigation preload enabled flag</dfn>. It is initially unset. | ||
|
|
||
| A [=/service worker registration=] has an associated <dfn export>navigation preload header value</dfn>, which is a [=byte sequence=]. It is initially set to \`<code>true</code>\`. | ||
|
|
||
| <section> | ||
| <h4 id="service-worker-registration-lifetime">Lifetime</h4> | ||
|
|
||
|
|
@@ -389,6 +395,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| readonly attribute ServiceWorker? installing; | ||
| readonly attribute ServiceWorker? waiting; | ||
| readonly attribute ServiceWorker? active; | ||
| readonly attribute NavigationPreloadManager navigationPreload; | ||
|
|
||
| readonly attribute USVString scope; | ||
| readonly attribute boolean useCache; | ||
|
|
@@ -427,6 +434,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| Note: The {{ServiceWorker}} objects returned from this attribute getter that represent the same [=/service worker=] are the same objects. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h4 id="service-worker-registration-navigationpreload"><dfn>{{ServiceWorkerRegistration/navigationPreload}}</dfn></h4> | ||
|
|
||
| The {{navigationPreload}} attribute's getter *must* return the [=/service worker registration's=] {{NavigationPreloadManager}} object. | ||
| </section> | ||
|
|
||
| <section algorithm="service-worker-registration-scope"> | ||
| <h4 id="service-worker-registration-scope">{{ServiceWorkerRegistration/scope}}</h4> | ||
|
|
||
|
|
@@ -731,6 +744,71 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| </section> | ||
| </section> | ||
|
|
||
| <section> | ||
| <h3 id="navigation-preload-manager">{{NavigationPreloadManager}}</h3> | ||
|
|
||
| <pre class="idl"> | ||
| [SecureContext, Exposed=(Window,Worker)] | ||
| interface NavigationPreloadManager { | ||
| Promise<void> enable(); | ||
| Promise<void> disable(); | ||
| Promise<void> setHeaderValue(ByteString value); | ||
| Promise<NavigationPreloadState> getState(); | ||
| }; | ||
|
|
||
| dictionary NavigationPreloadState { | ||
| boolean enabled = false; | ||
| ByteString headerValue; | ||
| }; | ||
| </pre> | ||
|
|
||
| <section algorithm> | ||
| <h4 id="navigation-preload-manager-enable"><dfn>{{NavigationPreloadManager/enable()}}</dfn></h4> | ||
|
|
||
| The {{NavigationPreloadManager/enable()}} method, when invoked, *must* return a new [=promise=] |promise| and run the following steps [=in parallel=]: | ||
|
|
||
| 1. Let |registration| be the [=context object=]'s associated [=/service worker registration=]. | ||
| 1. If |registration|'s [=active worker=] is null, [=reject=] |promise| with an "{{InvalidStateError}}" exception, and abort these steps. | ||
| 1. Set |registration|'s [=navigation preload enabled flag=]. | ||
| 1. [=Resolve=] |promise| with undefined. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h4 id="navigation-preload-manager-disable"><dfn>{{NavigationPreloadManager/disable()}}</dfn></h4> | ||
|
|
||
| The {{NavigationPreloadManager/disable()}} method, when invoked, *must* return a new [=promise=] |promise| and run the following steps [=in parallel=]: | ||
|
|
||
| 1. Let |registration| be the [=context object=]'s associated [=/service worker registration=]. | ||
| 1. If |registration|'s [=active worker=] is null, [=reject=] |promise| with an "{{InvalidStateError}}" exception, and abort these steps. | ||
| 1. Unset |registration|'s [=navigation preload enabled flag=]. | ||
| 1. [=Resolve=] |promise| with undefined. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h4 id="navigation-preload-manager-setheadervalue"><dfn>{{NavigationPreloadManager/setHeaderValue(value)}}</dfn></h4> | ||
|
|
||
| The <a method for="NavigationPreloadManager"><code>setHeaderValue(|value|)</code></a> method, when invoked, *must* return [=a new promise=] |promise| and run the following steps [=in parallel=]: | ||
|
|
||
| 1. Let |registration| be the [=context object=]'s associated [=/service worker registration=]. | ||
| 1. If |registration|'s [=active worker=] is null, [=reject=] |promise| with an "{{InvalidStateError}}" exception, and abort these steps. | ||
| 1. Set |registration|'s [=navigation preload header value=] to |value|. | ||
| 1. [=Resolve=] |promise| with undefined. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h4 id="navigation-preload-manager-getstate"><dfn>{{NavigationPreloadManager/getState()}}</dfn></h4> | ||
|
|
||
| The {{NavigationPreloadManager/getState()}} method, when invoked, *must* return [=a new promise=] |promise| and run the following steps [=in parallel=]: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/[=a new promise=]/a new [=promise=]/ |
||
|
|
||
| 1. Let |registration| be the [=context object=]'s associated [=/service worker registration=]. | ||
| 1. Let |state| be a new {{NavigationPreloadState}} dictionary. | ||
| 1. If |registration|'s [=navigation preload enabled flag=] is set, set |state|'s {{NavigationPreloadState/enabled}} dictionary member to true. | ||
| 1. Set |state|'s {{NavigationPreloadState/headerValue}} dictionary member to the |registration|'s [=navigation preload header value=]. | ||
| 1. [=Resolve=] |promise| with |state|. | ||
| </section> | ||
|
|
||
| </section> | ||
|
|
||
| <section> | ||
| <h2 id="execution-context">Execution Context</h2> | ||
|
|
||
|
|
@@ -1292,6 +1370,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| [Constructor(DOMString type, FetchEventInit eventInitDict), Exposed=ServiceWorker] | ||
| interface FetchEvent : ExtendableEvent { | ||
| [SameObject] readonly attribute Request request; | ||
| readonly attribute Promise<any> preloadResponse; | ||
| readonly attribute DOMString clientId; | ||
| readonly attribute DOMString reservedClientId; | ||
| readonly attribute DOMString targetClientId; | ||
|
|
@@ -1303,6 +1382,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| <pre class="idl" id="fetch-event-init-dictionary"> | ||
| dictionary FetchEventInit : ExtendableEventInit { | ||
| required Request request; | ||
| required Promise<any> preloadResponse; | ||
| DOMString clientId = ""; | ||
| DOMString reservedClientId = ""; | ||
| DOMString targetClientId = ""; | ||
|
|
@@ -1324,6 +1404,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| <dfn attribute for="FetchEvent"><code>request</code></dfn> attribute *must* return the value it was initialized to. | ||
| </section> | ||
|
|
||
| <section> | ||
| <h4 id="fetch-event-preloadresponse">{{FetchEvent/preloadResponse|event.preloadResponse}}</h4> | ||
|
|
||
| <dfn attribute for="FetchEvent"><code>preloadResponse</code></dfn> attribute *must* return the value it was initialized to. | ||
| </section> | ||
|
|
||
| <section> | ||
| <h4 id="fetch-event-clientid">{{FetchEvent/clientId|event.clientId}}</h4> | ||
|
|
||
|
|
@@ -2782,6 +2868,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| 1. Let |registration| be null. | ||
| 1. Let |client| be |request|'s [=request/client=]. | ||
| 1. Let |reservedClient| be |request|'s [=request/reserved client=]. | ||
| 1. Let |preloadResponse| be a new [=promise=]. | ||
| 1. Assert: |request|'s [=request/destination=] is not "<code>serviceworker</code>". | ||
| 1. If |request| is a <a>potential-navigation-or-subresource request</a>, then: | ||
| 1. Return null. | ||
|
|
@@ -2797,6 +2884,21 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| 1. Set |registration| to the result of running <a>Match Service Worker Registration</a> algorithm passing |request|'s [=request/url=] as the argument. | ||
| 1. If |registration| is null or |registration|'s <a>active worker</a> is null, return null. | ||
| 1. If |request|'s [=request/destination=] is not {{RequestDestination/"report"}}, set |reservedClient|'s <a>active service worker</a> to |registration|'s <a>active worker</a>. | ||
| 1. If |request| is a [=navigation request=] and |registration|'s [=navigation preload enabled flag=] is set, and |request|'s [=request/method=] is \`<code>GET</code>\`, then: | ||
| 1. Let |preloadRequest| be the result of [=request/cloning=] the request |request|. | ||
| 1. Let |preloadRequestHeaders| be |preloadRequest|'s [=request/header list=]. | ||
| 1. Let |preloadResponseObject| be a new {{Response}} object and a new associated {{Headers}} object whose [=guard=] is "`immutable`". | ||
| 1. [=header list/Append=] to |preloadRequestHeaders| a new [=header=] whose [=header/name=] is \`<code>Service-Worker-Navigation-Preload</code>\` and [=header/value=] is |registration|'s [=navigation preload header value=]. | ||
| 1. Set |preloadRequest|'s [=skip-service-worker flag=]. | ||
| 1. Run the following substeps [=in parallel=]: | ||
| 1. [=Fetch=] |preloadRequest|. | ||
|
|
||
| To [=process response=] for |navigationPreloadResponse|, run these substeps: | ||
|
|
||
| 1. If |navigationPreloadResponse|'s [=response/type=] is "`error`", reject |preloadResponse| with a `TypeError` and terminate these substeps. | ||
| 1. Associate |preloadResponseObject| with |navigationPreloadResponse|. | ||
| 1. Resolve |preloadResponse| with |navigationPreloadResponse|. | ||
| 1. Else, resolve |preloadResponse| with undefined. | ||
|
|
||
| Note: From this point, the [=/service worker client=] starts to <a>use</a> its <a>active service worker</a>'s <a>containing service worker registration</a>. | ||
|
|
||
|
|
@@ -2818,6 +2920,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe | |
| 1. Initialize |e|’s {{Event/type}} attribute to {{fetch!!event}}. | ||
| 1. Initialize |e|’s {{Event/cancelable}} attribute to true. | ||
| 1. Initialize |e|’s {{FetchEvent/request}} attribute to |r|. | ||
| 1. Initialize |e|’s {{FetchEvent/preloadResponse}} to |preloadResponse|. | ||
| 1. Initialize |e|'s {{FetchEvent/clientId}} attribute to |client|'s [=environment/id=]. | ||
| 1. If |request| is a <a>non-subresource request</a> and |request|'s [=request/destination=] is not {{RequestDestination/"report"}}, initialize |e|'s {{FetchEvent/reservedClientId}} attribute to |reservedClient|'s [=environment/id=], and to the empty string otherwise. | ||
| 1. If |request| is a <a>navigation request</a>, initialize |e|'s {{FetchEvent/targetClientId}} attribute to |request|'s [=request/target client id=], and to the empty string otherwise. | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/[=a new promise=]/a new [=promise=]/
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the same, but it's "a new promise".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah.. That's right. I got it.