From 37dfcad363aa8b72fd5d6c11a4e147714e323ac7 Mon Sep 17 00:00:00 2001 From: Mathias Picker Date: Sun, 13 Feb 2022 13:11:28 +0100 Subject: [PATCH 1/6] Updated style_manager cleanup to remove created stylesheets instead of making them empty --- src/runtime/internal/dom.ts | 9 ++------- src/runtime/internal/style_manager.ts | 19 ++++++++++--------- .../samples/style_manager-cleanup/_config.js | 18 ++++++++++++++++++ .../samples/style_manager-cleanup/main.svelte | 14 ++++++++++++++ 4 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 test/runtime/samples/style_manager-cleanup/_config.js create mode 100644 test/runtime/samples/style_manager-cleanup/main.svelte diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 287c16b5fc5..df25e7ab119 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -154,14 +154,9 @@ export function get_root_for_style(node: Node): ShadowRoot | Document { return node.ownerDocument; } -export function append_empty_stylesheet(node: Node) { - 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) { +export function append_stylesheet(node: ShadowRoot | Document, style: HTMLStyleElement): CSSStyleSheet { append((node as Document).head || node, style); + return style.sheet } export function append_hydration(target: NodeEx, node: NodeEx) { diff --git a/src/runtime/internal/style_manager.ts b/src/runtime/internal/style_manager.ts index 6907e5af029..bc37c588b96 100644 --- a/src/runtime/internal/style_manager.ts +++ b/src/runtime/internal/style_manager.ts @@ -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'; interface StyleInformation { - stylesheet: CSSStyleSheet; + style_element: HTMLStyleElement; rules: Record; } @@ -20,8 +20,8 @@ function hash(str: string) { return hash >>> 0; } -function create_style_information(doc: Document | ShadowRoot, node: Element & ElementCSSInlineStyle) { - const info = { stylesheet: append_empty_stylesheet(node), rules: {} }; +function create_style_information(doc: Document | ShadowRoot) { + const info = { style_element: element('style'), rules: {} }; managed_styles.set(doc, info); return info; } @@ -39,9 +39,10 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b: const name = `__svelte_${hash(rule)}_${uid}`; 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]) { + const stylesheet = append_stylesheet(doc, style_element) rules[name] = true; 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`; active += 1; + return name; } @@ -71,9 +73,8 @@ export function clear_rules() { raf(() => { if (active) return; managed_styles.forEach(info => { - const { stylesheet } = info; - let i = stylesheet.cssRules.length; - while (i--) stylesheet.deleteRule(i); + const { style_element } = info; + detach(style_element) info.rules = {}; }); managed_styles.clear(); diff --git a/test/runtime/samples/style_manager-cleanup/_config.js b/test/runtime/samples/style_manager-cleanup/_config.js new file mode 100644 index 00000000000..a31dd689171 --- /dev/null +++ b/test/runtime/samples/style_manager-cleanup/_config.js @@ -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, + '' + ); + } +}; diff --git a/test/runtime/samples/style_manager-cleanup/main.svelte b/test/runtime/samples/style_manager-cleanup/main.svelte new file mode 100644 index 00000000000..1fcf8d703c0 --- /dev/null +++ b/test/runtime/samples/style_manager-cleanup/main.svelte @@ -0,0 +1,14 @@ + + +{#if visible} +
+{/if} \ No newline at end of file From 5def8c72f99bfac86a9a09d6a8ff6f0c41cf1906 Mon Sep 17 00:00:00 2001 From: Mathias Picker Date: Sun, 13 Feb 2022 13:24:27 +0100 Subject: [PATCH 2/6] Linted files --- src/runtime/internal/dom.ts | 2 +- src/runtime/internal/style_manager.ts | 4 ++-- test/runtime/samples/style_manager-cleanup/_config.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index df25e7ab119..5b88f525f89 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -156,7 +156,7 @@ export function get_root_for_style(node: Node): ShadowRoot | Document { export function append_stylesheet(node: ShadowRoot | Document, style: HTMLStyleElement): CSSStyleSheet { append((node as Document).head || node, style); - return style.sheet + return style.sheet; } export function append_hydration(target: NodeEx, node: NodeEx) { diff --git a/src/runtime/internal/style_manager.ts b/src/runtime/internal/style_manager.ts index bc37c588b96..cf9a224a30c 100644 --- a/src/runtime/internal/style_manager.ts +++ b/src/runtime/internal/style_manager.ts @@ -42,7 +42,7 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b: const { style_element, rules } = managed_styles.get(doc) || create_style_information(doc); if (!rules[name]) { - const stylesheet = append_stylesheet(doc, style_element) + const stylesheet = append_stylesheet(doc, style_element); rules[name] = true; stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length); } @@ -74,7 +74,7 @@ export function clear_rules() { if (active) return; managed_styles.forEach(info => { const { style_element } = info; - detach(style_element) + detach(style_element); info.rules = {}; }); managed_styles.clear(); diff --git a/test/runtime/samples/style_manager-cleanup/_config.js b/test/runtime/samples/style_manager-cleanup/_config.js index a31dd689171..8133f86ff59 100644 --- a/test/runtime/samples/style_manager-cleanup/_config.js +++ b/test/runtime/samples/style_manager-cleanup/_config.js @@ -5,10 +5,10 @@ export default { async test({ raf, assert, component, window }) { component.visible = true; - raf.tick(100) + raf.tick(100); component.visible = false; - raf.tick(200) - raf.tick(60) + raf.tick(200); + raf.tick(60); assert.htmlEqual( window.document.head.innerHTML, From b00cadf18b07fa6f808e560e929ede179e7d62dd Mon Sep 17 00:00:00 2001 From: Mathias Picker Date: Sun, 13 Feb 2022 13:36:09 +0100 Subject: [PATCH 3/6] Fixed test --- test/runtime/samples/style_manager-cleanup/main.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtime/samples/style_manager-cleanup/main.svelte b/test/runtime/samples/style_manager-cleanup/main.svelte index 1fcf8d703c0..7d5595d5aa0 100644 --- a/test/runtime/samples/style_manager-cleanup/main.svelte +++ b/test/runtime/samples/style_manager-cleanup/main.svelte @@ -1,5 +1,5 @@