@@ -21,7 +21,7 @@ import type {OverlayRef} from '../overlay-ref';
21
21
export class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {
22
22
private _cursorOriginalValue : string ;
23
23
private _cursorStyleIsSet = false ;
24
- private _pointerDownEventTarget : EventTarget | null ;
24
+ private _pointerDownEventTarget : HTMLElement | null ;
25
25
26
26
constructor (
27
27
@Inject ( DOCUMENT ) document : any ,
@@ -89,12 +89,12 @@ export class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {
89
89
90
90
/** Store pointerdown event target to track origin of click. */
91
91
private _pointerDownListener = ( event : PointerEvent ) => {
92
- this . _pointerDownEventTarget = _getEventTarget ( event ) ;
92
+ this . _pointerDownEventTarget = _getEventTarget < HTMLElement > ( event ) ;
93
93
} ;
94
94
95
95
/** Click event listener that will be attached to the body propagate phase. */
96
96
private _clickListener = ( event : MouseEvent ) => {
97
- const target = _getEventTarget ( event ) ;
97
+ const target = _getEventTarget < HTMLElement > ( event ) ;
98
98
// In case of a click event, we want to check the origin of the click
99
99
// (e.g. in case where a user starts a click inside the overlay and
100
100
// releases the click outside of it).
@@ -128,8 +128,8 @@ export class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {
128
128
// If it's an outside click (both origin and target of the click) dispatch the mouse event,
129
129
// and proceed with the next overlay
130
130
if (
131
- overlayRef . overlayElement . contains ( target as Node ) ||
132
- overlayRef . overlayElement . contains ( origin as Node )
131
+ containsPierceShadowDom ( overlayRef . overlayElement , target ) ||
132
+ containsPierceShadowDom ( overlayRef . overlayElement , origin )
133
133
) {
134
134
break ;
135
135
}
@@ -144,3 +144,20 @@ export class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {
144
144
}
145
145
} ;
146
146
}
147
+
148
+ /** Version of `Element.contains` that transcends shadow DOM boundaries. */
149
+ function containsPierceShadowDom ( parent : HTMLElement , child : HTMLElement | null ) : boolean {
150
+ const supportsShadowRoot = typeof ShadowRoot !== 'undefined' && ShadowRoot ;
151
+ let current : Node | null = child ;
152
+
153
+ while ( current ) {
154
+ if ( current === parent ) {
155
+ return true ;
156
+ }
157
+
158
+ current =
159
+ supportsShadowRoot && current instanceof ShadowRoot ? current . host : current . parentNode ;
160
+ }
161
+
162
+ return false ;
163
+ }
0 commit comments