@jsenv/navi 0.29.413 → 0.29.414
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.
- package/dist/dev/jsenv_navi.js +379 -290
- package/dist/dev/jsenv_navi.js.map +10 -8
- package/dist/jsenv_navi.js +379 -290
- package/dist/jsenv_navi.js.map +10 -8
- package/docs/AI_INSTRUCTIONS.md +10 -5
- package/docs/route_transitions.md +90 -1
- package/docs/view_transitions.md +61 -0
- package/package.json +2 -2
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -6,8 +6,8 @@ import { installImportMetaCssBuild, coarsePointerSignal, windowHeightSignal, win
|
|
|
6
6
|
import { createPubSub, elementIsFocusable, createIterableWeakSet, dispatchInternalCustomEvent, dispatchCustomEvent, createEventGroupLogger, findEvent, mergeOneStyle, findFocusable, getElementSignature, chainEvent, isTouchDrivenEvent, getKeyboardEventDefaultAction, isPressDrivenClick, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, createValueEffect, findFocusDelegateTarget, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, getScrollContainerSet, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, keepTouchRefusable, waitForTap, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, dragSourceThatStoodDown, markDragSource, refuseDragTo, startDragTo, installPanZoom, createInternalCustomEvent, activeElementSignal, normalizeStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, getScrollContainer, watchWheelTravel, scrollRoomTowards, trapScrollInside, scrollIntoViewScoped, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, initFocusGroup, stringifyStyle as stringifyStyle$1, isScrollable, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, getVirtualKeyboardOverlayHeight, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, setVirtualKeyboardOverlaysContent, subscribeVirtualKeyboardGeometryChange } from "@jsenv/dom";
|
|
7
7
|
export { chainEvent, clickIsSuppressed, contrastColor, createDragGestureController, dragAfterIntent, findEvent, markDragSource, startDragTo } from "@jsenv/dom";
|
|
8
8
|
import { signal, computed, effect, untracked, batch, useComputed, useSignal } from "@preact/signals";
|
|
9
|
-
import { options, isValidElement, createContext, render, h, toChildArray, cloneElement, createElement, Fragment as Fragment$1 } from "preact";
|
|
10
|
-
import { useErrorBoundary, useLayoutEffect, useContext, useMemo, useRef, useEffect, useCallback, useState, useId } from "preact/hooks";
|
|
9
|
+
import { options, isValidElement, createContext, render, h, toChildArray, createRef, cloneElement, createElement, Fragment as Fragment$1 } from "preact";
|
|
10
|
+
import { useErrorBoundary, useLayoutEffect, useContext, useMemo, useRef, useEffect, useCallback, useState, useReducer, useId } from "preact/hooks";
|
|
11
11
|
import { humanizeI18n, prefixFirstAndIndentRemainingLines, setRuntimeLangSource, formatDuration, formatMonth, formatDay, resolveTimeRangePrecision, formatDatePlaceholder, toDate, getRelativeDay, formatDayRelative, formatMonthPlaceholder, formatWeekPlaceholder, formatDatetimePlaceholder, formatDatetime, toTimeOfDay, formatTimeOfDay, formatTime, formatMinuteDuration, formatSecondDuration, formatHourDuration, formatTimeRelative, formatNumber, interpolateText, installInterpolateJsx } from "@jsenv/humanize";
|
|
12
12
|
export { createI18n, formatDatetime, formatDay, formatDayRelative, formatDuration, formatHourDuration, formatMinuteDuration, formatMonth, formatNumber, formatSecondDuration, formatTime, formatTimeOfDay, formatTimeRange, formatTimeRelative, interpolateText } from "@jsenv/humanize";
|
|
13
13
|
import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
|
|
@@ -79,7 +79,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
79
79
|
* any of these, and a number is the last resort, not the first tool.
|
|
80
80
|
*/
|
|
81
81
|
|
|
82
|
-
const css$
|
|
82
|
+
const css$18 = /* css */ `@layer navi {
|
|
83
83
|
:root {
|
|
84
84
|
--navi-z-index-control-hovered: 1;
|
|
85
85
|
--navi-z-index-control-focused: 2;
|
|
@@ -92,7 +92,7 @@ const css$17 = /* css */ `@layer navi {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
`;
|
|
95
|
-
import.meta.css = [css$
|
|
95
|
+
import.meta.css = [css$18, "@jsenv/navi/src/navi_z_indexes.js"];
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* A navigation is ABOUT to be applied — said before its very first write.
|
|
@@ -457,7 +457,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
457
457
|
|
|
458
458
|
const URL_TARGET_ATTRIBUTE = "data-url-target";
|
|
459
459
|
|
|
460
|
-
const css$
|
|
460
|
+
const css$17 = /* css */ `@layer navi {
|
|
461
461
|
[data-url-target] {
|
|
462
462
|
animation: navi_url_target var(--navi-url-target-duration, 2s)
|
|
463
463
|
ease-out;
|
|
@@ -475,7 +475,7 @@ const css$16 = /* css */ `@layer navi {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
`;
|
|
478
|
-
import.meta.css = [css$
|
|
478
|
+
import.meta.css = [css$17, "@jsenv/navi/src/nav/url_target/url_target.js"];
|
|
479
479
|
|
|
480
480
|
let urlTargetOptions = {
|
|
481
481
|
block: "start",
|
|
@@ -2080,7 +2080,7 @@ const useActionStatus = (action) => {
|
|
|
2080
2080
|
};
|
|
2081
2081
|
|
|
2082
2082
|
installImportMetaCssBuild(import.meta);
|
|
2083
|
-
const css$
|
|
2083
|
+
const css$16 = /* css */`.action_error {
|
|
2084
2084
|
background: #fdd;
|
|
2085
2085
|
border: 1px solid red;
|
|
2086
2086
|
margin-top: 0;
|
|
@@ -2104,7 +2104,7 @@ const ActionRenderer = ({
|
|
|
2104
2104
|
children,
|
|
2105
2105
|
disabled
|
|
2106
2106
|
}) => {
|
|
2107
|
-
import.meta.css = [css$
|
|
2107
|
+
import.meta.css = [css$16, "@jsenv/navi/src/action/action_renderer.jsx"];
|
|
2108
2108
|
if (action === undefined) {
|
|
2109
2109
|
throw new Error("ActionRenderer requires an action to render, but none was provided.");
|
|
2110
2110
|
}
|
|
@@ -15941,7 +15941,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
15941
15941
|
* (see calloutTemplate in callout.js).
|
|
15942
15942
|
*/
|
|
15943
15943
|
|
|
15944
|
-
const css$
|
|
15944
|
+
const css$15 = /* css */`.navi_callout_status_icon {
|
|
15945
15945
|
--x-callout-status-icon-color: var(--navi-callout-neutral-color);
|
|
15946
15946
|
box-sizing: border-box;
|
|
15947
15947
|
aspect-ratio: 1;
|
|
@@ -16012,7 +16012,7 @@ const CalloutStatusIcon = ({
|
|
|
16012
16012
|
status = "info",
|
|
16013
16013
|
shape = "square"
|
|
16014
16014
|
}) => {
|
|
16015
|
-
import.meta.css = [css$
|
|
16015
|
+
import.meta.css = [css$15, "@jsenv/navi/src/control/rules/callout/callout_status_icon.jsx"];
|
|
16016
16016
|
return jsx("span", {
|
|
16017
16017
|
className: "navi_callout_status_icon",
|
|
16018
16018
|
"data-status": status === "none" ? undefined : status,
|
|
@@ -16039,7 +16039,7 @@ let calloutCount = 0;
|
|
|
16039
16039
|
// large enough to survive the pixel or two a trackpad rests on.
|
|
16040
16040
|
const CLOSE_BY_SCROLL_DISTANCE = 10;
|
|
16041
16041
|
|
|
16042
|
-
const css$
|
|
16042
|
+
const css$14 = /* css */ `
|
|
16043
16043
|
/* jsenv-css-opaque: same as dialog.jsx, cascade order. */
|
|
16044
16044
|
@layer navi {
|
|
16045
16045
|
.navi_callout {
|
|
@@ -16400,7 +16400,7 @@ const openCallout = (
|
|
|
16400
16400
|
debug = () => {},
|
|
16401
16401
|
} = {},
|
|
16402
16402
|
) => {
|
|
16403
|
-
import.meta.css = [css$
|
|
16403
|
+
import.meta.css = [css$14, "@jsenv/navi/src/control/rules/callout/callout.js"];
|
|
16404
16404
|
if (debug === true) {
|
|
16405
16405
|
debug = (e, ...args) => console.debug(`"${e.type}" -> `, ...args);
|
|
16406
16406
|
}
|
|
@@ -21532,7 +21532,9 @@ const swipeTypeOf = (axis, pulled) => {
|
|
|
21532
21532
|
* meantime, nothing is picked up. The carry is the element's own, outcomes and
|
|
21533
21533
|
* refusal included, without the wait for intent (the hold was the proof), and
|
|
21534
21534
|
* the copy is brought to the finger rather than following it from wherever the
|
|
21535
|
-
* element stands.
|
|
21535
|
+
* element stands. Let go of there before it has travelled — the hold only meant
|
|
21536
|
+
* to open the popup — it goes back and nothing is answered, whatever it was
|
|
21537
|
+
* brought over. A copy or nothing: `move` and `moving` carry the thing itself,
|
|
21536
21538
|
* which would leave its place just for being handed a press. When it starts is
|
|
21537
21539
|
* navi's — after a popup still being lifted (see `--navi-grab` in commands.js).
|
|
21538
21540
|
*
|
|
@@ -31796,6 +31798,12 @@ const useUrlSearchParam = (paramName, defaultValue) => {
|
|
|
31796
31798
|
return [value, setSearchParamValue];
|
|
31797
31799
|
};
|
|
31798
31800
|
|
|
31801
|
+
// The title belongs to the last Head to arrive, whatever order they leave in:
|
|
31802
|
+
// the page being left by a route transition is taken down AFTER the page
|
|
31803
|
+
// arriving is up (see keepLeavingPages in route.jsx), and putting back the
|
|
31804
|
+
// title it found would put its own page's title over the new one.
|
|
31805
|
+
const titleEntries = [];
|
|
31806
|
+
let titleWithoutHead = null;
|
|
31799
31807
|
const Head = ({
|
|
31800
31808
|
children
|
|
31801
31809
|
}) => {
|
|
@@ -31804,15 +31812,17 @@ const Head = ({
|
|
|
31804
31812
|
return undefined;
|
|
31805
31813
|
}
|
|
31806
31814
|
const childArray = Array.isArray(children) ? children : [children];
|
|
31807
|
-
const previousTitle = document.title;
|
|
31808
31815
|
const appendedElements = [];
|
|
31816
|
+
let titleEntry = null;
|
|
31809
31817
|
for (const child of childArray) {
|
|
31810
31818
|
if (!child) {
|
|
31811
31819
|
continue;
|
|
31812
31820
|
}
|
|
31813
31821
|
if (child.type === "title") {
|
|
31814
31822
|
const titleChildren = child.props.children;
|
|
31815
|
-
|
|
31823
|
+
titleEntry = {
|
|
31824
|
+
title: Array.isArray(titleChildren) ? titleChildren.join("") : titleChildren ?? ""
|
|
31825
|
+
};
|
|
31816
31826
|
continue;
|
|
31817
31827
|
}
|
|
31818
31828
|
const el = document.createElement(child.type);
|
|
@@ -31823,8 +31833,19 @@ const Head = ({
|
|
|
31823
31833
|
document.head.appendChild(el);
|
|
31824
31834
|
appendedElements.push(el);
|
|
31825
31835
|
}
|
|
31836
|
+
if (titleEntry) {
|
|
31837
|
+
if (titleEntries.length === 0) {
|
|
31838
|
+
titleWithoutHead = document.title;
|
|
31839
|
+
}
|
|
31840
|
+
titleEntries.push(titleEntry);
|
|
31841
|
+
document.title = titleEntry.title;
|
|
31842
|
+
}
|
|
31826
31843
|
return () => {
|
|
31827
|
-
|
|
31844
|
+
if (titleEntry) {
|
|
31845
|
+
titleEntries.splice(titleEntries.indexOf(titleEntry), 1);
|
|
31846
|
+
const lastEntry = titleEntries[titleEntries.length - 1];
|
|
31847
|
+
document.title = lastEntry ? lastEntry.title : titleWithoutHead;
|
|
31848
|
+
}
|
|
31828
31849
|
for (const el of appendedElements) {
|
|
31829
31850
|
el.remove();
|
|
31830
31851
|
}
|
|
@@ -31987,75 +32008,7 @@ const samePages = (pages, otherPages) => {
|
|
|
31987
32008
|
return true;
|
|
31988
32009
|
};
|
|
31989
32010
|
|
|
31990
|
-
|
|
31991
|
-
* Route is the single primitive for URL-based rendering.
|
|
31992
|
-
*
|
|
31993
|
-
* ## Layout pattern
|
|
31994
|
-
* Use this when multiple routes share a common layout but have no shared URL prefix,
|
|
31995
|
-
* making it impossible to set a guard route on the parent container.
|
|
31996
|
-
* For example, `/profile` and `/settings` both live inside `AuthLayout` but there
|
|
31997
|
-
* is no `/auth/` prefix to match on. A container Route wraps them: the active
|
|
31998
|
-
* child's element is injected as `children` into the layout element.
|
|
31999
|
-
* If a page needs state owned by the layout, the layout must expose it via context.
|
|
32000
|
-
*
|
|
32001
|
-
* ```jsx
|
|
32002
|
-
* const PROFILE_ROUTE = route("/profile");
|
|
32003
|
-
* const SETTINGS_ROUTE = route("/settings");
|
|
32004
|
-
*
|
|
32005
|
-
* <Route element={AuthLayout}>
|
|
32006
|
-
* <Route route={PROFILE_ROUTE} element={ProfilePage} />
|
|
32007
|
-
* <Route route={SETTINGS_ROUTE} element={SettingsPage} />
|
|
32008
|
-
* </Route>
|
|
32009
|
-
* ```
|
|
32010
|
-
*
|
|
32011
|
-
* Such a container holds no fallback, and cannot: what makes this one the right
|
|
32012
|
-
* layout is a child matching, and having no prefix is the very reason it was
|
|
32013
|
-
* reached for — so there is no address that belongs to it and to none of its
|
|
32014
|
-
* children. An address nothing claims is the router's to answer; write the
|
|
32015
|
-
* fallback there.
|
|
32016
|
-
*
|
|
32017
|
-
* ## Self-contained section pattern
|
|
32018
|
-
* Use this when routes share a common URL prefix (e.g. `/dashboard/`).
|
|
32019
|
-
* A single leaf Route in the top-level router matches the prefix; the component
|
|
32020
|
-
* it renders owns its sub-router and all related routes internally.
|
|
32021
|
-
* Everything about the section — routes, structure, sub-pages — is co-located.
|
|
32022
|
-
* The component is not a reusable layout; it is the section.
|
|
32023
|
-
*
|
|
32024
|
-
* Compared to the layout pattern, a dedicated section component is more powerful:
|
|
32025
|
-
* - Wrapper elements (chrome, nav, containers) are part of the component's render,
|
|
32026
|
-
* not injected via `children`, so a layout is not needed.
|
|
32027
|
-
* - Local state can be passed directly via `elementProps` to sub-pages. With the
|
|
32028
|
-
* layout pattern, sub-pages receive state only through `children` or context.
|
|
32029
|
-
*
|
|
32030
|
-
* The layout pattern remains necessary when a shared prefix does not exist
|
|
32031
|
-
* (see "Layout pattern" above).
|
|
32032
|
-
*
|
|
32033
|
-
* ```jsx
|
|
32034
|
-
* const DASHBOARD_SECTION_ROUTE = route("/dashboard/");
|
|
32035
|
-
* const DASHBOARD_HOME_ROUTE = route("/dashboard");
|
|
32036
|
-
* const DASHBOARD_POSTS_ROUTE = route("/dashboard/posts");
|
|
32037
|
-
*
|
|
32038
|
-
* // top-level router — only knows about the prefix
|
|
32039
|
-
* <Route route={DASHBOARD_SECTION_ROUTE} element={DashboardSection} />
|
|
32040
|
-
*
|
|
32041
|
-
* // Dashboard owns the rest
|
|
32042
|
-
* const DashboardSection = () => {
|
|
32043
|
-
* const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
32044
|
-
*
|
|
32045
|
-
* return <div
|
|
32046
|
-
* style="background: lightblue; padding: 10px;"
|
|
32047
|
-
* onClick={() => setSidebarOpen(o => !o)}
|
|
32048
|
-
* >
|
|
32049
|
-
* <Route>
|
|
32050
|
-
* <Route route={DASHBOARD_HOME_ROUTE} element={DashboardHomePage} elementProps={{ sidebarOpen}} />
|
|
32051
|
-
* <Route route={DASHBOARD_POSTS_ROUTE} element={DashboardPostsPage} elementProps={{ sidebarOpen }} />
|
|
32052
|
-
* <Route fallback element={DashboardNotFound} />
|
|
32053
|
-
* </Route>
|
|
32054
|
-
* </div>;
|
|
32055
|
-
* }
|
|
32056
|
-
* ```
|
|
32057
|
-
*/
|
|
32058
|
-
|
|
32011
|
+
installImportMetaCssBuild(import.meta);
|
|
32059
32012
|
|
|
32060
32013
|
/**
|
|
32061
32014
|
* Keep every container showing the page it is showing, whatever the routes say.
|
|
@@ -32079,6 +32032,56 @@ const freezeRouteRender = () => {
|
|
|
32079
32032
|
routeRenderFrozenSignal.value++;
|
|
32080
32033
|
};
|
|
32081
32034
|
};
|
|
32035
|
+
|
|
32036
|
+
/**
|
|
32037
|
+
* Keep the page a container leaves, hidden, until its route transition is over.
|
|
32038
|
+
*
|
|
32039
|
+
* The browser photographs the page being left before the change, and the page
|
|
32040
|
+
* arriving inside the transition's update callback — where everything done
|
|
32041
|
+
* delays the movement. Taking the page being left down is most of that: every
|
|
32042
|
+
* hook of every component in it is cleaned up, and a page of thirty cards
|
|
32043
|
+
* takes longer to take down than the page arriving takes to build. Its picture
|
|
32044
|
+
* is already taken, so it only has to stay out of the second one: a container
|
|
32045
|
+
* that changes page while this is held keeps the page it was showing, hidden,
|
|
32046
|
+
* and drops it once the movement is over (see route_transition.jsx).
|
|
32047
|
+
*
|
|
32048
|
+
* Kept only where Preact would have unmounted it: a page rendered by the same
|
|
32049
|
+
* element on both sides is the same component instance carried over, exactly
|
|
32050
|
+
* as without a movement.
|
|
32051
|
+
*/
|
|
32052
|
+
let leavingPagesHold = null;
|
|
32053
|
+
const keepLeavingPages = () => {
|
|
32054
|
+
const hold = {
|
|
32055
|
+
released: false,
|
|
32056
|
+
containers: new Set()
|
|
32057
|
+
};
|
|
32058
|
+
leavingPagesHold = hold;
|
|
32059
|
+
return () => {
|
|
32060
|
+
if (hold.released) {
|
|
32061
|
+
return;
|
|
32062
|
+
}
|
|
32063
|
+
hold.released = true;
|
|
32064
|
+
if (leavingPagesHold === hold) {
|
|
32065
|
+
leavingPagesHold = null;
|
|
32066
|
+
}
|
|
32067
|
+
for (const rerender of hold.containers) {
|
|
32068
|
+
rerender();
|
|
32069
|
+
}
|
|
32070
|
+
hold.containers.clear();
|
|
32071
|
+
};
|
|
32072
|
+
};
|
|
32073
|
+
|
|
32074
|
+
// What a page can learn about its place from the container rendering it:
|
|
32075
|
+
// whether it is a page kept while leaving (see keepLeavingPages). Such a page
|
|
32076
|
+
// is still mounted, and whatever it fills OUTSIDE its own nodes — a slot in a
|
|
32077
|
+
// bar, say — would otherwise go on showing with the page arriving (see
|
|
32078
|
+
// layout/slot.jsx).
|
|
32079
|
+
const RoutePageContext = createContext(null);
|
|
32080
|
+
const LEAVING_ATTRIBUTE = "data-navi-route-leaving";
|
|
32081
|
+
const css$13 = /* css */`[data-navi-route-leaving] {
|
|
32082
|
+
display: none !important;
|
|
32083
|
+
}
|
|
32084
|
+
`;
|
|
32082
32085
|
const debug$1 = (...args) => {
|
|
32083
32086
|
{
|
|
32084
32087
|
return;
|
|
@@ -32198,6 +32201,7 @@ const RouteContainer = ({
|
|
|
32198
32201
|
shownBranchRef.current = activeBranch;
|
|
32199
32202
|
}
|
|
32200
32203
|
const branch = shownBranchRef.current || activeBranch;
|
|
32204
|
+
const content = useContentKeepingLeavingPages(branch);
|
|
32201
32205
|
|
|
32202
32206
|
// The two things this component knows that nobody outside can find out: the
|
|
32203
32207
|
// pages a named fallback is the absence of — the children it was written
|
|
@@ -32219,7 +32223,6 @@ const RouteContainer = ({
|
|
|
32219
32223
|
};
|
|
32220
32224
|
}, [fallbackPage]);
|
|
32221
32225
|
debug$1(`[container "${id}"] RENDER, active=${branch ? branch.type : "none"}`);
|
|
32222
|
-
const content = branch ? branch.node : null;
|
|
32223
32226
|
if (!content) {
|
|
32224
32227
|
return null;
|
|
32225
32228
|
}
|
|
@@ -32228,12 +32231,141 @@ const RouteContainer = ({
|
|
|
32228
32231
|
}
|
|
32229
32232
|
return content;
|
|
32230
32233
|
};
|
|
32234
|
+
// What a container renders: the page it shows and, while a route transition
|
|
32235
|
+
// keeps them (see keepLeavingPages), the pages it has left — each the very
|
|
32236
|
+
// vnode rendered last time, which Preact does not look into, between two
|
|
32237
|
+
// markers that say which nodes to hide. Always an array, even of one page: the
|
|
32238
|
+
// page being left must stay the child it was when a page is added beside it,
|
|
32239
|
+
// or Preact takes it down and builds it again.
|
|
32240
|
+
let leavingKeyCount = 0;
|
|
32241
|
+
const useContentKeepingLeavingPages = branch => {
|
|
32242
|
+
const [, rerender] = useReducer(countRenders, 0);
|
|
32243
|
+
const shownRef = useRef(null);
|
|
32244
|
+
const leavingRef = useRef([]);
|
|
32245
|
+
const shown = shownRef.current;
|
|
32246
|
+
const element = branchElement(branch);
|
|
32247
|
+
let key;
|
|
32248
|
+
let page = null;
|
|
32249
|
+
if (shown && branch && (shown.id === branch.id || shown.element === element)) {
|
|
32250
|
+
// The same page, or one Preact carries over from it: the key it was
|
|
32251
|
+
// mounted with, or it would be mounted again.
|
|
32252
|
+
key = shown.key;
|
|
32253
|
+
page = shown.page;
|
|
32254
|
+
} else if (shown && leavingPagesHold) {
|
|
32255
|
+
leavingRef.current.push({
|
|
32256
|
+
vnode: shown.vnode,
|
|
32257
|
+
page: shown.page,
|
|
32258
|
+
key: `navi-route-leaving-${++leavingKeyCount}`,
|
|
32259
|
+
hold: leavingPagesHold,
|
|
32260
|
+
startRef: createRef(),
|
|
32261
|
+
endRef: createRef(),
|
|
32262
|
+
hidden: false
|
|
32263
|
+
});
|
|
32264
|
+
leavingPagesHold.containers.add(rerender);
|
|
32265
|
+
// Keyed apart from the page it takes the place of, which is still there.
|
|
32266
|
+
key = `navi-route-${++leavingKeyCount}`;
|
|
32267
|
+
}
|
|
32268
|
+
let vnode = null;
|
|
32269
|
+
if (branch) {
|
|
32270
|
+
if (!page) {
|
|
32271
|
+
page = {
|
|
32272
|
+
leavingSignal: signal(false)
|
|
32273
|
+
};
|
|
32274
|
+
}
|
|
32275
|
+
vnode = h(RoutePageContext.Provider, {
|
|
32276
|
+
key,
|
|
32277
|
+
value: page
|
|
32278
|
+
}, branch.node);
|
|
32279
|
+
}
|
|
32280
|
+
shownRef.current = branch ? {
|
|
32281
|
+
id: branch.id,
|
|
32282
|
+
element,
|
|
32283
|
+
key,
|
|
32284
|
+
vnode,
|
|
32285
|
+
page
|
|
32286
|
+
} : null;
|
|
32287
|
+
const leaving = leavingRef.current.filter(entry => !entry.hold.released);
|
|
32288
|
+
leavingRef.current = leaving;
|
|
32289
|
+
|
|
32290
|
+
// Hidden as soon as it is in the DOM next to the page arriving: this runs in
|
|
32291
|
+
// the update callback's render, before the second picture is taken.
|
|
32292
|
+
useLayoutEffect(() => {
|
|
32293
|
+
for (const entry of leavingRef.current) {
|
|
32294
|
+
const start = entry.startRef.current;
|
|
32295
|
+
const end = entry.endRef.current;
|
|
32296
|
+
if (entry.hidden || !start || !end) {
|
|
32297
|
+
continue;
|
|
32298
|
+
}
|
|
32299
|
+
entry.hidden = true;
|
|
32300
|
+
entry.page.leavingSignal.value = true;
|
|
32301
|
+
let node = start.nextSibling;
|
|
32302
|
+
while (node && node !== end) {
|
|
32303
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
32304
|
+
node.setAttribute(LEAVING_ATTRIBUTE, "");
|
|
32305
|
+
}
|
|
32306
|
+
node = node.nextSibling;
|
|
32307
|
+
}
|
|
32308
|
+
}
|
|
32309
|
+
});
|
|
32310
|
+
useLayoutEffect(() => {
|
|
32311
|
+
return () => {
|
|
32312
|
+
for (const entry of leavingRef.current) {
|
|
32313
|
+
entry.hold.containers.delete(rerender);
|
|
32314
|
+
}
|
|
32315
|
+
};
|
|
32316
|
+
}, []);
|
|
32317
|
+
if (leaving.length === 0) {
|
|
32318
|
+
return vnode ? [vnode] : null;
|
|
32319
|
+
}
|
|
32320
|
+
import.meta.css = [css$13, "@jsenv/navi/src/nav/route.jsx"];
|
|
32321
|
+
const children = vnode ? [vnode] : [];
|
|
32322
|
+
for (const entry of leaving) {
|
|
32323
|
+
children.push(h("template", {
|
|
32324
|
+
key: `${entry.key}-start`,
|
|
32325
|
+
ref: entry.startRef
|
|
32326
|
+
}), entry.vnode, h("template", {
|
|
32327
|
+
key: `${entry.key}-end`,
|
|
32328
|
+
ref: entry.endRef
|
|
32329
|
+
}));
|
|
32330
|
+
}
|
|
32331
|
+
return children;
|
|
32332
|
+
};
|
|
32333
|
+
const countRenders = count => count + 1;
|
|
32334
|
+
// What Preact compares when a container changes page, below the <Route> it
|
|
32335
|
+
// renders either way: the element the page is rendered with — a layout, for a
|
|
32336
|
+
// container branch.
|
|
32337
|
+
const branchElement = branch => {
|
|
32338
|
+
if (!branch) {
|
|
32339
|
+
return null;
|
|
32340
|
+
}
|
|
32341
|
+
let node = branch.node;
|
|
32342
|
+
while (node && node.type !== Route) {
|
|
32343
|
+
// A wrapper around the branch (see wrapBranch).
|
|
32344
|
+
node = node.props.children;
|
|
32345
|
+
}
|
|
32346
|
+
if (!node) {
|
|
32347
|
+
return null;
|
|
32348
|
+
}
|
|
32349
|
+
const {
|
|
32350
|
+
element
|
|
32351
|
+
} = node.props;
|
|
32352
|
+
if (element === undefined || typeof element === "function") {
|
|
32353
|
+
return element;
|
|
32354
|
+
}
|
|
32355
|
+
return element.type;
|
|
32356
|
+
};
|
|
32357
|
+
|
|
32231
32358
|
// Walk JSX children vnodes (without rendering) to build a branch list and
|
|
32232
32359
|
// find the active one in the same pass. Anything that is not a <Route> is read
|
|
32233
32360
|
// through and kept around the branch it holds (see below).
|
|
32234
32361
|
// Returns { matchingBranch, fallbackBranch, activeBranch, pages }.
|
|
32235
|
-
|
|
32362
|
+
//
|
|
32363
|
+
// Each branch is given an id from where it is written among the children,
|
|
32364
|
+
// which is what tells a container it changed page: the vnodes themselves are
|
|
32365
|
+
// new at every render of the parent.
|
|
32366
|
+
const collectBranches = (children, path = "") => {
|
|
32236
32367
|
let matchingBranch = null;
|
|
32368
|
+
let childIndex = 0;
|
|
32237
32369
|
let fallbackBranch = null;
|
|
32238
32370
|
// Every page a branch can be on, at any depth: what a named fallback is the
|
|
32239
32371
|
// ABSENCE of (see route_fallback.js). A container with a guard route counts
|
|
@@ -32251,6 +32383,7 @@ const collectBranches = children => {
|
|
|
32251
32383
|
}
|
|
32252
32384
|
return;
|
|
32253
32385
|
}
|
|
32386
|
+
const id = `${path}${childIndex++}`;
|
|
32254
32387
|
if (child.type !== Route) {
|
|
32255
32388
|
// Anything else is a wrapper around branches, and the two that matter are
|
|
32256
32389
|
// navi's own: a page says what it renders and delegates what it cannot —
|
|
@@ -32270,7 +32403,7 @@ const collectBranches = children => {
|
|
|
32270
32403
|
matchingBranch: matchingInside,
|
|
32271
32404
|
fallbackBranch: fallbackInside,
|
|
32272
32405
|
pages: pagesInside
|
|
32273
|
-
} = collectBranches(wrapperChildren);
|
|
32406
|
+
} = collectBranches(wrapperChildren, `${id}.`);
|
|
32274
32407
|
for (const pageInside of pagesInside) {
|
|
32275
32408
|
pages.push(pageInside);
|
|
32276
32409
|
}
|
|
@@ -32293,7 +32426,7 @@ const collectBranches = children => {
|
|
|
32293
32426
|
matchingBranch: matchingChild,
|
|
32294
32427
|
fallbackBranch: fallbackChild,
|
|
32295
32428
|
pages: pagesChild
|
|
32296
|
-
} = collectBranches(nodeChildren);
|
|
32429
|
+
} = collectBranches(nodeChildren, `${id}.`);
|
|
32297
32430
|
if (fallbackChild && !route) {
|
|
32298
32431
|
// A fallback is the branch taken for an address none of its siblings
|
|
32299
32432
|
// claim — so something has to make that address BELONG to this
|
|
@@ -32317,6 +32450,7 @@ const collectBranches = children => {
|
|
|
32317
32450
|
}
|
|
32318
32451
|
const branch = {
|
|
32319
32452
|
type: "container",
|
|
32453
|
+
id,
|
|
32320
32454
|
node: child
|
|
32321
32455
|
};
|
|
32322
32456
|
const guardMatching = route ? route.matchingSignal.value : false;
|
|
@@ -32334,6 +32468,7 @@ const collectBranches = children => {
|
|
|
32334
32468
|
if (!fallbackBranch) {
|
|
32335
32469
|
fallbackBranch = {
|
|
32336
32470
|
type: "fallback",
|
|
32471
|
+
id,
|
|
32337
32472
|
node: child,
|
|
32338
32473
|
page: fallback.isRouteFallback ? fallback : null
|
|
32339
32474
|
};
|
|
@@ -32341,6 +32476,7 @@ const collectBranches = children => {
|
|
|
32341
32476
|
} else {
|
|
32342
32477
|
const branch = {
|
|
32343
32478
|
type: "leaf",
|
|
32479
|
+
id,
|
|
32344
32480
|
node: child
|
|
32345
32481
|
};
|
|
32346
32482
|
pages.push({
|
|
@@ -32828,7 +32964,7 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
32828
32964
|
}
|
|
32829
32965
|
const namesLeaving = [];
|
|
32830
32966
|
for (const element of namedElements) {
|
|
32831
|
-
if (!element
|
|
32967
|
+
if (!isRendered(element)) {
|
|
32832
32968
|
namesLeaving.push(nameByElement.get(element));
|
|
32833
32969
|
} else if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
32834
32970
|
element.setAttribute(FURNITURE_ATTRIBUTE, "shared");
|
|
@@ -32947,11 +33083,16 @@ const travelRule = (side, names, movementProperty) => {
|
|
|
32947
33083
|
* The pictures are up and about to move: what no picture covers heads to the
|
|
32948
33084
|
* state arriving, on the same clock.
|
|
32949
33085
|
*/
|
|
32950
|
-
const startTransitionFurniture = (owner) => {
|
|
33086
|
+
const startTransitionFurniture = (owner, { duration } = {}) => {
|
|
32951
33087
|
if (owner !== furnitureOwner) {
|
|
32952
33088
|
return;
|
|
32953
33089
|
}
|
|
32954
33090
|
for (const restWall of restWallElements) {
|
|
33091
|
+
// A duration of the movement's own is written for its pictures alone (see
|
|
33092
|
+
// transition_values.js); the stand-in is an element, and is told.
|
|
33093
|
+
if (duration !== undefined) {
|
|
33094
|
+
restWall.style.setProperty("--navi-route-transition-duration", duration);
|
|
33095
|
+
}
|
|
32955
33096
|
restWall.style.opacity = restWallOpacity;
|
|
32956
33097
|
}
|
|
32957
33098
|
};
|
|
@@ -32982,7 +33123,9 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
32982
33123
|
// area's stand-in answers for it.
|
|
32983
33124
|
const paintTransitionWalls = (areaElement) => {
|
|
32984
33125
|
removeTransitionWalls();
|
|
32985
|
-
const sources =
|
|
33126
|
+
const sources = Array.from(
|
|
33127
|
+
document.querySelectorAll(TOP_LAYER_WALL_SELECTOR),
|
|
33128
|
+
).filter(isRendered);
|
|
32986
33129
|
if (sources.length === 0) {
|
|
32987
33130
|
return sources;
|
|
32988
33131
|
}
|
|
@@ -33184,6 +33327,14 @@ const subtractRect = (rect, hole) => {
|
|
|
33184
33327
|
return pieces;
|
|
33185
33328
|
};
|
|
33186
33329
|
|
|
33330
|
+
// Out of the state arriving: taken out of the document, or in a page kept
|
|
33331
|
+
// hidden until its movement is over (see keepLeavingPages in route.jsx) —
|
|
33332
|
+
// where a dialog is still :modal and a popover still :popover-open, and
|
|
33333
|
+
// neither is painted or photographed.
|
|
33334
|
+
const isRendered = (element) => {
|
|
33335
|
+
return element.isConnected && element.checkVisibility();
|
|
33336
|
+
};
|
|
33337
|
+
|
|
33187
33338
|
const removeRestWalls = () => {
|
|
33188
33339
|
for (const restWall of restWallElements) {
|
|
33189
33340
|
restWall.remove();
|
|
@@ -33193,6 +33344,52 @@ const removeRestWalls = () => {
|
|
|
33193
33344
|
leavingRects = new Map();
|
|
33194
33345
|
};
|
|
33195
33346
|
|
|
33347
|
+
/**
|
|
33348
|
+
* The values a movement hands to its pictures, written where only the pictures
|
|
33349
|
+
* read them: on ::view-transition, the root of the pseudo-element tree, rather
|
|
33350
|
+
* than on the document's root.
|
|
33351
|
+
*
|
|
33352
|
+
* A custom property written on :root is inherited by every element of the
|
|
33353
|
+
* document, and writing one restyles all of them. A movement writes its
|
|
33354
|
+
* numbers as its pages are held, again whenever a scroll moves the window, and
|
|
33355
|
+
* takes them off as it ends — each time a whole-document restyle of a page that
|
|
33356
|
+
* can be thousands of elements long. On ::view-transition they reach every
|
|
33357
|
+
* picture by plain inheritance, and no element at all.
|
|
33358
|
+
*
|
|
33359
|
+
* An inline style cannot target a pseudo-element, so they are declarations of
|
|
33360
|
+
* one rule, in a sheet of their own. Written only: what a pseudo-element that
|
|
33361
|
+
* is not on screen computes is not reliably readable, so nothing reads them
|
|
33362
|
+
* back from there.
|
|
33363
|
+
*/
|
|
33364
|
+
|
|
33365
|
+
let valuesStyle = null;
|
|
33366
|
+
const getValuesStyle = () => {
|
|
33367
|
+
if (valuesStyle) {
|
|
33368
|
+
return valuesStyle;
|
|
33369
|
+
}
|
|
33370
|
+
const sheet = new CSSStyleSheet();
|
|
33371
|
+
sheet.replaceSync(":root::view-transition {}");
|
|
33372
|
+
const [rule] = sheet.cssRules;
|
|
33373
|
+
if (rule) {
|
|
33374
|
+
document.adoptedStyleSheets.push(sheet);
|
|
33375
|
+
valuesStyle = rule.style;
|
|
33376
|
+
} else {
|
|
33377
|
+
// A browser without view transitions drops the rule: the movement runs its
|
|
33378
|
+
// steps all the same (see start_view_transition_polyfill.js), with no
|
|
33379
|
+
// pictures to hand anything to.
|
|
33380
|
+
valuesStyle = document.createElement("div").style;
|
|
33381
|
+
}
|
|
33382
|
+
return valuesStyle;
|
|
33383
|
+
};
|
|
33384
|
+
|
|
33385
|
+
const setTransitionValue = (name, value) => {
|
|
33386
|
+
getValuesStyle().setProperty(name, value);
|
|
33387
|
+
};
|
|
33388
|
+
|
|
33389
|
+
const removeTransitionValue = (name) => {
|
|
33390
|
+
getValuesStyle().removeProperty(name);
|
|
33391
|
+
};
|
|
33392
|
+
|
|
33196
33393
|
installImportMetaCssBuild(import.meta);
|
|
33197
33394
|
|
|
33198
33395
|
const TRANSITION_WINDOW_CSS = /* css */ `@property --navi-transition-cover-top {
|
|
@@ -33227,96 +33424,6 @@ const TRANSITION_WINDOW_CSS = /* css */ `@property --navi-transition-cover-top {
|
|
|
33227
33424
|
--navi-transition-cover-left: 0px;
|
|
33228
33425
|
}
|
|
33229
33426
|
}
|
|
33230
|
-
|
|
33231
|
-
@property --navi-transition-window-top {
|
|
33232
|
-
syntax: "*";
|
|
33233
|
-
inherits: false
|
|
33234
|
-
}
|
|
33235
|
-
|
|
33236
|
-
@property --navi-transition-window-left {
|
|
33237
|
-
syntax: "*";
|
|
33238
|
-
inherits: false
|
|
33239
|
-
}
|
|
33240
|
-
|
|
33241
|
-
@property --navi-transition-window-width {
|
|
33242
|
-
syntax: "*";
|
|
33243
|
-
inherits: false
|
|
33244
|
-
}
|
|
33245
|
-
|
|
33246
|
-
@property --navi-transition-window-height {
|
|
33247
|
-
syntax: "*";
|
|
33248
|
-
inherits: false
|
|
33249
|
-
}
|
|
33250
|
-
|
|
33251
|
-
@property --navi-transition-window-old-top {
|
|
33252
|
-
syntax: "*";
|
|
33253
|
-
inherits: false
|
|
33254
|
-
}
|
|
33255
|
-
|
|
33256
|
-
@property --navi-transition-window-old-left {
|
|
33257
|
-
syntax: "*";
|
|
33258
|
-
inherits: false
|
|
33259
|
-
}
|
|
33260
|
-
|
|
33261
|
-
@property --navi-transition-window-new-top {
|
|
33262
|
-
syntax: "*";
|
|
33263
|
-
inherits: false
|
|
33264
|
-
}
|
|
33265
|
-
|
|
33266
|
-
@property --navi-transition-window-new-left {
|
|
33267
|
-
syntax: "*";
|
|
33268
|
-
inherits: false
|
|
33269
|
-
}
|
|
33270
|
-
|
|
33271
|
-
@property --navi-transition-old-band-top {
|
|
33272
|
-
syntax: "*";
|
|
33273
|
-
inherits: false
|
|
33274
|
-
}
|
|
33275
|
-
|
|
33276
|
-
@property --navi-transition-old-band-right {
|
|
33277
|
-
syntax: "*";
|
|
33278
|
-
inherits: false
|
|
33279
|
-
}
|
|
33280
|
-
|
|
33281
|
-
@property --navi-transition-old-band-bottom {
|
|
33282
|
-
syntax: "*";
|
|
33283
|
-
inherits: false
|
|
33284
|
-
}
|
|
33285
|
-
|
|
33286
|
-
@property --navi-transition-old-band-left {
|
|
33287
|
-
syntax: "*";
|
|
33288
|
-
inherits: false
|
|
33289
|
-
}
|
|
33290
|
-
|
|
33291
|
-
:root::view-transition, :root::view-transition-group(*), :root::view-transition-image-pair(*), :root::view-transition-old(*), :root::view-transition-new(*) {
|
|
33292
|
-
--navi-transition-window-top: inherit;
|
|
33293
|
-
--navi-transition-window-left: inherit;
|
|
33294
|
-
--navi-transition-window-width: inherit;
|
|
33295
|
-
--navi-transition-window-height: inherit;
|
|
33296
|
-
--navi-transition-window-old-top: inherit;
|
|
33297
|
-
--navi-transition-window-old-left: inherit;
|
|
33298
|
-
--navi-transition-window-new-top: inherit;
|
|
33299
|
-
--navi-transition-window-new-left: inherit;
|
|
33300
|
-
--navi-transition-old-band-top: inherit;
|
|
33301
|
-
--navi-transition-old-band-right: inherit;
|
|
33302
|
-
--navi-transition-old-band-bottom: inherit;
|
|
33303
|
-
--navi-transition-old-band-left: inherit;
|
|
33304
|
-
}
|
|
33305
|
-
|
|
33306
|
-
:root::view-transition-group-children(*) {
|
|
33307
|
-
--navi-transition-window-top: inherit;
|
|
33308
|
-
--navi-transition-window-left: inherit;
|
|
33309
|
-
--navi-transition-window-width: inherit;
|
|
33310
|
-
--navi-transition-window-height: inherit;
|
|
33311
|
-
--navi-transition-window-old-top: inherit;
|
|
33312
|
-
--navi-transition-window-old-left: inherit;
|
|
33313
|
-
--navi-transition-window-new-top: inherit;
|
|
33314
|
-
--navi-transition-window-new-left: inherit;
|
|
33315
|
-
--navi-transition-old-band-top: inherit;
|
|
33316
|
-
--navi-transition-old-band-right: inherit;
|
|
33317
|
-
--navi-transition-old-band-bottom: inherit;
|
|
33318
|
-
--navi-transition-old-band-left: inherit;
|
|
33319
|
-
}
|
|
33320
33427
|
`;
|
|
33321
33428
|
|
|
33322
33429
|
// Called by whatever needs the window — a render, a movement declared or
|
|
@@ -33414,22 +33521,21 @@ const holdTransitionWindow = (
|
|
|
33414
33521
|
const right =
|
|
33415
33522
|
rectBefore.right > rectAfter.right ? rectBefore.right : rectAfter.right;
|
|
33416
33523
|
windowOwner = owner;
|
|
33417
|
-
|
|
33418
|
-
|
|
33419
|
-
|
|
33420
|
-
|
|
33421
|
-
|
|
33422
|
-
|
|
33423
|
-
|
|
33424
|
-
|
|
33425
|
-
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${rectAfter.left}px`);
|
|
33524
|
+
setTransitionValue(WINDOW_TOP_PROPERTY, `${top}px`);
|
|
33525
|
+
setTransitionValue(WINDOW_LEFT_PROPERTY, `${left}px`);
|
|
33526
|
+
setTransitionValue(WINDOW_WIDTH_PROPERTY, `${right - left}px`);
|
|
33527
|
+
setTransitionValue(WINDOW_HEIGHT_PROPERTY, `${bottom - top}px`);
|
|
33528
|
+
setTransitionValue(WINDOW_OLD_TOP_PROPERTY, `${rectBefore.top}px`);
|
|
33529
|
+
setTransitionValue(WINDOW_OLD_LEFT_PROPERTY, `${rectBefore.left}px`);
|
|
33530
|
+
setTransitionValue(WINDOW_NEW_TOP_PROPERTY, `${rectAfter.top}px`);
|
|
33531
|
+
setTransitionValue(WINDOW_NEW_LEFT_PROPERTY, `${rectAfter.left}px`);
|
|
33426
33532
|
const oldBand = furnitureLive
|
|
33427
33533
|
? bandTheCutMayBeRelaxedTo(bandBefore, bandAfter, rectAfter)
|
|
33428
33534
|
: bandBefore;
|
|
33429
|
-
|
|
33430
|
-
|
|
33431
|
-
|
|
33432
|
-
|
|
33535
|
+
setTransitionValue(OLD_BAND_TOP_PROPERTY, `${oldBand.top}px`);
|
|
33536
|
+
setTransitionValue(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
|
|
33537
|
+
setTransitionValue(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
|
|
33538
|
+
setTransitionValue(OLD_BAND_LEFT_PROPERTY, `${oldBand.left}px`);
|
|
33433
33539
|
followArrivingState(element, rectAfter, {
|
|
33434
33540
|
outerScroll,
|
|
33435
33541
|
windowTop: top,
|
|
@@ -33451,9 +33557,8 @@ const releaseTransitionWindow = (owner) => {
|
|
|
33451
33557
|
if (unfollowArrivingState) {
|
|
33452
33558
|
unfollowArrivingState();
|
|
33453
33559
|
}
|
|
33454
|
-
const { style } = document.documentElement;
|
|
33455
33560
|
for (const property of WINDOW_PROPERTIES) {
|
|
33456
|
-
|
|
33561
|
+
removeTransitionValue(property);
|
|
33457
33562
|
}
|
|
33458
33563
|
};
|
|
33459
33564
|
|
|
@@ -33462,12 +33567,11 @@ const releaseTransitionWindow = (owner) => {
|
|
|
33462
33567
|
// file) — and with it the offset outside the box, which carries the window
|
|
33463
33568
|
// and the corner of the state being left along. Requested, never awaited: the
|
|
33464
33569
|
// first call runs inside the update callback, where a frame cannot come.
|
|
33465
|
-
// Written only when it moved: every write restyles the
|
|
33570
|
+
// Written only when it moved: every write restyles the pictures.
|
|
33466
33571
|
const followArrivingState = (element, rectAtHold, heldAt) => {
|
|
33467
33572
|
if (unfollowArrivingState) {
|
|
33468
33573
|
unfollowArrivingState();
|
|
33469
33574
|
}
|
|
33470
|
-
const { style } = document.documentElement;
|
|
33471
33575
|
let top = rectAtHold.top;
|
|
33472
33576
|
let left = rectAtHold.left;
|
|
33473
33577
|
let outerTop = heldAt.outerScroll.top;
|
|
@@ -33476,24 +33580,27 @@ const followArrivingState = (element, rectAtHold, heldAt) => {
|
|
|
33476
33580
|
const rect = element.getBoundingClientRect();
|
|
33477
33581
|
if (rect.top !== top) {
|
|
33478
33582
|
top = rect.top;
|
|
33479
|
-
|
|
33583
|
+
setTransitionValue(WINDOW_NEW_TOP_PROPERTY, `${top}px`);
|
|
33480
33584
|
}
|
|
33481
33585
|
if (rect.left !== left) {
|
|
33482
33586
|
left = rect.left;
|
|
33483
|
-
|
|
33587
|
+
setTransitionValue(WINDOW_NEW_LEFT_PROPERTY, `${left}px`);
|
|
33484
33588
|
}
|
|
33485
33589
|
const outerScroll = readOuterScroll(element);
|
|
33486
33590
|
if (outerScroll.top !== outerTop) {
|
|
33487
33591
|
outerTop = outerScroll.top;
|
|
33488
33592
|
const shift = heldAt.outerScroll.top - outerTop;
|
|
33489
|
-
|
|
33490
|
-
|
|
33593
|
+
setTransitionValue(WINDOW_TOP_PROPERTY, `${heldAt.windowTop + shift}px`);
|
|
33594
|
+
setTransitionValue(WINDOW_OLD_TOP_PROPERTY, `${heldAt.oldTop + shift}px`);
|
|
33491
33595
|
}
|
|
33492
33596
|
if (outerScroll.left !== outerLeft) {
|
|
33493
33597
|
outerLeft = outerScroll.left;
|
|
33494
33598
|
const shift = heldAt.outerScroll.left - outerLeft;
|
|
33495
|
-
|
|
33496
|
-
|
|
33599
|
+
setTransitionValue(
|
|
33600
|
+
WINDOW_LEFT_PROPERTY,
|
|
33601
|
+
`${heldAt.windowLeft + shift}px`,
|
|
33602
|
+
);
|
|
33603
|
+
setTransitionValue(
|
|
33497
33604
|
WINDOW_OLD_LEFT_PROPERTY,
|
|
33498
33605
|
`${heldAt.oldLeft + shift}px`,
|
|
33499
33606
|
);
|
|
@@ -33856,58 +33963,9 @@ const css$12 = /* css */`@property --navi-route-transition-leave {
|
|
|
33856
33963
|
inherits: false
|
|
33857
33964
|
}
|
|
33858
33965
|
|
|
33859
|
-
@property --navi-route-transition-clip-top {
|
|
33860
|
-
syntax: "*";
|
|
33861
|
-
inherits: false
|
|
33862
|
-
}
|
|
33863
|
-
|
|
33864
|
-
@property --navi-route-transition-clip-right {
|
|
33865
|
-
syntax: "*";
|
|
33866
|
-
inherits: false
|
|
33867
|
-
}
|
|
33868
|
-
|
|
33869
|
-
@property --navi-route-transition-clip-bottom {
|
|
33870
|
-
syntax: "*";
|
|
33871
|
-
inherits: false
|
|
33872
|
-
}
|
|
33873
|
-
|
|
33874
|
-
@property --navi-route-transition-clip-left {
|
|
33875
|
-
syntax: "*";
|
|
33876
|
-
inherits: false
|
|
33877
|
-
}
|
|
33878
|
-
|
|
33879
|
-
@property --navi-route-transition-travel-x {
|
|
33880
|
-
syntax: "*";
|
|
33881
|
-
inherits: false
|
|
33882
|
-
}
|
|
33883
|
-
|
|
33884
|
-
@property --navi-route-transition-travel-y {
|
|
33885
|
-
syntax: "*";
|
|
33886
|
-
inherits: false
|
|
33887
|
-
}
|
|
33888
|
-
|
|
33889
33966
|
:root::view-transition, :root::view-transition-group(*), :root::view-transition-image-pair(*), :root::view-transition-old(*), :root::view-transition-new(*) {
|
|
33890
33967
|
--navi-route-transition-leave: inherit;
|
|
33891
33968
|
--navi-route-transition-enter: inherit;
|
|
33892
|
-
--navi-route-transition-covered: inherit;
|
|
33893
|
-
--navi-route-transition-clip-top: inherit;
|
|
33894
|
-
--navi-route-transition-clip-right: inherit;
|
|
33895
|
-
--navi-route-transition-clip-bottom: inherit;
|
|
33896
|
-
--navi-route-transition-clip-left: inherit;
|
|
33897
|
-
--navi-route-transition-travel-x: inherit;
|
|
33898
|
-
--navi-route-transition-travel-y: inherit;
|
|
33899
|
-
}
|
|
33900
|
-
|
|
33901
|
-
:root::view-transition-group-children(*) {
|
|
33902
|
-
--navi-route-transition-leave: inherit;
|
|
33903
|
-
--navi-route-transition-enter: inherit;
|
|
33904
|
-
--navi-route-transition-covered: inherit;
|
|
33905
|
-
--navi-route-transition-clip-top: inherit;
|
|
33906
|
-
--navi-route-transition-clip-right: inherit;
|
|
33907
|
-
--navi-route-transition-clip-bottom: inherit;
|
|
33908
|
-
--navi-route-transition-clip-left: inherit;
|
|
33909
|
-
--navi-route-transition-travel-x: inherit;
|
|
33910
|
-
--navi-route-transition-travel-y: inherit;
|
|
33911
33969
|
}
|
|
33912
33970
|
|
|
33913
33971
|
:root[data-navi-route-transition] [data-navi-route-transition-area] {
|
|
@@ -33928,28 +33986,32 @@ const css$12 = /* css */`@property --navi-route-transition-leave {
|
|
|
33928
33986
|
|
|
33929
33987
|
&[data-navi-route-transition-target="area"] {
|
|
33930
33988
|
view-transition-name: none;
|
|
33931
|
-
|
|
33932
|
-
|
|
33933
|
-
|
|
33934
|
-
|
|
33935
|
-
|
|
33936
|
-
|
|
33937
|
-
|
|
33938
|
-
|
|
33939
|
-
|
|
33940
|
-
|
|
33941
|
-
|
|
33942
|
-
var(--navi-transition-
|
|
33943
|
-
|
|
33944
|
-
|
|
33945
|
-
|
|
33946
|
-
|
|
33947
|
-
|
|
33948
|
-
|
|
33949
|
-
var(--navi-transition-
|
|
33950
|
-
|
|
33951
|
-
|
|
33952
|
-
|
|
33989
|
+
|
|
33990
|
+
&::view-transition {
|
|
33991
|
+
--navi-route-transition-clip-top: max(0px,
|
|
33992
|
+
min(var(--navi-safe-area-inset-top) + var(--navi-transition-cover-top),
|
|
33993
|
+
var(--navi-transition-old-band-top)) - var(--navi-transition-window-top));
|
|
33994
|
+
--navi-route-transition-clip-left: max(0px,
|
|
33995
|
+
min(var(--navi-safe-area-inset-left) +
|
|
33996
|
+
var(--navi-transition-cover-left),
|
|
33997
|
+
var(--navi-transition-old-band-left)) - var(--navi-transition-window-left));
|
|
33998
|
+
--navi-route-transition-clip-bottom: max(0px,
|
|
33999
|
+
var(--navi-transition-window-top) +
|
|
34000
|
+
var(--navi-transition-window-height) +
|
|
34001
|
+
min(var(--navi-safe-area-inset-bottom) +
|
|
34002
|
+
var(--navi-transition-cover-bottom),
|
|
34003
|
+
var(--navi-transition-old-band-bottom)) -
|
|
34004
|
+
100dvh);
|
|
34005
|
+
--navi-route-transition-clip-right: max(0px,
|
|
34006
|
+
var(--navi-transition-window-left) +
|
|
34007
|
+
var(--navi-transition-window-width) +
|
|
34008
|
+
min(var(--navi-safe-area-inset-right) +
|
|
34009
|
+
var(--navi-transition-cover-right),
|
|
34010
|
+
var(--navi-transition-old-band-right)) -
|
|
34011
|
+
100dvw);
|
|
34012
|
+
--navi-route-transition-travel-x: calc(var(--navi-transition-window-width) - var(--navi-route-transition-clip-left) - var(--navi-route-transition-clip-right));
|
|
34013
|
+
--navi-route-transition-travel-y: calc(var(--navi-transition-window-height) - var(--navi-route-transition-clip-top) - var(--navi-route-transition-clip-bottom));
|
|
34014
|
+
}
|
|
33953
34015
|
|
|
33954
34016
|
&::view-transition-group(*) {
|
|
33955
34017
|
z-index: 0;
|
|
@@ -34977,7 +35039,9 @@ const beginTransition = ({
|
|
|
34977
35039
|
decision: navigationDecision,
|
|
34978
35040
|
walkHome: null,
|
|
34979
35041
|
releaseReverting: null,
|
|
34980
|
-
|
|
35042
|
+
duration: undefined,
|
|
35043
|
+
restoreDuration: null,
|
|
35044
|
+
releaseLeavingPages: null
|
|
34981
35045
|
};
|
|
34982
35046
|
// The document wears one transition at a time, and the one this interrupts
|
|
34983
35047
|
// ends only after this one has begun — too late to take off what it wears
|
|
@@ -35030,18 +35094,13 @@ const beginTransition = ({
|
|
|
35030
35094
|
if (areaElement) {
|
|
35031
35095
|
documentElement.setAttribute(TRANSITION_TARGET_ATTRIBUTE, "area");
|
|
35032
35096
|
}
|
|
35033
|
-
// A duration of this relation's own, worn
|
|
35034
|
-
//
|
|
35035
|
-
// erased.
|
|
35097
|
+
// A duration of this relation's own, worn by the pictures for the length of
|
|
35098
|
+
// the transition, over whatever the application says on the root.
|
|
35036
35099
|
if (duration !== undefined) {
|
|
35037
|
-
|
|
35038
|
-
|
|
35100
|
+
transition.duration = typeof duration === "number" ? `${duration}ms` : duration;
|
|
35101
|
+
setTransitionValue(TRANSITION_DURATION_PROPERTY, transition.duration);
|
|
35039
35102
|
transition.restoreDuration = () => {
|
|
35040
|
-
|
|
35041
|
-
documentElement.style.setProperty(TRANSITION_DURATION_PROPERTY, durationBefore);
|
|
35042
|
-
} else {
|
|
35043
|
-
documentElement.style.removeProperty(TRANSITION_DURATION_PROPERTY);
|
|
35044
|
-
}
|
|
35103
|
+
removeTransitionValue(TRANSITION_DURATION_PROPERTY);
|
|
35045
35104
|
};
|
|
35046
35105
|
}
|
|
35047
35106
|
const releaseRendering = takeoverRoutingRenderingHold();
|
|
@@ -35054,7 +35113,9 @@ const beginTransition = ({
|
|
|
35054
35113
|
// the only place the silent misconfigurations show. They are all about the
|
|
35055
35114
|
// same thing — a movement playing on pictures that are not the pages.
|
|
35056
35115
|
const viewTransitionReady = () => {
|
|
35057
|
-
startTransitionFurniture(transition
|
|
35116
|
+
startTransitionFurniture(transition, {
|
|
35117
|
+
duration: transition.duration
|
|
35118
|
+
});
|
|
35058
35119
|
const capturedNames = capturedViewTransitionNames();
|
|
35059
35120
|
if (areaElements.length > 0) {
|
|
35060
35121
|
if (!capturedNames.has(AREA_NAME)) {
|
|
@@ -35080,6 +35141,10 @@ const beginTransition = ({
|
|
|
35080
35141
|
// is awaited here must be able to resolve without a frame: the document
|
|
35081
35142
|
// is frozen for the whole of this callback.
|
|
35082
35143
|
try {
|
|
35144
|
+
// The page being left is photographed already: it only has to stay out
|
|
35145
|
+
// of the second picture, not be taken down before it (see
|
|
35146
|
+
// keepLeavingPages in route.jsx).
|
|
35147
|
+
transition.releaseLeavingPages = keepLeavingPages();
|
|
35083
35148
|
// Releasing flushes the held render synchronously, so a route that
|
|
35084
35149
|
// rendered has already resolved the wait by the next line.
|
|
35085
35150
|
releaseRendering();
|
|
@@ -35132,6 +35197,11 @@ const beginTransition = ({
|
|
|
35132
35197
|
// must not strip what that one is wearing.
|
|
35133
35198
|
renderWait.stop();
|
|
35134
35199
|
releaseRendering();
|
|
35200
|
+
// Taken down once nobody sees it any more.
|
|
35201
|
+
if (transition.releaseLeavingPages) {
|
|
35202
|
+
transition.releaseLeavingPages();
|
|
35203
|
+
transition.releaseLeavingPages = null;
|
|
35204
|
+
}
|
|
35135
35205
|
// The hold a way back took, when it is still standing: the pictures were
|
|
35136
35206
|
// turned round a second time and played out, or something else took the
|
|
35137
35207
|
// document over mid-walk. A hold nobody gives back freezes the page.
|
|
@@ -92004,8 +92074,7 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
92004
92074
|
};
|
|
92005
92075
|
const SlotFill = props => {
|
|
92006
92076
|
const fillerRef = useRef();
|
|
92007
|
-
|
|
92008
|
-
slotPropsSignal.value = props;
|
|
92077
|
+
const routePage = useContext(RoutePageContext);
|
|
92009
92078
|
useLayoutEffect(() => {
|
|
92010
92079
|
return () => {
|
|
92011
92080
|
// Within one diff preact mounts the newcomer before unmounting the
|
|
@@ -92018,6 +92087,26 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
92018
92087
|
slotPropsSignal.value = null;
|
|
92019
92088
|
};
|
|
92020
92089
|
}, []);
|
|
92090
|
+
// In a page kept while leaving: out of the slot as if unmounted, since
|
|
92091
|
+
// the page arriving is what the slot must show — or nothing, when it
|
|
92092
|
+
// fills none.
|
|
92093
|
+
if (routePage && routePage.leavingSignal.value) {
|
|
92094
|
+
if (filler === fillerRef) {
|
|
92095
|
+
filler = null;
|
|
92096
|
+
slotPropsSignal.value = null;
|
|
92097
|
+
}
|
|
92098
|
+
return null;
|
|
92099
|
+
}
|
|
92100
|
+
if (!fillerRef.current) {
|
|
92101
|
+
fillerRef.current = true;
|
|
92102
|
+
filler = fillerRef;
|
|
92103
|
+
}
|
|
92104
|
+
if (filler === null) {
|
|
92105
|
+
filler = fillerRef;
|
|
92106
|
+
}
|
|
92107
|
+
if (filler === fillerRef) {
|
|
92108
|
+
slotPropsSignal.value = props;
|
|
92109
|
+
}
|
|
92021
92110
|
return null;
|
|
92022
92111
|
};
|
|
92023
92112
|
return [Slot, SlotFill];
|