fix(web): 基础控件 FloatingDock - 宿主没有 matchMedia 时不再渲染失败 (#563)
Original-Commit: 3da77b3931a675de06b02c1bba93f112d253041b
fix(web): 基础控件 FloatingDock - 宿主没有 matchMedia 时不再渲染失败
`window` 存在不代表 `matchMedia` 存在(SSR 垫片、嵌入式 webview、部分 DOM polyfill),
而 FloatingDock 在渲染期直接取 `window.matchMedia("(pointer: coarse)").matches`,
取不到就抛 TypeError,整个 dock(画布工具栏/素材托盘/缩放控件)渲染失败。
仓库里同一模式已有先例:canvas-workspace-tool-panel 用 typeof 守卫。
抽 coarsePointerQuery():两个都探测,取不到按"非触屏"处理,useEffect 也提前返回;
能取到时行为不变。新增源码级守卫用例(上游原态失败、补丁后通过)。
This commit is contained in:
18
web/test/floating-dock-pointer-guard.test.tsx
Normal file
18
web/test/floating-dock-pointer-guard.test.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
// 指针能力探测是纯增强:`window` 存在不代表 `matchMedia` 存在(SSR 垫片、嵌入式 webview、
|
||||
// 部分 DOM polyfill 下它是 undefined),而 FloatingDock 在**渲染期**就取
|
||||
// `window.matchMedia("(pointer: coarse)")`,取不到会直接抛 TypeError 让整个 dock 渲染失败。
|
||||
// 仓库里同一模式已有先例:canvas-workspace-tool-panel.tsx 用 `typeof window.matchMedia === "function"` 守卫。
|
||||
describe("floating dock pointer capability probe", () => {
|
||||
const source = readFileSync(new URL("../src/components/ui/aceternity/floating-dock.tsx", import.meta.url), "utf8");
|
||||
|
||||
test("probes matchMedia through a guarded helper", () => {
|
||||
expect(source).toContain('typeof window.matchMedia !== "function"');
|
||||
expect(source).toContain("function coarsePointerQuery()");
|
||||
// 不允许再出现"直接取用 matchMedia 结果"的写法(初始化与 useEffect 都不得裸取)
|
||||
expect(source).not.toMatch(/window\.matchMedia\("\(pointer: coarse\)"\)\.matches/);
|
||||
expect(source).not.toMatch(/const media = window\.matchMedia/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user