Updated style_manager cleanup to remove created stylesheets instead of making them empty

pull/7259/head
Mathias Picker 5 years ago
parent 5c256bffd1
commit 37dfcad363

@ -154,14 +154,9 @@ export function get_root_for_style(node: Node): ShadowRoot | Document {
return node.ownerDocument; return node.ownerDocument;
} }
export function append_empty_stylesheet(node: Node) { export function append_stylesheet(node: ShadowRoot | Document, style: HTMLStyleElement): CSSStyleSheet {
const style_element = element('style') as HTMLStyleElement;
append_stylesheet(get_root_for_style(node), style_element);
return style_element.sheet as CSSStyleSheet;
}
function append_stylesheet(node: ShadowRoot | Document, style: HTMLStyleElement) {
append((node as Document).head || node, style); append((node as Document).head || node, style);
return style.sheet
} }
export function append_hydration(target: NodeEx, node: NodeEx) { export function append_hydration(target: NodeEx, node: NodeEx) {

@ -1,8 +1,8 @@
import { append_empty_stylesheet, get_root_for_style } from './dom'; import { append_stylesheet, detach, element, get_root_for_style } from './dom';
import { raf } from './environment'; import { raf } from './environment';
interface StyleInformation { interface StyleInformation {
stylesheet: CSSStyleSheet; style_element: HTMLStyleElement;
rules: Record<string, true>; rules: Record<string, true>;
} }
@ -20,8 +20,8 @@ function hash(str: string) {
return hash >>> 0; return hash >>> 0;
} }
function create_style_information(doc: Document | ShadowRoot, node: Element & ElementCSSInlineStyle) { function create_style_information(doc: Document | ShadowRoot) {
const info = { stylesheet: append_empty_stylesheet(node), rules: {} }; const info = { style_element: element('style'), rules: {} };
managed_styles.set(doc, info); managed_styles.set(doc, info);
return info; return info;
} }
@ -39,9 +39,10 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
const name = `__svelte_${hash(rule)}_${uid}`; const name = `__svelte_${hash(rule)}_${uid}`;
const doc = get_root_for_style(node); const doc = get_root_for_style(node);
const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node); const { style_element, rules } = managed_styles.get(doc) || create_style_information(doc);
if (!rules[name]) { if (!rules[name]) {
const stylesheet = append_stylesheet(doc, style_element)
rules[name] = true; rules[name] = true;
stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length); stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);
} }
@ -50,6 +51,7 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`; node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;
active += 1; active += 1;
return name; return name;
} }
@ -71,9 +73,8 @@ export function clear_rules() {
raf(() => { raf(() => {
if (active) return; if (active) return;
managed_styles.forEach(info => { managed_styles.forEach(info => {
const { stylesheet } = info; const { style_element } = info;
let i = stylesheet.cssRules.length; detach(style_element)
while (i--) stylesheet.deleteRule(i);
info.rules = {}; info.rules = {};
}); });
managed_styles.clear(); managed_styles.clear();

@ -0,0 +1,18 @@
export default {
skip_if_ssr: true,
skip_if_hydrate: true,
skip_if_hydrate_from_ssr: true,
async test({ raf, assert, component, window }) {
component.visible = true;
raf.tick(100)
component.visible = false;
raf.tick(200)
raf.tick(60)
assert.htmlEqual(
window.document.head.innerHTML,
''
);
}
};

@ -0,0 +1,14 @@
<script>
export let visible = true;
function foo(node, params) {
return {
duration: 100,
css: () => ''
};
}
</script>
{#if visible}
<div transition:foo></div>
{/if}
Loading…
Cancel
Save