@@ -45,8 +45,8 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
4545
4646 var InertRoot = function ( ) {
4747 /**
48- * @param {Element } rootElement The Element at the root of the inert subtree.
49- * @param {InertManager } inertManager The global singleton InertManager object.
48+ * @param {! Element } rootElement The Element at the root of the inert subtree.
49+ * @param {! InertManager } inertManager The global singleton InertManager object.
5050 */
5151 function InertRoot ( rootElement , inertManager ) {
5252 _classCallCheck ( this , InertRoot ) ;
@@ -69,13 +69,23 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
6969 // Make all focusable elements in the subtree unfocusable and add them to _managedNodes
7070 this . _makeSubtreeUnfocusable ( this . _rootElement ) ;
7171
72+ this . _onMutation = this . _onMutation . bind ( this ) ;
7273 // Watch for:
7374 // - any additions in the subtree: make them unfocusable too
7475 // - any removals from the subtree: remove them from this inert root's managed nodes
7576 // - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable element,
7677 // make that node a managed node.
77- this . _observer = new MutationObserver ( this . _onMutation . bind ( this ) ) ;
78+ this . _observer = new MutationObserver ( this . _onMutation ) ;
7879 this . _observer . observe ( this . _rootElement , { attributes : true , childList : true , subtree : true } ) ;
80+
81+ // Watch for:
82+ // - any additions in the shadowRoot subtree: make them unfocusable too
83+ // - any removals from the shadowRoot subtree: remove them from this inert root's managed nodes
84+ var rootObserver = new MutationObserver ( this . _onMutation ) ;
85+ this . _rootObserver = rootObserver ;
86+ patchShadowRootCreation ( this . _rootElement , function ( shadowRoot ) {
87+ rootObserver . observe ( shadowRoot , { childList : true , subtree : true } ) ;
88+ } ) ;
7989 }
8090
8191 /**
@@ -90,7 +100,11 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
90100 this . _observer . disconnect ( ) ;
91101 this . _observer = null ;
92102
93- if ( this . _rootElement ) this . _rootElement . removeAttribute ( 'aria-hidden' ) ;
103+ this . _rootObserver . disconnect ( ) ;
104+ this . _rootObserver = null ;
105+
106+ this . _rootElement . removeAttribute ( 'aria-hidden' ) ;
107+ unpatchShadowRootCreation ( this . _rootElement ) ;
94108 this . _rootElement = null ;
95109
96110 var _iteratorNormalCompletion = true ;
@@ -915,6 +929,59 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
915929 node . appendChild ( style ) ;
916930 }
917931
932+ /**
933+ * Invokes the callback after the element attaches the shadow root. If `element`
934+ * has already a shadowRoot, the `callback` is invoked immediately.
935+ * Need to patch `attachShadow` and `createShadowRoot` methods as there is
936+ * no way to observe shadow root attachment (yet), see w3c/webcomponents#204
937+ * @param {!Element } element
938+ * @param {!Function(DocumentFragment) } callback
939+ */
940+ function patchShadowRootCreation ( element , callback ) {
941+ var shadowRoot = element . shadowRoot || element . webkitShadowRoot ;
942+ if ( shadowRoot ) {
943+ callback ( shadowRoot ) ;
944+ } else {
945+ ( function ( ) {
946+ // ShadowDOM v1 support.
947+ var attachShadowFn = element . attachShadow ;
948+ if ( attachShadowFn ) {
949+ element . attachShadow = function patchedAttachShadow ( ) {
950+ var shadowRoot = attachShadowFn . apply ( this , arguments ) ;
951+ callback ( shadowRoot ) ;
952+ return shadowRoot ;
953+ } ;
954+ element . attachShadow . _originalFn = attachShadowFn ;
955+ }
956+ // ShadowDOM v0 support.
957+ var createShadowRootFn = element . createShadowRoot ;
958+ if ( createShadowRootFn ) {
959+ element . createShadowRoot = function patchedCreateShadowRoot ( ) {
960+ var shadowRoot = createShadowRootFn . apply ( this , arguments ) ;
961+ callback ( shadowRoot ) ;
962+ return shadowRoot ;
963+ } ;
964+ element . createShadowRoot . _originalFn = createShadowRootFn ;
965+ }
966+ } ) ( ) ;
967+ }
968+ }
969+
970+ /**
971+ * Restores the original `attachShadow` and `createShadowRoot` methods of `element`.
972+ * @param {!Element } element
973+ */
974+ function unpatchShadowRootCreation ( element ) {
975+ // ShadowDOM v1 support.
976+ if ( element . attachShadow && element . attachShadow . _originalFn ) {
977+ element . attachShadow = element . attachShadow . _originalFn ;
978+ }
979+ // ShadowDOM v0 support.
980+ if ( element . createShadowRoot && element . createShadowRoot . _originalFn ) {
981+ element . createShadowRoot = element . createShadowRoot . _originalFn ;
982+ }
983+ }
984+
918985 var inertManager = new InertManager ( document ) ;
919986
920987 Object . defineProperty ( Element . prototype , 'inert' , {
0 commit comments