@@ -69,47 +69,23 @@ class InertRoot {
6969 // Make all focusable elements in the subtree unfocusable and add them to _managedNodes
7070 this . _makeSubtreeUnfocusable ( this . _rootElement ) ;
7171
72- const boundOnMutation = this . _onMutation . bind ( this ) ;
72+ this . _onMutation = this . _onMutation . bind ( this ) ;
7373 // Watch for:
7474 // - any additions in the subtree: make them unfocusable too
7575 // - any removals from the subtree: remove them from this inert root's managed nodes
7676 // - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable element,
7777 // make that node a managed node.
78- this . _observer = new MutationObserver ( boundOnMutation ) ;
78+ this . _observer = new MutationObserver ( this . _onMutation ) ;
7979 this . _observer . observe ( this . _rootElement , { attributes : true , childList : true , subtree : true } ) ;
8080
8181 // Watch for:
8282 // - any additions in the shadowRoot subtree: make them unfocusable too
8383 // - any removals from the shadowRoot subtree: remove them from this inert root's managed nodes
84- const rootObserver = new MutationObserver ( boundOnMutation ) ;
85- const shadowRoot = this . _rootElement . shadowRoot || this . _rootElement . webkitShadowRoot ;
86- if ( shadowRoot ) {
87- rootObserver . observe ( shadowRoot , { childList : true , subtree : true } ) ;
88- } else {
89- // ShadowDOM v1 support.
90- // NOTE(valdrin) There is no way to observe shadow root attachment (yet),
91- // patching might be slow https://github.com/w3c/webcomponents/issues/204
92- const attachShadowFn = this . _rootElement . attachShadow ;
93- if ( attachShadowFn ) {
94- this . _rootElement . attachShadow = function patchedAttachShadow ( ) {
95- const shadowRoot = attachShadowFn . apply ( this , arguments ) ;
96- rootObserver . observe ( shadowRoot , { childList : true , subtree : true } ) ;
97- return shadowRoot ;
98- } ;
99- }
100- // ShadowDOM v0 support.
101- // NOTE(valdrin) There is no way to observe shadow root attachment (yet),
102- // patching might be slow https://github.com/w3c/webcomponents/issues/204
103- const createShadowRootFn = this . _rootElement . createShadowRoot ;
104- if ( createShadowRootFn ) {
105- this . _rootElement . createShadowRoot = function patchedCreateShadowRoot ( ) {
106- const shadowRoot = createShadowRootFn . apply ( this , arguments ) ;
107- rootObserver . observe ( shadowRoot , { childList : true , subtree : true } ) ;
108- return shadowRoot ;
109- } ;
110- }
111- }
84+ const rootObserver = new MutationObserver ( this . _onMutation ) ;
11285 this . _rootObserver = rootObserver ;
86+ patchShadowRootCreation ( this . _rootElement , function ( shadowRoot ) {
87+ rootObserver . observe ( shadowRoot , { childList : true , subtree : true } ) ;
88+ } ) ;
11389 }
11490
11591 /**
@@ -124,9 +100,7 @@ class InertRoot {
124100 this . _rootObserver = null ;
125101
126102 this . _rootElement . removeAttribute ( 'aria-hidden' ) ;
127- // Restore original attachShadow and createShadowRoot.
128- delete this . _rootElement . attachShadow ;
129- delete this . _rootElement . createShadowRoot ;
103+ unpatchShadowRootCreation ( this . _rootElement ) ;
130104 this . _rootElement = null ;
131105
132106 for ( let inertNode of this . _managedNodes )
@@ -676,6 +650,57 @@ function addInertStyle(node) {
676650 node . appendChild ( style ) ;
677651}
678652
653+ /**
654+ * Invokes the callback after the element attaches the shadow root. If `element`
655+ * has already a shadowRoot, the `callback` is invoked immediately.
656+ * Need to patch `attachShadow` and `createShadowRoot` methods as there is
657+ * no way to observe shadow root attachment (yet), see w3c/webcomponents#204
658+ * @param {!Element } element
659+ * @param {!Function(DocumentFragment) } callback
660+ */
661+ function patchShadowRootCreation ( element , callback ) {
662+ const shadowRoot = element . shadowRoot || element . webkitShadowRoot ;
663+ if ( shadowRoot ) {
664+ callback ( shadowRoot ) ;
665+ } else {
666+ // ShadowDOM v1 support.
667+ const attachShadowFn = element . attachShadow ;
668+ if ( attachShadowFn ) {
669+ element . attachShadow = function patchedAttachShadow ( ) {
670+ const shadowRoot = attachShadowFn . apply ( this , arguments ) ;
671+ callback ( shadowRoot ) ;
672+ return shadowRoot ;
673+ } ;
674+ element . attachShadow . _originalFn = attachShadowFn ;
675+ }
676+ // ShadowDOM v0 support.
677+ const createShadowRootFn = this . _rootElement . createShadowRoot ;
678+ if ( createShadowRootFn ) {
679+ element . createShadowRoot = function patchedCreateShadowRoot ( ) {
680+ const shadowRoot = createShadowRootFn . apply ( this , arguments ) ;
681+ callback ( shadowRoot ) ;
682+ return shadowRoot ;
683+ } ;
684+ element . createShadowRoot . _originalFn = createShadowRootFn ;
685+ }
686+ }
687+ }
688+
689+ /**
690+ * Restores the original `attachShadow` and `createShadowRoot` methods of `element`.
691+ * @param {!Element } element
692+ */
693+ function unpatchShadowRootCreation ( element ) {
694+ // ShadowDOM v1 support.
695+ if ( element . attachShadow && element . attachShadow . _originalFn ) {
696+ element . attachShadow = element . attachShadow . _originalFn ;
697+ }
698+ // ShadowDOM v0 support.
699+ if ( element . createShadowRoot && element . createShadowRoot . _originalFn ) {
700+ element . createShadowRoot = element . createShadowRoot . _originalFn ;
701+ }
702+ }
703+
679704const inertManager = new InertManager ( document ) ;
680705
681706Object . defineProperty ( Element . prototype , 'inert' , {
0 commit comments