@jsenv/navi 0.29.496 → 0.29.498

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.
@@ -10429,8 +10429,8 @@ const suspendScrollRecording = () => {
10429
10429
  // the reader reaching for the page: where they are is theirs (see
10430
10430
  // installScrollRestoration).
10431
10431
  let pendingRestoration = null;
10432
- const startRestoration = (position) => {
10433
- const restoration = { position, due: false };
10432
+ const startRestoration = (position, { meanwhile = false } = {}) => {
10433
+ const restoration = { position, due: false, meanwhile };
10434
10434
  pendingRestoration = restoration;
10435
10435
  return restoration;
10436
10436
  };
@@ -10443,6 +10443,7 @@ const putBack = (restoration) => {
10443
10443
  restoration.due = true;
10444
10444
  if (restorationHoldCount) {
10445
10445
  // The page is not whole yet: the last release puts it back.
10446
+ putBackMeanwhile(restoration);
10446
10447
  return;
10447
10448
  }
10448
10449
  if (isDocumentHeld()) {
@@ -10489,6 +10490,24 @@ const isDocumentHeld = () => {
10489
10490
  return false;
10490
10491
  };
10491
10492
 
10493
+ // A return is photographed by its route transition as soon as its page has
10494
+ // rendered, stand-ins and all, and a position waiting for the page to be whole
10495
+ // is written after the movement, seen as a jump. So it is also written into
10496
+ // what is there meanwhile, as far as that goes — the browser clamps the rest —
10497
+ // and again once the page is whole, when what it stands on has grown or shrunk.
10498
+ const putBackMeanwhile = (restoration) => {
10499
+ if (!restoration.meanwhile) {
10500
+ return;
10501
+ }
10502
+ // Out of whatever commit or effect is asking: see scrollTo.
10503
+ queueMicrotask(() => {
10504
+ if (pendingRestoration !== restoration || isDocumentHeld()) {
10505
+ return;
10506
+ }
10507
+ scrollTo(restoration.position);
10508
+ });
10509
+ };
10510
+
10492
10511
  // What a page holds instead: not the place, which stays the url's, but the
10493
10512
  // moment it is put back (see useHoldScrollRestoration). Counted: several parts
10494
10513
  // of one page can be waiting.
@@ -10632,6 +10651,7 @@ const putBackOnceAnswered = (restoration) => {
10632
10651
  });
10633
10652
  return;
10634
10653
  }
10654
+ putBackMeanwhile(restoration);
10635
10655
  // A reader drawing its own wait subscribes in an effect, after the first
10636
10656
  // paint (see afterPaint): an answer that came before is drawn only then.
10637
10657
  let waitCount = 2;
@@ -10755,11 +10775,12 @@ const restoreScrollPosition = (url) => {
10755
10775
  };
10756
10776
 
10757
10777
  // A traversal back to `url`. The offset is written once the page returned to is
10758
- // rendered and answered (see putBackOnceAnswered): written sooner, the document
10759
- // still holds the page being left, or a stand-in for the one arriving, and
10760
- // clamps it to that height. It is read at once all the same — a page left
10761
- // taller than the one arriving is clamped by the render itself, and that clamp
10762
- // is a scroll recorded under the url already returned to.
10778
+ // rendered (see whenPageRendered): written sooner, the document still holds the
10779
+ // page being left and clamps it to that height. Again once it has answered (see
10780
+ // putBackOnceAnswered), when it rendered stand-ins (see putBackMeanwhile). It
10781
+ // is read at once all the same — a page left taller than the one arriving is
10782
+ // clamped by the render itself, and that clamp is a scroll recorded under the
10783
+ // url already returned to.
10763
10784
  const restoreScrollPositionOnReturn = (url) => {
10764
10785
  pendingRestoration = null;
10765
10786
  const href = new URL(url, window.location.href).href;
@@ -10768,7 +10789,7 @@ const restoreScrollPositionOnReturn = (url) => {
10768
10789
  if (!position) {
10769
10790
  return;
10770
10791
  }
10771
- const restoration = startRestoration(position);
10792
+ const restoration = startRestoration(position, { meanwhile: true });
10772
10793
  whenPageRendered(() => {
10773
10794
  putBackOnceAnswered(restoration);
10774
10795
  });
@@ -86715,19 +86736,28 @@ const useListScrollSync = ({
86715
86736
  });
86716
86737
  }, []);
86717
86738
  // What to do when the list's own geometry moves under it, kept fresh for the
86718
- // observer below (which is installed once).
86739
+ // observer below (which is installed once). A held list is placed inside the
86740
+ // resize delivery, so the browser paints it where it lands; answers whether
86741
+ // it was.
86719
86742
  const onGeometryChangeRef = useRef(null);
86720
86743
  onGeometryChangeRef.current = () => {
86721
- settleWindow();
86722
- if (heldSomewhere) {
86723
- placeWhereHeld();
86724
- return true;
86744
+ if (!heldSomewhere) {
86745
+ return false;
86725
86746
  }
86726
- // Items that came in at another size than what stood in for them (a
86727
- // skeleton becoming its item) leave the window short of the screen, or past
86728
- // it, and nothing scrolled to say so.
86747
+ settleWindow();
86748
+ placeWhereHeld();
86749
+ return true;
86750
+ };
86751
+ // Items that came in at another size than what stood in for them (a
86752
+ // skeleton becoming its item) leave the window short of the screen, or past
86753
+ // it, and nothing scrolled to say so. Asked on the next frame, not inside
86754
+ // the resize delivery: the window it frames is a render, which resizes what
86755
+ // is observed once more, and the browser gives up on the loop
86756
+ // ("ResizeObserver loop completed with undelivered notifications").
86757
+ const onItemsResizedRef = useRef(null);
86758
+ onItemsResizedRef.current = () => {
86759
+ settleWindow();
86729
86760
  evaluateWindowRef.current("items resized");
86730
- return false;
86731
86761
  };
86732
86762
  // The box around a held list changing shape is the hold's to answer too: it
86733
86763
  // places the list again, the way it writes every scroll of its own (see
@@ -86876,10 +86906,20 @@ const useListScrollSync = ({
86876
86906
  // which this would undo. The SCROLLER resizing is the window around it
86877
86907
  // changing shape, and then the item that was at the top goes back where it
86878
86908
  // was.
86909
+ let itemsResizedFrame;
86879
86910
  const putTopItemBack = entries => {
86880
86911
  const listResized = entries.some(entry => entry.target === listEl);
86881
- if (listResized && onGeometryChangeRef.current()) {
86882
- return;
86912
+ if (listResized) {
86913
+ if (onGeometryChangeRef.current()) {
86914
+ return;
86915
+ }
86916
+ cancelAnimationFrame(itemsResizedFrame);
86917
+ itemsResizedFrame = requestAnimationFrame(() => {
86918
+ if (pageLeftRef.current) {
86919
+ return;
86920
+ }
86921
+ onItemsResizedRef.current();
86922
+ });
86883
86923
  }
86884
86924
  if (!entries.some(entry => entry.target === scrollerEl)) {
86885
86925
  return;
@@ -86932,6 +86972,7 @@ const useListScrollSync = ({
86932
86972
  observer.observe(listEl);
86933
86973
  return () => {
86934
86974
  observer.disconnect();
86975
+ cancelAnimationFrame(itemsResizedFrame);
86935
86976
  };
86936
86977
  }, [scrollerElResolved]);
86937
86978
 
@@ -87537,7 +87578,7 @@ const useStuckWindowWarning = ({
87537
87578
  // Scrolling nothing, the box keeps out of reach only the items past what
87538
87579
  // it shows. A list standing whole on the window's screen is one the window
87539
87580
  // covers at its next evaluation: an item added in this commit is drawn on
87540
- // the resize it causes (see onGeometryChangeRef), after this effect.
87581
+ // the resize it causes (see onItemsResizedRef), after this effect.
87541
87582
  const listEl = getListEl();
87542
87583
  if (!listEl) {
87543
87584
  return;