Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[View Transition] Event on old Document to set transition state #9702

Closed
khushalsagar opened this issue Sep 6, 2023 · 65 comments · Fixed by #10002
Closed

[View Transition] Event on old Document to set transition state #9702

khushalsagar opened this issue Sep 6, 2023 · 65 comments · Fixed by #10002

Comments

@khushalsagar
Copy link
Contributor

Cross document VT needs an event on the old Document so authors can set up view-transition-names based on where the user is navigating to. The navigate event seems like the perfect choice but it has the following issues:

  • It doesn't tell the final URL (after redirects) so authors will have to set state based on initial URL. We can't do this if there are cross-origin redirects (that won't allow a transition anyway) for security reasons but it can be considered for same-origin redirects. I don't know how significant that use-case is.
  • It doesn't fire for all browser initiated navs, looks like its meant to be only for back/fwd buttons. We discussed whether all browser initiated navs should allow View Transitions at CSSWG. For example if the user enters a same-origin URL in the omnibox. And the resolution was to let the browser decide this: [css-view-transitions-2] Define navigation descriptor for @view-transition w3c/csswg-drafts#8783. So if there is any nav which supports transitions, it will need the event.
  • The event fires too early, when the nav is initiated. The user can continue interacting with the page before we have a server response. For example you click a link and continue to scroll the current page or click something which expands a menu. These interactions could require a change in the transition.
    Authors could work around this by tracking these updates themselves, like a scroll listener but better if we can give them an event right before the frame which is captured.

@noamr @vmpstr @domenic

@vmpstr
Copy link
Member

vmpstr commented Sep 6, 2023

We also have things like pagehide and beforeunload that are closer to the right time, and I believe are always dispatched (Although there are some awkward interactions with bfcache).

Are these events correct in their time? If not, is there a specific time during the document lifecycle where this event has to be dispatched?

@domenic
Copy link
Member

domenic commented Sep 7, 2023

Yeah, when you described the conditions in the OP, I think unload and pagehide (not beforeunload) are much closer to what you're looking for. Those are the events that fire when we actually have the post-redirects HEAD response in hand and are ready to destroy the current Document.

@khushalsagar
Copy link
Contributor Author

pagehide seems like the right one to me as well, just need to check if its guaranteed to be dispatched before the new Document starts executing script. I'm not sure about that.

We likely don't do it for cross-origin navs, since it will delay the navigation but can make an exception if its a same-origin nav with a transition?

@domenic
Copy link
Member

domenic commented Sep 11, 2023

just need to check if its guaranteed to be dispatched before the new Document starts executing script.

For non-prerendering cases, it is guaranteed. New documents don't start executing script until https://html.spec.whatwg.org/#scripts-may-run-for-the-newly-created-document

@noamr
Copy link
Contributor

noamr commented Sep 11, 2023

pagehide seems like the right one to me as well, just need to check if its guaranteed to be dispatched before the new Document starts executing script. I'm not sure about that.

For same origin navs it does.

@khushalsagar
Copy link
Contributor Author

For same origin navs it does.

Great!

Documenting a point @noamr made in our offline discussion, whatever event authors use will be followed by a frame, so that the names they setup influence what's captured. And it would be odd to render a frame after pagehide. I'm not sure if there's any API contract like this.

One model I'm gravitating towards is:

  • Authors set up the opt-in config (to decide whether there will be a transition) using the navigate event. If that needs to change based on redirects we can explore adding events that informs the page of redirects going forward.
  • Dispatching a VT specific event right before the frame that will be captured? So the authors knows the exact DOM state that will be captured and names can be set accordingly.

@domenic
Copy link
Member

domenic commented Sep 12, 2023

How does this model work with prerendering? I know combining prerendering and MPA view transitions is a goal we all share :)

@khushalsagar
Copy link
Contributor Author

How does this model work with prerendering? I know combining prerendering and MPA view transitions is a goal we all share :)

For sure! I'm not seeing which aspect is ambiguous with respect to pre-rendering. Mind clarifying the question you had in mind?

@domenic
Copy link
Member

domenic commented Sep 12, 2023

Well, I guess I'm not 100% clear on the model, but I was scared by the question about whether pagehide (or any similar event) is "guaranteed to be dispatched before the new Document starts executing script". That's not going to be true in prerendering cases; the new Document will start executing script at an arbitrarily-early time.

Does that mess up the model here in any way? Your description in #9702 (comment) seems to be entirely about the preceding page, so maybe it's fine? But I wanted to double-check.

@noamr
Copy link
Contributor

noamr commented Sep 12, 2023

There is no inherent reason to perform this before the new document can run any script, but we didn't want to make this invoke an implicit type of prerendering (having two "live" pages without explicitly using speculationrules). It's OK if those events run after scripts have run in the prerender case

@khushalsagar
Copy link
Contributor Author

It's OK if those events run after scripts have run in the prerender case

+1, I now see my statement was confusing. Clarifying the model to make sure I got it right:

  1. We need to recommend a hook that authors use on the old Document to set up names. This is before the Document renders its last frame which is captured as snapshots.
  2. The new Document should be made visible after the step above. So whatever event devs will use to set up animations on the new Document must happen after 1 above. That'll likely be the reveal event: Proposal: fire an event before the first rendering opportunity after activation #9315.

@noamr
Copy link
Contributor

noamr commented Nov 20, 2023

Going back to this, I think the event should not be specific to view transitions, but rather a counterpart to pagereveal on the old document, that allows:

  • knowing the new URL, post same-origin
  • affect capturing of the old state

I see 3 options here:

  1. Fire a new event on navigation commit, that's guaranteed to happen before a last capture frame. such event is likely VT-specific.
  2. Fire an event for each same-origin navigation redirect. This allows the old document to prepare early rather than wait till the last moment.
  3. Change the VT model so that the last capture is done after we send the pagehide event, and add some info to pagehide.

All of the above shouldn't fire for prerender, only for a regular navigation redirect/commit.

I'm currently slightly leaning towards 2 but if we can find a way to make (3) not break things I'm open.

@khushalsagar
Copy link
Contributor Author

I actually prefer (1) without making it VT-specific. It could be a counterpart to the navigate event in the navigation API except this one is not cancellable.

The con with (2) is that it doesn't cover the other use-case for this event: "The user can continue interacting with the page before we have a server response." Imagine that the transition depends on scrolling which changes which elements are onscreen. Without an event which fires right before browser capture, authors need to run a scroll handler to keep the DOM in "capture ready" state until snapshot or navigation cancellation. I also don't think there is work the browser can "prepare early". Other than changing layerization decisions based on view-transition-names we try to defer the heavy rendering work until the last frame.

(3) is interesting but could run into assumptions that pagehide is dispatched after the Document is made invisible? Also it's likely fired on tab switching too. The navigation API seems like a better place for this info.

@smaug----
Copy link
Collaborator

pagehide isn't fired on tab switching. pagehide is like the better version of unload event.

@khushalsagar
Copy link
Contributor Author

Thanks for clarifying @smaug----. Do you have thoughts on the other point: "rendering a frame after pagehide"? Would that mismatch developer expectations of how pagehide behaves today?

@smaug----
Copy link
Collaborator

We discussed with @petervanderbeken, and if possible would prefer reusing pagehide. It is after all not that different from (2) in case there are no redirects.
And per spec page visibility is changed to hidden after firing pagehide.
Adding yet another unload type of event would be a bit unfortunate.

The extra rendering is a new thing anyhow. If the old page is rather static, it might currently not trigger any paints while the new page is loading.
But, do we want that the extra rendering triggers all the relevant callbacks? And what should those callbacks be able to do? What if one triggers new fetches? Or loads something using sync XHR even? Or tries to navigate to some other page?

@khushalsagar
Copy link
Contributor Author

But, do we want that the extra rendering triggers all the relevant callbacks?

We need the update the rendering loop to run for snapshots. That's because if the author changes which elements have a view-transition-name, it changes layerization and needs the engine to push a new frame to the compositing stack.

And while we can suppress callbacks that run as a part of update-the-rendering, it doesn't help make the script interaction any simpler. Script can trigger anything with a setTimeout instead. But I see your point that we should probably disallow triggering a new navigation once we've begun capturing the old Document for a transition. Is there already a way to place the Document in this state? I'm guessing we similarly don't want script to do this in the pagehide event?

And per spec page visibility is changed to hidden after firing pagehide.

The challenge here is that we'll need to add an async step between firing the pagehide event and marking the page hidden. So we can produce one last frame to snapshot before the page is marked hidden. In the current spec marking the Document hidden is synchronous after pagehide dispatch here and is a part of unloading the Document. So there's no opportunity to produce another frame after dispatching pagehide.

That's why we intentionally added this async step earlier here, before the unload algorithm is triggered. Since there's already an async task to run step 11, it was easier to add a new async step for rendering and capturing the last frame at the beginning. And we can introduce a new event at this spot for the author to configure state that affects the captured frame.

@smaug----
Copy link
Collaborator

Why would there be async step between firing pagehide and marking page hidden. We can have a rendering step there if we want. (I'm not saying we should do that, but just that we can, if we want)

@khushalsagar
Copy link
Contributor Author

Why would there be async step between firing pagehide and marking page hidden. We can have a rendering step there if we want.

Because update-the-rendering steps run on a new task (generally driven by platform vsync notifications). So we'd need to go back to the event loop after firing pagehide, wait for the next update-the-rendering loop and then continue with the unload steps starting with marking the Document hidden. Are you suggesting synchronously triggering update-the-rendering after dispatching pagehide?

@smaug----
Copy link
Collaborator

I'm just saying that it would be possible, if we want that.

@khushalsagar
Copy link
Contributor Author

I'm just saying that it would be possible, if we want that.

Its way too complicated to support in Chromium. We have a pull model where the compositor pulls an update from Blink while this will require Blink pushing a frame to the compositor which is a fundamental change. So I would prefer keeping the capture step async.

@noamr
Copy link
Contributor

noamr commented Nov 23, 2023

Summarizing internal discussion:
Fitting in an "update the rendering" phase (and thus a task) between pagehide and visibilitychange would break existing author assumptions, that pagehide is happening in the last task of the page. e.g. you might be tearing down things in pagehide if not persisted, and having a rAF callback afterwards would be buggy.

Thus perhaps a pagewillhide or a outboundviewtransition event with a ViewTransition object (similar to pagereveal) would work the best. Unlike pagereveal, it's ok if this event is sent only when there is an actual view transition.

@noamr noamr added the agenda+ To be discussed at a triage meeting label Nov 29, 2023
@past past removed the agenda+ To be discussed at a triage meeting label Nov 30, 2023
@smaug----
Copy link
Collaborator

At which point would pagewillhide fire?

@noamr
Copy link
Contributor

noamr commented Dec 1, 2023

At which point would pagewillhide fire?

When we get the final response for the new document, it will fire, delay hiding/unloading and render one more frame if there is a view transition. If there is no vt it will fire right before pagehide.

Note that this event should include the URL of the target page in case it's same-origin. In general this event probably only makes sense for same-origin navigations, as in cross-origin navigations you can't delay the commit and you don't have a ViewTransition anyway.

Perhaps beforepagehide to match beforeunload, or beforepagetransition (note that pagehide is a PageTransitionEvent`), and have it only for actual same-origin page transitions.

@smaug----
Copy link
Collaborator

beforeunload timing is quite different. That happens when you're about to start loading the next page. This new event would fire when the new page is about to be shown to the user.
But pagehide and unload event timing is basically the same.

So perhaps better to not use name beforepagehide.

I'm still trying to figure out the timing of the new event from implementation point of view. In Gecko we'd need to do one extra parent process -> content process -> parent process round trip for this, I think. And I guess check whether window.stop() is called or new navigations started or history.go() used... hmm, couldn't sites misuse the event?

@noamr
Copy link
Contributor

noamr commented Dec 1, 2023

beforeunload timing is quite different. That happens when you're about to start loading the next page. This new event would fire when the new page is about to be shown to the user. But pagehide and unload event timing is basically the same.

So perhaps better to not use name beforepagehide.

How about beforepagetransition?

I'm still trying to figure out the timing of the new event from implementation point of view. In Gecko we'd need to do one extra parent process -> content process -> parent process round trip for this, I think.

Sounds right.

And I guess check whether window.stop() is called or new navigations started or history.go() used... hmm, couldn't sites misuse the event?

Yes, that's why I'm thinking to fire it for same-origin navigations only, or even fire it only when you have a pending cross-document view transition.

@noamr
Copy link
Contributor

noamr commented Dec 13, 2023

I want to make progress on this. My main contemplation is where this should be a document event like pagehide or in the navigation namespace.

The way it's going to work:

  • When response headers come and we're about to unload and switch to a same-origin document:
    • Fire this event, with:
      • View transition object if there's an outbound view transition.
      • URL you're going to
      • Navigation type
    • If there's an outbound view transition, wait until capture before running the remaining steps. During this wait the developer still has a chance to cancel the navigation, skip the transition etc.
    • Unload the old document as usual
    • Activate the new document as usual

So thinking navigation.oncommit, or document.onbeforepagetransition, or document.onpageconceal (to be symmetrical with pagereveal).

@smaug---- @domenic thoughts?

@domenic
Copy link
Member

domenic commented Jan 18, 2024

I think I've followed all the recent discussion, and it sounds reasonable to me. But I'm still a bit stuck back on the questions of where the event is located and how often it fires. The latest proposal from @khushalsagar in #9702 (comment) has it fire on every navigation, right? Or only on cross-document navigations? Or are we still planning only same-origin cross-document navigations, like we were back in #9702 (comment) ?

@noamr
Copy link
Contributor

noamr commented Jan 18, 2024

I think I've followed all the recent discussion, and it sounds reasonable to me. But I'm still a bit stuck back on the questions of where the event is located and how often it fires. The latest proposal from @khushalsagar in #9702 (comment) has it fire on every navigation, right? Or only on cross-document navigations? Or are we still planning only same-origin cross-document navigations, like we were back in #9702 (comment) ?

I think we can fire it for every cross-document navigation. If there is no view transition opt-in in css it would be fired right before pagehide, and if it's a cross-origin navigation you wouldn't get the post-cross-origin-redirect url.

@noamr
Copy link
Contributor

noamr commented Jan 19, 2024

I think I've followed all the recent discussion, and it sounds reasonable to me. But I'm still a bit stuck back on the questions of where the event is located and how often it fires. The latest proposal from @khushalsagar in #9702 (comment) has it fire on every navigation, right? Or only on cross-document navigations? Or are we still planning only same-origin cross-document navigations, like we were back in #9702 (comment) ?

I've completed a first revision of the PR, I think it explains it: #10002
We can of course revise it if we decide on a different logic.

  • It fires whenever you navigate to a different document, unlike pagehide which would also fire for other unloading reasons.
  • It would usually fire right before unloading in the same task, but if there's a view transition it would fire in own task and then the unloading sequence would be deferred until after the old document's state is captured (essentially waiting for a rendering update cycle).

@smaug----
Copy link
Collaborator

(I think this was discussed somewhere, but I can't find where) How does this all work in background tabs. The to be unloaded page might be first visibilityHidden when pageconceal would fire and then becomes visible right before pagehide. Or the to be unload might be hidden for a longer time, but new page is visible etc.
I couldn't immediately find where this all is spec'ed.

@khushalsagar
Copy link
Contributor Author

But I'm still a bit stuck back on the questions of where the event is located and how often it fires. The latest proposal from @khushalsagar in #9702 (comment) has it fire on every navigation, right?

I'm actually leaning towards aligning this event with navigate, i.e., it fires for the class of navigations which also fire navigate:

  • A requirement for this event is that it must fire for the set of navigations which can have a ViewTransition. This works out based on the resolution on [css-view-transitions-2] Define navigation descriptor for @view-transition w3c/csswg-drafts#8783 (comment), we don't support View Transition on navigations that don't fire navigate.

  • navigate is fired when a navigation is initiated and pageconceal fires before it will be committed. So the events are fired at different stages of a navigation's lifecycle. It would be odd to fire pageconceal but not navigate. It's possible to get navigate but not pageconceal if the navigation is cancelled.

@noamr
Copy link
Contributor

noamr commented Feb 1, 2024

So I'm seeing the following options here, I'd like us to resolve on promptly.

  1. An event that fires for each cross-document navigation, not always with a viewTransition, and with a nullable activation.entry. This is what the current PR does, and perhaps window.onpageconceal is ok for that.
  2. An event that fires only for navigations that receive a navigate event, ie same-origin navigations that are either traverse or renderer/script-initiated. This can maybe be navigation.oncommit.
  3. If we go with something like (2), Expose this as a promise on a navigate event, as the NavigateEvent already has a lot of the info (navigation type, user-initiated...): something like: const {finalURL, viewTransition} = navigateEvent.committed

@domenic
Copy link
Member

domenic commented Feb 1, 2024

Hmm, all three of those seem pretty nice to me. I think I'd be happy with any of them as good scopes for the event to fire, but the naming gets a bit tricky with (2) and (3) because of how it overlaps with the existing concept of "committed" in the navigation API.

Right now, "committed" is exposed through the return values of navigation.navigate() and friends, as a promise that fulfills once the URL has changed. And, that promise only fulfills for same-document navigations, since in general any promises will go away after the URL has changed (i.e. "after commit") for cross-document navigations. (Technically if you were doing const { committed } = frames[0].navigation.navigate(...), you could observe the commit. But we decided not to support that.)

Given this, assuming the idea for (2) or (3) would still be only for cross-document navigations, then I think we need to include that fact in the name.

And, since the API today treats "committed" as "after the URL has already changed", I don't think "committed" should be used to mean "right before the URL is about to be changed". We should either say something like "before commit", or introduce a new term like "finalized" or something.

So, some possible names for (2) and (3) might be:

  • navigation.onbeforecrossdocumentcommit
  • navigation.onbeforecrossdocument
  • navigation.oncrossdocumentfinalized
  • navigateEvent.readyToCrossDocumentCommit
  • navigateEvent.aboutToCrossDocuments
  • navigateEvent.nextDocument
  • navigateEvent.crossDocumentFinalized

Other notes for (3):

  • Existing code references navigateEvent.destination.sameDocument. Maybe worth considering when naming.
  • Promise types are not currently allowed to be nullable in IDL, so either we'd have to change that (a bit controversial) or we'd leave the promise pending forever for same-document cases, and people would need to be sure to do a !navigateEvent.destination.sameDocument guard before accessing the promise.
    • Or, we could consider having this promise fulfill immediately for same-document cases? That would change the naming space too; I guess navigateEvent.readyToCommit is pretty good then.

Overall, (1) is probably the simplest. But you all know better what kind of code people will be writing in this handler, which could steer toward (2) or (3).

@khushalsagar
Copy link
Contributor Author

Overall, (1) is probably the simplest.

Ok, then SGTM. Just one minor correction in the comment above: "An event that fires for each cross-document navigation...".

with a nullable activation.entry

This will be the case if the navigation is cross-origin. Do we need to hide this if the final URL is same-origin but there are cross-origin redirects?

@noamr
Copy link
Contributor

noamr commented Feb 1, 2024

Overall, (1) is probably the simplest.

Ok, then SGTM. Just one minor correction in the comment above: "An event that fires for each cross-document navigation...".

with a nullable activation.entry

This will be the case if the navigation is cross-origin. Do we need to hide this if the final URL is same-origin but there are cross-origin redirects?

We don't need to hide it in that case. We currently don't hide anything based on cross-origin redirects, except for timing.

@noamr
Copy link
Contributor

noamr commented Feb 1, 2024

Overall, (1) is probably the simplest.

Ok, then SGTM. Just one minor correction in the comment above: "An event that fires for each cross-document navigation...".

Agreed, and fixed the comment. So proposing to move forward with way the current PR is going (fire for every cross-document navigation, either right before pagehide or at a special task if there is a view-transition).

@noamr
Copy link
Contributor

noamr commented Feb 1, 2024

Some more naming alternative, as seems like other people raised that pageconceal is confusing: pageswap. It tells the story of this being about being relevant only when moving from document a to document b (not closing), and keeps the "page" theme that revolves around cross-document navigations.

@khushalsagar
Copy link
Contributor Author

Other options which we discarded:

  • pagewillnavigate: The event is dispatched at the end of the navigation's lifecycle so its already navigating when it fires.
  • pagereadytocommit: The commit word is used for same-document navigations in the navigation API as mentioned above.
  • pagebeforecrossdocumentcommit: It's getting too verbose...

@noamr
Copy link
Contributor

noamr commented Feb 2, 2024

Sorry for going back and forth, but @khushalsagar raised a good point that we can't expose navigationType for browser-initiated cross-origin navigations. I'm thinking that makes option (1) a bit too null-ish, and option (3) has this strange issue with nullable promises, so perhaps option 2 is the cleanest: navigation.onnextdocument, navigation.onnextdocumentready, or navigation.ondocumentswap, and apply the same rules as the navigate event in terms of when we send it.

@khushalsagar
Copy link
Contributor Author

I'm still ok with option (1) in terms of the API shape. The fact that navigation API events try to be agnostic to same-document or cross-document navigations vs page* events are specifically about cross-document navigations convinced me that option (1) is a better place for this.

In terms of which navigations the event fires for, the use-case we have (with VT) is limited to cross-document same-origin navigations. Including any more navigations will be from the perspective of future proofing because we won't be able to change this, should use-cases come up, without compat risk.

With the above in mind, firing it for all cross-document navigations but hiding both the destination entry and navigation type seems like a good path for now. I expect it will be feasible to expose a bit (like navigationType) for a class of navigations later on but not change whether the event fires for a nav or not.

@noamr
Copy link
Contributor

noamr commented Feb 6, 2024

Added Agenda+ to make sure we have concensus about where we landed with this & picking a final name before merging.

@noamr
Copy link
Contributor

noamr commented Feb 6, 2024

(I think this was discussed somewhere, but I can't find where) How does this all work in background tabs. The to be unloaded page might be first visibilityHidden when pageconceal would fire and then becomes visible right before pagehide. Or the to be unload might be hidden for a longer time, but new page is visible etc. I couldn't immediately find where this all is spec'ed.

Sorry I missed this comment,
If the tab is hidden there will be no view transition, and pageconceal would fire right before pagehide.
pageconceal has a special task & timing meaning only if a view transition is possible, otherwise it's just a "pagehide that's fired only when you're going to a new document"

@bramus
Copy link

bramus commented Feb 8, 2024

Some more naming alternative, as seems like other people raised that pageconceal is confusing: pageswap.

Hmm, I think it’s the exact opposite here … swapping is an action between two things (here: two pages) and can apply to either of those two. By using “swap” as the name you can’t really tell if it targets the swapped from (outgoing) or swapped to (incoming) one.

With pageconceal it is much clearer that it applies to the outgoing page. It also pairs nicely with the already specced pagereveal.

IUC the order for all page* events would be this: pagehidepageconcealpagerevealpageshow.
Feels nice that there’s a virtual mirror right in the middle there, creating the antonym-pairs concealreveal and hideshow.

@noamr
Copy link
Contributor

noamr commented Feb 8, 2024

Some more naming alternative, as seems like other people raised that pageconceal is confusing: pageswap.

Hmm, I think it’s the exact opposite here … swapping is an action between two things (here: two pages) and can apply to either of those two. By using “swap” as the name you can’t really tell if it targets the swapped from (outgoing) or swapped to (incoming) one.

This refers to the old page "being swapped", which you can't say about the new page. The same way a page is "being hidden", "being clicked" or "being revealed" - those are all passive terms, which in the context of the verb swap relates only to the "old" member of the swapped things.

The problem with conceal is that it implies gradual hiding, while it might be fired when you don't have a chance to do anything in the last frame.

With pageconceal it is much clearer that it applies to the outgoing page. It also pairs nicely with the already specced pagereveal.

IUC the order for all page* events would be this: pagehidepageconcealpagerevealpageshow. Feels nice that there’s a virtual mirror right in the middle there, creating the antonym-pairs concealreveal and hideshow.

This is not the order of events.
It would be:
pageconceal
pagehide
pagereveal / pageshow (order can change based on whether the load event was already fired).

@bramus
Copy link

bramus commented Feb 8, 2024

This refers to the old page "being swapped", which you can't say about the new page.

But you are swapping one thing for the other – the action requires two participants. From the name itself it’s not clear which of the two participants you mean. By having the antonym of reveal as a name, it’s clear which one it applies to at that very moment.

The same way a page is "being hidden", "being clicked" or "being revealed" - those are all passive terms, which in the context of the verb swap relates only to the "old" member of the swapped things.

Difference is that these actions only require 1 participant. You can’t be confused about which participant you mean.

The problem with conceal is that it implies gradual hiding

Same thing can be said about reveal? e.g. “revealing curtain”.

This is not the order of events. It would be: pageconceal pagehide pagereveal / pageshow (order can change based on whether the load event was already fired).

Got it (to say I already had the correct order in my notes somewhere 🤦‍♂️)

@noamr
Copy link
Contributor

noamr commented Feb 8, 2024

The problem with conceal is that it implies gradual hiding

Same thing can be said about reveal? e.g. “revealing curtain”.

Yes, but I think the confusion here is trying to create symmetry.
The only thing symmetrical about these events is in the context of view-transitions.

While pagereveal only happens once the document can render, this new event is not related to rendering at all. It can fire even if the tab is hidden - as long as there are two documents involved (a swap). So the symmetry can create confusion.

@past past removed the agenda+ To be discussed at a triage meeting label Feb 8, 2024
@bramus
Copy link

bramus commented Feb 8, 2024

Thanks for clarifying things here, @noamr. My expectation that these events were symmetric in nature put me on the wrong track here.

domenic pushed a commit that referenced this issue Feb 29, 2024
See also w3c/csswg-drafts#9819.

The pageswap event is specified here to work as follows:

* It's sent whenever a document navigates away, to a different document, but not when unloaded for other reasons, such as closing the browser types or unloading an ancestor.

* It includes a NavigationActivation object for same-origin navigations.

* If the navigation might trigger a cross-document view-transition (this is determined when snapshotting the source document, by reading the CSS), pageswap is fired and then unloading is deferred until the old state is captured for the view transition. Otherwise, if the view transition is skipped, unloading happens immediately.

Closes #9702.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

9 participants