UNPKG

2.12 kBHTMLView Raw
1<script src="./index.js"></script>
2<script>
3 function __ssr () {
4 const script = document.currentScript;
5 const host = script.previousElementSibling;
6 const fakeShadowRoot = host.firstElementChild;
7 const slots = host.getElementsByTagName('slot');
8 const move = (from, to) => { while (from.firstChild) to.appendChild(from.firstChild) };
9
10 // At each Shadow Root, we only care about its slots, not composed slots,
11 // therefore we need to move the children of top level slots, but no others
12 // Also can't 'move' in loop as that will mutate the DOM and ruin the
13 // 'contains' checks for subsequent slots.
14 const topLevelSlots = (() => {
15 let top = [],
16 ref;
17
18 for (let i = 0, k = slots.length; i < k; i++) {
19 const slot = slots[i];
20
21 // Ref is last known top level slot, if current slot is contained by it,
22 // then that slot is nested and can be ignored
23 if (!(ref && ref.contains(slot))) {
24 top.push(slot);
25 ref = slot;
26 }
27 }
28
29 return top;
30 })();
31
32 topLevelSlots.forEach(slot => move(slot, host));
33
34 // // Removing the script speeds up rendering by a few hundred ms when
35 // // not optimised and only a few when optimised.
36 script.parentNode.removeChild(script);
37
38 // The fastest overall method is to simply use innerHTML. This seems to be
39 // faster when not optimised (by about 50%) but is slightly slower when
40 // optimised compared to traversing the fake shadow root and appending each
41 // element to the real one:
42 const realShadowRoot = host.attachShadow({ mode: 'open' });
43 move(fakeShadowRoot, realShadowRoot);
44 host.removeChild(fakeShadowRoot);
45 }
46</script>
47<script>
48 test(a => {
49 const frag = document.createDocumentFragment();
50 const div = document.createElement('div');
51 const script = document.createElement('script');
52
53 div.innerHTML = `<shadow-root><strong><slot>${a}</slot></strong></shadow-root>`;
54 script.innerHTML = `__ssr();`;
55
56 frag.appendChild(div);
57 frag.appendChild(script);
58
59 return frag;
60 });
61</script>