Skip to content

Commit e081474

Browse files
authored
fix: add td to th's implicit close set (#2389)
Opening a <th> now correctly auto-closes an open <td>, matching the HTML spec's optional tag rules. Previously <th> only closed other <th> elements, which caused <th> to become a child of <td> instead of a sibling. The <td> entry already had this the other way around. Ref: https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
1 parent 365b719 commit e081474

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

src/Parser.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,25 @@ describe("API", () => {
179179
p.write("<__proto__>");
180180
});
181181

182+
it("should implicitly close <td> when <th> opens", () => {
183+
const onclosetag = vi.fn();
184+
const onopentagname = vi.fn();
185+
186+
new Parser({ onclosetag, onopentagname }).end(
187+
"<table><tr><td>A<th>B</tr></table>",
188+
);
189+
190+
// <th> must auto-close <td>, making them siblings per the HTML spec
191+
expect(onclosetag).toHaveBeenCalledWith("td", true);
192+
const tdClose = onclosetag.mock.calls.findIndex(
193+
([name]: [string]) => name === "td",
194+
);
195+
const thOpen = onopentagname.mock.calls.findIndex(
196+
([name]: [string]) => name === "th",
197+
);
198+
expect(tdClose).toBeLessThan(thOpen);
199+
});
200+
182201
it("should support custom tokenizer", () => {
183202
class CustomTokenizer extends Tokenizer {}
184203

src/Parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const rtpTags = new Set(["rt", "rp"]);
1919

2020
const openImpliesClose = new Map<string, Set<string>>([
2121
["tr", new Set(["tr", "th", "td"])],
22-
["th", new Set(["th"])],
22+
["th", new Set(["th", "td"])],
2323
["td", new Set(["thead", "th", "td"])],
2424
["body", new Set(["head", "link", "script"])],
2525
["a", new Set(["a"])],

0 commit comments

Comments
 (0)