Skip to content

Commit

Permalink
Fix parsing of <script> and <style> tags
Browse files Browse the repository at this point in the history
- Ensure empty <script> tag is converted to a React element and
  not an empty array `[]`
- Add missing logic for parsing <style> DOM nodes to React element
- Update tests and mocks
  • Loading branch information
remarkablemark committed Aug 30, 2016
1 parent 7522a0a commit 9170e92
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
15 changes: 9 additions & 6 deletions lib/dom-to-react.js
Expand Up @@ -50,13 +50,16 @@ function domToReact(nodes, options) {
props = attributesToProps(node.attribs);
children = null;

// node type for script is "script" not "tag"
if (node.name === 'script' && node.children[0]) {
// prevent text in script tag from being escaped
// node type for <script> is "script"
// node type for <style> is "style"
if (node.type === 'script' || node.type === 'style') {
// prevent text in <script> or <style> from being escaped
// https://facebook.github.io/react/tips/dangerously-set-inner-html.html
props.dangerouslySetInnerHTML = {
__html: node.children[0].data
};
if (node.children[0]) {
props.dangerouslySetInnerHTML = {
__html: node.children[0].data
};
}

} else if (node.type === 'tag') {
// setting textarea value in children is an antipattern in React
Expand Down
1 change: 1 addition & 0 deletions test/data.json
Expand Up @@ -7,6 +7,7 @@
"complex": "<html><head><meta charset=\"utf-8\"/><title>Title</title><link rel=\"stylesheet\" href=\"style.css\"/></head><body><header id=\"header\">Header</header><h1 style=\"color:#000;font-size:42px;\">Heading</h1><hr/><p>Paragraph</p><img src=\"image.jpg\"/><div class=\"class1 class2\">Some <em>text</em>.</div><script>alert();</script></body></html>",
"textarea": "<textarea>foo</textarea>",
"script": "<script>alert(1 < 2);</script>",
"style": "<style>body > .foo { color: #f00; }</style>",
"img": "<img src=\"http://stat.ic/img.jpg\" alt=\"Image\"/>",
"void": "<link/><meta/><img/><br/><hr/><input/>",
"comment": "<!-- comment -->"
Expand Down
16 changes: 15 additions & 1 deletion test/dom-to-react.js
Expand Up @@ -54,7 +54,7 @@ describe('dom-to-react parser', function() {
);
});

it('converts <script> correctly', function() {
it('does not escape <script> content', function() {
var html = data.html.script;
var reactElement = domToReact(htmlToDOMServer(html));
assert(React.isValidElement(reactElement));
Expand All @@ -68,6 +68,20 @@ describe('dom-to-react parser', function() {
);
});

it('does not escape <style> content', function() {
var html = data.html.style;
var reactElement = domToReact(htmlToDOMServer(html));
assert(React.isValidElement(reactElement));
assert.deepEqual(
reactElement,
React.createElement('style', {
dangerouslySetInnerHTML: {
__html: 'body > .foo { color: #f00; }'
}
}, null)
);
});

it('does not have `children` for void elements', function() {
var html = data.html.img;
var reactElement = domToReact(htmlToDOMServer(html));
Expand Down
12 changes: 12 additions & 0 deletions test/html-to-react.js
Expand Up @@ -59,6 +59,18 @@ describe('html-to-react', function() {
assert.equal(helpers.render(reactElement), html);
});

it('converts empty <script> to React', function() {
var html = '<script></script>';
var reactElement = Parser(html);
assert.equal(helpers.render(reactElement), html);
});

it('converts empty <style> to React', function() {
var html = '<style></style>';
var reactElement = Parser(html);
assert.equal(helpers.render(reactElement), html);
});

it('converts SVG to React', function() {
var svg = data.svg.complex;
var reactElement = Parser(svg);
Expand Down

0 comments on commit 9170e92

Please sign in to comment.