1616
1717import type { SelectorEngine , SelectorRoot } from './selectorEngine' ;
1818import { matchesAttributePart } from './selectorUtils' ;
19- import { beginAriaCaches , endAriaCaches , getAriaChecked , getAriaDisabled , getAriaExpanded , getAriaLevel , getAriaPressed , getAriaRole , getAriaSelected , getElementAccessibleName , isElementHiddenForAria , kAriaCheckedRoles , kAriaExpandedRoles , kAriaLevelRoles , kAriaPressedRoles , kAriaSelectedRoles } from './roleUtils' ;
19+ import { beginAriaCaches , endAriaCaches , getAriaChecked , getAriaDisabled , getAriaExpanded , getAriaLevel , getAriaPressed , getAriaSelected , getElementAccessibleName , getElementsByRole , isElementHiddenForAria , kAriaCheckedRoles , kAriaExpandedRoles , kAriaLevelRoles , kAriaPressedRoles , kAriaSelectedRoles } from './roleUtils' ;
2020import { parseAttributeSelector , type AttributeSelectorPart , type AttributeSelectorOperator } from '../../utils/isomorphic/selectorParser' ;
2121import { normalizeWhiteSpace } from '../../utils/isomorphic/stringUtils' ;
22+ import { isInsideScope } from './domUtils' ;
2223
2324type RoleEngineOptions = {
2425 role : string ;
@@ -125,26 +126,27 @@ function validateAttributes(attrs: AttributeSelectorPart[], role: string): RoleE
125126}
126127
127128function queryRole ( scope : SelectorRoot , options : RoleEngineOptions , internal : boolean ) : Element [ ] {
128- const result : Element [ ] = [ ] ;
129- const match = ( element : Element ) => {
130- if ( getAriaRole ( element ) !== options . role )
131- return ;
129+ const doc = scope . nodeType === 9 /* Node.DOCUMENT_NODE */ ? scope as Document : scope . ownerDocument ;
130+ const elements = doc ? getElementsByRole ( doc , options . role ) : [ ] ;
131+ return elements . filter ( element => {
132+ if ( ! isInsideScope ( scope , element ) )
133+ return false ;
132134 if ( options . selected !== undefined && getAriaSelected ( element ) !== options . selected )
133- return ;
135+ return false ;
134136 if ( options . checked !== undefined && getAriaChecked ( element ) !== options . checked )
135- return ;
137+ return false ;
136138 if ( options . pressed !== undefined && getAriaPressed ( element ) !== options . pressed )
137- return ;
139+ return false ;
138140 if ( options . expanded !== undefined && getAriaExpanded ( element ) !== options . expanded )
139- return ;
141+ return false ;
140142 if ( options . level !== undefined && getAriaLevel ( element ) !== options . level )
141- return ;
143+ return false ;
142144 if ( options . disabled !== undefined && getAriaDisabled ( element ) !== options . disabled )
143- return ;
145+ return false ;
144146 if ( ! options . includeHidden ) {
145147 const isHidden = isElementHiddenForAria ( element ) ;
146148 if ( isHidden )
147- return ;
149+ return false ;
148150 }
149151 if ( options . name !== undefined ) {
150152 // Always normalize whitespace in the accessible name.
@@ -155,25 +157,10 @@ function queryRole(scope: SelectorRoot, options: RoleEngineOptions, internal: bo
155157 if ( internal && ! options . exact && options . nameOp === '=' )
156158 options . nameOp = '*=' ;
157159 if ( ! matchesAttributePart ( accessibleName , { name : '' , jsonPath : [ ] , op : options . nameOp || '=' , value : options . name , caseSensitive : ! ! options . exact } ) )
158- return ;
160+ return false ;
159161 }
160- result . push ( element ) ;
161- } ;
162-
163- const query = ( root : Element | ShadowRoot | Document ) => {
164- const shadows : ShadowRoot [ ] = [ ] ;
165- if ( ( root as Element ) . shadowRoot )
166- shadows . push ( ( root as Element ) . shadowRoot ! ) ;
167- for ( const element of root . querySelectorAll ( '*' ) ) {
168- match ( element ) ;
169- if ( element . shadowRoot )
170- shadows . push ( element . shadowRoot ) ;
171- }
172- shadows . forEach ( query ) ;
173- } ;
174-
175- query ( scope ) ;
176- return result ;
162+ return true ;
163+ } ) ;
177164}
178165
179166export function createRoleEngine ( internal : boolean ) : SelectorEngine {
0 commit comments