@@ -15,9 +15,7 @@ use std::collections::BTreeMap;
1515use std:: ops:: Deref ;
1616use std:: rc:: Rc ;
1717
18- use perspective_js:: utils:: global;
1918use wasm_bindgen:: JsCast ;
20- use web_sys:: HtmlStyleElement ;
2119
2220use crate :: * ;
2321
@@ -48,8 +46,8 @@ impl PartialEq for StyleCache {
4846}
4947
5048impl StyleCache {
51- pub fn new ( is_shadow : bool ) -> StyleCache {
52- StyleCache ( Rc :: new ( StyleCacheData :: new ( is_shadow) ) )
49+ pub fn new ( is_shadow : bool , elem : & web_sys :: HtmlElement ) -> StyleCache {
50+ StyleCache ( Rc :: new ( StyleCacheData :: new ( is_shadow, elem ) ) )
5351 }
5452
5553 /// Insert a new stylesheet into this manager, _immediately_ inserting it
@@ -64,62 +62,53 @@ impl StyleCache {
6462 pub fn add_style ( & self , name : & ' static str , css : & ' static str ) {
6563 let mut map = self . 0 . styles . borrow_mut ( ) ;
6664 if !map. contains_key ( name) {
67- let style = Self :: into_style ( name, css, self . 0 . is_shadow ) ;
68- let first = map. values ( ) . next ( ) . cloned ( ) ;
65+ let style = Self :: into_style ( css) ;
6966 map. insert ( name, style. clone ( ) ) ;
70- let mut values = map. values ( ) ;
71- if let Some ( mut x) = first {
72- while let Some ( y) = values. next ( )
73- && y. get_attribute ( "name" ) . as_deref ( ) < Some ( name)
74- {
75- x = y. clone ( ) ;
76- }
77-
78- x. parent_node ( )
79- . unwrap_or_else ( || x. get_root_node ( ) )
80- . insert_before ( & style, x. next_sibling ( ) . as_ref ( ) )
81- . unwrap ( ) ;
82- }
67+ self . adopted_style_sheets . push ( & style. into ( ) ) ;
8368 }
8469 }
8570
8671 /// Concert a CSS string to an `HtmlStyleElement`, which are memoized due
8772 /// to their size and DOM performance impact.
88- fn into_style ( name : & str , css : & str , is_shadow : bool ) -> web_sys:: HtmlStyleElement {
89- let elem = global:: document ( ) . create_element ( "style" ) . unwrap ( ) ;
90- if is_shadow {
91- elem. set_text_content ( Some ( css) ) ;
92- } else {
93- let new_css = css. replace ( ":host" , ":root" ) ;
94- elem. set_text_content ( Some ( & new_css) ) ;
95- }
96-
97- elem. set_attribute ( "name" , name) . unwrap ( ) ;
98- elem. unchecked_into ( )
99- }
100-
101- pub fn iter_styles ( & self ) -> impl Iterator < Item = ( & ' static str , HtmlStyleElement ) > {
102- self . styles . borrow ( ) . clone ( ) . into_iter ( )
73+ fn into_style ( css : & str ) -> web_sys:: CssStyleSheet {
74+ let sheet = web_sys:: CssStyleSheet :: new ( ) . unwrap ( ) ;
75+ sheet. replace_sync ( css) . unwrap ( ) ;
76+ sheet
10377 }
10478}
10579
10680/// Using a `BTreeMap` so the resulting `<style>` elements have a stable order
10781/// when rendered to the DOM.
10882pub struct StyleCacheData {
109- styles : RefCell < BTreeMap < & ' static str , web_sys:: HtmlStyleElement > > ,
110- is_shadow : bool ,
83+ styles : RefCell < BTreeMap < & ' static str , web_sys:: CssStyleSheet > > ,
84+ adopted_style_sheets : js_sys :: Array ,
11185}
11286
11387impl StyleCacheData {
114- fn new ( is_shadow : bool ) -> Self {
88+ fn new ( is_shadow : bool , elem : & web_sys :: HtmlElement ) -> Self {
11589 let styles = DOM_STYLES
11690 . iter ( )
117- . map ( |x| ( x. 0 , StyleCache :: into_style ( x. 0 , x . 1 , is_shadow ) ) )
91+ . map ( |x| ( x. 0 , StyleCache :: into_style ( x. 1 ) ) )
11892 . collect ( ) ;
11993
94+ let root: & JsValue = if is_shadow {
95+ & elem. shadow_root ( ) . unwrap ( )
96+ } else {
97+ & web_sys:: window ( ) . unwrap ( ) . document ( ) . unwrap ( )
98+ } ;
99+
100+ let adopted_style_sheets = js_sys:: Reflect :: get ( root, & "adoptedStyleSheets" . into ( ) )
101+ . unwrap ( )
102+ . unchecked_into :: < js_sys:: Array > ( ) ;
103+
104+ for ( _, style) in DOM_STYLES . iter ( ) {
105+ let style = StyleCache :: into_style ( style) ;
106+ adopted_style_sheets. push ( & style) ;
107+ }
108+
120109 Self {
121110 styles : RefCell :: new ( styles) ,
122- is_shadow ,
111+ adopted_style_sheets ,
123112 }
124113 }
125114}
0 commit comments