Skip to content

Commit 6b3ad1b

Browse files
committed
Prevent span elements in table html
Prevent span elements from being created for each newline character in the html string returned by the markdown parser. These span elements should not exist in the table markup which is causing css rules to not work as expected.
1 parent d719b6b commit 6b3ad1b

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

src/vs/base/common/htmlParser.ts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ const voidElements: Record<string, boolean> = {
8484
'wbr': true
8585
};
8686

87+
/**
88+
* Quick lookup table for table elements.
89+
*/
90+
const tableElements: Record<string, boolean> = {
91+
'table': true,
92+
'thead': true,
93+
'tbody': true,
94+
'tfoot': true,
95+
'tr': true,
96+
'colgroup': true
97+
};
98+
8799
/**
88100
* Checks if a node is nested inside a <pre> element.
89101
* In <pre> elements, whitespace must be preserved per HTML spec.
@@ -107,6 +119,19 @@ function isInsidePreElement(node: HtmlNode | undefined): boolean {
107119
return false;
108120
}
109121

122+
/**
123+
* Checks if a node is a table elemen
124+
*
125+
* @param node The node to check (typically parent of a text node)
126+
* @returns true if node is a table element
127+
*/
128+
function isTableElement(node: HtmlNode | undefined): boolean {
129+
if (!node || !node.name) {
130+
return false;
131+
}
132+
return tableElements[node.name] === true;
133+
}
134+
110135
/**
111136
* Parses a single HTML tag.
112137
*
@@ -321,14 +346,22 @@ export function parseHtml(html: string): Array<HtmlNode> {
321346
nextChar &&
322347
nextChar !== '<'
323348
) {
324-
// This is a text node; add it as a child node
325-
if (current.children === undefined) {
326-
current.children = [];
349+
const textContent = html.slice(start, html.indexOf('<', start));
350+
const isWhitespace = whitespaceRE.test(textContent);
351+
// Check if we are in a table element context with whitespace-only text node
352+
const whitespaceInTable = isWhitespace && isTableElement(current);
353+
354+
// Don't add whitespace-only text nodes if they are inside table elements
355+
if (!whitespaceInTable) {
356+
// This is a text node; add it as a child node
357+
if (current.children === undefined) {
358+
current.children = [];
359+
}
360+
current.children.push({
361+
type: 'text',
362+
content: decode(textContent),
363+
});
327364
}
328-
current.children.push({
329-
type: 'text',
330-
content: decode(html.slice(start, html.indexOf('<', start))),
331-
});
332365
}
333366

334367
// if we're at root, push new base node
@@ -383,11 +416,14 @@ export function parseHtml(html: string): Array<HtmlNode> {
383416
content = ' ';
384417
}
385418

386-
// Don't add whitespace-only text nodes if they would be trailing text nodes
387-
// or if they would be leading whitespace-only text nodes:
419+
// Check if we are in a table element context with whitespace-only text node
420+
const whitespaceInTable = whitespaceRE.test(content) && isTableElement(current);
421+
422+
// Don't add whitespace-only text nodes if they would be: trailing text nodes
423+
// leading whitespace-only text nodes, or inside table elements:
388424
// * end > -1 indicates this is not a trailing text node
389425
// * leading node is when level is -1 and parent has length 0
390-
if ((end > -1 && level + parent.length >= 0) || content !== ' ') {
426+
if (!whitespaceInTable && ((end > -1 && level + parent.length >= 0) || content !== ' ')) {
391427
parent.push({
392428
type: 'text',
393429
parent: current,

0 commit comments

Comments
 (0)