Skip to content

Commit 87e5b86

Browse files
committed
take 2
Signed-off-by: Brian DeHamer <bdehamer@github.com>
1 parent a3c1886 commit 87e5b86

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

workspaces/arborist/lib/query-selector-all.js

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -697,20 +697,9 @@ const hasParent = (node, compareNodes) => {
697697
// All it takes is one so we loop and return on the first hit
698698
for (const compareNode of compareNodes) {
699699
// follows logical parent for link anscestors
700-
if (node.isTop) {
701-
if (node.resolveParent === compareNode) {
702-
return true
703-
} else {
704-
// Top-level nodes have no edgesIn, so check the edgesOut
705-
// of the parent to see if any of them are links to this node
706-
for (const edge of compareNode.edgesOut.values()) {
707-
if (edge.to === node || edge.to?.target === node) {
708-
return true
709-
}
710-
}
711-
}
700+
if (node.isTop && (node.resolveParent === compareNode)) {
701+
return true
712702
}
713-
714703
// follows edges-in to check if they match a possible parent
715704
for (const edge of node.edgesIn) {
716705
if (edge && edge.from === compareNode) {
@@ -721,25 +710,33 @@ const hasParent = (node, compareNodes) => {
721710
return false
722711
}
723712

724-
// checks if a given node is a descendant of any of the nodes provided in the
725-
// compareNodes array
726-
const hasAscendant = (node, compareNodes, seen = new Set()) => {
727-
// TODO (future) loop over ancestry property
728-
if (hasParent(node, compareNodes)) {
729-
return true
713+
// checks if a given node is a child of the provided compareNode
714+
const isChild = (node, compareNode) => {
715+
for (const edge of compareNode.edgesOut.values()) {
716+
if (edge.to === node || edge.to?.target === node) {
717+
return true
718+
}
730719
}
720+
return false
721+
}
731722

732-
if (node.isTop && node.resolveParent) {
733-
return hasAscendant(node.resolveParent, compareNodes)
723+
// checks if a given node is the descendant of the provided compareNode
724+
const isDescendant = (node, compareNode, seen = new Set()) => {
725+
// Direct child
726+
if (isChild(node, compareNode)) {
727+
return true
734728
}
735-
for (const edge of node.edgesIn) {
736-
// TODO Need a test with an infinite loop
729+
730+
// Loop through edgesOut of compareNode to see if there is a path to node
731+
for (const edge of compareNode.edgesOut.values()) {
737732
if (seen.has(edge)) {
738733
continue
739734
}
740735
seen.add(edge)
741-
if (edge && edge.from && hasAscendant(edge.from, compareNodes, seen)) {
742-
return true
736+
if (edge.to) {
737+
if (isDescendant(node, edge.to.isLink ? edge.to.target : edge.to, seen)) {
738+
return true
739+
}
743740
}
744741
}
745742
return false
@@ -752,7 +749,9 @@ const combinators = {
752749
},
753750
// any descendant
754751
' ' (prevResults, nextResults) {
755-
return nextResults.filter(node => hasAscendant(node, prevResults))
752+
return nextResults.filter(node =>
753+
prevResults.some(compareNode => isDescendant(node, compareNode))
754+
)
756755
},
757756
// sibling
758757
'~' (prevResults, nextResults) {

0 commit comments

Comments
 (0)