Skip to content

Commit

Permalink
[css-view-transitions-1] Fix some promise timing, and avoid duplicate…
Browse files Browse the repository at this point in the history
… unhandled rejections (#8454)

Fixes #8455
  • Loading branch information
jakearchibald committed Feb 24, 2023
1 parent e7c1c82 commit 37902c4
Showing 1 changed file with 35 additions and 16 deletions.
51 changes: 35 additions & 16 deletions css-view-transitions-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; type: dfn;
{{UpdateCallback|updateCallback}} is called asynchronously, once the current state of the document is captured.
Then, when the promise returned by {{UpdateCallback|updateCallback}} fulfills, the new state of the document is captured.

{{UpdateCallback|updateCallback}} is _always_ called, even if the transition cannot happen (e.g. due to duplicate `view-transition-name` values).
{{UpdateCallback|updateCallback}} is *always* called, even if the transition cannot happen (e.g. due to duplicate `view-transition-name` values).
The transition is an enhancement around the state change, so a failure to create a transition never prevents the state change.
See [[#transitions-as-enhancements]] for more details on this principle.

Expand Down Expand Up @@ -1015,9 +1015,17 @@ urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; type: dfn;
:: a {{Promise}}.
Initially [=a new promise=] in [=this's=] [=relevant Realm=].

Note: The [=ready promise=] and [=update callback done promise=] are immediately created,
so rejections will cause {{unhandledrejection}}s unless they're [=mark as handled|handled=],
even if the getters such as {{updateCallbackDone}} are not accessed.

: <dfn>finished promise</dfn>
:: a {{Promise}}.
Initially [=a new promise=] in [=this's=] [=relevant Realm=].
Initially [=a new promise=] in [=this's=] [=relevant Realm=],
[=marked as handled=].

Note: This is [=marked as handled=] to prevent duplicate {{unhandledrejection}}s,
as this promise only ever rejects along with the [=update callback done promise=].

: <dfn>transition root pseudo-element</dfn>
:: a ''::view-transition''.
Expand Down Expand Up @@ -1135,9 +1143,14 @@ urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; type: dfn;

Note: This happens if |transition| was [=skip the view transition|skipped=] before this point.

1. [=Mark as handled=] |transition|'s [=ViewTransition/ready promise=].

Note: |transition|'s [=ViewTransition/update callback done promise=] will provide the {{unhandledrejection}}.
This step avoids a duplicate.

1. [=Skip the view transition=] |transition| with |reason|.

* If the promise was resolved, then:
* If the promise was fulfilled, then:

1. If |transition|'s [=ViewTransition/phase=] is "`done`", then return.

Expand Down Expand Up @@ -1424,19 +1437,23 @@ urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; type: dfn;

1. [=Assert=]: |transition|'s [=ViewTransition/phase=] is [=phases/before=] "`update-callback-called`".

1. Let |callbackPromise| be [=a new promise=] in |transition|'s [=relevant Realm=].
1. Let |callbackPromise| be null.

* If |transition|'s [=ViewTransition/update callback=] is null, then resolve |callbackPromise|.
1. If |transition|'s [=ViewTransition/update callback=] is null,
then set |callbackPromise| to [=a promise resolved with=] undefined,
in |transition|'s [=relevant Realm=].

* Otherwise, let |callbackPromise| be the result of [=/invoking=] |transition|'s [=ViewTransition/update callback=].
1. Otherwise, set |callbackPromise| to the result of [=/invoking=] |transition|'s [=ViewTransition/update callback=].

1. Set |transition|'s [=ViewTransition/phase=] to "`update-callback-called`".

1. [=promise/React=] to |callbackPromise|:
1. [=Resolve=] |transition|'s [=ViewTransition/update callback done promise=]
with the result of [=reacting=] to |callbackPromise|:

* If |callbackPromise| was resolved, then [=resolve=] |transition|'s [=ViewTransition/update callback done promise=].
- If the promise was fulfilled, then return undefined.

* If |callbackPromise| was rejected with reason |r|, then [=reject=] |transition|'s [=ViewTransition/update callback done promise=] with |r|.
Note: Since the rejection of |callbackPromise| isn't explicitly handled here,
if |callbackPromise| rejects, then |transition|'s [=ViewTransition/update callback done promise=] will reject with the same reason.
</div>

## [=Skip the view transition=] ## {#skip-the-view-transition-algorithm}
Expand All @@ -1458,17 +1475,19 @@ urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; type: dfn;

1. Set |transition|'s [=ViewTransition/phase=] to "`done`".

1. If |transition|'s [=ViewTransition/ready promise=] has not yet been resolved, [=reject=] it with |reason|.
1. [=Reject=] |transition|'s [=ViewTransition/ready promise=] with |reason|.

Note: The ready promise would've been resolved if {{ViewTransition/skipTransition()}} is called after we start animating.
Note: The [=ViewTransition/ready promise=] may already be resolved at this point,
if {{ViewTransition/skipTransition()}} is called after we start animating.
In that case, this step is a no-op.

1. [=promise/React=] to |transition|'s [=ViewTransition/update callback done promise=]:
1. [=Resolve=] |transition|'s [=ViewTransition/finished promise=] with the result of [=reacting=] to |transition|'s [=ViewTransition/update callback done promise=]:

* If |transition|'s [=ViewTransition/update callback done promise=] was resolved,
then [=resolve=] |transition|'s [=ViewTransition/finished promise=].
- If the promise was fulfilled, then return undefined.

* If |transition|'s [=ViewTransition/update callback done promise=] was rejected with reason |reason|,
then [=reject=] |transition|'s [=ViewTransition/finished promise=] with |reason|.
Note: Since the rejection of |transition|'s [=ViewTransition/update callback done promise=] isn't explicitly handled here,
if |transition|'s [=ViewTransition/update callback done promise=] rejects,
then |transition|'s [=ViewTransition/finished promise=] will reject with the same reason.
</div>

## [=Capture the image=] ## {#capture-the-image-algorithm}
Expand Down

0 comments on commit 37902c4

Please sign in to comment.