UNPKG

2.27 kBJavaScriptView Raw
1// Used as Node.TYPE
2const ELEMENT_NODE = 1;
3const types = {
4 ELEMENT_NODE,
5 ATTRIBUTE_NODE: 2,
6 TEXT_NODE: 3,
7 COMMENT_NODE: 8,
8 DOCUMENT_NODE: 9,
9 DOCUMENT_TYPE_NODE: 10,
10 DOCUMENT_FRAGMENT_NODE: 11
11};
12
13// void cases
14const VOID_ELEMENT = /^area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr$/i;
15const VOID_ELEMENTS = new RegExp(`<(${VOID_ELEMENT.source})([^>]*?)>`, 'gi');
16const VOID_SANITIZER = (_, $1, $2) => `<${$1}${$2}${/\/$/.test($2) ? '' : ' /'}>`;
17
18// shared constants
19const connect = (parentNode, child) => {
20 if (
21 child.nodeType === ELEMENT_NODE &&
22 child.isCustomElement && 'connectedCallback' in child &&
23 parentNode && parentNode.nodeType !== types.DOCUMENT_FRAGMENT_NODE
24 ) {
25 child.connectedCallback();
26 }
27};
28
29const disconnect = (parentNode, child) => {
30 if (
31 child.nodeType === ELEMENT_NODE &&
32 child.isCustomElement && 'disconnectedCallback' in child &&
33 parentNode && parentNode.nodeType !== types.DOCUMENT_FRAGMENT_NODE
34 ) {
35 child.disconnectedCallback();
36 }
37};
38
39const notifyAttributeChanged = (el, name, oldValue, newValue) => {
40 if (
41 el.isCustomElement &&
42 'attributeChangedCallback' in el &&
43 (el.constructor.observedAttributes || []).includes(name)
44 ) {
45 el.attributeChangedCallback(name, oldValue, newValue);
46 }
47};
48
49const CSS_SPLITTER = /\s*,\s*/;
50function findBySelector(css) {
51 switch (css[0]) {
52 case '#':
53 return this.ownerDocument.getElementById(css.slice(1));
54 case '.':
55 return this.getElementsByClassName(css.slice(1));
56 case '[':
57 return findBAttributeName(this, css.replace(/[\[\]]/g, ''), []);
58 default:
59 return this.getElementsByTagName(css);
60 }
61}
62
63module.exports = {
64 VOID_ELEMENT,
65 connect,
66 disconnect,
67 notifyAttributeChanged,
68 types,
69 querySelectorAll(css) {
70 return [].concat(...('' + css).split(CSS_SPLITTER).map(findBySelector, this));
71 },
72 voidSanitizer: html => html.replace(VOID_ELEMENTS, VOID_SANITIZER)
73};
74
75function findBAttributeName(node, name, all) {
76 for (let children = node.children, {length} = children, i = 0; i < length; i++) {
77 const child = children[i];
78 if (child.hasAttribute(name))
79 all.push(child);
80 findBAttributeName(child, name, all);
81 }
82 return all;
83}