fix: 修复行缘、切分还原与语言解析并同步文档
保留逐字 margin/jiya.bias 字体后备方案;补齐 demo 重排、量测边界说明及共享规则 1.0.1 反例向量。 验证:完整构建通过,Node 376 项、WKWebView 64 项及原生 demo 9 项通过;Firefox 仍暂缓。
This commit is contained in:
+23
-13
@@ -67,6 +67,7 @@ CSS box、observer、瀏覽器量測,以及 TeX node/glue/penalty/macro
|
||||
其他實例內容。沒有外部修改時,DOM 回到處理前的**邏輯等價**態;`spacing` 正規化的
|
||||
贅餘作者空格不還原(見 I1),此差異不隨反覆 render/revert 累積。
|
||||
外部克隆、替換、刪除後,按產物及來源完整性檢查安全回退,不復活過時文字;
|
||||
splitoff 無法安全併回時保留作者當前樣式及文字位置,僅撤銷本庫標記及憑證;
|
||||
不保證恢復歷史快照或清空所有 `[data-jz]`。DOM 標記本身不授予所有權。
|
||||
- **I7 邊界感知**:跨樣式行內元素的鄰接(如 `<strong>是</strong>A`)須能識別並
|
||||
正確處理——由核心 finder 統一提供,各 pass 不自行重複造輪。
|
||||
@@ -367,8 +368,9 @@ avoid」用組合入口 `isAvoided`(=自身或祖先,階段二歸一,免
|
||||
|
||||
- **結構克隆切分安全**(`core/split` 之 `canSplit`)——更窄白名單(`STRONG/EM/…`,排除
|
||||
`<a>`/`ABBR`/`RUBY`/帶 `id` 等——切分會重複語義/結構),故「可透明穿越」⊋「可克隆切分」。
|
||||
- **物理版面**(`lineedge` 之 `edgeRect`)——依 `getClientRects` 之物理相鄰判行首/行尾,攀爬集
|
||||
由 `styleInlines` 派生(免遺漏 `ins`/`del`/`sub` 致行端誤判 T4),且**須跨 isolate**(`<mark>`)
|
||||
- **物理版面**(`lineedge` 之 `edgeRect`)——依 `getClientRects` 之物理相鄰判行首/行尾,以 computed `display` 判斷物理行內流(inline 系列/ruby/contents 可攀出;block 停止),
|
||||
可見 `br` 是強制行緣,隱藏 `br` 跳過。無計算樣式時才用 `styleInlines`+jz 包裹標籤後備,
|
||||
包含 `jz-orphan`。**須跨物理行內的 isolate/opaque**(如 `<mark>`/自訂標籤)
|
||||
找真實相鄰內容:isolate 斷的是**邏輯** run/相鄰,非**物理**位置(`文字<mark>「引」</mark>` 之
|
||||
`「` 物理上接在「文字」後、非行首,若停在 mark 邊界會誤判行首而錯收左半)。
|
||||
|
||||
@@ -388,7 +390,8 @@ avoid」用組合入口 `isAvoided`(=自身或祖先,階段二歸一,免
|
||||
- **規則正則**:中西間隙邊界、擠壓相鄰組合、禁則對象等,皆以此表組裝。
|
||||
|
||||
**規則集抽象(`Ruleset`/`charClass`,可配置)**:字符分類不再各 pass 硬編碼,而統一為
|
||||
一個**規則集**——`{ cjk, ansAfter, ansBefore, biaodian{6 子類} }`,各為 regex 字元類片段。
|
||||
一個**規則集**——`{ cjk, ansAfter, ansBefore, biaodian{6 子類} }`,中文/西文為 regex 字元類片段,標點各子類為逐碼點字串;
|
||||
後者不解讀範圍(追加 `①②③`,不能以 `①-③` 表示三個圈碼)。regex 特殊字元須轉義。
|
||||
`DEFAULT_RULESET` 即內置默認(上述 CJK/西文/BD_* 值)。消費端經 `options.charClass`
|
||||
(`{ cjk?, western?, biaodian? }`)**擴充**,`resolveRuleset(override)` 以**追加**語義合併
|
||||
為最終規則集,置於 `ResolvedOptions.ruleset`。各 pass 由此取分類:
|
||||
@@ -410,9 +413,13 @@ avoid」用組合入口 `isAvoided`(=自身或祖先,階段二歸一,免
|
||||
|
||||
### 4.3 `locale.ts`——語言與全角/開明政策
|
||||
|
||||
- `effectiveLang(node)`:最近祖先 `lang`(小寫),無則回退 `options.lang.default`。
|
||||
- `effectiveLang(node)`:自身及祖先最近的 `lang`(小寫),僅缺失時回退 `options.lang.default`;
|
||||
顯式空值為未知語言,不繼承祖先。空 default 亦表示未知。
|
||||
- `classify(lang)`:歸為 `zh-Hans` / `zh-Hant`(含 `zh-TW`/`zh-HK`)/ `ja` / 其他;
|
||||
BCP-47 前綴邊界比對(`zh` 命中 `zh-Hant`,不命中 `zhx`)。
|
||||
BCP-47 前綴邊界比對(`zh` 命中 `zh-Hant`,不命中 `zhx`)。只讀 language/
|
||||
extlang 後的 script/region 位置,不把 extension/private-use 當腳本或地區。
|
||||
本函數不提供完整 BCP-47 有效性驗證。依據 [RFC 5646 §2.1](https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1);
|
||||
HTML 空 lang 依 [HTML 語言契約](https://html.spec.whatwg.org/multipage/dom.html#the-lang-and-xml:lang-attributes)。
|
||||
- `resolveStyle(node)`:回傳節點之有效標點寬度政策——`quanjiao`(全角式)|`kaiming`
|
||||
(開明式)|`banjiao`(半角式)。**優先序**:**逐元素覆寫**(`resolveStyleOverride`:自身及
|
||||
祖先鏈掃 `data-jz-style` 屬性/`stylePolicy` 選擇器命中,近祖先勝、同層屬性優先於選擇器)
|
||||
@@ -433,8 +440,11 @@ avoid」用組合入口 `isAvoided`(=自身或祖先,階段二歸一,免
|
||||
|
||||
`revertPass(pass, root, ownedElements)` 先驗證本實例所有權與合法 pass/kind/tag 組合。
|
||||
目前接受 `wrap`(包裝原內容)與 **`splitoff`**(行內元素克隆切分之邊界詞元);不提供
|
||||
泛用 `marker` 還原。第一階段逆序解包 wrap,第二階段把 splitoff 併回同標籤前兄弟,
|
||||
最後 normalize 受影響父節點。順序必要,否則 splitoff 前兄弟可能仍是 wrap 殼。
|
||||
泛用 `marker` 還原。第一階段逆序解包 wrap,第二階段依私有來源弱映射,僅在前兄弟仍為切分來源或經私有切分/合併鏈證明同源的片段、
|
||||
同標籤且作者屬性一致時併回,
|
||||
最後 normalize 受影響父節點。外部插入、替換來源或改樣式導致不安全合併時,保留片段
|
||||
元素、樣式及文字位置,還原其原有 marker 屬性並撤銷本庫憑證,不跨新內容搬字。
|
||||
順序必要,否則 splitoff 前兄弟可能仍是 wrap 殼。
|
||||
|
||||
`recordUnwrappedParent`/`resolveUnwrappedParent` 記錄及解析合法產物的受控解包鏈,
|
||||
供跨節點來源回退使用;重用空殼會使舊位置失效,重定向環不作為文字恢復依據。
|
||||
@@ -662,8 +672,8 @@ class 約定以現有 CSS/pass 為準:標點採 `bd-open`/`bd-close`/`bd
|
||||
改以 `isolateBoundaryToken(el, side)` **克隆切分**:沿「文本節點→邊界元素」祖先鏈逐層
|
||||
把邊界詞元剝入一個淺克隆(保留標籤/class/style/lang,去 id),只綁該克隆(最小綁定),
|
||||
原元素其餘部分留原位、渲染視覺無縫。克隆標 `data-jz-kind="splitoff"`,`revertPass` 之**延後
|
||||
階段**(先解包 wrap、後併 splitoff,確保前兄弟為原元素而非 wrap 殼)併回原元素、還原一致
|
||||
(I6)。僅純樣式標籤白名單可切,且 `canSplit` **諮詢 finder 三分類**(§4.1):`a`/`abbr`/
|
||||
階段**(先解包 wrap、後併 splitoff)驗私有來源身份、鄰接與屬性一致後併回;
|
||||
未受外部干預時還原一致(I6),無法安全合併時保留片段,詳見 §4.4。僅純樣式標籤白名單可切,且 `canSplit` **諮詢 finder 三分類**(§4.1):`a`/`abbr`/
|
||||
`ruby`/帶 id 者,以及 **pill(整體)/isolate(隔離)**,可退化為
|
||||
整元素綁定(安全)——pill 即「作為原子鄰字單位整體綁入 `jz-jinze`」之期望行為(下游問題六:
|
||||
KaTeX 全樹皆 SPAN,舊版僅憑標籤白名單曾整棵下潛肢解公式);isolate(如背景色 `mark`)切分
|
||||
@@ -701,8 +711,8 @@ class 約定以現有 CSS/pass 為準:標點採 `bd-open`/`bd-close`/`bd
|
||||
> **標點懸掛移除之根因**(純 CSS 之寬度守恆矛盾,headless + 真實瀏覽器實測):行端標點盒若
|
||||
> 保持非零寬,墨色出去多少、版心內就空出多少(行末實義字無法齊版心右緣);若收為零寬,釋放
|
||||
> 一整字寬、斷行器把下一字拉上本行與標點重疊(且 justifyAtoms 預設之 inline-block 下負 margin
|
||||
> 被 justify 吸收)。**CSS hack 接觸不到斷行器,此恒等式無解**。唯一正解為原生
|
||||
> `hanging-punctuation`(僅 Safari 支援、且 jz-char 為 inline-block 原子非文本,原生懸掛不作用),
|
||||
> 被 justify 吸收)。**CSS hack 接觸不到斷行器,此恒等式無解**。未來可評估原生
|
||||
> `hanging-punctuation`(須驗證引擎能力,且 jz-char 為 inline-block 原子非文本),
|
||||
> 屬遠期「原生管線」新功能、與已移除程式碼無共享。詳見 6.5.6。
|
||||
|
||||
#### 6.5.0a 功能分級:文本級 vs 段落級 + 元素標記(前置基礎設施)
|
||||
@@ -860,8 +870,8 @@ order `90 jiyaLineEdge`,`revert` 清 `jz-half-le`。純版面、jsdom 跳過
|
||||
`ResolvedOptions.lineEnd`/`features.hanging`;`index.ts` 之 `lineEnd` 鎖。行端僅餘半形擠壓
|
||||
(`jz-half-le`)。`hanging` 公開選項保留為 **@deprecated no-op**(API 相容;測試覆蓋
|
||||
option/data-juzhen/blocks 各路徑皆不產生 jz-hang-* 且輸出與不傳一致)。
|
||||
- **未來路徑(與已移除碼無共享)**:原生 CSS `hanging-punctuation` 為唯一正解,惟 Chrome/
|
||||
Firefox 至今不支援(僅 Safari);且本庫 `jz-char` 為 inline-block 原子、非文本,原生懸掛
|
||||
- **未來路徑(與已移除碼無共享)**:原生 CSS `hanging-punctuation` 為可評估路徑,須另行核對
|
||||
各引擎實際能力及字型行為;且本庫 `jz-char` 為 inline-block 原子、非文本,原生懸掛
|
||||
不作用之。未來若做,須是**繞開 jz-char 的「原生管線」新功能**——`text-spacing-trim` 接管
|
||||
擠壓 + `hanging-punctuation` 接管懸掛,按 `CSS.supports` 能力門控,整體退出 jz-char 機制。
|
||||
與已移除之負 margin 程式碼**沒有一行可複用**,故不保留休眠碼。
|
||||
|
||||
Reference in New Issue
Block a user