mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(ui): ensure GFM tables render in WebChat markdown (#20410)
- Pass gfm:true + breaks:true explicitly to marked.parse() so table support is guaranteed even if global setOptions() is bypassed or reset by a future refactor (defense-in-depth) - Add display:block + overflow-x:auto to .chat-text table so wide multi-column tables scroll horizontally instead of being clipped by the parent overflow-x:hidden chat container - Add regression tests for GFM table rendering in markdown.test.ts
This commit is contained in:
committed by
Peter Steinberger
parent
346d3590fb
commit
5084621f43
@@ -1923,7 +1923,10 @@
|
|||||||
margin-top: 0.75em;
|
margin-top: 0.75em;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-text :where(th, td) {
|
.chat-text :where(th, td) {
|
||||||
|
|||||||
@@ -48,4 +48,38 @@ describe("toSanitizedMarkdownHtml", () => {
|
|||||||
expect(html).not.toContain("javascript:");
|
expect(html).not.toContain("javascript:");
|
||||||
expect(html).not.toContain("src=");
|
expect(html).not.toContain("src=");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("renders GFM markdown tables (#20410)", () => {
|
||||||
|
const md = [
|
||||||
|
"| Feature | Status |",
|
||||||
|
"|---------|--------|",
|
||||||
|
"| Tables | ✅ |",
|
||||||
|
"| Borders | ✅ |",
|
||||||
|
].join("\n");
|
||||||
|
const html = toSanitizedMarkdownHtml(md);
|
||||||
|
expect(html).toContain("<table");
|
||||||
|
expect(html).toContain("<thead");
|
||||||
|
expect(html).toContain("<th>");
|
||||||
|
expect(html).toContain("Feature");
|
||||||
|
expect(html).toContain("Tables");
|
||||||
|
expect(html).not.toContain("|---------|");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders GFM tables surrounded by text (#20410)", () => {
|
||||||
|
const md = [
|
||||||
|
"Text before.",
|
||||||
|
"",
|
||||||
|
"| Col1 | Col2 |",
|
||||||
|
"|------|------|",
|
||||||
|
"| A | B |",
|
||||||
|
"",
|
||||||
|
"Text after.",
|
||||||
|
].join("\n");
|
||||||
|
const html = toSanitizedMarkdownHtml(md);
|
||||||
|
expect(html).toContain("<table");
|
||||||
|
expect(html).toContain("Col1");
|
||||||
|
expect(html).toContain("Col2");
|
||||||
|
// Pipes from table delimiters must not appear as raw text
|
||||||
|
expect(html).not.toContain("|------|");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ export function toSanitizedMarkdownHtml(markdown: string): string {
|
|||||||
}
|
}
|
||||||
const rendered = marked.parse(`${truncated.text}${suffix}`, {
|
const rendered = marked.parse(`${truncated.text}${suffix}`, {
|
||||||
renderer: htmlEscapeRenderer,
|
renderer: htmlEscapeRenderer,
|
||||||
|
gfm: true,
|
||||||
|
breaks: true,
|
||||||
}) as string;
|
}) as string;
|
||||||
const sanitized = DOMPurify.sanitize(rendered, sanitizeOptions);
|
const sanitized = DOMPurify.sanitize(rendered, sanitizeOptions);
|
||||||
if (input.length <= MARKDOWN_CACHE_MAX_CHARS) {
|
if (input.length <= MARKDOWN_CACHE_MAX_CHARS) {
|
||||||
|
|||||||
Reference in New Issue
Block a user