@@ -116,6 +116,8 @@ export function isNotch(shape: Shape): shape is Notch {
116116 ) ;
117117}
118118
119+ const injectionSites = new Map < string , WeakSet < Document | ShadowRoot > > ( ) ;
120+
119121/**
120122 * An object that provides constants for rendering blocks.
121123 */
@@ -327,9 +329,6 @@ export class ConstantProvider {
327329 */
328330 private debugFilter : SVGElement | null = null ;
329331
330- /** The <style> element to use for injecting renderer specific CSS. */
331- private cssNode : HTMLStyleElement | null = null ;
332-
333332 /**
334333 * Cursor colour.
335334 */
@@ -696,7 +695,6 @@ export class ConstantProvider {
696695 if ( this . debugFilter ) {
697696 dom . removeNode ( this . debugFilter ) ;
698697 }
699- this . cssNode = null ;
700698 }
701699
702700 /**
@@ -924,7 +922,6 @@ export class ConstantProvider {
924922 * Create any DOM elements that this renderer needs (filters, patterns, etc).
925923 *
926924 * @param svg The root of the workspace's SVG.
927- * @param tagName The name to use for the CSS style tag.
928925 * @param selector The CSS selector to use.
929926 * @param injectionDivIfIsParent The div containing the parent workspace and
930927 * all related workspaces and block containers, if this renderer is for the
@@ -934,11 +931,15 @@ export class ConstantProvider {
934931 */
935932 createDom (
936933 svg : SVGElement ,
937- tagName : string ,
938934 selector : string ,
939935 injectionDivIfIsParent ?: HTMLElement ,
940936 ) {
941- this . injectCSS_ ( tagName , selector ) ;
937+ if ( injectionDivIfIsParent ) {
938+ const root = injectionDivIfIsParent . getRootNode ( ) as
939+ | Document
940+ | ShadowRoot ;
941+ this . injectCSS_ ( root , selector ) ;
942+ }
942943
943944 /*
944945 <defs>
@@ -1121,26 +1122,26 @@ export class ConstantProvider {
11211122 /**
11221123 * Inject renderer specific CSS into the page.
11231124 *
1124- * @param tagName The name of the style tag to use .
1125- * @param selector The CSS selector to use .
1125+ * @param root The document root to inject the CSS into .
1126+ * @param selector The CSS selector to interpolate into the stylesheet .
11261127 */
1127- protected injectCSS_ ( tagName : string , selector : string ) {
1128- const cssArray = this . getCSS_ ( selector ) ;
1129- const cssNodeId = 'blockly-renderer-style-' + tagName ;
1130- this . cssNode = document . getElementById ( cssNodeId ) as HTMLStyleElement ;
1131- const text = cssArray . join ( '\n' ) ;
1132- if ( this . cssNode ) {
1133- // Already injected, update if the theme changed.
1134- this . cssNode . firstChild ! . textContent = text ;
1128+ protected injectCSS_ ( root : Document | ShadowRoot , selector : string ) {
1129+ if (
1130+ typeof window === 'undefined' ||
1131+ ! window . CSSStyleSheet ||
1132+ injectionSites . get ( selector ) ?. has ( root )
1133+ ) {
11351134 return ;
11361135 }
1137- // Inject CSS tag at start of head.
1138- const cssNode = document . createElement ( 'style' ) ;
1139- cssNode . id = cssNodeId ;
1140- const cssTextNode = document . createTextNode ( text ) ;
1141- cssNode . appendChild ( cssTextNode ) ;
1142- document . head . insertBefore ( cssNode , document . head . firstChild ) ;
1143- this . cssNode = cssNode ;
1136+
1137+ const sheet = new CSSStyleSheet ( ) ;
1138+ sheet . replace ( this . getCSS_ ( selector ) . join ( '\n' ) ) ;
1139+ root . adoptedStyleSheets . push ( sheet ) ;
1140+
1141+ const sitesForSelector =
1142+ injectionSites . get ( selector ) ?? new WeakSet < Document | ShadowRoot > ( ) ;
1143+ sitesForSelector . add ( root ) ;
1144+ injectionSites . set ( selector , sitesForSelector ) ;
11441145 }
11451146
11461147 /**
0 commit comments