@@ -236,7 +236,7 @@ export type MatcherReceived = {
236236
237237export  function  matchesAriaTree ( builtins : Builtins ,  rootElement : Element ,  template : AriaTemplateNode ) : {  matches : AriaNode [ ] ,  received : MatcherReceived  }  { 
238238  const  snapshot  =  generateAriaTree ( builtins ,  rootElement ,  0 ,  false ) ; 
239-   const  matches  =  matchesNodeDeep ( snapshot . root ,  template ,  false ) ; 
239+   const  matches  =  matchesNodeDeep ( snapshot . root ,  template ,  false ,   false ) ; 
240240  return  { 
241241    matches, 
242242    received : { 
@@ -248,49 +248,65 @@ export function matchesAriaTree(builtins: Builtins, rootElement: Element, templa
248248
249249export  function  getAllByAria ( builtins : Builtins ,  rootElement : Element ,  template : AriaTemplateNode ) : Element [ ]  { 
250250  const  root  =  generateAriaTree ( builtins ,  rootElement ,  0 ,  false ) . root ; 
251-   const  matches  =  matchesNodeDeep ( root ,  template ,  true ) ; 
251+   const  matches  =  matchesNodeDeep ( root ,  template ,  true ,   false ) ; 
252252  return  matches . map ( n  =>  n . element ) ; 
253253} 
254254
255- function  matchesNode ( node : AriaNode  |  string ,  template : AriaTemplateNode ,  depth :  number ) : boolean  { 
255+ function  matchesNode ( node : AriaNode  |  string ,  template : AriaTemplateNode ,  isDeepEqual :  boolean ) : boolean  { 
256256  if  ( typeof  node  ===  'string'  &&  template . kind  ===  'text' ) 
257257    return  matchesTextNode ( node ,  template ) ; 
258258
259-   if  ( node  !==  null  &&  typeof  node  ===  'object'  &&  template . kind  ===  'role' )  { 
260-     if  ( template . role  !==  'fragment'  &&  template . role  !==  node . role ) 
261-       return  false ; 
262-     if  ( template . checked  !==  undefined  &&  template . checked  !==  node . checked ) 
263-       return  false ; 
264-     if  ( template . disabled  !==  undefined  &&  template . disabled  !==  node . disabled ) 
265-       return  false ; 
266-     if  ( template . expanded  !==  undefined  &&  template . expanded  !==  node . expanded ) 
267-       return  false ; 
268-     if  ( template . level  !==  undefined  &&  template . level  !==  node . level ) 
269-       return  false ; 
270-     if  ( template . pressed  !==  undefined  &&  template . pressed  !==  node . pressed ) 
271-       return  false ; 
272-     if  ( template . selected  !==  undefined  &&  template . selected  !==  node . selected ) 
273-       return  false ; 
274-     if  ( ! matchesName ( node . name ,  template ) ) 
275-       return  false ; 
276-     if  ( ! matchesText ( node . props . url ,  template . props ?. url ) ) 
277-       return  false ; 
278-     if  ( ! containsList ( node . children  ||  [ ] ,  template . children  ||  [ ] ,  depth ) ) 
259+   if  ( node  ===  null  ||  typeof  node  !==  'object'  ||  template . kind  !==  'role' ) 
260+     return  false ; 
261+ 
262+   if  ( template . role  !==  'fragment'  &&  template . role  !==  node . role ) 
263+     return  false ; 
264+   if  ( template . checked  !==  undefined  &&  template . checked  !==  node . checked ) 
265+     return  false ; 
266+   if  ( template . disabled  !==  undefined  &&  template . disabled  !==  node . disabled ) 
267+     return  false ; 
268+   if  ( template . expanded  !==  undefined  &&  template . expanded  !==  node . expanded ) 
269+     return  false ; 
270+   if  ( template . level  !==  undefined  &&  template . level  !==  node . level ) 
271+     return  false ; 
272+   if  ( template . pressed  !==  undefined  &&  template . pressed  !==  node . pressed ) 
273+     return  false ; 
274+   if  ( template . selected  !==  undefined  &&  template . selected  !==  node . selected ) 
275+     return  false ; 
276+   if  ( ! matchesName ( node . name ,  template ) ) 
277+     return  false ; 
278+   if  ( ! matchesText ( node . props . url ,  template . props ?. url ) ) 
279+     return  false ; 
280+ 
281+   // Proceed based on the container mode. 
282+   if  ( template . containerMode  ===  'contain' ) 
283+     return  containsList ( node . children  ||  [ ] ,  template . children  ||  [ ] ) ; 
284+   if  ( template . containerMode  ===  'equal' ) 
285+     return  listEqual ( node . children  ||  [ ] ,  template . children  ||  [ ] ,  false ) ; 
286+   if  ( template . containerMode  ===  'deep-equal'  ||  isDeepEqual ) 
287+     return  listEqual ( node . children  ||  [ ] ,  template . children  ||  [ ] ,  true ) ; 
288+   return  containsList ( node . children  ||  [ ] ,  template . children  ||  [ ] ) ; 
289+ } 
290+ 
291+ function  listEqual ( children : ( AriaNode  |  string ) [ ] ,  template : AriaTemplateNode [ ] ,  isDeepEqual : boolean ) : boolean  { 
292+   if  ( template . length  !==  children . length ) 
293+     return  false ; 
294+   for  ( let  i  =  0 ;  i  <  template . length ;  ++ i )  { 
295+     if  ( ! matchesNode ( children [ i ] ,  template [ i ] ,  isDeepEqual ) ) 
279296      return  false ; 
280-     return  true ; 
281297  } 
282-   return  false ; 
298+   return  true ; 
283299} 
284300
285- function  containsList ( children : ( AriaNode  |  string ) [ ] ,  template : AriaTemplateNode [ ] ,   depth :  number ) : boolean  { 
301+ function  containsList ( children : ( AriaNode  |  string ) [ ] ,  template : AriaTemplateNode [ ] ) : boolean  { 
286302  if  ( template . length  >  children . length ) 
287303    return  false ; 
288304  const  cc  =  children . slice ( ) ; 
289305  const  tt  =  template . slice ( ) ; 
290306  for  ( const  t  of  tt )  { 
291307    let  c  =  cc . shift ( ) ; 
292308    while  ( c )  { 
293-       if  ( matchesNode ( c ,  t ,  depth   +   1 ) ) 
309+       if  ( matchesNode ( c ,  t ,  false ) ) 
294310        break ; 
295311      c  =  cc . shift ( ) ; 
296312    } 
@@ -300,10 +316,10 @@ function containsList(children: (AriaNode | string)[], template: AriaTemplateNod
300316  return  true ; 
301317} 
302318
303- function  matchesNodeDeep ( root : AriaNode ,  template : AriaTemplateNode ,  collectAll : boolean ) : AriaNode [ ]  { 
319+ function  matchesNodeDeep ( root : AriaNode ,  template : AriaTemplateNode ,  collectAll : boolean ,   isDeepEqual :  boolean ) : AriaNode [ ]  { 
304320  const  results : AriaNode [ ]  =  [ ] ; 
305321  const  visit  =  ( node : AriaNode  |  string ,  parent : AriaNode  |  null ) : boolean  =>  { 
306-     if  ( matchesNode ( node ,  template ,  0 ) )  { 
322+     if  ( matchesNode ( node ,  template ,  isDeepEqual ) )  { 
307323      const  result  =  typeof  node  ===  'string'  ? parent  : node ; 
308324      if  ( result ) 
309325        results . push ( result ) ; 
0 commit comments