fix(webui): keep Markdown table diffs inline
This commit is contained in:
@@ -79,7 +79,7 @@ const LazyDiffSyntaxHighlight = lazy(async () => {
|
|||||||
const node = rows[index];
|
const node = rows[index];
|
||||||
if (!node) return line.content || " ";
|
if (!node) return line.content || " ";
|
||||||
return createSyntaxElement({
|
return createSyntaxElement({
|
||||||
node: trimTrailingLineBreak(node),
|
node: stripConflictingTableClass(trimTrailingLineBreak(node)),
|
||||||
stylesheet,
|
stylesheet,
|
||||||
useInlineStyles,
|
useInlineStyles,
|
||||||
key: `diff-code-${index}`,
|
key: `diff-code-${index}`,
|
||||||
@@ -184,3 +184,26 @@ function trimTrailingLineBreak(node: SyntaxNode): SyntaxNode {
|
|||||||
children[children.length - 1] = trimTrailingLineBreak(children[children.length - 1]!);
|
children[children.length - 1] = trimTrailingLineBreak(children[children.length - 1]!);
|
||||||
return { ...node, children };
|
return { ...node, children };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stripConflictingTableClass(node: SyntaxNode): SyntaxNode {
|
||||||
|
const className = node.properties?.className;
|
||||||
|
const children = node.children?.map(stripConflictingTableClass);
|
||||||
|
const hasTableClass = Array.isArray(className) && className.includes("table");
|
||||||
|
|
||||||
|
if (!hasTableClass && !children) return node;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
...(hasTableClass
|
||||||
|
? {
|
||||||
|
properties: {
|
||||||
|
...node.properties,
|
||||||
|
// Tailwind's global `.table` utility changes Prism's inline Markdown
|
||||||
|
// table tokens into CSS tables, splitting a single diff line vertically.
|
||||||
|
className: className.filter((name) => name !== "table"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...(children ? { children } : {}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,4 +61,41 @@ describe("DiffSyntaxHighlight with Prism", () => {
|
|||||||
expect(highlighted).toHaveAttribute("data-language", "tsx");
|
expect(highlighted).toHaveAttribute("data-language", "tsx");
|
||||||
expect(highlighted.querySelectorAll("tbody tr")).toHaveLength(4);
|
expect(highlighted.querySelectorAll("tbody tr")).toHaveLength(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves markdown table line boundaries", async () => {
|
||||||
|
const lines = [
|
||||||
|
"## 发布安排",
|
||||||
|
"",
|
||||||
|
"| 日期 | 角色 | 方向 | 是否进实验 |",
|
||||||
|
"| --- | --- | --- | --- |",
|
||||||
|
"| 7/22 | trust / core | data-driven | yes |",
|
||||||
|
];
|
||||||
|
|
||||||
|
render(
|
||||||
|
<ThemeProvider theme="light">
|
||||||
|
<DiffSyntaxHighlight
|
||||||
|
language="markdown"
|
||||||
|
lines={lines.map((content, index) => ({
|
||||||
|
kind: "add" as const,
|
||||||
|
old_lineno: null,
|
||||||
|
new_lineno: 20 + index,
|
||||||
|
content,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
</ThemeProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const highlighted = await screen.findByTestId(
|
||||||
|
"syntax-highlighted-diff-hunk",
|
||||||
|
{},
|
||||||
|
{ timeout: 10_000 },
|
||||||
|
);
|
||||||
|
const rows = [...highlighted.querySelectorAll("tbody tr")];
|
||||||
|
|
||||||
|
expect(rows).toHaveLength(lines.length);
|
||||||
|
expect(rows.map((row) => row.querySelector("td:last-child")?.textContent)).toEqual(
|
||||||
|
lines.map((line) => line || " "),
|
||||||
|
);
|
||||||
|
expect(highlighted.querySelector(".token.table")).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user