fix(web): 修復排版邊界與增量生命週期
This commit is contained in:
@@ -730,3 +730,91 @@ test("observer provenance: transition inference and queue consumption scale line
|
||||
}
|
||||
context.diagnostic("linear probes complete " + JSON.stringify(reports));
|
||||
});
|
||||
|
||||
test("observer:手動局部操作先結算其他兄弟塊的待交付變更", async () =>
|
||||
{
|
||||
for (const operation of [ "render", "rerender", "revert" ])
|
||||
{
|
||||
const { dom, document } = setupDom('<main><p id="a">原文,甲。</p><p id="b">原文,乙。</p></main>');
|
||||
const root = document.querySelector("main");
|
||||
const a = document.getElementById("a");
|
||||
const b = document.getElementById("b");
|
||||
const jz = createJuzhen({ jinze: false, orphan: false, longWord: false });
|
||||
try
|
||||
{
|
||||
jz.render(root);
|
||||
jz.observe(root);
|
||||
a.textContent = "改後,新文。";
|
||||
jz[operation](b);
|
||||
await tick();
|
||||
assert.equal(a.querySelectorAll("jz-char").length, 2, operation + " 不丟棄兄弟變更");
|
||||
if (operation === "revert") { assert.equal(b.querySelector("[data-jz]"), null); }
|
||||
a.textContent = "再次,更新。";
|
||||
await tick();
|
||||
assert.equal(a.querySelectorAll("jz-char").length, 2, "結算後繼續觀察");
|
||||
}
|
||||
finally { jz.disconnect(); dom.window.close(); }
|
||||
}
|
||||
});
|
||||
|
||||
test("observer:祖先分類待更新時手動 revert 子塊仍最後生效", async () =>
|
||||
{
|
||||
const { dom, document } = setupDom('<main><p id="a">甲文,內容。</p><p id="b">乙文,內容。</p></main>');
|
||||
const root = document.querySelector("main");
|
||||
const a = document.getElementById("a");
|
||||
const b = document.getElementById("b");
|
||||
const jz = createJuzhen();
|
||||
try
|
||||
{
|
||||
jz.render(root);
|
||||
jz.observe(root);
|
||||
root.setAttribute("data-jz-level", "text");
|
||||
jz.revert(b);
|
||||
await tick();
|
||||
assert.equal(a.getAttribute("data-jz-block-level"), "text");
|
||||
assert.equal(a.querySelector("jz-orphan"), null, "兄弟塊採新祖先級別");
|
||||
assert.equal(b.querySelector("[data-jz]"), null, "舊祖先記錄不重新 render 已回退子塊");
|
||||
assert.equal(b.hasAttribute("data-jz-block-level"), false);
|
||||
}
|
||||
finally { jz.disconnect(); dom.window.close(); }
|
||||
});
|
||||
|
||||
test("observer:暫停前結算失敗仍非同步報錯,不阻擋手動操作及後續觀察", async () =>
|
||||
{
|
||||
const { dom, document } = setupDom('<main><p id="a">甲文,內容。</p><p id="b">乙文,內容。</p></main>');
|
||||
const root = document.querySelector("main");
|
||||
const a = document.getElementById("a");
|
||||
const b = document.getElementById("b");
|
||||
const expected = new Error("pending mutation failure");
|
||||
let shouldThrow = false;
|
||||
const errors = [];
|
||||
dom.window.addEventListener("error", (event) =>
|
||||
{
|
||||
errors.push(event.error);
|
||||
event.preventDefault();
|
||||
});
|
||||
const jz = createJuzhen({
|
||||
jinze: false, orphan: false, longWord: false,
|
||||
isSkipped(node)
|
||||
{
|
||||
if (shouldThrow && node === a) { shouldThrow = false; throw expected; }
|
||||
return false;
|
||||
},
|
||||
});
|
||||
try
|
||||
{
|
||||
jz.render(root);
|
||||
jz.observe(root);
|
||||
a.textContent = "改後,新文。";
|
||||
shouldThrow = true;
|
||||
assert.doesNotThrow(() => jz.revert(b), "舊 observer 錯誤不變成同步 API 例外");
|
||||
assert.equal(errors.length, 0);
|
||||
await tick();
|
||||
assert.deepEqual(errors, [ expected ]);
|
||||
assert.equal(b.querySelector("[data-jz]"), null);
|
||||
a.textContent = "再次,更新。";
|
||||
await tick();
|
||||
assert.equal(a.querySelectorAll("jz-char").length, 2);
|
||||
}
|
||||
finally { jz.disconnect(); dom.window.close(); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user