From 2fb350922d10a7bf46ea0b1695c38e61ee71d97d Mon Sep 17 00:00:00 2001 From: Ade Bateman Date: Wed, 11 May 2016 11:13:05 -0700 Subject: [PATCH] Remove delegated state and make abort() return a promise The current spec defines a `delegated` state but there is no way to observe a change into this state. The state concept is used to help describe algorithms in the spec in a succinct way and isn't exposed to web pages. This change removes the delegated state from the spec. Previously the only impact of delegated was to prevent abort() from being called. Determining whether abort is possible might require asynchronous processing. For example, some implementations may support abort even if they have delegated to a payment app but may not be able to tell synchronously if this is possible. With this change, the abort() method attempts to abort the request and returns a promise while it tries. If it is not possible to abort then the promise is rejected (instead of throwing). If abort completes successfully then the promise is resolved. --- specs/paymentrequest.html | 114 +++++++++++++----------------------- specs/state-transitions.svg | 77 ++++++++++-------------- 2 files changed, 70 insertions(+), 121 deletions(-) diff --git a/specs/paymentrequest.html b/specs/paymentrequest.html index d0e62dc8..1bf714ce 100644 --- a/specs/paymentrequest.html +++ b/specs/paymentrequest.html @@ -231,7 +231,7 @@

PaymentRequest interface

SecureContext] interface PaymentRequest : EventTarget { Promise<PaymentResponse> show(); - void abort(); + Promise<void> abort(); readonly attribute ShippingAddress? shippingAddress; readonly attribute DOMString? shippingOption; @@ -480,9 +480,36 @@

show()

abort()

-

The abort method may be called if the web page wishes to abort the payment - request after the show method has been called and before the request@[[\acceptPromise]] - has been resolved.

+ +

+ The abort method may be called if the web page wishes to tell the + user agent to abort the payment request and to tear down any user interface that + might be shown. abort can only be called after the show method + has been called and before the request@[[\acceptPromise]] has been resolved. + For example, a web page might choose to do this if the goods they are selling are + only available for a limited amount of time. If the user does not accept the payment request + within the allowed time period, then the request will be aborted. +

+ +

+ A user agent might not always be able to abort a request. For example, if the user agent + has delegated responsibility for the request to another app. In this situation, abort will + reject the returned Promise. +

+ +

+ The architecture document suggests that payment apps may take + numerous forms, including as web-based apps. This specification + should describe how the user-agent will pass the payment request + data and the complete signal to a web-based payment app and also how + it will receive the payment response from the payment app. +

+ +

+ This specification should describe how the user agent will pass the + payment request data and the complete signal to a native payment app + and also how it will receive the payment response from the payment app. +

The abort method MUST act as follows:

    @@ -491,9 +518,13 @@

    abort()

  1. If the value of request@[[\state]] is not interactive then throw an InvalidStateError.
  2. +
  3. Let promise be a new Promise.
  4. +
  5. Return promise and asynchronously perform the remaining steps.
  6. +
  7. Try to abort the current user interaction and close down any remaining user interface.
  8. +
  9. If it is not possible to abort the current user interaction, then reject promise + with InvalidStateError and abort this algorithm.
  10. Set the value of the internal slot request@[[\state]] to closed.
  11. -
  12. Return from the method and asynchronously perform the remaining steps.
  13. -
  14. Abort the current user interaction and close down any remaining user interface
  15. +
  16. Resolve promise with undefined.
@@ -501,7 +532,7 @@

abort()

State transitions

The internal slot [[\state]] follows the following state transitions:

Transition diagram for internal slot state of a PaymentRequest object + src="state-transitions.svg" width="518" height="125">
@@ -1159,71 +1190,6 @@

PaymentRequest updated algorithm

-
-

User agent delegates payment request algorithm

- -

- The PaymentRequest interface allows a web page to call abort - to tell the user agent to abort the payment request and to tear down any user interface that - might be shown. For example, a web page might choose to do this if the goods they are selling are - only available for a limited amount of time. If the user does not accept the payment request - within the allowed time period, then the request will be aborted. -

- -

- A user agent might not always be able to abort a request. For example, if the user agent - has delegated responsibility for the request to another app. To support this situation, - the user agent must run the User agent delegates payment request algorithm. - The algorithm MUST run the following steps: -

- -
    -
  1. - Let request be the PaymentRequest object that the user is - interacting with. -
  2. -
  3. - If the request@[[\updating]] is true, then terminate this - algorithm and take no further action. The user agent user interface should ensure - that this never occurs. -
  4. -
  5. - If the request@[[\state]] is not interactive, then terminate this - algorithm and take no further action. The user agent user interface should ensure - that this never occurs. -
  6. -
  7. - Set request@[[\state]] to delegated. -
  8. -
- -

- The architecture document suggests that payment apps may take - numerous forms, including as web-based apps. This specification - should describe how the user-agent will pass the payment request - data and the complete signal to a web-based payment app and also how - it will receive the payment response from the payment app. -

- -
-

We believe there are user agent configurations that can cause the UI to get into a state - where cancellation by the web page during user interaction is difficult. Users should still - be able to cancel the payment but script will not be able to. We need to investigate in more - detail the consequences of this and whether it is really needed.

-

If we specify delegated then it isn't necessary for all user agents to be - able to move to this state but it would be necessary for all payment flows that wish to call - abort to account for the situation where this may fail in the delegated - state.

-
- -

- This specification should describe how the user agent will pass the - payment request data and the complete signal to a native payment app - and also how it will receive the payment response from the payment app. -

- -
-

User accepts the payment request algorithm

@@ -1242,8 +1208,8 @@

User accepts the payment request algorithm

that this never occurs.
  • - If request@[[\state]] is not interactive and - not delegated, then terminate this algorithm and take no further action. + If request@[[\state]] is not interactive, then terminate this + algorithm and take no further action. The user agent user interface should ensure that this never occurs.
  • diff --git a/specs/state-transitions.svg b/specs/state-transitions.svg index 3f6819ce..0c1ec5a4 100644 --- a/specs/state-transitions.svg +++ b/specs/state-transitions.svg @@ -1,16 +1,16 @@ - +