Skip to content

Commit

Permalink
Fix to filter whitespace in tables
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Jan 18, 2023
1 parent 0682f97 commit b660735
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
31 changes: 26 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,23 @@ import {stringify as spaces} from 'space-separated-tokens'
import styleToObject from 'style-to-object'
import {pointStart} from 'unist-util-position'
import {VFileMessage} from 'vfile-message'
import {whitespace} from 'hast-util-whitespace'

const own = {}.hasOwnProperty

// `react-dom` triggers a warning for *any* white space in tables.
// To follow GFM, `mdast-util-to-hast` injects line endings between elements.
// Other tools might do so too, but they don’t do here, so we remove all of
// that.

// See: <https://github.com/facebook/react/pull/7081>.
// See: <https://github.com/facebook/react/pull/7515>.
// See: <https://github.com/remarkjs/remark-react/issues/64>.
// See: <https://github.com/rehypejs/rehype-react/pull/29>.
// See: <https://github.com/rehypejs/rehype-react/pull/32>.
// See: <https://github.com/rehypejs/rehype-react/pull/45>.
const tableElements = new Set(['table', 'thead', 'tbody', 'tfoot', 'tr'])

/**
* Transform a hast tree to preact, react, solid, svelte, vue, etc.,
* with an automatic JSX runtime.
Expand Down Expand Up @@ -272,14 +286,21 @@ function one(state, node, key) {
state.schema = schema
}

const children = createChildren(state, node)
let children = createChildren(state, node)
const props = createProperties(state, node)
let type = state.Fragment

let type = node.type === 'root' ? state.Fragment : node.tagName
if (node.type === 'element') {
if (tableElements.has(node.tagName)) {
children = children.filter((child) => !whitespace(child))
}

if (typeof type === 'string' && own.call(state.components, type)) {
const key = /** @type {keyof JSX.IntrinsicElements} */ (type)
type = state.components[key]
if (own.call(state.components, node.tagName)) {
const key = /** @type {keyof JSX.IntrinsicElements} */ (node.tagName)
type = state.components[key]
} else {
type = node.tagName
}
}

props.children = children
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@types/hast": "^2.0.0",
"@types/unist": "^2.0.0",
"comma-separated-tokens": "^2.0.0",
"hast-util-whitespace": "^2.0.0",
"property-information": "^6.0.0",
"space-separated-tokens": "^2.0.0",
"style-to-object": "^0.4.1",
Expand Down
35 changes: 35 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,38 @@ test('components', () => {
'should support class components'
)
})

test('react specific: filter whitespace in tables', () => {
assert.equal(
renderToStaticMarkup(
toJsxRuntime(
h(null, [
h('table', [
' ',
h('thead', [
' ',
h('tr', [' ', h('th', [' ', h('b', 'a'), ' ']), ' ']),
' '
]),
' ',
h('tbody', [
' ',
h('tr', [' ', h('td', [' ', h('b', 'b'), ' ']), ' ']),
' '
]),
' ',
h('tfoot', [
' ',
h('tr', [' ', h('td', [' ', h('b', 'c'), ' ']), ' ']),
' '
]),
' '
])
]),
production
)
),
'<table><thead><tr><th> <b>a</b> </th></tr></thead><tbody><tr><td> <b>b</b> </td></tr></tbody><tfoot><tr><td> <b>c</b> </td></tr></tfoot></table>',
'should ignore whitespace in `table`, `thead`, `tbody`, `tfoot`, and `tr`'
)
})

0 comments on commit b660735

Please sign in to comment.