This repository has been archived by the owner on Jan 4, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathutils.js
76 lines (63 loc) · 2.29 KB
/
utils.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
const { minify } = require("uglify-es");
const cache = {};
// Rehydrates the host element with a shadow root.
function rehydrate() {
var script = document.currentScript;
var fakeShadowRoot = script.parentNode;
var host = fakeShadowRoot.parentNode;
var move = function(from, to) {
while (from && from.firstChild) {
to.appendChild(from.firstChild);
}
};
// This cleans up the resulting DOM but also seems to have a positive impact on performance.
fakeShadowRoot.removeChild(script);
// First thing we do is remove the fake shadow root so we can attach a shadow root safely.
host.removeChild(fakeShadowRoot);
// Create the real shadow root once we've cleaned up.
var realShadowRoot = host.attachShadow({ mode: "open" });
// Then we can move stuff over from the fake root to the real one.
move(fakeShadowRoot, realShadowRoot);
// We must find the slots *after* the shadow root is hydrated so we don't get any unwanted ones.
var slots = realShadowRoot.querySelectorAll("slot");
// At each Shadow Root, we only care about its slots, not composed slots,
// therefore we need to move the children of top level slots, but not others
// Also can't 'move' in loop as that will mutate the DOM and ruin the
// 'contains' checks for subsequent slots.
var topLevelSlots = (function() {
var top = [],
ref;
for (var i = 0, k = slots.length; i < k; i++) {
var slot = slots[i];
// Ref is last known top level slot, if current slot is contained by it,
// then that slot is nested and can be ignored
if (!(ref && ref.contains(slot))) {
top.push(slot);
ref = slot;
}
}
return top;
})();
topLevelSlots.forEach(function(slot) {
move(slot, host);
});
}
// Replaces a script tag with the corresponding style tag.
function restyle() {
var script = document.currentScript;
var style = document.createElement("style");
style.textContent = document.getElementById(
script.getAttribute("data-style-id")
).textContent;
script.parentNode.replaceChild(style, script);
}
const funcs = { rehydrate, restyle };
module.exports = function(func, name) {
return (
cache[func] ||
(cache[func] = minify(funcs[func].toString()).code.replace(
`function ${func}`,
`function ${name}_${func}`
))
);
};