Download packages/app/src/pages/session/timeline/observe-element-offset.test.ts from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 6.13 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/src/pages/session/timeline/observe-element-offset.test.ts
- Command line
-
hf download hf://SaylorTwift/opencode/packages/app/src/pages/session/timeline/observe-element-offset.test.ts
-
curl -L -o observe-element-offset.test.ts https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/src/pages/session/timeline/observe-element-offset.test.ts
6.13 kB
| import { expect, test } from "bun:test" | |
| import { type Virtualizer } from "@tanstack/solid-virtual" | |
| import { mutationNodesContainElement, observeElementOffsetReconnectAware } from "./observe-element-offset" | |
| test("matches only the scroll element or an ancestor containing it", () => { | |
| const route = document.createElement("section") | |
| const viewport = document.createElement("div") | |
| const child = document.createElement("div") | |
| const sibling = document.createElement("div") | |
| route.append(viewport) | |
| viewport.append(child) | |
| expect(mutationNodesContainElement([viewport], viewport)).toBe(true) | |
| expect(mutationNodesContainElement([route], viewport)).toBe(true) | |
| expect(mutationNodesContainElement([child, sibling], viewport)).toBe(false) | |
| }) | |
| test("reports a divergent native offset once and ignores equal offsets and unrelated mutations", async () => { | |
| const route = document.createElement("section") | |
| const viewport = document.createElement("div") | |
| const unrelated = document.createElement("div") | |
| route.append(viewport) | |
| document.body.append(route) | |
| const instance = { | |
| scrollElement: viewport, | |
| targetWindow: window, | |
| scrollOffset: 79_400, | |
| options: { | |
| horizontal: false, | |
| isRtl: false, | |
| isScrollingResetDelay: 0, | |
| useScrollendEvent: false, | |
| }, | |
| } as unknown as Virtualizer<HTMLDivElement, HTMLDivElement> | |
| const calls: [number, boolean][] = [] | |
| const cleanup = observeElementOffsetReconnectAware(instance, (offset, isScrolling) => { | |
| calls.push([offset, isScrolling]) | |
| instance.scrollOffset = offset | |
| }) | |
| document.body.append(unrelated) | |
| unrelated.remove() | |
| await frames(2) | |
| expect(calls).toEqual([]) | |
| route.remove() | |
| document.body.append(route) | |
| await new Promise((resolve) => setTimeout(resolve, 0)) | |
| await frames(3) | |
| expect(calls).toEqual([[0, false]]) | |
| route.remove() | |
| document.body.append(route) | |
| await new Promise((resolve) => setTimeout(resolve, 0)) | |
| await frames(3) | |
| expect(calls).toEqual([[0, false]]) | |
| cleanup?.() | |
| route.remove() | |
| }) | |
| test("keeps checking until stale reset-delay callbacks can no longer win", async () => { | |
| const route = document.createElement("section") | |
| const viewport = document.createElement("div") | |
| route.append(viewport) | |
| document.body.append(route) | |
| const instance = { | |
| scrollElement: viewport, | |
| targetWindow: window, | |
| scrollOffset: 79_400, | |
| options: { | |
| horizontal: false, | |
| isRtl: false, | |
| isScrollingResetDelay: 20, | |
| useScrollendEvent: false, | |
| }, | |
| } as unknown as Virtualizer<HTMLDivElement, HTMLDivElement> | |
| const calls: number[] = [] | |
| const cleanup = observeElementOffsetReconnectAware(instance, (offset) => { | |
| calls.push(offset) | |
| instance.scrollOffset = offset | |
| }) | |
| route.remove() | |
| document.body.append(route) | |
| await new Promise((resolve) => setTimeout(resolve, 0)) | |
| await frames(1) | |
| expect(instance.scrollOffset).toBe(0) | |
| instance.scrollOffset = 79_400 | |
| await new Promise((resolve) => setTimeout(resolve, 25)) | |
| await frames(3) | |
| expect(instance.scrollOffset).toBe(0) | |
| expect(calls).toEqual([0, 0]) | |
| cleanup?.() | |
| route.remove() | |
| }) | |
| test.each([ | |
| { name: "LTR", isRtl: false, expected: 240 }, | |
| { name: "RTL", isRtl: true, expected: -240 }, | |
| ])("reports the TanStack horizontal $name offset after reconnect", async ({ isRtl, expected }) => { | |
| const route = document.createElement("section") | |
| const viewport = document.createElement("div") | |
| route.append(viewport) | |
| document.body.append(route) | |
| viewport.scrollLeft = 240 | |
| const instance = { | |
| scrollElement: viewport, | |
| targetWindow: window, | |
| scrollOffset: 0, | |
| options: { | |
| horizontal: true, | |
| isRtl, | |
| isScrollingResetDelay: 0, | |
| useScrollendEvent: false, | |
| }, | |
| } as unknown as Virtualizer<HTMLDivElement, HTMLDivElement> | |
| const calls: [number, boolean][] = [] | |
| const cleanup = observeElementOffsetReconnectAware(instance, (offset, isScrolling) => { | |
| calls.push([offset, isScrolling]) | |
| instance.scrollOffset = offset | |
| }) | |
| route.remove() | |
| document.body.append(route) | |
| await new Promise((resolve) => setTimeout(resolve, 0)) | |
| await frames(3) | |
| expect(calls).toEqual([[expected, false]]) | |
| cleanup?.() | |
| route.remove() | |
| }) | |
| test("cleanup suppresses an already queued delegated offset callback", async () => { | |
| const viewport = document.createElement("div") | |
| document.body.append(viewport) | |
| viewport.scrollTop = 100 | |
| const instance = { | |
| scrollElement: viewport, | |
| targetWindow: window, | |
| scrollOffset: 0, | |
| options: { | |
| horizontal: false, | |
| isRtl: false, | |
| isScrollingResetDelay: 10, | |
| useScrollendEvent: false, | |
| }, | |
| } as unknown as Virtualizer<HTMLDivElement, HTMLDivElement> | |
| const calls: [number, boolean][] = [] | |
| const cleanup = observeElementOffsetReconnectAware(instance, (offset, isScrolling) => | |
| calls.push([offset, isScrolling]), | |
| ) | |
| viewport.dispatchEvent(new Event("scroll")) | |
| cleanup?.() | |
| await new Promise((resolve) => setTimeout(resolve, 25)) | |
| expect(calls).toEqual([[100, true]]) | |
| viewport.remove() | |
| }) | |
| test("cleanup cancels reconnect checks and delegated offset observation", async () => { | |
| const route = document.createElement("section") | |
| const viewport = document.createElement("div") | |
| route.append(viewport) | |
| document.body.append(route) | |
| const instance = { | |
| scrollElement: viewport, | |
| targetWindow: window, | |
| scrollOffset: 0, | |
| options: { | |
| horizontal: false, | |
| isRtl: false, | |
| isScrollingResetDelay: 50, | |
| useScrollendEvent: false, | |
| }, | |
| } as unknown as Virtualizer<HTMLDivElement, HTMLDivElement> | |
| const calls: number[] = [] | |
| const cleanup = observeElementOffsetReconnectAware(instance, (offset) => calls.push(offset)) | |
| route.remove() | |
| document.body.append(route) | |
| await new Promise((resolve) => setTimeout(resolve, 0)) | |
| cleanup?.() | |
| instance.scrollOffset = 100 | |
| viewport.dispatchEvent(new Event("scroll")) | |
| await frames(4) | |
| expect(calls).toEqual([]) | |
| route.remove() | |
| }) | |
| async function frames(count: number) { | |
| for (let index = 0; index < count; index++) { | |
| await new Promise<void>((resolve) => requestAnimationFrame(() => resolve())) | |
| } | |
| } | |