@@ -399,3 +399,64 @@ DOMTokenList.prototype['toggle'] = function(token: string, force: boolean|undefi
399399 return originalToggle . call ( this , token , Boolean ( force ) ) ;
400400} ;
401401} ) ( ) ;
402+
403+ // DevTools uses multiple documents when the main window is undocked, and the
404+ // device mode toolbar is enabled. Since `CSSStyleSheet` objects cannot be
405+ // shared across multiple documents, we override the `adoptedStyleSheets`
406+ // accessor here, and clone the `CSSStyleSheet` objects under hood on-demand.
407+ //
408+ // NOTE: Since `adoptedStyleSheets` is an `ObservableArray`, which can be
409+ // mutated in place, we need to override both the setter and the getter, and
410+ // for the latter, we need to return a proxy that intercepts mutations to the
411+ // array-indexed properties.
412+ const originalAdoptedStyleSheets = Object . getOwnPropertyDescriptor ( ShadowRoot . prototype , 'adoptedStyleSheets' ) ;
413+ if ( originalAdoptedStyleSheets ) {
414+ const styleSheetInDocumentCache = new WeakMap < CSSStyleSheet , WeakMap < Document , CSSStyleSheet > > ( ) ;
415+
416+ /**
417+ * Returns a clone of the `styleSheet` within the given `document`.
418+ */
419+ function styleSheetInDocument ( styleSheet : CSSStyleSheet , document : Document ) : CSSStyleSheet {
420+ let styleSheetCache = styleSheetInDocumentCache . get ( styleSheet ) ;
421+ if ( styleSheetCache ) {
422+ const cachedSheet = styleSheetCache . get ( document ) ;
423+ if ( cachedSheet ) {
424+ return cachedSheet ;
425+ }
426+ } else {
427+ styleSheetCache = new WeakMap < Document , CSSStyleSheet > ( ) ;
428+ styleSheetInDocumentCache . set ( styleSheet , styleSheetCache ) ;
429+ }
430+
431+ const clonedStyleSheet = new document . defaultView . CSSStyleSheet ( ) ;
432+ for ( const { cssText} of styleSheet . cssRules ) {
433+ clonedStyleSheet . insertRule ( cssText ) ;
434+ }
435+ styleSheetCache . set ( document , clonedStyleSheet ) ;
436+ return clonedStyleSheet ;
437+ }
438+
439+ Object . defineProperty ( ShadowRoot . prototype , 'adoptedStyleSheets' , {
440+ configurable : true ,
441+ enumerable : true ,
442+ get ( this : ShadowRoot ) : CSSStyleSheet [ ] {
443+ const target = originalAdoptedStyleSheets . get . call ( this ) ;
444+ const { ownerDocument} = this . host ;
445+ return new Proxy ( target , {
446+ set ( target , propertyKey , value , receiver ) {
447+ if ( propertyKey === String ( propertyKey >>> 0 ) && ownerDocument !== document ) {
448+ value = styleSheetInDocument ( value , ownerDocument ) ;
449+ }
450+ return Reflect . set ( target , propertyKey , value , receiver ) ;
451+ } ,
452+ } ) ;
453+ } ,
454+ set ( this : ShadowRoot , styleSheets : CSSStyleSheet [ ] ) {
455+ const { ownerDocument} = this . host ;
456+ if ( ownerDocument !== document ) {
457+ styleSheets = styleSheets . map ( styleSheet => styleSheetInDocument ( styleSheet , ownerDocument ) ) ;
458+ }
459+ originalAdoptedStyleSheets . set . call ( this , styleSheets ) ;
460+ }
461+ } ) ;
462+ }
0 commit comments