···478 }
479480 // Match elements by isEqualNode
481- for (const i of unmatchedElements) {
482- const element = toChildNodes[i] as Element
483484 for (const candidateIndex of candidateElements) {
485 const candidate = fromChildNodes[candidateIndex]!
486 if (candidate.isEqualNode(element)) {
487- matches[i] = candidate
488 candidateElements.delete(candidateIndex)
489- unmatchedElements.delete(i)
490 break
491 }
492 }
493 }
494495 // Match by exact id
496- for (const i of unmatchedElements) {
497- const element = toChildNodes[i] as Element
498499 const id = element.id
500 if (id === "") continue
···502 for (const candidateIndex of candidateElements) {
503 const candidate = fromChildNodes[candidateIndex] as Element
504 if (element.localName === candidate.localName && id === candidate.id) {
505- matches[i] = candidate
506 candidateElements.delete(candidateIndex)
507- unmatchedElements.delete(i)
508 break
509 }
510 }
511 }
512513 // Match by idSet
514- for (const i of unmatchedElements) {
515- const element = toChildNodes[i] as Element
516517 const idSet = this.#idMap.get(element)
518 if (!idSet) continue
···523 if (candidateIdSet) {
524 for (const id of idSet) {
525 if (candidateIdSet.has(id)) {
526- matches[i] = candidate
527 candidateElements.delete(candidateIndex)
528- unmatchedElements.delete(i)
529 break candidateLoop
530 }
531 }
···534 }
535536 // Match by heuristics
537- for (const i of unmatchedElements) {
538- const element = toChildNodes[i] as Element
539540 const name = element.getAttribute("name")
541 const href = element.getAttribute("href")
···549 (href && href === candidate.getAttribute("href")) ||
550 (src && src === candidate.getAttribute("src")))
551 ) {
552- matches[i] = candidate
553 candidateElements.delete(candidateIndex)
554- unmatchedElements.delete(i)
555 break
556 }
557 }
558 }
559560 // Match by tagName
561- for (const i of unmatchedElements) {
562- const element = toChildNodes[i] as Element
563564 const localName = element.localName
565···570 // Treat inputs with different type as though they are different tags.
571 continue
572 }
573- matches[i] = candidate
574 candidateElements.delete(candidateIndex)
575- unmatchedElements.delete(i)
576 break
577 }
578 }
579 }
580581 // Match nodes by isEqualNode (skip whitespace-only text nodes)
582- for (const i of unmatchedNodes) {
583- const node = toChildNodes[i]!
584 if (isWhitespace(node)) continue
585586 for (const candidateIndex of candidateNodes) {
587 const candidate = fromChildNodes[candidateIndex]!
588 if (candidate.isEqualNode(node)) {
589- matches[i] = candidate
590 candidateNodes.delete(candidateIndex)
591- unmatchedNodes.delete(i)
592 break
593 }
594 }
595 }
596597 // Match by nodeType (skip whitespace-only text nodes)
598- for (const i of unmatchedNodes) {
599- const node = toChildNodes[i]!
600 if (isWhitespace(node)) continue
601602 const nodeType = node.nodeType
···604 for (const candidateIndex of candidateNodes) {
605 const candidate = fromChildNodes[candidateIndex]!
606 if (nodeType === candidate.nodeType) {
607- matches[i] = candidate
608 candidateNodes.delete(candidateIndex)
609- unmatchedNodes.delete(i)
610 break
611 }
612 }
···478 }
479480 // Match elements by isEqualNode
481+ for (const unmatchedIndex of unmatchedElements) {
482+ const element = toChildNodes[unmatchedIndex] as Element
483484 for (const candidateIndex of candidateElements) {
485 const candidate = fromChildNodes[candidateIndex]!
486 if (candidate.isEqualNode(element)) {
487+ matches[unmatchedIndex] = candidate
488 candidateElements.delete(candidateIndex)
489+ unmatchedElements.delete(unmatchedIndex)
490 break
491 }
492 }
493 }
494495 // Match by exact id
496+ for (const unmatchedIndex of unmatchedElements) {
497+ const element = toChildNodes[unmatchedIndex] as Element
498499 const id = element.id
500 if (id === "") continue
···502 for (const candidateIndex of candidateElements) {
503 const candidate = fromChildNodes[candidateIndex] as Element
504 if (element.localName === candidate.localName && id === candidate.id) {
505+ matches[unmatchedIndex] = candidate
506 candidateElements.delete(candidateIndex)
507+ unmatchedElements.delete(unmatchedIndex)
508 break
509 }
510 }
511 }
512513 // Match by idSet
514+ for (const unmatchedIndex of unmatchedElements) {
515+ const element = toChildNodes[unmatchedIndex] as Element
516517 const idSet = this.#idMap.get(element)
518 if (!idSet) continue
···523 if (candidateIdSet) {
524 for (const id of idSet) {
525 if (candidateIdSet.has(id)) {
526+ matches[unmatchedIndex] = candidate
527 candidateElements.delete(candidateIndex)
528+ unmatchedElements.delete(unmatchedIndex)
529 break candidateLoop
530 }
531 }
···534 }
535536 // Match by heuristics
537+ for (const unmatchedIndex of unmatchedElements) {
538+ const element = toChildNodes[unmatchedIndex] as Element
539540 const name = element.getAttribute("name")
541 const href = element.getAttribute("href")
···549 (href && href === candidate.getAttribute("href")) ||
550 (src && src === candidate.getAttribute("src")))
551 ) {
552+ matches[unmatchedIndex] = candidate
553 candidateElements.delete(candidateIndex)
554+ unmatchedElements.delete(unmatchedIndex)
555 break
556 }
557 }
558 }
559560 // Match by tagName
561+ for (const unmatchedIndex of unmatchedElements) {
562+ const element = toChildNodes[unmatchedIndex] as Element
563564 const localName = element.localName
565···570 // Treat inputs with different type as though they are different tags.
571 continue
572 }
573+ matches[unmatchedIndex] = candidate
574 candidateElements.delete(candidateIndex)
575+ unmatchedElements.delete(unmatchedIndex)
576 break
577 }
578 }
579 }
580581 // Match nodes by isEqualNode (skip whitespace-only text nodes)
582+ for (const unmatchedIndex of unmatchedNodes) {
583+ const node = toChildNodes[unmatchedIndex]!
584 if (isWhitespace(node)) continue
585586 for (const candidateIndex of candidateNodes) {
587 const candidate = fromChildNodes[candidateIndex]!
588 if (candidate.isEqualNode(node)) {
589+ matches[unmatchedIndex] = candidate
590 candidateNodes.delete(candidateIndex)
591+ unmatchedNodes.delete(unmatchedIndex)
592 break
593 }
594 }
595 }
596597 // Match by nodeType (skip whitespace-only text nodes)
598+ for (const unmatchedIndex of unmatchedNodes) {
599+ const node = toChildNodes[unmatchedIndex]!
600 if (isWhitespace(node)) continue
601602 const nodeType = node.nodeType
···604 for (const candidateIndex of candidateNodes) {
605 const candidate = fromChildNodes[candidateIndex]!
606 if (nodeType === candidate.nodeType) {
607+ matches[unmatchedIndex] = candidate
608 candidateNodes.delete(candidateIndex)
609+ unmatchedNodes.delete(unmatchedIndex)
610 break
611 }
612 }