From 28f6ffa9f7e4799b7371f9a131b48cde1ea6fd0f Mon Sep 17 00:00:00 2001 From: Thomas Ebert Date: Sat, 17 Nov 2018 16:16:38 +0100 Subject: [PATCH] Add ability to pass in a custom parser e.g. for server-side-rendering. --- README.md | 9 +++++++++ package.json | 3 ++- src/index.js | 5 +++-- src/markup-to-vdom.js | 2 +- src/parse-markup.js | 5 +++-- test/index.js | 7 +++++++ 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7f5c42a..c219f73 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,15 @@ Subsequent `render()`s diff against that DOM just like a normal JSX rendering fl > render(, document.body); > ``` +`parser` – With this property you can pass in a custom parser, such as `dom-parser`. This enables you to do server-side-rendering. + +> ##### Example +> +> ```js +> const parser = typeof document==='undefined' && require('dom-parser'); +> render(); +> ``` + --- diff --git a/package.json b/package.json index 83ad74a..5e5d0dd 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "sinon": "^1.17.4", "sinon-chai": "^2.8.0", "uglify-js": "^2.6.2", - "webpack": "^1.13.1" + "webpack": "^1.13.1", + "dom-parser": "^0.1.5" } } diff --git a/src/index.js b/src/index.js index 92585bf..743bf46 100644 --- a/src/index.js +++ b/src/index.js @@ -25,7 +25,7 @@ export default class Markup extends Component { } } - render({ wrap=true, type, markup, components, reviver, onError, 'allow-scripts':allowScripts, 'allow-events':allowEvents, trim, ...props }) { + render({ wrap=true, type, markup, components, reviver, onError, 'allow-scripts':allowScripts, 'allow-events':allowEvents, trim, parser=null, ...props }) { let h = reviver || this.reviver || this.constructor.prototype.reviver || customReviver || defaultReviver, vdom; @@ -34,7 +34,8 @@ export default class Markup extends Component { let options = { allowScripts, allowEvents, - trim + trim, + parser }; try { diff --git a/src/markup-to-vdom.js b/src/markup-to-vdom.js index 552a5a7..d715915 100644 --- a/src/markup-to-vdom.js +++ b/src/markup-to-vdom.js @@ -10,7 +10,7 @@ const EMPTY_OBJ = {}; * @param {Object} [map] Optional map of custom element names to Components or variant element names. */ export default function markupToVdom(markup, type, reviver, map, options) { - let dom = parseMarkup(markup, type); + let dom = parseMarkup(markup, type, options.parser); if (dom && dom.error) { throw new Error(dom.error); diff --git a/src/parse-markup.js b/src/parse-markup.js index c0b8e66..c7e671b 100644 --- a/src/parse-markup.js +++ b/src/parse-markup.js @@ -3,7 +3,7 @@ let parserDoc; /** Parse markup into a DOM using the given mimetype. * @param {String} markup */ -export default function parseMarkup(markup, type) { +export default function parseMarkup(markup, type, customParser=null) { let doc, mime = type==='html' ? 'text/html' : 'application/xml', parserError, wrappedMarkup, tag; @@ -20,7 +20,8 @@ export default function parseMarkup(markup, type) { // if available (browser support varies), using DOMPaser in HTML mode is much faster, safer and cleaner than injecting HTML into an iframe. try { - doc = new DOMParser().parseFromString(wrappedMarkup, mime); + const parser = customParser ? customParser : new DOMParser(); + doc = parser.parseFromString(wrappedMarkup, mime); } catch (err) { parserError = err; } diff --git a/test/index.js b/test/index.js index 130b254..d5596eb 100644 --- a/test/index.js +++ b/test/index.js @@ -4,6 +4,7 @@ import sinonChai from 'sinon-chai'; chai.use(assertJsx); chai.use(sinonChai); import Markup from 'src'; +import DomParser from 'dom-parser'; /*eslint-env browser,mocha*/ /*global sinon,expect,chai*/ @@ -325,4 +326,10 @@ describe('Markup', () => { ); }); + + it('should render when using a custom parser', () => { + let markup = `hello!

asdflkj

`; + render(, scratch); + expect(scratch.firstChild.innerHTML).to.equal(markup); + }); });