[ServiceWorker] ServiceWorkerClient to Client (#588)

These shouldn't be specific to ServiceWorker, and should move into the Fetch spec.

These bits stay the same:

```
partial interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  readonly attribute ServiceWorkerClients clients;
}

interface ServiceWorkerClients {
  Promise<sequence<Client>> getAll(optional ServiceWorkerClientQueryParams params);
}

dictionary ServiceWorkerClientQueryParams {
  // include clients on the origin that aren't controlled by this SW
  boolean includeUncontrolled;
}
```

Here's the different bits:

```
enum ClientType { "window", "worker", "sharedworker", "serviceworker" };

dictionary ClientOptions {
  ClientType type = "window";
};

[Constructor(USVString url, optional ClientOptions options), Exposed=Window, Worker]
interface Client {
  readonly attribute Promise<void> update;
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  readonly attribute USVString url;
  readonly attribute ContextFrameType frameType;
  readonly attribute ClientType type;
  readonly attribute ServiceWorkerRegistration? serviceWorkerRegistration;
  void postMessage(any message, optional sequence<Transferable> transfer);
  Promise<focus> focus();
}
```

The properties of a client do not change after construction unless **update** is called.

The **constructor** takes a `url` and `options`. The options are a bit useless at the moment, as it should throw if `type` is set to anything other than `window`. If `type` is `window` (the default), the user agent is requested to open a new tab/window. This may depend on a user-interaction event, as `window.open` does now.

**update** causes `visibilityState`, `focused`, `url`, and `serviceWorkerRegistration` to refresh to the client's current values. If the client hasn't yet succeeded/failed to open, it waits. It rejects if the client is no longer running, or failed to ever run. It doubles as a ready method. **Question**: Do we need a ready method regardless?

**visibilityState** is from [Page Visibility](http://www.w3.org/TR/page-visibility/#VisibilityState). It reports `hidden` for non-window types.

**focused** is the result of `hasFocus()` from the [focus management APIs](https://html.spec.whatwg.org/multipage/interaction.html#focus-management-apis). **Question**: Or should it be true if the browser window has focus and the containing tab is active? As in, should it be true for a top-level client if a contained client (such as an iframe) has focus? Should it be true for a frame in a frameset even if focus is in one of the other frames in the frameset? Should it be true for a top-level client if docked devtools has focus?

**url** is the current url of the client. This is the script url for workers, but can change throughout the life of a window via hash changes and `pushState`. **Question**: Or should this be the creation url, therefore static for windows too? Once we get `clients.claim()`, it'll be taking over clients based on creation url so `pushState` cannot allow pages to "jump scope" and be claimed by a registration they otherwise wouldn't be.

**frameType** comes from the [fetch spec](https://fetch.spec.whatwg.org/#concept-request-context-frame-type). It lets you tell iframes apart from top-level windows.

**type** lets you tell windows apart from different types of worker.

**serviceWorkerRegistration** lets you know if the client is controlled by a worker or not.

**postMessage** does what you'd expect.

**focus** rejects if the type is not "window". Calls `window.focus()` on the related window. Resolves if successful, rejects otherwise. This may depend on a user-interaction event. **Question**: Should this implicitly call update?

I thought about having separate constructors rather than a `type` attribute, such as `WindowClient`, `WorkerClient` etc etc, but that means we'd have more constructors that'd throw, and I know how y'all hate that!

---
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/588

Received on Friday, 12 December 2014 13:30:30 UTC