-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
77 lines (77 loc) · 2.41 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
/*! (c) Andrea Giammarchi - ISC */
const HTMLParsedElement = (() => {
const DCL = 'DOMContentLoaded';
const init = new WeakMap;
const queue = [];
const isParsed = el => {
do {
if (el.nextSibling)
return true;
} while (el = el.parentNode);
return false;
};
const upgrade = () => {
queue.splice(0).forEach(info => {
if (init.get(info[0]) !== true) {
init.set(info[0], true);
info[0][info[1]]();
}
});
};
document.addEventListener(DCL, upgrade);
class HTMLParsedElement extends HTMLElement {
static withParsedCallback(Class, name = 'parsed') {
const {prototype} = Class;
const {connectedCallback} = prototype;
const method = name + 'Callback';
const cleanUp = (el, observer, ownerDocument, onDCL) => {
observer.disconnect();
ownerDocument.removeEventListener(DCL, onDCL);
parsedCallback(el);
};
const parsedCallback = el => {
if (!queue.length)
requestAnimationFrame(upgrade);
queue.push([el, method]);
};
Object.defineProperties(
prototype,
{
connectedCallback: {
configurable: true,
writable: true,
value() {
if (connectedCallback)
connectedCallback.apply(this, arguments);
if (method in this && !init.has(this)) {
const self = this;
const {ownerDocument} = self;
init.set(self, false);
if (ownerDocument.readyState === 'complete' || isParsed(self))
parsedCallback(self);
else {
const onDCL = () => cleanUp(self, observer, ownerDocument, onDCL);
ownerDocument.addEventListener(DCL, onDCL);
const observer = new MutationObserver(() => {
/* istanbul ignore else */
if (isParsed(self))
cleanUp(self, observer, ownerDocument, onDCL);
});
observer.observe(self.parentNode, {childList: true, subtree: true});
}
}
}
},
[name]: {
configurable: true,
get() {
return init.get(this) === true;
}
}
}
);
return Class;
}
}
return HTMLParsedElement.withParsedCallback(HTMLParsedElement);
})();