mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(sdk): preserve unquoted escapes in inline styles (#5246)
This commit is contained in:
@@ -236,11 +236,11 @@ interface StyleDeclarationScan {
|
||||
}
|
||||
|
||||
function advanceStyleDeclarationScan(scan: StyleDeclarationScan, ch: string, next: string): void {
|
||||
if (ch === "\\" && next) {
|
||||
scan.skip = true;
|
||||
return;
|
||||
}
|
||||
if (scan.quote) {
|
||||
if (ch === "\\" && next) {
|
||||
scan.skip = true;
|
||||
return;
|
||||
}
|
||||
if (ch === scan.quote) scan.quote = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -914,6 +914,52 @@ describe("setElementStyles key normalization", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("setElementStyles unquoted CSS escapes", () => {
|
||||
it.each([
|
||||
[
|
||||
"semicolon",
|
||||
String.raw`--label: alpha\;beta; width: 120px; color: red`,
|
||||
String.raw`alpha\;beta`,
|
||||
],
|
||||
[
|
||||
"opening parenthesis",
|
||||
String.raw`--label: alpha\(beta; width: 120px; color: red`,
|
||||
String.raw`alpha\(beta`,
|
||||
],
|
||||
[
|
||||
"double quote",
|
||||
String.raw`--label: alpha\"beta; width: 120px; color: red`,
|
||||
String.raw`alpha\"beta`,
|
||||
],
|
||||
[
|
||||
"single quote",
|
||||
String.raw`--label: alpha\'beta; width: 120px; color: red`,
|
||||
String.raw`alpha\'beta`,
|
||||
],
|
||||
])("preserves an escaped %s and the following declarations", (_name, style, label) => {
|
||||
const parsed = parseMutable('<div data-hf-id="hf-x" data-hf-root></div>');
|
||||
const el = parsed.document.querySelector('[data-hf-id="hf-x"]');
|
||||
if (!el) throw new Error("missing fixture element");
|
||||
el.setAttribute("style", style);
|
||||
expect(getElementStyles(el)).toMatchObject({ "--label": label, width: "120px", color: "red" });
|
||||
setElementStyles(el, { color: "blue" });
|
||||
expect(getElementStyles(el)).toMatchObject({ "--label": label, width: "120px", color: "blue" });
|
||||
});
|
||||
|
||||
it("treats the semicolon after an escaped backslash as a declaration boundary", () => {
|
||||
const parsed = parseMutable('<div data-hf-id="hf-x" data-hf-root></div>');
|
||||
const el = parsed.document.querySelector('[data-hf-id="hf-x"]');
|
||||
if (!el) throw new Error("missing fixture element");
|
||||
el.setAttribute("style", String.raw`--label: alpha\\; width: 120px; color: red`);
|
||||
setElementStyles(el, { color: "blue" });
|
||||
expect(getElementStyles(el)).toMatchObject({
|
||||
"--label": String.raw`alpha\\`,
|
||||
width: "120px",
|
||||
color: "blue",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ─── setVariableValue ─────────────────────────────────────────────────────────
|
||||
|
||||
describe("setVariableValue", () => {
|
||||
|
||||
@@ -185,3 +185,27 @@ describe("serialize() render-faithfulness (WS-F)", () => {
|
||||
expect(comp2.getElement("hf-body")?.text).toContain("Round-tripped body");
|
||||
});
|
||||
});
|
||||
|
||||
describe("serialize() preserves unquoted CSS escapes", () => {
|
||||
it.each([
|
||||
String.raw`alpha\;beta`,
|
||||
String.raw`alpha\(beta`,
|
||||
String.raw`alpha\"beta`,
|
||||
String.raw`alpha\'beta`,
|
||||
])("keeps %s through edit, undo, redo, and saved overrides", async (label) => {
|
||||
const style = `--label: ${label}; width: 120px; color: red`.replace(/"/g, """);
|
||||
const source = `<div data-hf-id="hf-box" data-hf-root style="${style}"></div>`;
|
||||
const comp = await openComposition(source);
|
||||
const expected = { "--label": label, width: "120px", color: "blue" };
|
||||
comp.setStyle("hf-box", { color: "blue" });
|
||||
expect(comp.getElement("hf-box")?.inlineStyles).toMatchObject(expected);
|
||||
comp.undo();
|
||||
expect(comp.getElement("hf-box")?.inlineStyles).toMatchObject({ ...expected, color: "red" });
|
||||
comp.redo();
|
||||
expect(comp.getElement("hf-box")?.inlineStyles).toMatchObject(expected);
|
||||
const reopened = await openComposition(comp.serialize());
|
||||
expect(reopened.getElement("hf-box")?.inlineStyles).toMatchObject(expected);
|
||||
const overrides = await openComposition(source, { overrides: comp.getOverrides() });
|
||||
expect(overrides.getElement("hf-box")?.inlineStyles).toMatchObject(expected);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user