Skip to content

Commit

Permalink
Merge pull request #2 from wrakky/void_elements
Browse files Browse the repository at this point in the history
Add void element checking to TagElementType
  • Loading branch information
peternewnham committed Jan 29, 2016
2 parents 8b179c8 + 91729ec commit 492441b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# React HTML Parser

A utility library for converting HTML strings into [React](https://facebook.github.io/react/) components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.
A utility for converting HTML strings into [React](https://facebook.github.io/react/) components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.

[Try the Live Demo](https://wrakky.github.io/react-html-parser)

Expand Down
10 changes: 7 additions & 3 deletions src/elementTypes/TagElementType.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import ProcessNodes from '../utils/ProcessNodes';
import GeneratePropsFromAttributes from '../utils/GeneratePropsFromAttributes';
import TransformTagName from '../utils/TransformTagName';
import isVoidElement from '../utils/isVoidElement';

/**
* Converts any element (excluding style - see StyleElementType - and script) to a react element.
Expand All @@ -12,15 +13,18 @@ import TransformTagName from '../utils/TransformTagName';
*/
export default function TagElementType(node, key) {

// If the node has children process them
const children = ProcessNodes(node.children);

// generate props
const props = GeneratePropsFromAttributes(node.attribs, key);

// transform the tag name if needed
const tagName = TransformTagName(node.name);

// If the node is not a void element and has children then process them
let children = null;
if (!isVoidElement(tagName)) {
children = ProcessNodes(node.children);
}

// create and return the element
return React.createElement(tagName, props, children);
}
24 changes: 24 additions & 0 deletions src/utils/isVoidElement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const voidElements = [
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
];

export default function isVoidElement(element) {

return voidElements.indexOf(element) >= 0;

}
4 changes: 4 additions & 0 deletions test/integration/integration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,8 @@ describe('Integration tests: ', () => {
test('<body>test</body>', '<div>test</div>');
});

it('should not allow nesting of void elements', () => {
test('<img><p>test</p></img>', '<img/><p>test</p>');
});

});
22 changes: 21 additions & 1 deletion test/unit/elementTypes/TagElementType.spec.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
const GeneratePropsFromAttributes = jasmine.createSpy('GeneratePropsFromAttributes').and.callFake(attrs => attrs);
const ProcessNodes = jasmine.createSpy('ProcessNodes').and.returnValue('children');
const isVoidElement = jasmine.createSpy('isVoidElement').and.returnValue(false);

const TagElementType = require('inject!elementTypes/TagElementType')({
'../utils/GeneratePropsFromAttributes': GeneratePropsFromAttributes,
'../utils/ProcessNodes': ProcessNodes
'../utils/ProcessNodes': ProcessNodes,
'../utils/isVoidElement': isVoidElement
}).default;

describe('Testing `elementTypes/TagElementType', () => {

beforeEach(() => {
GeneratePropsFromAttributes.calls.reset();
ProcessNodes.calls.reset();
isVoidElement.calls.reset();
});

it('should return a React element corresponding to the node name', () => {
Expand All @@ -33,4 +36,21 @@ describe('Testing `elementTypes/TagElementType', () => {

});

it('should not pass though children for void elements', () => {

const voidNode = {
name: 'void',
attribs: {
id: 'test'
},
children: 'child'
};
isVoidElement.and.returnValue(true);

const voidElement = TagElementType(voidNode, 'key');
expect(voidElement.type).toBe('void');
expect(voidElement.props.children).toBe(null);

});

});
12 changes: 12 additions & 0 deletions test/unit/utils/isVoidElement.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import isVoidElement from 'utils/isVoidElement';

describe('Testing `utils/isVoidElement`', () => {

it('should return whether the element is a void element', () => {
expect(isVoidElement('img')).toBe(true);
expect(isVoidElement('br')).toBe(true);
expect(isVoidElement('div')).toBe(false);
expect(isVoidElement('p')).toBe(false);
});

});

0 comments on commit 492441b

Please sign in to comment.