Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,17 @@ test.each<[string, Node, Node, string, Options | undefined]>([
'<p>123</p><p class="vdd-removed">456</p><p>789</p>',
undefined,
],
[
'table - identical (but with newline breaks)',
htmlToFragment(
'<table>\n<thead>\n<tr><th>Environment variable</th>\n<th>Zope option</th>\n<th>Default value</th>\n</tr>\n</thead>\n<tbody>\n<tr><td>DEBUG_MODE</td>\n<td>debug-mode</td>\n<td>off</td>\n</tr>\n</tbody>\n</table>',
),
htmlToFragment(
'<table>\n<thead>\n<tr><th>Environment variable</th>\n<th>Zope option</th>\n<th>Default value</th>\n</tr>\n</thead>\n<tbody>\n<tr><td>DEBUG_MODE</td>\n<td>debug-mode</td>\n<td>off</td>\n</tr>\n</tbody>\n</table>',
),
'<table>\n<thead>\n<tr><th>Environment variable</th>\n<th>Zope option</th>\n<th>Default value</th>\n</tr>\n</thead>\n<tbody>\n<tr><td>DEBUG_MODE</td>\n<td>debug-mode</td>\n<td>off</td>\n</tr>\n</tbody>\n</table>',
undefined,
],
[
'table - added',
htmlToFragment('<table><tbody><tr><td>one</td></tr></tbody></table>'),
Expand Down
44 changes: 28 additions & 16 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ function getAttributeNames(element: Element): string[] {
}
}

function stripNewlines(nodes: NodeList): Node[] {
return Array.from(nodes).filter((node: Node) => {
return (
node.nodeName !== '#text' ||
(node.textContent && node.textContent.trim() !== '')
)
})
}

/**
* Compares DOM nodes for equality.
* @param node1 The first node to compare.
Expand Down Expand Up @@ -322,31 +331,32 @@ export function isTableValid(table: Node, verifyColumns: boolean): boolean {
return validateTable(table)

function validateTable({ childNodes }: Node): boolean {
const l = childNodes.length
const filteredChildNodes = stripNewlines(childNodes)
const l = filteredChildNodes.length
let i = 0

if (i < l && childNodes[i].nodeName === 'CAPTION') {
if (i < l && filteredChildNodes[i].nodeName === 'CAPTION') {
i++
}

if (i < l && childNodes[i].nodeName === 'THEAD') {
if (!validateRowGroup(childNodes[i])) {
if (i < l && filteredChildNodes[i].nodeName === 'THEAD') {
if (!validateRowGroup(filteredChildNodes[i])) {
return false
}
i++
}

if (i < l && childNodes[i].nodeName === 'TBODY') {
if (!validateRowGroup(childNodes[i])) {
if (i < l && filteredChildNodes[i].nodeName === 'TBODY') {
if (!validateRowGroup(filteredChildNodes[i])) {
return false
}
i++
} else {
return false
}

if (i < l && childNodes[i].nodeName === 'TFOOT') {
if (!validateRowGroup(childNodes[i])) {
if (i < l && filteredChildNodes[i].nodeName === 'TFOOT') {
if (!validateRowGroup(filteredChildNodes[i])) {
return false
}
i++
Expand All @@ -356,30 +366,32 @@ export function isTableValid(table: Node, verifyColumns: boolean): boolean {
}

function validateRowGroup({ childNodes, nodeName }: Node): boolean {
if (nodeName === 'TBODY' && childNodes.length === 0) {
const filteredChildNodes = stripNewlines(childNodes)
if (nodeName === 'TBODY' && filteredChildNodes.length === 0) {
return false
}
for (let i = 0, l = childNodes.length; i < l; ++i) {
if (!validateRow(childNodes[i])) {
for (let i = 0, l = filteredChildNodes.length; i < l; ++i) {
if (!validateRow(filteredChildNodes[i])) {
return false
}
}
return true
}

function validateRow({ childNodes, nodeName }: Node): boolean {
if (nodeName !== 'TR' || childNodes.length === 0) {
const filteredChildNodes = stripNewlines(childNodes)
if (nodeName !== 'TR' || filteredChildNodes.length === 0) {
return false
}
if (verifyColumns) {
if (columnCount === undefined) {
columnCount = childNodes.length
} else if (columnCount !== childNodes.length) {
columnCount = filteredChildNodes.length
} else if (columnCount !== filteredChildNodes.length) {
return false
}
}
for (let i = 0, l = childNodes.length; i < l; ++i) {
if (!validateCell(childNodes[i])) {
for (let i = 0, l = filteredChildNodes.length; i < l; ++i) {
if (!validateCell(filteredChildNodes[i])) {
return false
}
}
Expand Down