11import hash from '@emotion/hash' ;
22
33const elementId = 'rcx-styles' ;
4- let element : HTMLStyleElement ;
5- const getStyleTag = ( ) : HTMLStyleElement => {
4+ const documentStyleElementMap = new WeakMap < Document , HTMLStyleElement > ( ) ;
5+
6+ const getStyleTag = ( document : Document ) : HTMLStyleElement => {
7+ let element = documentStyleElementMap . get ( document ) ;
8+
69 if ( ! element ) {
710 const el = document . getElementById ( elementId ) as HTMLStyleElement ;
811 if ( el ) {
9- element = el ;
10- return element ;
12+ documentStyleElementMap . set ( document , el ) ;
13+ return el ;
1114 }
1215 }
1316
1417 if ( ! element ) {
1518 element = document . createElement ( 'style' ) ;
19+
20+ documentStyleElementMap . set ( document , element ) ;
21+
1622 element . id = elementId ;
1723 element . appendChild ( document . createTextNode ( '' ) ) ;
24+
1825 if ( document . head ) {
1926 document . head . appendChild ( element ) ;
2027 }
@@ -23,10 +30,12 @@ const getStyleTag = (): HTMLStyleElement => {
2330 return element ;
2431} ;
2532
26- let styleSheet : CSSStyleSheet ;
27- const getStyleSheet = ( ) : CSSStyleSheet => {
33+ const documentStyleSheetMap = new WeakMap < Document , CSSStyleSheet > ( ) ;
34+ const getStyleSheet = ( document : Document ) : CSSStyleSheet => {
35+ let styleSheet = documentStyleSheetMap . get ( document ) ;
36+
2837 if ( ! styleSheet ) {
29- const styleTag = getStyleTag ( ) ;
38+ const styleTag = getStyleTag ( document ) ;
3039 const _styleSheet =
3140 styleTag . sheet ||
3241 Array . from ( document . styleSheets ) . find (
@@ -40,24 +49,34 @@ const getStyleSheet = (): CSSStyleSheet => {
4049 styleSheet = _styleSheet ;
4150 }
4251
52+ documentStyleSheetMap . set ( document , styleSheet ) ;
53+
4354 return styleSheet ;
4455} ;
4556
46- type RuleAttacher = ( rules : string ) => ( ) => void ;
57+ type StrictRuleAttacher = (
58+ rules : string ,
59+ options : { document : Document } ,
60+ ) => ( ) => void ;
61+
62+ type RuleAttacher = (
63+ rules : string ,
64+ options ?: { document ?: Document } ,
65+ ) => ( ) => void ;
4766
4867const discardRules : RuleAttacher = ( ) => ( ) => undefined ;
4968
50- const attachRulesIntoElement : RuleAttacher = ( rules ) => {
51- const element = getStyleTag ( ) ;
69+ const attachRulesIntoElement : StrictRuleAttacher = ( rules , { document } ) => {
70+ const element = getStyleTag ( document ) ;
5271
5372 const textNode = document . createTextNode ( rules ) ;
5473 element . appendChild ( textNode ) ;
5574
5675 return ( ) => textNode . remove ( ) ;
5776} ;
5877
59- const attachRulesIntoStyleSheet : RuleAttacher = ( rules ) => {
60- const styleSheet = getStyleSheet ( ) ;
78+ const attachRulesIntoStyleSheet : StrictRuleAttacher = ( rules , { document } ) => {
79+ const styleSheet = getStyleSheet ( document ) ;
6180 const index = styleSheet . insertRule (
6281 `@media all{${ rules } }` ,
6382 styleSheet . cssRules . length ,
@@ -73,8 +92,10 @@ const attachRulesIntoStyleSheet: RuleAttacher = (rules) => {
7392 } ;
7493} ;
7594
76- const wrapReferenceCounting = ( attacher : RuleAttacher ) : RuleAttacher => {
77- const refs : Record < string , { ref ( ) : void ; unref ( ) : void } > = { } ;
95+ type RefCounter = Record < string , { ref ( ) : void ; unref ( ) : void } > ;
96+
97+ const wrapReferenceCounting = ( attacher : StrictRuleAttacher ) : RuleAttacher => {
98+ const refDocumentMap = new WeakMap < Document , RefCounter > ( ) ;
7899
79100 const queueMicrotask = ( fn : ( ) => void ) : void => {
80101 if (
@@ -88,11 +109,21 @@ const wrapReferenceCounting = (attacher: RuleAttacher): RuleAttacher => {
88109 window . queueMicrotask ( fn ) ;
89110 } ;
90111
91- const enhancedAttacher : RuleAttacher = ( content : string ) => {
112+ const enhancedAttacher : RuleAttacher = ( content , options = { } ) => {
92113 const id = hash ( content ) ;
114+ const document = options . document ? options . document : window . document ;
115+
116+ const refs = refDocumentMap . get ( document ) || { } ;
117+
118+ if ( ! refDocumentMap . has ( document ) ) {
119+ refDocumentMap . set ( document , refs ) ;
120+ }
93121
94122 if ( ! refs [ id ] ) {
95- const detach = attacher ( content ) ;
123+ const detach = attacher ( content , {
124+ ...options ,
125+ document : options . document ? options . document : window . document ,
126+ } ) ;
96127 let count = 0 ;
97128
98129 const ref = ( ) : void => {
0 commit comments