@@ -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