[fix] no root node for detached dom node (#6570)

pull/6577/head
Tan Li Hau 3 years ago committed by GitHub
parent a3fb765d6f
commit 1952ea22de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -134,9 +134,9 @@ export function append_styles(
style_sheet_id: string,
styles: string
) {
const append_styles_to = get_root_for_styles(target);
const append_styles_to = get_root_for_style(target);
if (!append_styles_to?.getElementById(style_sheet_id)) {
if (!append_styles_to.getElementById(style_sheet_id)) {
const style = element('style');
style.id = style_sheet_id;
style.textContent = styles;
@ -144,20 +144,19 @@ export function append_styles(
}
}
export function get_root_for_node(node: Node) {
export function get_root_for_style(node: Node): ShadowRoot | Document {
if (!node) return document;
return (node.getRootNode ? node.getRootNode() : node.ownerDocument); // check for getRootNode because IE is still supported
}
function get_root_for_styles(node: Node) {
const root = get_root_for_node(node);
return (root as ShadowRoot).host ? root as ShadowRoot : root as Document;
const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
if ((root as ShadowRoot).host) {
return root as ShadowRoot;
}
return document;
}
export function append_empty_stylesheet(node: Node) {
const style_element = element('style') as HTMLStyleElement;
append_stylesheet(get_root_for_styles(node), style_element);
append_stylesheet(get_root_for_style(node), style_element);
return style_element;
}

@ -1,4 +1,4 @@
import { append_empty_stylesheet, get_root_for_node } from './dom';
import { append_empty_stylesheet, get_root_for_style } from './dom';
import { raf } from './environment';
interface ExtendedDoc extends Document {
@ -29,7 +29,7 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
const rule = keyframes + `100% {${fn(b, 1 - b)}}\n}`;
const name = `__svelte_${hash(rule)}_${uid}`;
const doc = get_root_for_node(node) as unknown as ExtendedDoc;
const doc = get_root_for_style(node) as ExtendedDoc;
active_docs.add(doc);
const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = append_empty_stylesheet(node).sheet as CSSStyleSheet);
const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});

@ -0,0 +1,11 @@
<script>
let name = 'World';
</script>
<div>Hello {name}</div>
<style>
div {
color: red;
}
</style>

@ -0,0 +1,16 @@
export default {
skip_if_ssr: true,
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, target, window }) {
assert.htmlEqual(
window.document.head.innerHTML,
'<style id="svelte-xyz">div.svelte-xyz{color:red}</style>'
);
assert.htmlEqual(
component.div.innerHTML,
'<div class="svelte-xyz">Hello World</div>'
);
}
};

@ -0,0 +1,18 @@
<script>
import App from './App.svelte';
import { onMount } from 'svelte';
export let div;
onMount(() => {
div = document.createElement('div');
const app = new App({
target: div
});
return () => {
app.$destroy();
}
});
</script>

@ -0,0 +1,11 @@
<script>
let name = 'World';
</script>
<div>Hello {name}</div>
<style>
div {
color: red;
}
</style>

@ -0,0 +1,16 @@
export default {
skip_if_ssr: true,
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, target, window }) {
assert.htmlEqual(
window.document.head.innerHTML,
'<style id="svelte-xyz">div.svelte-xyz{color:red}</style>'
);
assert.htmlEqual(
component.div.innerHTML,
'<div class="svelte-xyz">Hello World</div>'
);
}
};

@ -0,0 +1,18 @@
<script>
import App from './App.svelte';
import { onMount } from 'svelte';
export let div;
onMount(() => {
const app = new App({
target: div
});
return () => {
app.$destroy();
}
});
</script>
<div bind:this={div} />

@ -0,0 +1,11 @@
<script>
let name = 'World';
</script>
<div>Hello {name}</div>
<style>
div {
color: red;
}
</style>

@ -0,0 +1,13 @@
export default {
skip_if_ssr: true,
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, target, window }) {
assert.htmlEqual(window.document.head.innerHTML, '');
assert.htmlEqual(component.div.shadowRoot.innerHTML, `
<style id="svelte-xyz">div.svelte-xyz{color:red}</style>
<div class="svelte-xyz">Hello World</div>
`);
}
};

@ -0,0 +1,19 @@
<script>
import App from './App.svelte';
import { onMount } from 'svelte';
export let div;
onMount(() => {
const root = div.attachShadow({ mode: 'open' });
const app = new App({
target: root
});
return () => {
app.$destroy();
}
});
</script>
<div bind:this={div} />
Loading…
Cancel
Save