refactor: 專案整理階段二——透明判定單一真相源+跨透明邊界避頭尾+avoid 排除歸一
承階段一之下游審計。核心貫穿問題:「透明穿越」判定實有兩套口徑散落各處,抵觸 finder 檔頭「所有遍歷共用同一判定」之聲明。用戶抉擇:**嚴格白名單**(未知行內標籤=邊界, 透明須顯式登記 styleInlines)。 透明判定單一真相源(2a): ・transparentInline 提升為公開 isTransparent,作邏輯文本流之單一透明判定。 ・collectRuns 改由 isTransparent 判定——未在 styleInlines 之未知行內標籤(如 <button>/自訂 元素)當隔離式邊界(斷 run、內部自成脈絡);isolate 與未知行內併為同一分支。 ・jiyaAdjacency 同改用 finder.isTransparent;adjacentLogicalChar 沿用(僅隨改名)。 ・分層澄清(承 #4 教訓,不強行一統):邏輯文本流統一為 isTransparent;另兩層各有正當之 不同邊界、刻意不併入——結構切分安全(split canSplit:更窄白名單,<a>/ABBR 不可切)與 物理版面(lineedge:getClientRects 物理相鄰,須跨 isolate 找真實鄰接)。檔頭改分層表述。 跨透明元素邊界避頭尾綁定(2b,修下游審計 #3): ・避頭類標點若落於透明元素邊緣(「你好<strong>。世界</strong>」之 。位於 strong 首位、與 「好」不同 DOM parent),舊版 forbiddenBreak 僅認直接 jz-char、render 僅處理 jz-char 之直接 父(strong),外層 p 之「好↔strong」綁定從不被評估 → 。漏綁、可誤置行首。 ・偵測:edgeCharEl 經 finder.isTransparent 穿越透明元素定位邊緣 jz-char。 ・父級處理:render 沿透明元素邊緣上攀納入外層 parent,父集深者先處理。綁定端沿用 isolateBoundaryToken(可切則最小綁定;邊界字為已 charify 之 jz-char 無法越過時退化整綁, 安全、與 <a> 同型)。 avoid 排除機制歸一(2c): ・isAvoided 改單一組合入口(自身即邊界 或 祖先鏈任一邊界),免除「avoidsSelf ‖ isAvoided」 易漏一半之誤用(階段一 #2 即此類);avoidsSelf 保留供遍歷原語逐元素下探自判(免 O(n²))。 ・processPills/orphan/spacing root 收斂為 isAvoided(x);doc 補齊七種 avoid 來源與優先序。 一致性小項(2e):scope.include 型別去多餘 `| null`;PASSES 陣列補註(執行序由 pass.order 分群排序決定);gapTrim 補 featureEnabledFor("spacing"),與 lineEdge relayout 逐節點閘對稱。 評估後不做(2d):五處幂等判斷(jiya 祖先/longword 父/spacing 父/orphan 子/jinze 父)檢查 不同位置關係、無單一 isJz 形狀可全覆蓋;真正缺陷(jinze 二次 render 巢狀)已於階段一以 isJz 修復,其餘各自正確,強行歸一徒增風險(承 #4 教訓:正當差異不硬併)。 新增契約/回歸測試(button 嚴格白名單、跨透明邊界避頭);121 測試全綠、構建乾淨。
This commit is contained in:
+7
-9
@@ -131,8 +131,7 @@ export const jiyaAdjacencyPass: StandalonePass = {
|
||||
enabled: (o) => o.features.jiya,
|
||||
render(ctx: RenderContext): void
|
||||
{
|
||||
const { finder, options } = ctx;
|
||||
const blockSet = options.finder.blockTags;
|
||||
const { finder } = ctx;
|
||||
let prev: Element | null = null;
|
||||
|
||||
const squeeze = (L: Element, R: Element): void =>
|
||||
@@ -166,17 +165,16 @@ export const jiyaAdjacencyPass: StandalonePass = {
|
||||
if (prev) { squeeze(prev, el); }
|
||||
prev = el; // jz-char 為原子,不下探(內含 jz-inner)
|
||||
}
|
||||
else if (finder.pillMatches(el)) { prev = null; } // pill(整體):斷相鄰、不下探(內容對排版不可見)
|
||||
else if (finder.avoidsSelf(el)) { prev = null; } // avoid 邊界(自身判定):斷、不下探
|
||||
else if (finder.isolateMatches(el))
|
||||
else if (finder.pillMatches(el) || finder.avoidsSelf(el))
|
||||
{
|
||||
prev = null; visit(el); prev = null; // 隔離:前後皆斷相鄰,內部自成脈絡(同 block)
|
||||
prev = null; // 整體 pill/avoid:斷相鄰、不下探(內容不可見/不處理)
|
||||
}
|
||||
else if (blockSet.has(nm))
|
||||
else if (finder.isTransparent(el)) { visit(el); } // 透明:穿越、相鄰性延續
|
||||
else
|
||||
{
|
||||
prev = null; visit(el); prev = null; // block 邊界:前後皆斷相鄰,內部另計
|
||||
// 隔離/block/嚴格白名單下之未知行內:前後皆斷相鄰,內部自成脈絡(另計)。
|
||||
prev = null; visit(el); prev = null;
|
||||
}
|
||||
else { visit(el); } // 行內(樣式行內 / pill 等):透明穿越、相鄰性延續
|
||||
}
|
||||
};
|
||||
visit(ctx.root);
|
||||
|
||||
Reference in New Issue
Block a user