WICG / nav-speculation

Proposal to enable privacy-enhanced preloading
https://wicg.github.io/nav-speculation/
Other
152 stars 35 forks source link

Interaction with ServiceWorker `Client` #111

Open noamr opened 2 years ago

noamr commented 2 years ago

https://github.com/WICG/nav-speculation/issues/44 mentions restrictions for ServiceWorkers. But ServiceWorkers should have some knowledge about prerender state, in addition to the restrictions.

I believe new API has to be added to ServiceWorker Client API:

nhiroki commented 2 years ago

According to the current Service Worker / HTML specs, focus() should return a promise to be rejected with TypeError as a prerendered page doesn't have "system focus" as follows:

  1. Let focusState be the result of running the has focus steps with this's browsing context's active document.

https://w3c.github.io/ServiceWorker/#client-focus

The has focus steps, given a Document object target, are as follows:

  1. If target's browsing context's top-level browsing context does not have system focus, then return false.

https://html.spec.whatwg.org/multipage/interaction.html#has-focus-steps

A top-level browsing context has system focus when it can receive keyboard input channeled from the operating system.

https://html.spec.whatwg.org/multipage/interaction.html#tlbc-system-focus

  1. If windowClient’s focus state is true, resolve promise with windowClient.
  2. Else, reject promise with a TypeError.

https://w3c.github.io/ServiceWorker/#client-focus

In Chromium, this behavior is tested by wpt_internal/prerender/focus-on-prerendered-window-client.https.html.

noamr commented 2 years ago

According to the current Service Worker / HTML specs, focus() should return a promise to be rejected with TypeError as a prerendered page doesn't have "system focus" as follows:

  1. Let focusState be the result of running the has focus steps with this's browsing context's active document.

https://w3c.github.io/ServiceWorker/#client-focus

The has focus steps, given a Document object target, are as follows:

  1. If target's browsing context's top-level browsing context does not have system focus, then return false.

https://html.spec.whatwg.org/multipage/interaction.html#has-focus-steps

A top-level browsing context has system focus when it can receive keyboard input channeled from the operating system.

https://html.spec.whatwg.org/multipage/interaction.html#tlbc-system-focus

  1. If windowClient’s focus state is true, resolve promise with windowClient.
  2. Else, reject promise with a TypeError.

https://w3c.github.io/ServiceWorker/#client-focus

In Chromium, this behavior is tested by wpt_internal/prerender/focus-on-prerendered-window-client.https.html.

This is about focus, and I find it very clear. What about the first bullet? Shouldn't the service worker know that the client is in prerendering mode somehow?

Clqsin45 commented 2 years ago

Renew this thread for the discussion about windowclient.navigate(). IIUC, currently that navigate() returns a TypeError seems reasonable.

I read some context([1], [2]) while reading https://crrev.com/c/3916197.

Given the following descriptions:

  1. (service worker) If this's associated service worker client's active service worker is not this's relevant global object’s service worker, return a promise rejected with a TypeError.

  2. (prerender ) A worker is said to be an active needed worker if any of its owners are either Document objects that are fully active and their browsing context is not a prerendering browsing context, or active needed workers.

IIUC it seems that in the client, there is no active SW, so we'd modify service worker's spec, and say something be like: if there is no active SW, reject with a type error?

[1] https://chromium-review.googlesource.com/c/chromium/src/+/2936739/ [2] https://w3c.github.io/ServiceWorker/#dom-windowclient-navigate

domenic commented 2 years ago

As far as I can tell, the definition of "active needed worker" is unrelated to the definition of "active service worker". (Bad naming, I guess :-/.) "active service worker" is set in Handle Fetch step 15.8, and I think that spec text runs for prerendering browsing contexts as well. So I think prerendering browsing contexts have active service workers.

I think instead, you'd modify the service worker spec to check if this's browsing context is a prerendering browsing context, and if so, return a promise rejected with a TypeError.

Clqsin45 commented 2 years ago

Thanks Domenic! 👍 They are diffrent concepts and I totally got confused :)

I was attempting to understand the reason why service worker decided to return a TypeError here, but may not understand this for sure. It seems to me that navigate() would return TypeError in the following two cases:

  1. the given URL is not allowed to be naviageted by SW window client.
  2. changes to lifecycle. ( associated service worker client's active service worker is not this's relevant global object’s service worker, discarding documents..., ). Is this correct?

For the prerendering case, it may belong to 2? If not, does it mean each type of browsing contexts can restrict SW's behavior and define their own TypeError criteria?

domenic commented 2 years ago

I think your understanding is a correct way of categorizing the ways the navigate() algorithm currently fails.

I'm not sure we need to pay too much attention to the existing failures, when designing our own failure. We can modify navigate(), if we think doing so is the right thing to do. Maybe our proposed modification is kind of like the existing ones in your (2) category, but I don't think it's too important how we categorize it.