-
-
Notifications
You must be signed in to change notification settings - Fork 32
/
index.js
80 lines (65 loc) · 1.9 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const wrapMap = {
legend: [1, '<fieldset>', '</fieldset>'],
tr: [2, '<table><tbody>', '</tbody></table>'],
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
_default: [0, '', ''],
};
wrapMap.td
= wrapMap.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
wrapMap.option
= wrapMap.optgroup = [1, '<select multiple="multiple">', '</select>'];
wrapMap.thead
= wrapMap.tbody
= wrapMap.colgroup
= wrapMap.caption
= wrapMap.tfoot = [1, '<table>', '</table>'];
wrapMap.polyline
= wrapMap.ellipse
= wrapMap.polygon
= wrapMap.circle
= wrapMap.text
= wrapMap.line
= wrapMap.path
= wrapMap.rect
= wrapMap.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>'];
function domify(htmlString, document = globalThis.document) {
if (typeof htmlString !== 'string') {
throw new TypeError('String expected');
}
// Handle comment nodes
const commentMatch = /^<!--(.*?)-->$/s.exec(htmlString);
if (commentMatch) {
return document.createComment(commentMatch[1]);
}
const tagName = /<([\w:]+)/.exec(htmlString)?.[1];
if (!tagName) {
return document.createTextNode(htmlString);
}
htmlString = htmlString.trim();
// Body support
if (tagName === 'body') {
const element = document.createElement('html');
element.innerHTML = htmlString;
const {lastChild} = element;
lastChild.remove();
return lastChild;
}
// Wrap map
let [depth, prefix, suffix] = Object.hasOwn(wrapMap, tagName) ? wrapMap[tagName] : wrapMap._default;
let element = document.createElement('div');
element.innerHTML = prefix + htmlString + suffix;
while (depth--) {
element = element.lastChild;
}
// One element
if (element.firstChild === element.lastChild) {
const {firstChild} = element;
firstChild.remove();
return firstChild;
}
// Several elements
const fragment = document.createDocumentFragment();
fragment.append(...element.childNodes);
return fragment;
}
module.exports = domify;