@@ -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