Skip to content

Commit 7c05003

Browse files
authored
fix: properly support details and summary elements (#5285)
This fixes headings inside of summary and interactive elements inside of details content.
1 parent 83159aa commit 7c05003

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

apps/builder/app/shared/content-model.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,40 @@ test("support xml node with tags", () => {
521521
).toBeTruthy();
522522
});
523523

524+
test("support headings inside of summary", () => {
525+
expect(
526+
isTreeSatisfyingContentModel({
527+
...renderData(
528+
<ws.element ws:tag="body" ws:id="bodyId">
529+
<ws.element ws:tag="details">
530+
<ws.element ws:tag="summary">
531+
<ws.element ws:tag="h3"></ws.element>
532+
</ws.element>
533+
</ws.element>
534+
</ws.element>
535+
),
536+
metas: defaultMetas,
537+
instanceSelector: ["bodyId"],
538+
})
539+
).toBeTruthy();
540+
});
541+
542+
test("support links inside of details", () => {
543+
expect(
544+
isTreeSatisfyingContentModel({
545+
...renderData(
546+
<ws.element ws:tag="body" ws:id="bodyId">
547+
<ws.element ws:tag="details">
548+
<ws.element ws:tag="a"></ws.element>
549+
</ws.element>
550+
</ws.element>
551+
),
552+
metas: defaultMetas,
553+
instanceSelector: ["bodyId"],
554+
})
555+
).toBeTruthy();
556+
});
557+
524558
describe("component content model", () => {
525559
test("restrict children with specific component", () => {
526560
expect(

packages/html-data/bin/elements.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,30 @@ const elementsByTag: Record<string, Element> = {};
4545
return !tag.includes(" ");
4646
});
4747
const description = getTextContent(row.childNodes[1]);
48-
const categories = parseList(getTextContent(row.childNodes[2]));
48+
let categories = parseList(getTextContent(row.childNodes[2])).map(
49+
(item) => {
50+
if (item === "heading") {
51+
// legend and summary refer to it as heading content
52+
return "heading content";
53+
}
54+
return item;
55+
}
56+
);
4957
let children = parseList(getTextContent(row.childNodes[4]));
5058
for (const tag of elements) {
5159
// textarea does not have value attribute and text content is used as initial value
5260
// introduce fake value attribute to manage initial state similar to input
5361
if (tag === "textarea") {
5462
children = [];
5563
}
64+
// move interactive category from details to summary
65+
// so details content could accept other interactive elements
66+
if (tag === "details") {
67+
categories = categories.filter((item) => item !== "interactive");
68+
}
69+
if (tag === "summary") {
70+
categories.push("interactive");
71+
}
5672
elementsByTag[tag] = {
5773
description,
5874
categories,

packages/html-data/src/__generated__/elements.ts

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)