Skip to content

Commit dcf8d08

Browse files
committed
Add support for passing a document
Closes GH-3.
1 parent 8d2e389 commit dcf8d08

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ Transform a [**hast**][hast] [*tree*][tree] to a DOM tree.
8080

8181
Whether a DOM fragment should be returned (default: `false`).
8282

83+
###### `options.document`
84+
85+
Document interface to use (default: `global.document`).
86+
8387
###### `options.namespace`
8488

8589
`namespace` to use to create [*elements*][element].

src/index.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function transform(node, options) {
2020

2121
// Create a document.
2222
function root(node, options) {
23-
const { fragment, namespace: optionsNamespace } = options;
23+
const { doc, fragment, namespace: optionsNamespace } = options;
2424
const { children = [] } = node;
2525
const { length: childrenLength } = children;
2626

@@ -45,43 +45,43 @@ function root(node, options) {
4545
let el;
4646

4747
if (rootIsDocument) {
48-
el = document.implementation.createDocument(namespace, '', null);
48+
el = doc.implementation.createDocument(namespace, '', null);
4949
} else if (fragment) {
50-
el = document.createDocumentFragment();
50+
el = doc.createDocumentFragment();
5151
} else {
52-
el = document.createElement('html');
52+
el = doc.createElement('html');
5353
}
5454

5555
return appendAll(el, children, Object.assign({ fragment, namespace }, options));
5656
}
5757

5858
// Create a `doctype`.
59-
function doctype(node) {
60-
return document.implementation.createDocumentType(
59+
function doctype(node, { doc }) {
60+
return doc.implementation.createDocumentType(
6161
node.name || 'html',
6262
node.public || '',
6363
node.system || '',
6464
);
6565
}
6666

6767
// Create a `text`.
68-
function text(node) {
69-
return document.createTextNode(node.value);
68+
function text(node, { doc }) {
69+
return doc.createTextNode(node.value);
7070
}
7171

7272
// Create a `comment`.
73-
function comment(node) {
74-
return document.createComment(node.value);
73+
function comment(node, { doc }) {
74+
return doc.createComment(node.value);
7575
}
7676

7777
// Create an `element`.
7878
function element(node, options) {
79-
const { namespace } = options;
79+
const { namespace, doc } = options;
8080
// TODO: use `g` in SVG space.
8181
const { tagName = 'div', properties = {}, children = [] } = node;
8282
const el = typeof namespace !== 'undefined'
83-
? document.createElementNS(namespace, tagName)
84-
: document.createElement(tagName);
83+
? doc.createElementNS(namespace, tagName)
84+
: doc.createElement(tagName);
8585

8686
// Add HTML attributes.
8787
const props = Object.keys(properties);
@@ -146,5 +146,5 @@ function appendAll(node, children, options) {
146146

147147

148148
export default function toDOM(hast, options = {}) {
149-
return transform(hast, options);
149+
return transform(hast, { ...options, doc: options.document || document });
150150
}

src/index.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,37 @@ describe('hast-util-to-dom', () => {
254254
expect(actual).toEqual('<html xmlns="http://example.com"/>');
255255
});
256256

257+
it('should support a given document', () => {
258+
const doc = {
259+
createElementNS(namespace, tagName) {
260+
const name = tagName === 'h1' ? 'h2' : tagName;
261+
return document.createElementNS(namespace, name);
262+
},
263+
createTextNode(value) {
264+
return document.createTextNode(value.toUpperCase());
265+
},
266+
implementation: {
267+
createDocument(namespace, qualifiedName, documentType) {
268+
return document.implementation.createDocument(namespace, qualifiedName, documentType);
269+
},
270+
},
271+
};
272+
273+
const actual = serializeNodeToHtmlString(
274+
toDOM({
275+
type: 'root',
276+
children: [
277+
h('html', [
278+
h('title', 'foo'),
279+
h('h1', 'bar'),
280+
]),
281+
],
282+
}, { document: doc }),
283+
);
284+
285+
expect(actual).toEqual('<html><title>FOO</title><h2>BAR</h2></html>');
286+
});
287+
257288
describe('booleanish property', () => {
258289
it('handles booleanish attribute with `true` value correctly', () => {
259290
const actual = serializeNodeToHtmlString(toDOM(h('div', {

0 commit comments

Comments
 (0)