[w3c/payment-handler] Suggest changing a shape of openWindow() (#300)

## Introduction
Currently, there are some known issues in `openWindow()` API.
  - First, when window client's focus state is changed, it's not clear how it works.
    - Tab switching
    - Explicit `windowClient.focus()` calls
  - Second, in SW side, there is no way to detect that opened window's state is changed.
    - The `pagevisibilitychange`, `beforeunload` events are unhelpful. (https://github.com/w3c/payment-handler/issues/299)
    - For example, when users click `X` button, if the opened window can not send a response to SW, then `respondWith()`'s input promise may be pending forever during SW life time.
  - Third, when users click `refresh` button, the input data (coming from SW to window) may be lost.
    - For example, users might unintentially use `pull to refresh` during scrolling page on Chrome mobile. In the opened window, PH authors can try to store the receive data to persistent storage(e.g. Indexed DB) but the refresh might happen before finishing to store the data.

## Proposal
I'd suggest changing a shape of openWindow API. (based on https://github.com/w3c/payment-handler/issues/97)

#### Before
```webidl
Promise<WindowClient> openWindow(USVString url);
```
#### After
```webidl
Promise<PaymentHandlerResponse> openWindow(USVString url, optional object data);
```

Additionally, we will have to define the following interfaces to use in opened window.
```webidl
partial interface Navigator {
  [SecureContext, SameObject] readonly attribute PaymentHandlerContainer paymentHandler;
};

[SecureContext, Exposed=Window]
interface PaymentHandlerContainer {
    readonly attribute object data;
    void providerResponse(PaymentHandlerResponse response);
};
```
- `PaymentHandlerContainer` should be exposed to opened window only.
- `PaymentHandlerContainer.data` should be synced with the `data` passed in when calling `openWindow()`.
- `PaymentHandlerContainer.providerResponse()` is only allowed in opened window and when it is called, should resolve `openWindow()`'s result promise.

## Example
#### SW side
```js
self.addEventListener('paymentrequest', e => {
  e.respondWith(e.openWindow('...', {
    id: 'xxxxx',
    param1: 'param1',
    param2: 'param2',
  }));
});
```
#### Opened window
```js
window.addEventListener('load', e => {
  assert 'xxxxx' === navigator.paymentHandler.data.id;
  assert 'param1' === navigator.paymentHandler.data.param1;
  assert 'param2' === navigator.paymentHandler.data.param2;

  ...

  navigator.paymentHandler.provideResponse({
    method: 'basic-card',
    data: {}
  });
});
```

WDYT?

/cc @rsolomakhin, @gogerald 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/payment-handler/issues/300

Received on Monday, 30 April 2018 14:21:25 UTC