@hyperframes/studio 0.7.92 → 0.7.93
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/assets/{hyperframes-player-9qOa08Tv.js → hyperframes-player-NSdcoOcK.js} +1 -1
- package/dist/assets/{index-CDTN2ZVa.js → index-CCGnc_0M.js} +1 -1
- package/dist/assets/index-D78KEjgB.css +1 -0
- package/dist/assets/index-Dp1zVb9X.js +428 -0
- package/dist/assets/{index-Bw4lNdtO.js → index-wS6f7F5q.js} +1 -1
- package/dist/index.d.ts +20 -20
- package/dist/index.html +2 -2
- package/dist/index.js +7055 -5321
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
- package/src/App.tsx +14 -14
- package/src/components/DesignPanelPromoteProvider.tsx +1 -1
- package/src/components/ExternalFileConflictBanner.test.tsx +142 -0
- package/src/components/ExternalFileConflictBanner.tsx +255 -0
- package/src/components/editor/propertyPanel3dTransform.tsx +1 -1
- package/src/components/editor/propertyPanelCommitField.tsx +37 -2
- package/src/components/editor/propertyPanelFlatPrimitives.test.tsx +69 -0
- package/src/components/editor/propertyPanelFlatPrimitives.tsx +2 -2
- package/src/components/editor/propertyPanelPrimitives.tsx +2 -2
- package/src/components/editor/propertyPanelTransformCommit.test.ts +57 -0
- package/src/components/editor/propertyPanelTransformCommit.ts +14 -14
- package/src/components/editor/propertyPanelTypes.ts +9 -3
- package/src/components/editor/useInspectorGestureTransaction.test.tsx +65 -0
- package/src/components/editor/useInspectorGestureTransaction.ts +66 -10
- package/src/components/sidebar/AssetCard.tsx +4 -3
- package/src/components/sidebar/AudioRow.tsx +4 -3
- package/src/contexts/FileManagerContext.tsx +12 -0
- package/src/hooks/externalFileChangeOwnership.test.ts +17 -0
- package/src/hooks/externalFileReloadBus.test.ts +34 -0
- package/src/hooks/externalFileReloadBus.ts +18 -0
- package/src/hooks/gsapDragCommit.test.ts +39 -1
- package/src/hooks/gsapDragCommit.ts +12 -40
- package/src/hooks/gsapEditOutcome.ts +72 -0
- package/src/hooks/gsapResizeIntercept.test.ts +90 -2
- package/src/hooks/gsapResizeIntercept.ts +44 -16
- package/src/hooks/gsapRuntimeBridge.test.ts +195 -27
- package/src/hooks/gsapRuntimeBridge.ts +93 -28
- package/src/hooks/useAnimatedPropertyCommit.test.tsx +194 -24
- package/src/hooks/useAnimatedPropertyCommit.ts +101 -49
- package/src/hooks/useAppHotkeys.textEditing.test.tsx +215 -0
- package/src/hooks/useDomGeometryCommits.test.tsx +61 -0
- package/src/hooks/useDomGeometryCommits.ts +20 -0
- package/src/hooks/useEditorSave.test.tsx +131 -0
- package/src/hooks/useEditorSave.ts +113 -39
- package/src/hooks/useExternalFileChangeCoordinator.test.tsx +221 -0
- package/src/hooks/useExternalFileChangeCoordinator.ts +429 -0
- package/src/hooks/useFileManager.projectOwnership.test.tsx +139 -7
- package/src/hooks/useFileManager.ts +32 -3
- package/src/hooks/useGsapAnimationFetchFallback.ts +45 -24
- package/src/hooks/useGsapAwareEditing.test.tsx +125 -39
- package/src/hooks/useGsapAwareEditing.ts +88 -27
- package/src/hooks/useGsapInteractionFailureTelemetry.test.tsx +42 -0
- package/src/hooks/useGsapInteractionFailureTelemetry.ts +5 -1
- package/src/hooks/usePreviewPersistence.test.ts +23 -0
- package/src/hooks/usePreviewPersistence.ts +22 -58
- package/src/hooks/useSdkSession.ts +8 -52
- package/src/hooks/useStudioExternalFileChanges.ts +81 -0
- package/src/hooks/useStudioSdkSessions.ts +2 -7
- package/src/hooks/useStudioSessionStart.ts +15 -0
- package/src/hooks/useStudioTestHooks.test.tsx +11 -7
- package/src/player/components/LayerDisclosureRow.tsx +2 -0
- package/src/player/components/Timeline.test.ts +24 -5
- package/src/player/components/Timeline.tsx +40 -40
- package/src/player/components/Timeline.virtualization.test.tsx +54 -11
- package/src/player/components/TimelineClip.test.tsx +17 -2
- package/src/player/components/TimelineClip.tsx +15 -3
- package/src/player/components/TimelineClipDiamonds.test.tsx +95 -10
- package/src/player/components/TimelineClipDiamonds.tsx +53 -13
- package/src/player/components/TimelineCompactDiamonds.tsx +84 -0
- package/src/player/components/TimelineDiamondConnectors.tsx +31 -3
- package/src/player/components/TimelineLanes.test.tsx +64 -6
- package/src/player/components/TimelineLanes.tsx +81 -64
- package/src/player/components/TimelinePropertyLanes.test.tsx +9 -5
- package/src/player/components/TimelinePropertyLanes.tsx +9 -2
- package/src/player/components/TimelineTrackHeader.test.tsx +1 -0
- package/src/player/components/TimelineTrackHeader.tsx +16 -0
- package/src/player/components/TimelineTrackRow.tsx +58 -7
- package/src/player/components/timelineDiamondTypes.ts +14 -7
- package/src/player/components/timelineKeyboardNavigation.test.ts +303 -0
- package/src/player/components/timelineKeyboardNavigation.ts +337 -0
- package/src/player/components/timelineLaneProps.ts +3 -0
- package/src/player/components/timelineNavigationIdentity.ts +38 -0
- package/src/player/components/useTimelineClipRenderWindow.ts +4 -35
- package/src/player/components/useTimelineFocusCoordinator.test.tsx +174 -0
- package/src/player/components/useTimelineFocusCoordinator.ts +221 -0
- package/src/player/components/useTimelineKeyboardActor.test.tsx +267 -0
- package/src/player/components/useTimelineKeyboardActor.ts +147 -0
- package/src/player/components/useTimelineLogicalFocus.ts +80 -0
- package/src/player/components/useTimelineLogicalRows.test.tsx +57 -0
- package/src/player/components/useTimelineLogicalRows.ts +47 -0
- package/src/player/components/useTimelineRowVirtualization.ts +16 -26
- package/src/player/store/liveTime.ts +11 -0
- package/src/player/store/playerStore.test.ts +29 -22
- package/src/player/store/playerStore.ts +24 -29
- package/src/player/store/timelineFocusState.ts +15 -0
- package/src/utils/domEditSaveQueue.test.ts +37 -1
- package/src/utils/domEditSaveQueue.ts +22 -4
- package/src/utils/externalConflictStorage.test.ts +95 -0
- package/src/utils/externalConflictStorage.ts +172 -0
- package/src/utils/studioFileVersion.test.ts +28 -1
- package/src/utils/studioFileVersion.ts +30 -0
- package/src/utils/studioPendingEdits.test.ts +108 -1
- package/src/utils/studioPendingEdits.ts +39 -2
- package/src/utils/studioSaveDiagnostics.ts +5 -0
- package/dist/assets/index-BXkzp_OU.css +0 -1
- package/dist/assets/index-DIntkrQl.js +0 -428
- package/src/player/components/useTimelineRevealClip.test.tsx +0 -139
- package/src/player/components/useTimelineRevealClip.ts +0 -180
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// @vitest-environment happy-dom
|
|
2
|
-
|
|
3
|
-
import React, { act, useRef } from "react";
|
|
4
|
-
import { createRoot, type Root } from "react-dom/client";
|
|
5
|
-
import { afterEach, describe, expect, it } from "vitest";
|
|
6
|
-
import type { TimelineElement } from "../store/playerStore";
|
|
7
|
-
import { usePlayerStore } from "../store/playerStore";
|
|
8
|
-
import { createTimelineRowGeometry } from "./timelineLayout";
|
|
9
|
-
import { useTimelineRevealClip } from "./useTimelineRevealClip";
|
|
10
|
-
|
|
11
|
-
Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true });
|
|
12
|
-
|
|
13
|
-
const element: TimelineElement = {
|
|
14
|
-
id: "hero",
|
|
15
|
-
tag: "div",
|
|
16
|
-
start: 20,
|
|
17
|
-
duration: 2,
|
|
18
|
-
track: 1,
|
|
19
|
-
};
|
|
20
|
-
const geometry = createTimelineRowGeometry([1], [48]);
|
|
21
|
-
|
|
22
|
-
function createHarnessRoot() {
|
|
23
|
-
const host = document.createElement("div");
|
|
24
|
-
document.body.append(host);
|
|
25
|
-
return { host, root: createRoot(host) };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface HarnessProps {
|
|
29
|
-
mounted: boolean;
|
|
30
|
-
version: number;
|
|
31
|
-
width?: number;
|
|
32
|
-
height?: number;
|
|
33
|
-
deferFocusUntilViewportUpdate?: boolean;
|
|
34
|
-
focusedElementId?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function Harness({
|
|
38
|
-
mounted,
|
|
39
|
-
version,
|
|
40
|
-
width = 300,
|
|
41
|
-
height = 100,
|
|
42
|
-
deferFocusUntilViewportUpdate = false,
|
|
43
|
-
focusedElementId,
|
|
44
|
-
}: HarnessProps) {
|
|
45
|
-
const scrollRef = useRef<HTMLDivElement>(null);
|
|
46
|
-
useTimelineRevealClip({
|
|
47
|
-
scrollRef,
|
|
48
|
-
elements: [element],
|
|
49
|
-
rowGeometry: geometry,
|
|
50
|
-
pixelsPerSecond: 100,
|
|
51
|
-
contentOrigin: 32,
|
|
52
|
-
allowHorizontal: true,
|
|
53
|
-
deferFocusUntilViewportUpdate,
|
|
54
|
-
focusedElementId,
|
|
55
|
-
viewportVersion: version,
|
|
56
|
-
sessionEpoch: 1,
|
|
57
|
-
});
|
|
58
|
-
return (
|
|
59
|
-
<div
|
|
60
|
-
ref={(node) => {
|
|
61
|
-
scrollRef.current = node;
|
|
62
|
-
if (node) {
|
|
63
|
-
Object.defineProperty(node, "clientWidth", { configurable: true, value: width });
|
|
64
|
-
Object.defineProperty(node, "clientHeight", { configurable: true, value: height });
|
|
65
|
-
}
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
{mounted && <div data-el-id="hero" tabIndex={-1} />}
|
|
69
|
-
</div>
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async function renderHarness(root: Root, props: HarnessProps): Promise<void> {
|
|
74
|
-
await act(async () => root.render(<Harness {...props} />));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
afterEach(() => {
|
|
78
|
-
usePlayerStore.getState().reset();
|
|
79
|
-
document.body.replaceChildren();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe("useTimelineRevealClip", () => {
|
|
83
|
-
it("scrolls from model coordinates, then consumes only after the clip mounts", async () => {
|
|
84
|
-
const { host, root } = createHarnessRoot();
|
|
85
|
-
usePlayerStore.getState().requestClipReveal("hero");
|
|
86
|
-
|
|
87
|
-
await renderHarness(root, { mounted: false, version: 0 });
|
|
88
|
-
const scroll = host.firstElementChild as HTMLDivElement;
|
|
89
|
-
expect(scroll.scrollLeft).toBe(1_944);
|
|
90
|
-
expect(usePlayerStore.getState().clipRevealRequest?.elementId).toBe("hero");
|
|
91
|
-
|
|
92
|
-
await renderHarness(root, { mounted: true, version: 1 });
|
|
93
|
-
expect(usePlayerStore.getState().clipRevealRequest).toBeNull();
|
|
94
|
-
expect(document.activeElement?.getAttribute("data-el-id")).toBe("hero");
|
|
95
|
-
|
|
96
|
-
scroll.scrollLeft = 0;
|
|
97
|
-
await act(async () => usePlayerStore.getState().requestClipReveal("hero"));
|
|
98
|
-
await renderHarness(root, { mounted: true, version: 2 });
|
|
99
|
-
expect(scroll.scrollLeft).toBe(1_944);
|
|
100
|
-
expect(usePlayerStore.getState().clipRevealRequest).toBeNull();
|
|
101
|
-
await act(async () => root.unmount());
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("consumes an invalid target without scrolling", async () => {
|
|
105
|
-
const { root } = createHarnessRoot();
|
|
106
|
-
usePlayerStore.getState().requestClipReveal("missing");
|
|
107
|
-
await renderHarness(root, { mounted: false, version: 0 });
|
|
108
|
-
expect(usePlayerStore.getState().clipRevealRequest).toBeNull();
|
|
109
|
-
await act(async () => root.unmount());
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("keeps a reveal pending through zero-size viewport and virtualized focus handoff", async () => {
|
|
113
|
-
const { host, root } = createHarnessRoot();
|
|
114
|
-
usePlayerStore.getState().requestClipReveal("hero");
|
|
115
|
-
|
|
116
|
-
await renderHarness(root, { mounted: true, version: 0, width: 0, height: 0 });
|
|
117
|
-
const scroll = host.firstElementChild as HTMLDivElement;
|
|
118
|
-
expect(scroll.scrollLeft).toBe(0);
|
|
119
|
-
expect(usePlayerStore.getState().clipRevealRequest?.elementId).toBe("hero");
|
|
120
|
-
expect(document.activeElement?.getAttribute("data-el-id")).not.toBe("hero");
|
|
121
|
-
|
|
122
|
-
await renderHarness(root, {
|
|
123
|
-
mounted: true,
|
|
124
|
-
version: 1,
|
|
125
|
-
deferFocusUntilViewportUpdate: true,
|
|
126
|
-
});
|
|
127
|
-
expect(scroll.scrollLeft).toBe(1_944);
|
|
128
|
-
expect(usePlayerStore.getState().clipRevealRequest?.elementId).toBe("hero");
|
|
129
|
-
await renderHarness(root, {
|
|
130
|
-
mounted: true,
|
|
131
|
-
version: 2,
|
|
132
|
-
deferFocusUntilViewportUpdate: true,
|
|
133
|
-
focusedElementId: "hero",
|
|
134
|
-
});
|
|
135
|
-
expect(usePlayerStore.getState().clipRevealRequest).toBeNull();
|
|
136
|
-
expect(document.activeElement?.getAttribute("data-el-id")).toBe("hero");
|
|
137
|
-
await act(async () => root.unmount());
|
|
138
|
-
});
|
|
139
|
-
});
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react";
|
|
2
|
-
import type { TimelineElement } from "../store/playerStore";
|
|
3
|
-
import { usePlayerStore } from "../store/playerStore";
|
|
4
|
-
import { getTimelineElementIdentity } from "../lib/timelineElementHelpers";
|
|
5
|
-
import { CLIP_Y, RULER_H, type TimelineRowGeometry } from "./timelineLayout";
|
|
6
|
-
import { computeRevealScroll } from "./timelineRevealScroll";
|
|
7
|
-
|
|
8
|
-
interface UseTimelineRevealClipInput {
|
|
9
|
-
scrollRef: React.RefObject<HTMLDivElement | null>;
|
|
10
|
-
elements: readonly TimelineElement[];
|
|
11
|
-
rowGeometry: TimelineRowGeometry;
|
|
12
|
-
pixelsPerSecond: number;
|
|
13
|
-
contentOrigin: number;
|
|
14
|
-
allowHorizontal: boolean;
|
|
15
|
-
deferFocusUntilViewportUpdate: boolean;
|
|
16
|
-
focusedElementId?: string;
|
|
17
|
-
viewportVersion: unknown;
|
|
18
|
-
sessionEpoch: number;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function escapeSelectorValue(value: string): string {
|
|
22
|
-
return typeof CSS !== "undefined" && typeof CSS.escape === "function"
|
|
23
|
-
? CSS.escape(value)
|
|
24
|
-
: value.replace(/["\\]/g, "\\$&");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function scrollToTimelineElement(
|
|
28
|
-
container: HTMLDivElement,
|
|
29
|
-
element: TimelineElement,
|
|
30
|
-
row: number,
|
|
31
|
-
rowGeometry: TimelineRowGeometry,
|
|
32
|
-
pixelsPerSecond: number,
|
|
33
|
-
contentOrigin: number,
|
|
34
|
-
allowHorizontal: boolean,
|
|
35
|
-
): boolean {
|
|
36
|
-
const clipLeft = contentOrigin + element.start * pixelsPerSecond;
|
|
37
|
-
const target = computeRevealScroll({
|
|
38
|
-
scrollLeft: container.scrollLeft,
|
|
39
|
-
scrollTop: container.scrollTop,
|
|
40
|
-
viewportWidth: container.clientWidth,
|
|
41
|
-
viewportHeight: container.clientHeight,
|
|
42
|
-
clipLeft,
|
|
43
|
-
clipRight: clipLeft + Math.max(element.duration * pixelsPerSecond, 4),
|
|
44
|
-
clipTop: rowGeometry.getRowTop(row) + CLIP_Y,
|
|
45
|
-
clipBottom: rowGeometry.getRowTop(row) + rowGeometry.getRowHeight(row) - CLIP_Y,
|
|
46
|
-
stickyLeft: contentOrigin,
|
|
47
|
-
stickyTop: RULER_H,
|
|
48
|
-
allowHorizontal,
|
|
49
|
-
});
|
|
50
|
-
if (target.left !== null) container.scrollLeft = target.left;
|
|
51
|
-
if (target.top !== null) container.scrollTop = target.top;
|
|
52
|
-
const didScroll = target.left !== null || target.top !== null;
|
|
53
|
-
if (didScroll) container.dispatchEvent(new Event("scroll"));
|
|
54
|
-
return didScroll;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function focusRevealedElement(container: HTMLDivElement, elementId: string): boolean {
|
|
58
|
-
const clip = container.querySelector(`[data-el-id="${escapeSelectorValue(elementId)}"]`);
|
|
59
|
-
if (!(clip instanceof HTMLElement)) return false;
|
|
60
|
-
const alreadyHighlighted = clip.hasAttribute("data-reveal-highlight");
|
|
61
|
-
clip.setAttribute("data-reveal-highlight", "true");
|
|
62
|
-
clip.focus({ preventScroll: true });
|
|
63
|
-
if (document.activeElement !== clip) {
|
|
64
|
-
clip.removeAttribute("data-reveal-highlight");
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
if (!alreadyHighlighted) {
|
|
68
|
-
clip.addEventListener("blur", () => clip.removeAttribute("data-reveal-highlight"), {
|
|
69
|
-
once: true,
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function focusAndConsumeReveal(
|
|
76
|
-
container: HTMLDivElement,
|
|
77
|
-
request: { elementId: string; nonce: number },
|
|
78
|
-
deferUntilFocusPin: boolean,
|
|
79
|
-
focusedElementId?: string,
|
|
80
|
-
): void {
|
|
81
|
-
if (!focusRevealedElement(container, request.elementId)) return;
|
|
82
|
-
if (deferUntilFocusPin && focusedElementId !== request.elementId) return;
|
|
83
|
-
if (usePlayerStore.getState().clipRevealRequest === request) {
|
|
84
|
-
usePlayerStore.getState().clearClipRevealRequest();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function resolveRevealTarget(
|
|
89
|
-
elements: readonly TimelineElement[],
|
|
90
|
-
rowGeometry: TimelineRowGeometry,
|
|
91
|
-
elementId: string,
|
|
92
|
-
): { element: TimelineElement; row: number } | null {
|
|
93
|
-
const element = elements.find((candidate) => getTimelineElementIdentity(candidate) === elementId);
|
|
94
|
-
if (!element) return null;
|
|
95
|
-
const row = rowGeometry.getRowIndex(element.track);
|
|
96
|
-
return row < 0 ? null : { element, row };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function shouldScrollReveal(
|
|
100
|
-
previous: { request: { elementId: string; nonce: number }; sessionEpoch: number } | null,
|
|
101
|
-
request: { elementId: string; nonce: number },
|
|
102
|
-
sessionEpoch: number,
|
|
103
|
-
): boolean {
|
|
104
|
-
return previous?.request !== request || previous.sessionEpoch !== sessionEpoch;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Coordinate-first reveal; the request remains pinned until its clip mounts. */
|
|
108
|
-
export function useTimelineRevealClip({
|
|
109
|
-
scrollRef,
|
|
110
|
-
elements,
|
|
111
|
-
rowGeometry,
|
|
112
|
-
pixelsPerSecond,
|
|
113
|
-
contentOrigin,
|
|
114
|
-
allowHorizontal,
|
|
115
|
-
deferFocusUntilViewportUpdate,
|
|
116
|
-
focusedElementId,
|
|
117
|
-
viewportVersion,
|
|
118
|
-
sessionEpoch,
|
|
119
|
-
}: UseTimelineRevealClipInput): void {
|
|
120
|
-
const revealRequest = usePlayerStore((state) => state.clipRevealRequest);
|
|
121
|
-
const scrolledRequestRef = useRef<{
|
|
122
|
-
request: { elementId: string; nonce: number };
|
|
123
|
-
sessionEpoch: number;
|
|
124
|
-
} | null>(null);
|
|
125
|
-
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
if (!revealRequest) {
|
|
128
|
-
scrolledRequestRef.current = null;
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
const target = resolveRevealTarget(elements, rowGeometry, revealRequest.elementId);
|
|
132
|
-
if (!target) {
|
|
133
|
-
usePlayerStore.getState().clearClipRevealRequest();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const container = scrollRef.current;
|
|
137
|
-
if (!container) return;
|
|
138
|
-
if (container.clientWidth <= 0 || container.clientHeight <= 0) return;
|
|
139
|
-
|
|
140
|
-
if (shouldScrollReveal(scrolledRequestRef.current, revealRequest, sessionEpoch)) {
|
|
141
|
-
scrolledRequestRef.current = { request: revealRequest, sessionEpoch };
|
|
142
|
-
const didScroll = scrollToTimelineElement(
|
|
143
|
-
container,
|
|
144
|
-
target.element,
|
|
145
|
-
target.row,
|
|
146
|
-
rowGeometry,
|
|
147
|
-
pixelsPerSecond,
|
|
148
|
-
contentOrigin,
|
|
149
|
-
allowHorizontal,
|
|
150
|
-
);
|
|
151
|
-
// Keep the reveal pin alive until the scroll snapshot catches up. If the
|
|
152
|
-
// request were consumed here, horizontal windowing could unmount and
|
|
153
|
-
// recreate the focused clip between the programmatic scroll and the next
|
|
154
|
-
// viewport publication.
|
|
155
|
-
if (didScroll && deferFocusUntilViewportUpdate) return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Focus is the durable row/clip pin. Do not consume the reveal pin until
|
|
159
|
-
// the focus listener has published that replacement, or windowing can
|
|
160
|
-
// briefly unmount and recreate the element between the two owners.
|
|
161
|
-
focusAndConsumeReveal(
|
|
162
|
-
container,
|
|
163
|
-
revealRequest,
|
|
164
|
-
deferFocusUntilViewportUpdate,
|
|
165
|
-
focusedElementId,
|
|
166
|
-
);
|
|
167
|
-
}, [
|
|
168
|
-
allowHorizontal,
|
|
169
|
-
contentOrigin,
|
|
170
|
-
deferFocusUntilViewportUpdate,
|
|
171
|
-
elements,
|
|
172
|
-
focusedElementId,
|
|
173
|
-
pixelsPerSecond,
|
|
174
|
-
revealRequest,
|
|
175
|
-
rowGeometry,
|
|
176
|
-
scrollRef,
|
|
177
|
-
sessionEpoch,
|
|
178
|
-
viewportVersion,
|
|
179
|
-
]);
|
|
180
|
-
}
|