Fixes issue #7026 with multiple independent Svelte apps running at the same time.

pull/7107/head
typhonrt 5 years ago
parent 966c03a317
commit 81c43ef933

@ -2,13 +2,19 @@ import { append_empty_stylesheet, get_root_for_style } from './dom';
import { raf } from './environment'; import { raf } from './environment';
interface ExtendedDoc extends Document { interface ExtendedDoc extends Document {
__svelte_stylesheet: CSSStyleSheet; [key: string]: any;
__svelte_rules: Record<string, true>;
} }
const active_docs = new Set<ExtendedDoc>(); const active_docs = new Set<ExtendedDoc>();
let active = 0; let active = 0;
// A suitable unique ID to create separate style sheets per Svelte runtime. Fixes issue #7026.
// It is possible a more universal / UUID may be relevant to use instead of `Date.now` in the future.
// Define unique keys to store the style transitions so one Svelte runtime does not clobber the data of another.
const unique_id = Date.now();
const svelte_stylesheet = `__svelte_stylesheet_${unique_id}`;
const svelte_rules = `__svelte_rules_${unique_id}`;
// https://github.com/darkskyapp/string-hash/blob/master/index.js // https://github.com/darkskyapp/string-hash/blob/master/index.js
function hash(str: string) { function hash(str: string) {
let hash = 5381; let hash = 5381;
@ -31,8 +37,8 @@ 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) as ExtendedDoc; const doc = get_root_for_style(node) as ExtendedDoc;
active_docs.add(doc); active_docs.add(doc);
const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = append_empty_stylesheet(node).sheet as CSSStyleSheet); const stylesheet = doc[svelte_stylesheet] || (doc[svelte_stylesheet] = append_empty_stylesheet(node).sheet as CSSStyleSheet);
const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {}); const current_rules = doc[svelte_rules] || (doc[svelte_rules] = {});
if (!current_rules[name]) { if (!current_rules[name]) {
current_rules[name] = true; current_rules[name] = true;
@ -64,10 +70,10 @@ export function clear_rules() {
raf(() => { raf(() => {
if (active) return; if (active) return;
active_docs.forEach(doc => { active_docs.forEach(doc => {
const stylesheet = doc.__svelte_stylesheet; const stylesheet = doc[svelte_stylesheet];
let i = stylesheet.cssRules.length; let i = stylesheet.cssRules.length;
while (i--) stylesheet.deleteRule(i); while (i--) stylesheet.deleteRule(i);
doc.__svelte_rules = {}; doc[svelte_rules] = {};
}); });
active_docs.clear(); active_docs.clear();
}); });

Loading…
Cancel
Save