Skip to content

Refactor HTML to DOM modules and environment detection logic #5

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

Merged
merged 1 commit into from
Aug 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,21 @@
/**
* Module dependencies.
*/
var htmlToDOM = require('./lib/html-to-dom');
var domToReact = require('./lib/dom-to-react');
var htmlToDOM;

/**
* Detect environment.
*/

/** Client (Browser). */
if (typeof window !== 'undefined' && this === window) {
htmlToDOM = require('./html-to-dom-client');

/** Server (Node). */
} else {
htmlToDOM = require('./lib/html-to-dom-server');
}

/**
* Convert HTML to React.
Expand All @@ -14,11 +27,6 @@ var domToReact = require('./lib/dom-to-react');
* @param {Function} [options.replace] - The replace method.
* @return {ReactElement|Array}
*/
function htmlToReact(html, options) {
module.exports = function(html, options) {
return domToReact(htmlToDOM(html), options);
}

/**
* Export HTML to React parser.
*/
module.exports = htmlToReact;
};
30 changes: 28 additions & 2 deletions lib/html-to-dom-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ function formatDOM(nodes, parentNode) {
}

/**
* Export HTML to DOM client helper.
* Parse HTML string to DOM nodes.
* This uses the browser DOM API.
*
* @param {String} html - The HTML.
* @return {Object} - The DOM nodes.
*/
function htmlToDOMClient(html) {
var root;

// `DOMParser` can parse full HTML
// https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
if (window.DOMParser) {
var parser = new window.DOMParser();
root = parser.parseFromString(html, 'text/html');

// otherwise, use `innerHTML`
// but this will strip out tags like <html> and <body>
} else {
root = document.createElement('div');
root.innerHTML = html;
}

return formatDOM(root.childNodes);
}

/**
* Export HTML to DOM parser (client).
*/
module.exports = formatDOM;
module.exports = htmlToDOMClient;
26 changes: 26 additions & 0 deletions lib/html-to-dom-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

/**
* Module dependencies.
*/
var Parser = require('htmlparser2/lib/Parser');
var DomHandler = require('domhandler');

/**
* Parse HTML string to DOM nodes.
* This is the same method as `require('htmlparser2').parseDOM`.
*
* @param {String} html - The HTML.
* @param {Object} options - The parser options.
* @return {Object} - The DOM nodes.
*/
function htmlToDOMServer(html, options) {
var handler = new DomHandler(options);
new Parser(handler, options).end(html);
return handler.dom;
}

/**
* Export HTML to DOM parser (server).
*/
module.exports = htmlToDOMServer;
53 changes: 0 additions & 53 deletions lib/html-to-dom.js

This file was deleted.

2 changes: 1 addition & 1 deletion test/attributes-to-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('attributes to props helper', function() {
{
className: 'ic',
htmlFor: 'tran',
httpEquiv: 'refresh',
httpEquiv: 'refresh'
}
);
});
Expand Down
12 changes: 6 additions & 6 deletions test/dom-to-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
var assert = require('assert');
var React = require('react');
var htmlToDOM = require('../lib/html-to-dom');
var htmlToDOMServer = require('../lib/html-to-dom-server');
var domToReact = require('../lib/dom-to-react');
var data = require('./data');

Expand All @@ -16,7 +16,7 @@ describe('dom-to-react parser', function() {

it('converts single DOM node to React', function() {
var html = data.html.single;
var reactElement = domToReact(htmlToDOM(html));
var reactElement = domToReact(htmlToDOMServer(html));
assert(React.isValidElement(reactElement));
assert.deepEqual(
reactElement,
Expand All @@ -26,7 +26,7 @@ describe('dom-to-react parser', function() {

it('converts multiple DOM nodes to React', function() {
var html = data.html.multiple;
var reactElements = domToReact(htmlToDOM(html));
var reactElements = domToReact(htmlToDOMServer(html));
reactElements.forEach(function(reactElement) {
assert(React.isValidElement(reactElement));
assert(reactElement.key);
Expand All @@ -43,7 +43,7 @@ describe('dom-to-react parser', function() {
// https://facebook.github.io/react/docs/forms.html#why-textarea-value
it('converts <textarea> correctly', function() {
var html = data.html.textarea;
var reactElement = domToReact(htmlToDOM(html));
var reactElement = domToReact(htmlToDOMServer(html));
assert(React.isValidElement(reactElement));
assert.deepEqual(
reactElement,
Expand All @@ -55,7 +55,7 @@ describe('dom-to-react parser', function() {

it('converts <script> correctly', function() {
var html = data.html.script;
var reactElement = domToReact(htmlToDOM(html));
var reactElement = domToReact(htmlToDOMServer(html));
assert(React.isValidElement(reactElement));
assert.deepEqual(
reactElement,
Expand All @@ -69,7 +69,7 @@ describe('dom-to-react parser', function() {

it('skips HTML comments', function() {
var html = [data.html.single, data.html.comment, data.html.single].join('');
var reactElements = domToReact(htmlToDOM(html));
var reactElements = domToReact(htmlToDOMServer(html));
reactElements.forEach(function(reactElement) {
assert(React.isValidElement(reactElement));
assert(reactElement.key);
Expand Down
21 changes: 11 additions & 10 deletions test/html-to-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ var assert = require('assert');
var util = require('util');
var jsdomify = require('jsdomify').default;
var htmlparser = require('htmlparser2');
var parseDOM = require('../lib/html-to-dom');
var formatDOM = require('../lib/html-to-dom-client');
var htmlToDOMServer = require('../lib/html-to-dom-server');
var htmlToDOMClient = require('../lib/html-to-dom-client');
var helpers = require('./helpers/');
var data = require('./data');

Expand All @@ -26,7 +26,7 @@ describe('html-to-dom', function() {
var html = data.html.complex;
// use `util.inspect` to resolve circular references
assert.equal(
util.inspect(parseDOM(html), { showHidden: true, depth: null }),
util.inspect(htmlToDOMServer(html), { showHidden: true, depth: null }),
util.inspect(htmlparser.parseDOM(html), { showHidden: true, depth: null })
);
});
Expand All @@ -48,13 +48,14 @@ describe('html-to-dom', function() {
jsdomify.destroy();
});

it('formats the nodes like `htmlparser2.parseDOM`', function() {
var html = data.html.attributes + data.html.nested + data.html.comment + data.html.script;
var root = document.createElement('div');
root.innerHTML = html;
var clientNodes = formatDOM(root.childNodes);
var serverNodes = parseDOM(html);
helpers.deepEqualCircular(clientNodes, serverNodes);
it('outputs the same result as the server parser', function() {
var html = (
data.html.attributes +
data.html.nested +
data.html.comment +
data.html.script
);
helpers.deepEqualCircular(htmlToDOMClient(html), htmlToDOMServer(html));
});

});
Expand Down