feat: 功能分級(文本級 vs 段落級)+ data-jz-level 標記(§6.5.0a)
整體計劃 §6.5 之前置基礎設施。把已實作功能切為兩級:
- 文本級(spacing 中西間隙、jiya 標點擠壓/鄰接):任意文本片段皆適用。
- 段落級(jinze 禁則、longWord 斷詞、lineEdge 行端、gapTrim):需行/段布局。
標記 API:
- 預設塊級元素 → 段落級(全功能)。
- 元素屬性 data-jz-level="text"|"paragraph"(最近祖先勝)。
- 選項 level:{ text: "選擇器" }(如標題/按鈕一鍵降為文本級)。
實作:
- 每個 pass 加 level 元數據;Finder.levelFor/levelAllows(含快取)。
- charify 段落級 pass(longWord)於共享走訪受閘;standalone 段落級 pass
(jinze/lineEdge/gapTrim)逐元素受閘。文本級不受限。
- spacing 補單元素 root 支援:root 為行內/單一非塊元素時亦處理(標題等
之中西間隙、標點半形生效)。
6 項新單元測試(text-level 跳段落級、選擇器標記、巢狀最近勝、單元素 spacing、
預設段落級回歸)。共 76 測試全綠。
This commit is contained in:
@@ -642,3 +642,63 @@ test("charClass.biaodian:多子類同傳,各自生效(stop/pause)", ()
|
||||
const pause = p.querySelector("jz-char.bd-pause");
|
||||
assert.ok(pause && pause.classList.contains("jz-half"), "• → bd-pause 且開明式挤半形");
|
||||
});
|
||||
|
||||
// ----- 功能分級(§6.5.0a,text-level vs paragraph-level)-----
|
||||
|
||||
test("分級:data-jz-level=text 之子樹只跑文本級——jiya/spacing 生效、jinze 跳過", () =>
|
||||
{
|
||||
const { document } = setupDom('<p data-jz-level="text" lang="zh-Hant">說「你好」用Neovim寫</p>');
|
||||
createJuzhen().render(document.body);
|
||||
const p = document.querySelector("p");
|
||||
// 文本級:標點 charify(jz-char)、中西間隙(jz-hws)照常。
|
||||
assert.ok(countTag(p, "jz-char") >= 1, "text-level 仍跑 jiya(jz-char)");
|
||||
assert.ok(countTag(p, "jz-hws") >= 1, "text-level 仍跑 spacing(jz-hws)");
|
||||
// 段落級:禁則跳過——無 jz-jinze(「」本會綁鄰字)。
|
||||
assert.equal(countTag(p, "jz-jinze"), 0, "text-level 段落級禁則跳過(無 jz-jinze)");
|
||||
});
|
||||
|
||||
test("分級:data-jz-level=text 跳過段落級 longWord(charify 亦受閘)", () =>
|
||||
{
|
||||
const { document } = setupDom('<p data-jz-level="text">用 configuration 設定</p>');
|
||||
createJuzhen().render(document.body);
|
||||
const p = document.querySelector("p");
|
||||
assert.equal(p.querySelectorAll('[data-jz="longWord"]').length, 0, "text-level 不跑 longWord(無 span[data-jz=longWord])");
|
||||
});
|
||||
|
||||
test("分級:選項 level.text 選擇器標記(h1 → text-level,禁則跳過)", () =>
|
||||
{
|
||||
const { document } = setupDom('<h1 lang="zh-Hant">說「你好」結束</h1><p lang="zh-Hant">說「你好」結束</p>');
|
||||
createJuzhen({ level: { text: "h1" } }).render(document.body);
|
||||
const h1 = document.querySelector("h1");
|
||||
const p = document.querySelector("p");
|
||||
assert.equal(countTag(h1, "jz-jinze"), 0, "h1 命中 level.text → 段落級禁則跳過");
|
||||
assert.ok(countTag(h1, "jz-char") >= 1, "h1 文本級 jiya 仍生效");
|
||||
assert.ok(countTag(p, "jz-jinze") >= 1, "未命中之 p 仍跑禁則");
|
||||
});
|
||||
|
||||
test("分級:data-jz-level=paragraph 巢狀於 text 子樹內,最近祖先勝(恢復全功能)", () =>
|
||||
{
|
||||
const { document } = setupDom(
|
||||
'<div data-jz-level="text" lang="zh-Hant">'
|
||||
+ '<p data-jz-level="paragraph">說「你好」結束</p></div>',
|
||||
);
|
||||
createJuzhen().render(document.body);
|
||||
const p = document.querySelector("p");
|
||||
assert.ok(countTag(p, "jz-jinze") >= 1, "最近 data-jz-level=paragraph 勝 → 禁則恢復");
|
||||
});
|
||||
|
||||
test("分級:spacing 文本級支持單元素 root(render 於 <span>)", () =>
|
||||
{
|
||||
const { document } = setupDom("<span>我用Neovim寫程式</span>");
|
||||
const span = document.querySelector("span");
|
||||
createJuzhen({ jiya: false, jinze: false, longWord: false }).render(span);
|
||||
assert.ok(countTag(span, "jz-hws") >= 1, "行內單元素 root 亦補中西間隙");
|
||||
assert.equal(span.textContent, "我用Neovim寫程式", "textContent 不變");
|
||||
});
|
||||
|
||||
test("分級:預設(無標記)塊級元素為段落級——禁則照常", () =>
|
||||
{
|
||||
const { document } = setupDom('<p lang="zh-Hant">說「你好」結束</p>');
|
||||
createJuzhen().render(document.body);
|
||||
assert.ok(countTag(document.querySelector("p"), "jz-jinze") >= 1, "預設段落級,禁則綁定");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user