refactor: 元素分類單一入口 finder.category + ResizeObserver 派發序不變量確認
承階段二之兩件收尾:確認 lineedge 雙 ResizeObserver 之派發序(審計唯一未闭環項),並把散落 各遍歷原語之元素分類優先序收斂為單一 finder.category。 ResizeObserver 派發序——**確認為非缺陷**(Chrome headless 實測):resize 時回調按 observer **創建順序**派發(ResizeObserver 規範遍歷 observers 之插入序,非 observe 序;實測 seq=12—— 反向 observe 仍按創建序)。lineEdgePass(order 90)之 observer 先於 gapTrimPass(order 92)建、 故每次 resize 皆先派發,gapTrim 之行末去隙判定恆基於 lineEdge **已套用**之半形版面(非陳舊態)。 以註解鎖為不變量(勿調換兩 pass 之 order/創建序),不需改碼。 元素分類單一入口:新增 `Finder.category(el): InlineCategory`——一元素恰屬 avoid/pill/isolate/ block/transparent/opaque 之一,優先序 `avoid > pill > isolate > block > transparent > opaque` 集中一處(原散落 collectRuns/jiyaAdjacency/canSplit/isTransparent 各自短路、易漂移)。 ・isTransparent = `category === "transparent"`;collectRuns/jiyaAdjacency 改 `switch(category)`; canSplit = `SPLITTABLE ∩ transparent`(結構切分為獨立層、白名單更窄)。 ・行為等價(121 全綠);多命中優先序(data-jz-skip pill→avoid、pill+isolate→pill、未知行內 →opaque 邊界)由既有行為測試覆蓋。 ・README 三分類要點+ARCHITECTURE §4.1 補優先序與 category 說明。
This commit is contained in:
+19
-7
@@ -165,15 +165,27 @@ export const jiyaAdjacencyPass: StandalonePass = {
|
||||
if (prev) { squeeze(prev, el); }
|
||||
prev = el; // jz-char 為原子,不下探(內含 jz-inner)
|
||||
}
|
||||
else if (finder.pillMatches(el) || finder.avoidsSelf(el))
|
||||
{
|
||||
prev = null; // 整體 pill/avoid:斷相鄰、不下探(內容不可見/不處理)
|
||||
}
|
||||
else if (finder.isTransparent(el)) { visit(el); } // 透明:穿越、相鄰性延續
|
||||
else
|
||||
{
|
||||
// 隔離/block/嚴格白名單下之未知行內:前後皆斷相鄰,內部自成脈絡(另計)。
|
||||
prev = null; visit(el); prev = null;
|
||||
switch (finder.category(el)) // 與 collectRuns 共用同一分類(§4.1)
|
||||
{
|
||||
case "avoid":
|
||||
case "pill":
|
||||
{
|
||||
prev = null; // 斷相鄰、不下探(內容不可見/不處理)
|
||||
break;
|
||||
}
|
||||
case "transparent":
|
||||
{
|
||||
visit(el); // 穿越、相鄰性延續
|
||||
break;
|
||||
}
|
||||
default: // isolate/block/opaque(未知行內)
|
||||
{
|
||||
prev = null; visit(el); prev = null; // 斷相鄰、內部自成脈絡
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,6 +26,13 @@ const HEAD_CLASSES = new Set([ "bd-open" ]);
|
||||
const TAIL_CLASSES = new Set([ "bd-close" ]);
|
||||
|
||||
// 每 root 各 layout pass(以 key 區分)一個 ResizeObserver。
|
||||
//
|
||||
// **跨 observer 派發序不變量(已於 Chrome headless 實測確認)**:resize 時 ResizeObserver
|
||||
// 之回調按 **observer 創建順序** 派發(ResizeObserver 規範遍歷 observers 列表之插入序,非
|
||||
// observe 序)。lineEdgePass(order 90)先於 gapTrimPass(order 92)執行、故其 observer 先
|
||||
// 建,於每次 resize 皆先派發——確保 gapTrim 之行末去隙判定恆基於 lineEdge **已套用**之半形
|
||||
// 版面(非陳舊態)。**勿調換兩 pass 之 order 或創建序**,否則 gapTrim 可能以 resize 前之半形
|
||||
// 狀態誤判行末(且 ResizeObserver 只觀 root 尺寸、不因內部 class 變化重觸發,錯誤會持續)。
|
||||
const observers = new WeakMap<Element, Map<string, ResizeObserver>>();
|
||||
|
||||
function hasLayout(): boolean
|
||||
|
||||
Reference in New Issue
Block a user