diff --git a/README.md b/README.md index a242442d..144b4c1f 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,32 @@ See [htmlparser2 options](https://github.com/fb55/htmlparser2/wiki/Parser-option > **Warning**: By overriding htmlparser2 options, there's a chance of breaking universal rendering. Do this at your own risk. +### trim + +Normally, whitespace is preserved: + +```js +parse('
\n'); // [React.createElement('br'), '\n'] +``` + +By enabling the `trim` option, whitespace text nodes will be skipped: + +```js +parse('
\n', { trim: true }); // React.createElement('br') +``` + +This addresses the warning: + +``` +Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of . Make sure you don't have any extra whitespace between tags on each line of your source code. +``` + +However, this option may strip out intentional whitespace: + +```js +parse('

', { trim: true }); // React.createElement('p') +``` + ## FAQ #### Is this library XSS safe? @@ -288,6 +314,10 @@ parse('
'); // returns single element instead of array of elements See [#158](https://github.com/remarkablemark/html-react-parser/issues/158). +#### I get "Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of table." + +Enable the [trim](https://github.com/remarkablemark/html-react-parser#trim) option. See [#155](https://github.com/remarkablemark/html-react-parser/issues/155). + ## Benchmarks ```sh diff --git a/index.d.ts b/index.d.ts index 28b40dc3..c67d6aaf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -21,6 +21,8 @@ export interface HTMLReactParserOptions { replace?: ( domNode: DomElement ) => JSX.Element | object | void | undefined | null | false; + + trim?: boolean; } /** diff --git a/lib/dom-to-react.js b/lib/dom-to-react.js index 695dd2de..7e3d788e 100644 --- a/lib/dom-to-react.js +++ b/lib/dom-to-react.js @@ -24,6 +24,8 @@ function domToReact(nodes, options) { var replaceElement; var props; var children; + var data; + var trim = options.trim; for (var i = 0, len = nodes.length; i < len; i++) { node = nodes[i]; @@ -33,7 +35,7 @@ function domToReact(nodes, options) { replaceElement = options.replace(node); if (isValidElement(replaceElement)) { - // specify a "key" prop if element has siblings + // set "key" prop for sibling elements // https://fb.me/react-warning-keys if (len > 1) { replaceElement = cloneElement(replaceElement, { @@ -46,45 +48,54 @@ function domToReact(nodes, options) { } if (node.type === 'text') { - result.push(node.data); + // if trim option is enabled, skip whitespace text nodes + if (trim) { + data = node.data.trim(); + if (data) { + result.push(node.data); + } + } else { + result.push(node.data); + } continue; } props = node.attribs; if (!shouldPassAttributesUnaltered(node)) { - // update values props = attributesToProps(node.attribs); } children = null; - // node type for