@@ -21,25 +21,39 @@ export class DomRenderer {
2121 const shadowHost = container . createDiv ( { cls : "html-reader-shadow-host" } ) ;
2222 const shadow = shadowHost . attachShadow ( { mode : "open" } ) ;
2323
24- if ( settings . darkModeSupport ) {
25- const sheet = new CSSStyleSheet ( ) ;
26- sheet . replaceSync ( DARK_MODE_SHADOW_CSS ) ;
27- shadow . adoptedStyleSheets = [ sheet ] ;
28- }
29-
3024 const parser = new DOMParser ( ) ;
3125 let doc : Document ;
3226
3327 if ( settings . securityMode === SecurityMode . Unrestricted ) {
34- // Parse directly and strip only scripts for DOM safety.
35- // Avoids the serialize→re-parse round-trip that can lose style elements.
3628 doc = parser . parseFromString ( html , "text/html" ) ;
3729 doc . querySelectorAll ( "script" ) . forEach ( el => el . remove ( ) ) ;
3830 } else {
3931 const sanitized = sanitizeHtml ( html , settings ) ;
4032 doc = parser . parseFromString ( sanitized , "text/html" ) ;
4133 }
4234
35+ // Extract <style> elements into adoptedStyleSheets.
36+ // Obsidian strips <style> DOM nodes (no-forbidden-elements); adopted sheets bypass this.
37+ const sheets : CSSStyleSheet [ ] = [ ] ;
38+ if ( settings . darkModeSupport ) {
39+ const darkSheet = new CSSStyleSheet ( ) ;
40+ darkSheet . replaceSync ( DARK_MODE_SHADOW_CSS ) ;
41+ sheets . push ( darkSheet ) ;
42+ }
43+ for ( const style of Array . from ( doc . querySelectorAll ( "style" ) ) ) {
44+ let css = style . textContent ?? "" ;
45+ // :root and body selectors have no target in shadow DOM; remap to :host
46+ css = css . replace ( / : r o o t / g, ":host" ) ;
47+ css = css . replace ( / ( ^ | [ \s , } ] ) b o d y (? = \s * \{ ) / gm, "$1:host" ) ;
48+ try {
49+ const sheet = new CSSStyleSheet ( ) ;
50+ sheet . replaceSync ( css ) ;
51+ sheets . push ( sheet ) ;
52+ } catch { /* skip unparseable CSS */ }
53+ style . remove ( ) ;
54+ }
55+ shadow . adoptedStyleSheets = sheets ;
56+
4357 const wrapper = document . createElement ( "div" ) ;
4458 for ( const node of Array . from ( doc . head . childNodes ) ) {
4559 wrapper . appendChild ( node ) ;
0 commit comments