@jsenv/navi 0.29.498 → 0.29.500

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9871,15 +9871,16 @@ const [publishRouteRender, observeRouteRender] = createPubSub();
9871
9871
  *
9872
9872
  * A page whose height depends on something still loading is not there at the
9873
9873
  * moment it is put back, and a position beyond what has arrived is clamped.
9874
- * What navi knows a first render left out, it waits for: a `<Box
9875
- * mount="after-paint">` is built before the offset that shows it is written
9876
- * (see mount_after_paint.jsx), and a reload or a return waits for the route
9877
- * actions the page has nothing to draw for — its code among them — including
9878
- * one whose `when` lets it ask after the position is written (see
9879
- * stayForLateAsks). Anything else only the page knows, and it says so
9880
- * (useHoldScrollRestoration). A wait can be long, so the reader reaching for
9881
- * the page during it cancels the position: moved afterwards, they would lose
9882
- * whatever they had started on.
9874
+ * So it is written into what is there, as far as that goes, and written again
9875
+ * once the page is whole (see putBackMeanwhile). What navi knows a first render
9876
+ * left out, it waits for: a `<Box mount="after-paint">` is built before the
9877
+ * offset that shows it is written (see mount_after_paint.jsx), and a reload or
9878
+ * a return waits for the route actions the page has nothing to draw for — its
9879
+ * code among them — including one whose `when` lets it ask after the position
9880
+ * is written (see stayForLateAsks). Anything else only the page knows, and it
9881
+ * says so (useHoldScrollRestoration). A wait can be long, so the reader
9882
+ * reaching for the page during it cancels the position: moved afterwards, they
9883
+ * would lose whatever they had started on.
9883
9884
  *
9884
9885
  * WHEN a page is arrived at is not decided here either. A document navigation
9885
9886
  * lands where its kind says (see via_history.js), and one scrollport can be
@@ -10024,8 +10025,8 @@ const suspendScrollRecording = () => {
10024
10025
  // the reader reaching for the page: where they are is theirs (see
10025
10026
  // installScrollRestoration).
10026
10027
  let pendingRestoration = null;
10027
- const startRestoration = (position, { meanwhile = false } = {}) => {
10028
- const restoration = { position, due: false, meanwhile };
10028
+ const startRestoration = (position) => {
10029
+ const restoration = { position, due: false };
10029
10030
  pendingRestoration = restoration;
10030
10031
  return restoration;
10031
10032
  };
@@ -10085,15 +10086,13 @@ const isDocumentHeld = () => {
10085
10086
  return false;
10086
10087
  };
10087
10088
 
10088
- // A return is photographed by its route transition as soon as its page has
10089
- // rendered, stand-ins and all, and a position waiting for the page to be whole
10090
- // is written after the movement, seen as a jump. So it is also written into
10091
- // what is there meanwhile, as far as that goes — the browser clamps the rest —
10092
- // and again once the page is whole, when what it stands on has grown or shrunk.
10089
+ // A position waiting for the page to be whole is written after the reader has
10090
+ // seen the page at its top, and seen as a jump — after the movement, when a
10091
+ // route transition photographs the page as soon as it renders, stand-ins and
10092
+ // all. So it is also written into what is there meanwhile, as far as that goes
10093
+ // (the browser clamps the rest), and again once the page is whole, when what
10094
+ // it stands on has grown or shrunk.
10093
10095
  const putBackMeanwhile = (restoration) => {
10094
- if (!restoration.meanwhile) {
10095
- return;
10096
- }
10097
10096
  // Out of whatever commit or effect is asking: see scrollTo.
10098
10097
  queueMicrotask(() => {
10099
10098
  if (pendingRestoration !== restoration || isDocumentHeld()) {
@@ -10130,11 +10129,11 @@ const holdScrollRestoration = () => {
10130
10129
  };
10131
10130
 
10132
10131
  /**
10133
- * Holds back the scroll position a reload or a back/forward gives the page,
10134
- * while the page is not whole yet: written into what the page shows meanwhile,
10135
- * it is clamped to that height and lost. Put back after the commit in which
10136
- * `held` turns false — unless the reader has reached for the page in the
10137
- * meantime (a finger, a click, a wheel, a key), or gone elsewhere.
10132
+ * Says the page is not whole yet to the scroll position a reload or a
10133
+ * back/forward gives it: written into what the page shows meanwhile, it is
10134
+ * clamped to that height. Put back again after the commit in which `held`
10135
+ * turns false — unless the reader has reached for the page in the meantime (a
10136
+ * finger, a click, a wheel, a key), or gone elsewhere.
10138
10137
  *
10139
10138
  * The page's route actions are waited for without this — its code, a read
10140
10139
  * with no answer yet, one whose `when` holds later. This is for
@@ -10384,7 +10383,7 @@ const restoreScrollPositionOnReturn = (url) => {
10384
10383
  if (!position) {
10385
10384
  return;
10386
10385
  }
10387
- const restoration = startRestoration(position, { meanwhile: true });
10386
+ const restoration = startRestoration(position);
10388
10387
  whenPageRendered(() => {
10389
10388
  putBackOnceAnswered(restoration);
10390
10389
  });
@@ -14357,7 +14356,21 @@ const setupBrowserIntegrationViaHistory = ({
14357
14356
  // asked for it (see navBack's `landOn`). Read by the popstate listener,
14358
14357
  // which is the one place the landing is applied.
14359
14358
  let landOnPending = null;
14360
- const navBack = ({ fallback, landOn } = {}) => {
14359
+ // The back navBack asked for, from history.back() to the "popstate" that
14360
+ // answers it. Meanwhile the document still reads the entry being left (see
14361
+ // whenBackLanded).
14362
+ let backInFlight = null;
14363
+ const whenBackLanded = (callback) => {
14364
+ if (backInFlight) {
14365
+ return backInFlight.then(callback);
14366
+ }
14367
+ return callback();
14368
+ };
14369
+ // A second back asked before the first one landed (two popups closed in the
14370
+ // same handler) waits for it: the browser would queue both, but the landing
14371
+ // has one slot, and its `landOn` was read on the entry the first back leaves.
14372
+ const navBack = (options) => whenBackLanded(() => navBackNow(options));
14373
+ const navBackNow = ({ fallback, landOn } = {}) => {
14361
14374
  if (canNavBackSignal.peek()) {
14362
14375
  // Resolved once the back has landed: the "popstate" it is answered with
14363
14376
  // reaches the routing listener first (registered at setup, before this
@@ -14369,10 +14382,12 @@ const setupBrowserIntegrationViaHistory = ({
14369
14382
  return;
14370
14383
  }
14371
14384
  window.removeEventListener("popstate", onPopstate);
14385
+ backInFlight = null;
14372
14386
  resolve(true);
14373
14387
  };
14374
14388
  window.addEventListener("popstate", onPopstate);
14375
14389
  });
14390
+ backInFlight = landedPromise;
14376
14391
  landOnPending = landOn || null;
14377
14392
  window.history.back();
14378
14393
  return landedPromise;
@@ -14416,6 +14431,7 @@ const setupBrowserIntegrationViaHistory = ({
14416
14431
  stop,
14417
14432
  reload,
14418
14433
  navBack,
14434
+ whenBackLanded,
14419
14435
  navForward,
14420
14436
  getDocumentState,
14421
14437
  carryByLinkNavigation,
@@ -14709,6 +14725,10 @@ const reload = browserIntegration.reload;
14709
14725
  * current entry's place.
14710
14726
  */
14711
14727
  const navBack = browserIntegration.navBack;
14728
+ // Runs `callback` once the back navBack started has landed, at once when there
14729
+ // is none: until then the document reads the entry that back is leaving, and
14730
+ // a write made there is gone with it.
14731
+ const whenBackLanded = browserIntegration.whenBackLanded;
14712
14732
  const navForward = browserIntegration.navForward;
14713
14733
  const isVisited = browserIntegration.isVisited;
14714
14734
  const visitedUrlsSignal = browserIntegration.visitedUrlsSignal;
@@ -14874,7 +14894,14 @@ const useNavStateBasic = (
14874
14894
  }
14875
14895
  leaveEntry({ isBack, discard });
14876
14896
  };
14897
+ // Read and written on the entry the document lands on: a leave asked while
14898
+ // another one's back is in flight (a popup closed with the one under it)
14899
+ // would otherwise carry that entry's url and state — the other key
14900
+ // included — onto the wrong one.
14877
14901
  const leaveEntry = ({ isBack, discard }) => {
14902
+ whenBackLanded(() => leaveLandedEntry({ isBack, discard }));
14903
+ };
14904
+ const leaveLandedEntry = ({ isBack, discard }) => {
14878
14905
  if (!Object.hasOwn(browserIntegration.getDocumentState() || {}, id)) {
14879
14906
  return;
14880
14907
  }
@@ -18144,7 +18171,14 @@ const writeInSignal = (signal, value, { history }) => {
18144
18171
  // `discard` empties what belongs to the popup alone (its `ownSignals`): before
18145
18172
  // a keep-close reads the url it lands on, and once a back has landed — the
18146
18173
  // entry behind may hold them too, written by an `onOpen` before the push.
18147
- const writeOpenedInSignal = (
18174
+ //
18175
+ // Read and written on the entry the document lands on: a close asked while
18176
+ // another popup's back is in flight (a popup closed with the one under it)
18177
+ // would otherwise read the url that back is leaving, and write onto it.
18178
+ const writeOpenedInSignal = (...args) => {
18179
+ whenBackLanded(() => writeOpenedInLandedSignal(...args));
18180
+ };
18181
+ const writeOpenedInLandedSignal = (
18148
18182
  signal,
18149
18183
  opened,
18150
18184
  event,