File tree 4 files changed +52
-8
lines changed
4 files changed +52
-8
lines changed Original file line number Diff line number Diff line change @@ -1025,7 +1025,10 @@ export default class Node extends EventTarget {
1025
1025
*/
1026
1026
public [ PropertySymbol . disconnectedFromDocument ] ( ) : void {
1027
1027
this [ PropertySymbol . isConnected ] = false ;
1028
- this [ PropertySymbol . rootNode ] = null ;
1028
+
1029
+ if ( this [ PropertySymbol . nodeType ] !== NodeTypeEnum . documentFragmentNode ) {
1030
+ this [ PropertySymbol . rootNode ] = null ;
1031
+ }
1029
1032
1030
1033
if ( this [ PropertySymbol . ownerDocument ] [ PropertySymbol . activeElement ] === < unknown > this ) {
1031
1034
this [ PropertySymbol . ownerDocument ] [ PropertySymbol . clearCache ] ( ) ;
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ import CSSStyleSheet from '../../css/CSSStyleSheet.js';
7
7
import HTMLElement from '../../nodes/html-element/HTMLElement.js' ;
8
8
import Event from '../../event/Event.js' ;
9
9
import SVGElement from '../svg-element/SVGElement.js' ;
10
+ import Document from '../document/Document.js' ;
10
11
11
12
/**
12
13
* ShadowRoot.
@@ -165,16 +166,25 @@ export default class ShadowRoot extends DocumentFragment {
165
166
* @returns Active element.
166
167
*/
167
168
public get activeElement ( ) : HTMLElement | SVGElement | null {
168
- const activeElement : HTMLElement | SVGElement =
169
+ let activeElement : HTMLElement | SVGElement =
169
170
this [ PropertySymbol . ownerDocument ] [ PropertySymbol . activeElement ] ;
170
- if (
171
- activeElement &&
172
- activeElement [ PropertySymbol . isConnected ] &&
173
- activeElement . getRootNode ( ) === this
174
- ) {
171
+
172
+ let rootNode : ShadowRoot | Document = < ShadowRoot | Document > activeElement ?. getRootNode ( ) ;
173
+
174
+ if ( ! rootNode || rootNode === this [ PropertySymbol . ownerDocument ] ) {
175
+ return null ;
176
+ }
177
+
178
+ if ( rootNode === this ) {
175
179
return activeElement ;
176
180
}
177
- return null ;
181
+
182
+ while ( rootNode && rootNode !== this ) {
183
+ activeElement = < HTMLElement | SVGElement > ( < ShadowRoot > rootNode ) . host ;
184
+ rootNode = < ShadowRoot | Document > activeElement . getRootNode ( ) ;
185
+ }
186
+
187
+ return activeElement ;
178
188
}
179
189
180
190
/**
Original file line number Diff line number Diff line change @@ -366,6 +366,14 @@ describe('Node', () => {
366
366
const rootNode = ( < ShadowRoot > customElement . shadowRoot ) . querySelector ( 'span' ) ?. getRootNode ( ) ;
367
367
368
368
expect ( rootNode === customElement . shadowRoot ) . toBe ( true ) ;
369
+
370
+ document . body . removeChild ( customElement ) ;
371
+
372
+ document . body . appendChild ( customElement ) ;
373
+
374
+ const rootNode2 = ( < ShadowRoot > customElement . shadowRoot ) . querySelector ( 'span' ) ?. getRootNode ( ) ;
375
+
376
+ expect ( rootNode2 === customElement . shadowRoot ) . toBe ( true ) ;
369
377
} ) ;
370
378
371
379
it ( 'Returns Document when used on a node inside a ShadowRoot and the option "composed" is set to "true".' , ( ) => {
Original file line number Diff line number Diff line change @@ -218,6 +218,29 @@ describe('ShadowRoot', () => {
218
218
219
219
expect ( shadowRoot . activeElement === null ) . toBe ( true ) ;
220
220
} ) ;
221
+
222
+ it ( 'Returns the first custom element when the active element is not a child of the ShadowRoot, but is a child of a custom element within it.' , ( ) => {
223
+ const customElement = document . createElement ( 'custom-element' ) ;
224
+ const shadowRoot = < ShadowRoot > customElement . shadowRoot ;
225
+ const div = < HTMLElement > document . createElement ( 'div' ) ;
226
+ const customElementA = document . createElement ( 'custom-element-a' ) ;
227
+ const shadowRootA = < ShadowRoot > customElementA . shadowRoot ;
228
+
229
+ document . body . appendChild ( customElement ) ;
230
+
231
+ shadowRoot . appendChild ( customElementA ) ;
232
+ shadowRootA . appendChild ( div ) ;
233
+
234
+ expect ( shadowRoot . activeElement === null ) . toBe ( true ) ;
235
+
236
+ div . focus ( ) ;
237
+
238
+ expect ( shadowRoot . activeElement ) . toBe ( customElementA ) ;
239
+
240
+ customElementA . remove ( ) ;
241
+
242
+ expect ( shadowRoot . activeElement === null ) . toBe ( true ) ;
243
+ } ) ;
221
244
} ) ;
222
245
223
246
describe ( 'getAnimations()' , ( ) => {
You can’t perform that action at this time.
0 commit comments