From cbd126f7669a31454013e4220de628517d15111c Mon Sep 17 00:00:00 2001 From: Aisland Date: Wed, 2 Sep 2026 01:05:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(annotate):=20=E6=A0=87=E6=B3=A8=20payload?= =?UTF-8?q?=20=E5=8A=A0=E7=AA=97=E5=8F=A3=E8=BA=AB=E4=BB=BD(=E7=BC=96?= =?UTF-8?q?=E5=8F=B7+=E7=AA=97=E6=A0=BC=E6=A0=87=E9=A2=98+=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E7=B1=BB=E5=9E=8B/URL)=E2=80=94=E2=80=94=E6=8E=A5?= =?UTF-8?q?=E6=94=B6=E6=96=B9=E6=97=A0=E9=9C=80=E7=8C=9C=E5=93=AA=E4=B8=AA?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=EF=BC=9B=E6=A1=86=E5=86=85=E6=96=87=E5=AD=97?= =?UTF-8?q?=E8=81=9A=E5=90=88=E6=94=B9=E7=9B=B8=E4=BA=A4=E5=8D=B3=E5=85=A5?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=B0=8F=E6=A1=86=E5=8D=8A=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E6=96=87=E5=AD=97=E4=B9=9F=E8=83=BD=E6=8A=93=E5=88=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01_content/lib/client.js | 28 +++++++++++++++++++++------- 01_content/src/client/split.tsx | 28 ++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/01_content/lib/client.js b/01_content/lib/client.js index 52a7f07..194a682 100644 --- a/01_content/lib/client.js +++ b/01_content/lib/client.js @@ -16855,10 +16855,26 @@ function windowLabelOf(row, index) { const spec = splitStore.spec; if (!spec) return "\u7A97\u53E3?"; let num = spec.left ? 2 : 1; - if (row === "left") return "\u7A97\u53E31"; - if (row === "top") return "\u7A97\u53E3" + (num + index); - num += spec.top?.length ?? 0; - return "\u7A97\u53E3" + (num + index); + if (row === "left") num = 1; + else if (row === "top") num = num + index; + else { + num += (spec.top?.length ?? 0) + index; + } + let label = "\u7A97\u53E3" + num; + const pane = row === "left" ? spec.left : row === "top" ? spec.top?.[index] : spec.main?.[index]; + const title = pane?.title; + if (title) label += "\u300C" + title + "\u300D"; + const tab = pane?.tabs?.[pane.active ?? 0]; + const c = tab?.content; + if (c) { + try { + if (c.kind === "iframe" && c.url) label += "\uFF08\u7F51\u9875 " + new URL(c.url).hostname + "\uFF09"; + else if (c.kind === "builtin") label += "\uFF08\u5185\u7F6E\xB7" + c.type + "\uFF09"; + else if (c.kind === "file") label += "\uFF08\u6587\u4EF6\uFF09"; + } catch { + } + } + return label; } function ctxOf(t) { const el = t instanceof Element ? t : null; @@ -16881,9 +16897,7 @@ function elementsInBox(x0, y0, x1, y1) { if (tag === "script" || tag === "style" || tag === "svg" || tag === "path" || tag === "br" || tag === "template" || tag === "iframe") continue; const rect = el.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) continue; - const cx = rect.left + rect.width / 2; - const cy = rect.top + rect.height / 2; - if (cx < L || cx > R || cy < T2 || cy > B) continue; + if (rect.right < L || rect.left > R || rect.bottom < T2 || rect.top > B) continue; const text2 = (el.textContent || "").trim().replace(/\s+/g, " "); if (text2.length < 1 || text2.length > 80) continue; out.push({ text: text2, area: rect.width * rect.height }); diff --git a/01_content/src/client/split.tsx b/01_content/src/client/split.tsx index 5ee04a0..a4d93b7 100644 --- a/01_content/src/client/split.tsx +++ b/01_content/src/client/split.tsx @@ -341,15 +341,28 @@ function cancelAnnot() { setAnnot({ on: false, started: false, drawing: false }) } -/** 窗口编号(约定:左栏 → 顶行 → 主行,从 1 起) */ +/** 窗口身份(约定:左栏 → 顶行 → 主行,从 1 起;附窗格标题与内容类型/URL,让接收方无需猜"这是哪个界面") */ function windowLabelOf(row: PaneRow, index: number): string { const spec = splitStore.spec if (!spec) return '窗口?' let num = spec.left ? 2 : 1 - if (row === 'left') return '窗口1' - if (row === 'top') return '窗口' + (num + index) - num += (spec.top?.length ?? 0) - return '窗口' + (num + index) + if (row === 'left') num = 1 + else if (row === 'top') num = num + index + else { num += (spec.top?.length ?? 0) + index } + let label = '窗口' + num + const pane = row === 'left' ? spec.left : row === 'top' ? spec.top?.[index] : spec.main?.[index] + const title = pane?.title + if (title) label += '「' + title + '」' + const tab = pane?.tabs?.[pane.active ?? 0] + const c = tab?.content + if (c) { + try { + if (c.kind === 'iframe' && c.url) label += '(网页 ' + new URL(c.url).hostname + ')' + else if (c.kind === 'builtin') label += '(内置·' + c.type + ')' + else if (c.kind === 'file') label += '(文件)' + } catch {} + } + return label } /** 被点元素上下文(标签 + 类名 + 文字) */ @@ -376,9 +389,8 @@ function elementsInBox(x0: number, y0: number, x1: number, y1: number): string[] if (tag === 'script' || tag === 'style' || tag === 'svg' || tag === 'path' || tag === 'br' || tag === 'template' || tag === 'iframe') continue const rect = el.getBoundingClientRect() if (rect.width <= 0 || rect.height <= 0) continue - const cx = rect.left + rect.width / 2 - const cy = rect.top + rect.height / 2 - if (cx < L || cx > R || cy < T || cy > B) continue + // 相交即入:元素矩形与框有任意重叠就收录(小框框住一半文字也能抓到) + if (rect.right < L || rect.left > R || rect.bottom < T || rect.top > B) continue const text = (el.textContent || '').trim().replace(/\s+/g, ' ') if (text.length < 1 || text.length > 80) continue out.push({ text, area: rect.width * rect.height })