From 6841cfe38f6eb375b3070f1ed6cfe6eb6ebcba34 Mon Sep 17 00:00:00 2001 From: lofyer Date: Wed, 5 Aug 2026 20:19:08 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E7=84=A6=E7=82=B9=E9=94=9A=E5=AE=9A?= =?UTF-8?q?=E5=AE=B9=E5=B7=AE=E6=8C=89=E5=AE=9E=E9=99=85=E6=AF=8F=E8=A1=8C?= =?UTF-8?q?=E5=AD=97=E6=95=B0=E7=AE=97=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=86=99?= =?UTF-8?q?=E6=AD=BB=E5=AD=97=E7=AC=A6=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../electron/reader-features.integration.js | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/_test/electron/reader-features.integration.js b/src/_test/electron/reader-features.integration.js index 4cc1d30..c7be371 100644 --- a/src/_test/electron/reader-features.integration.js +++ b/src/_test/electron/reader-features.integration.js @@ -1373,7 +1373,7 @@ app.whenReady().then(async () => { return progress && progress.locator && progress.locator.kind === 'epub'; }, 5000); const epubProgress = readerStore.getState(entry.id).progress; - const focalOffsetAfter = await js(epubWin, `(() => { + const focalAfter = await js(epubWin, `(() => { const frame = document.querySelector('.host-epub iframe'); const doc = frame.contentDocument; const outerRect = document.querySelector('.epub-scroll').getBoundingClientRect(); @@ -1387,18 +1387,31 @@ app.whenReady().then(async () => { const range = doc.caretRangeFromPoint(x, y); if (range) caret = { offsetNode: range.startContainer, offset: range.startOffset }; } - if (!caret) return -1; + if (!caret) return { offset: -1, charsPerLine: 0 }; + // 容差要按"一行有多少字"算:字体不同,同样的一行在不同平台字数不同, + // 写死字符数的话换个字体集就会假失败 + let charsPerLine = 0; + const host = caret.offsetNode.parentElement; + if (host && host.textContent) { + const range = doc.createRange(); + range.selectNodeContents(host); + const lines = range.getClientRects().length; + if (lines > 0) charsPerLine = host.textContent.length / lines; + } const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT); let offset = 0; for (let node = walker.nextNode(); node; node = walker.nextNode()) { - if (node === caret.offsetNode) return offset + caret.offset; + if (node === caret.offsetNode) return { offset: offset + caret.offset, charsPerLine }; offset += node.data.length; } - return -1; + return { offset: -1, charsPerLine }; })()`); + const focalOffsetAfter = focalAfter.offset; + // 焦点锚定的语义是"停在原来那行附近",超过一行就说明锚点真的漂了 + const focalTolerance = Math.max(12, Math.ceil(focalAfter.charsPerLine)); check('EPUB 双指缩放保持焦点附近字符偏移', - Math.abs(focalOffsetAfter - pinchResult.anchorOffset) <= 12, - `${pinchResult.anchorOffset} -> ${focalOffsetAfter}; 顶部=${epubProgress.locator.offset}`); + Math.abs(focalOffsetAfter - pinchResult.anchorOffset) <= focalTolerance, + `${pinchResult.anchorOffset} -> ${focalOffsetAfter}; 容差=${focalTolerance}; 顶部=${epubProgress.locator.offset}`); const epubSelection = await selectEpubText(epubWin); await waitForJs(epubWin, `!document.getElementById('selBar').classList.contains('hidden')`);