fix: 修复长文档分页与滚动同步
This commit is contained in:
@@ -11,6 +11,7 @@ describe("Mermaid 站点配置", () => {
|
||||
expect(config.look).toBe("classic");
|
||||
expect(config.securityLevel).toBe("strict");
|
||||
expect(config.startOnLoad).toBe(false);
|
||||
expect(config.flowchart?.wrappingWidth).toBe(320);
|
||||
});
|
||||
|
||||
it("锁定安全限制和原始主题 CSS", () => {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveBreakTokenElement } from "../src/paged-break-token";
|
||||
|
||||
describe("Paged.js 分页断点", () => {
|
||||
it("直接返回元素断点", () => {
|
||||
const element = {
|
||||
nodeType: 1,
|
||||
parentElement: null
|
||||
} as unknown as Element;
|
||||
|
||||
expect(resolveBreakTokenElement(element)).toBe(element);
|
||||
});
|
||||
|
||||
it("文本断点使用父元素继续查找", () => {
|
||||
const parentElement = {} as Element;
|
||||
const textNode = {
|
||||
nodeType: 3,
|
||||
parentElement
|
||||
} as unknown as Node;
|
||||
|
||||
expect(resolveBreakTokenElement(textNode)).toBe(parentElement);
|
||||
});
|
||||
|
||||
it("安全跳过空断点和无父元素节点", () => {
|
||||
const detachedTextNode = {
|
||||
nodeType: 3,
|
||||
parentElement: null
|
||||
} as unknown as Node;
|
||||
|
||||
expect(resolveBreakTokenElement(undefined)).toBeUndefined();
|
||||
expect(
|
||||
resolveBreakTokenElement(detachedTextNode)
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -38,7 +38,12 @@ describe("分页预览协议", () => {
|
||||
expect(css).toContain("display: table-header-group");
|
||||
expect(css).toContain("break-inside: avoid");
|
||||
expect(css).toContain(".pagedjs_pages");
|
||||
expect(css).toContain("padding: 34px 0");
|
||||
expect(css).toContain('html[data-render-target="preview"]');
|
||||
expect(css).toContain("overflow-x: hidden");
|
||||
expect(css).toContain("overflow-y: scroll");
|
||||
expect(css).toContain('html[data-render-target="pdf"]');
|
||||
expect(css).toContain("padding: 0");
|
||||
expect(css).toContain("break-after: page");
|
||||
expect(css).not.toContain("@media print");
|
||||
});
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getNearestPageNumber } from "../src/preview-page";
|
||||
|
||||
const pages = [
|
||||
{ top: 0, bottom: 100 },
|
||||
{ top: 124, bottom: 224 },
|
||||
{ top: 248, bottom: 348 }
|
||||
];
|
||||
|
||||
describe("getNearestPageNumber", () => {
|
||||
it("返回视口中心所在的页面", () => {
|
||||
expect(getNearestPageNumber(180, pages)).toBe(2);
|
||||
});
|
||||
|
||||
it("在页间空隙中返回距离最近的页面", () => {
|
||||
expect(getNearestPageNumber(110, pages)).toBe(1);
|
||||
expect(getNearestPageNumber(116, pages)).toBe(2);
|
||||
});
|
||||
|
||||
it("没有页面或中心坐标无效时返回 0", () => {
|
||||
expect(getNearestPageNumber(20, [])).toBe(0);
|
||||
expect(getNearestPageNumber(Number.NaN, pages)).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
getScrollProgress,
|
||||
getSyncedScrollTop
|
||||
} from "../src/scroll-sync";
|
||||
|
||||
describe("编辑与预览滚动同步", () => {
|
||||
it("按可滚动范围计算阅读进度", () => {
|
||||
expect(
|
||||
getScrollProgress({
|
||||
scrollTop: 600,
|
||||
scrollHeight: 1600,
|
||||
clientHeight: 400
|
||||
})
|
||||
).toBe(0.5);
|
||||
});
|
||||
|
||||
it("把源区域进度映射到目标区域", () => {
|
||||
expect(
|
||||
getSyncedScrollTop(
|
||||
{
|
||||
scrollTop: 600,
|
||||
scrollHeight: 1600,
|
||||
clientHeight: 400
|
||||
},
|
||||
{
|
||||
scrollTop: 0,
|
||||
scrollHeight: 5000,
|
||||
clientHeight: 1000
|
||||
}
|
||||
)
|
||||
).toBe(2000);
|
||||
});
|
||||
|
||||
it("处理无滚动范围和越界位置", () => {
|
||||
expect(
|
||||
getScrollProgress({
|
||||
scrollTop: 100,
|
||||
scrollHeight: 500,
|
||||
clientHeight: 500
|
||||
})
|
||||
).toBe(0);
|
||||
expect(
|
||||
getScrollProgress({
|
||||
scrollTop: 1800,
|
||||
scrollHeight: 1600,
|
||||
clientHeight: 400
|
||||
})
|
||||
).toBe(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user