@ -1,10 +1,12 @@
import { element } from './dom' ;
import { element } from './dom' ;
import { raf } from './environment' ;
import { raf } from './environment' ;
type DocStyles = [ CSSStyleSheet , Record < string , true > ] ;
interface ExtendedDoc extends Document {
__svelte_stylesheet : CSSStyleSheet ;
__svelte_rules : Record < string , true > ;
}
const active_docs = new Set < Document > ( ) ;
const active_docs = new Set < ExtendedDoc > ( ) ;
const doc_styles = new Map < Document , DocStyles > ( ) ;
let active = 0 ;
let active = 0 ;
// https://github.com/darkskyapp/string-hash/blob/master/index.js
// https://github.com/darkskyapp/string-hash/blob/master/index.js
@ -27,12 +29,10 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
const rule = keyframes + ` 100% { ${ fn ( b , 1 - b ) } } \ n} ` ;
const rule = keyframes + ` 100% { ${ fn ( b , 1 - b ) } } \ n} ` ;
const name = ` __svelte_ ${ hash ( rule ) } _ ${ uid } ` ;
const name = ` __svelte_ ${ hash ( rule ) } _ ${ uid } ` ;
const doc = node . ownerDocument ;
const doc = node . ownerDocument as ExtendedDoc ;
active_docs . add ( doc ) ;
active_docs . add ( doc ) ;
const [ stylesheet , current_rules ] = ( doc_styles . has ( doc ) ? doc_styles : doc_styles.set ( doc , [
const stylesheet = doc . __svelte_stylesheet || ( doc . __svelte_stylesheet = doc . head . appendChild ( element ( 'style' ) as HTMLStyleElement ) . sheet as CSSStyleSheet ) ;
( doc . head . appendChild ( element ( 'style' ) as HTMLStyleElement ) . sheet as CSSStyleSheet ) ,
const current_rules = doc . __svelte_rules || ( doc . __svelte_rules = { } ) ;
{ }
] ) ) . get ( doc ) as DocStyles ;
if ( ! current_rules [ name ] ) {
if ( ! current_rules [ name ] ) {
current_rules [ name ] = true ;
current_rules [ name ] = true ;
@ -47,25 +47,27 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
}
}
export function delete_rule ( node : Element & ElementCSSInlineStyle , name? : string ) {
export function delete_rule ( node : Element & ElementCSSInlineStyle , name? : string ) {
node . style . animation = ( node . style . animation || '' )
const previous = ( node . style . animation || '' ) . split ( ', ' ) ;
. split ( ', ' )
const next = previous . filter ( name
. filter ( name
? anim = > anim . indexOf ( name ) < 0 // remove specific animation
? anim = > anim . indexOf ( name ) < 0 // remove specific animation
: anim = > anim . indexOf ( '__svelte' ) === - 1 // remove all Svelte animations
: anim = > anim . indexOf ( '__svelte' ) === - 1 // remove all Svelte animations
) ;
)
const deleted = previous . length - next . length ;
. join ( ', ' ) ;
if ( deleted ) {
node . style . animation = next . join ( ', ' ) ;
if ( name && ! -- active ) clear_rules ( ) ;
active -= deleted ;
if ( ! active ) clear_rules ( ) ;
}
}
}
export function clear_rules() {
export function clear_rules() {
raf ( ( ) = > {
raf ( ( ) = > {
if ( active ) return ;
if ( active ) return ;
active_docs . forEach ( doc = > {
active_docs . forEach ( doc = > {
const [ stylesheet ] = doc_styles . get ( doc ) ;
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 _styles. set ( doc , [ stylesheet , { } ] ) ;
doc . __svelte_rules = { } ;
} ) ;
} ) ;
active_docs . clear ( ) ;
active_docs . clear ( ) ;
} ) ;
} ) ;