Skip to content

Whitespace text nodes cannot appear as a child of <table> #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
benmb1984 opened this issue Jan 2, 2019 · 12 comments
Closed

Whitespace text nodes cannot appear as a child of <table> #79

benmb1984 opened this issue Jan 2, 2019 · 12 comments

Comments

@benmb1984
Copy link

benmb1984 commented Jan 2, 2019

When I want to create a React table from a multi line string I will get a warning from React:

index.js:1452 Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <table>. Make sure you don't have any extra whitespace between tags on each line of your source code.

Example code that will trigger the error

render() {
  const table = parser.parse(`
    <table>
      <tbody>
        <tr>
          <td>Lorem Ipsum</td>
        </tr>
      </tbody>
    </table>
  `);

  return (
    <React.Fragment>
      {table}
    </React.Fragment>
  );

Off course I can fix this warning by writing the table on one line, but that is not the solution where I'm looking for.
const table = parser.parse('<table><tbody><tr><td>Lorem Ipsum</td></tr></tbody></table>');

With dangerouslySetInnerHTML I can use a multi line string without any problems. I also tried the package html-react-parser but it will have the same problem.

Thanks for your time and help,
Ben

@aknuds1
Copy link
Owner

aknuds1 commented Jan 2, 2019 via email

@aknuds1
Copy link
Owner

aknuds1 commented Jan 2, 2019

Never mind, I see the error stems from React. Can you please provide a PR with a corresponding test case?

@aknuds1
Copy link
Owner

aknuds1 commented Jan 8, 2019

I looked a bit closer at the problem now, and I realize that htmlparser2, which we use to parse the HTML into a DOM tree, creates whitespace text nodes corresponding to the indentation in the input HTML.

The question, as I see it is, should we solve this by compacting the input HTML (i.e., "de-prettifying" it)? That's the potential solution I see. However, neither htmlparser2 does this nor React (as is evident from the warning you get). The question is then why should de-prettification be part of html-to-react? I'm dubious as to whether html-to-react should implement HTML compacting, when support for this would be more natural in htmlparser2.

I think this issue in htmlparser2 corresponds to the functionality you're requesting. There's also this issue.

I think the best option might be to compact the HTML yourself before parsing it with html-to-react, as sanitizing the HTML is really out of the scope html-to-react tries to solve.

You should alternatively be able to use a custom processing instruction to drop whitespace text nodes.

@benmb1984
Copy link
Author

I think you are right that support for this would be more natural in htmlparser2. On the other hand html-to-react is specific for React and with this mindset it would be great if it can catch struggles like this.

Before I was already de-prettifying table HTML but the function/regex became too complex. https://stackoverflow.com/questions/53988210/remove-whitespace-between-table-tags. My scripting skills does not go that far to create a descent solution.

Many thanks for now!

@nvenegas
Copy link

nvenegas commented Apr 10, 2019

You should alternatively be able to use a custom processing instruction to drop whitespace text nodes.

In case it isn't clear how to drop whitespace nodes, here's a TypeScript example:

import { DomElement } from 'htmlparser2';

function isDescendantTableTag(parent: Pick<DomElement, 'name'>, node: Pick<DomElement, 'name'>): boolean {
  const descendants: Record<string, string[]> = {
    table: ['colgroup', 'thead', 'tbody'],
    colgroup: ['col'],
    thead: ['tr'],
    tbody: ['tr'],
    tr: ['th', 'td'],
  };

  if (!parent.name || !node.name) {
    return false;
  }

  return (descendants[parent.name] || []).indexOf(node.name) >= 0;
}

const ignoreWhitespaceBetweenTableTags = {
  shouldProcessNode(node: Pick<DomElement, 'next' | 'parent' | 'prev' | 'type'>) {
    if (node.type === 'text' && node.parent) {
      if (node.next) {
        return isDescendantTableTag(node.parent, node.next);
      }
      if (node.prev) {
        return isDescendantTableTag(node.parent, node.prev);
      }
    }
    return false;
  },
  processNode() {
    return null;
  },
};

@cwellsx
Copy link

cwellsx commented Jun 25, 2019

I had the same problem -- and so I wrote a series of regular expressions to preprocess the HTML (i.e. to strip whitespace between table tags).

@C0DK
Copy link

C0DK commented Aug 28, 2019

Is this being addressed? i can see that the issue is closed on html2parser?.

@aknuds1
Copy link
Owner

aknuds1 commented Aug 28, 2019

@C0DK Have you tried the test in #80, to see if it's fixed or not?

@ysulyma
Copy link

ysulyma commented Sep 8, 2019

@nicolasv thank you, this is solving my problem. Can you include the definition of the type DomElement? That isn't defined in either TypeScript or React.

@C0DK
Copy link

C0DK commented Sep 10, 2019

@aknuds1 i did not. i simply reformated my code so it wasn't an issue. It just seems like a bug that it is so syntax dependent, and even more that i have to create some custom code to make it possible to write the layout however i like, essentially.. but I don't really care enough to put in the energy to fix it :P I'm bad like that.

@nvenegas
Copy link

nvenegas commented Sep 15, 2019

@nicolasv thank you, this is solving my problem. Can you include the definition of the type DomElement? That isn't defined in either TypeScript or React.

@ysulyma I've updated my code listing to include the following import

import { DomElement } from 'htmlparser2';

@constantindjonkam
Copy link

On my end. I removed all spaces in between my fragment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants