11const _ = require ( 'lodash' )
22
3- function findLinkedNode ( nodes , linkPath ) {
3+ function findLinkedNode ( sourceNode , allNodes , linkPath ) {
44 const leafSlug = linkPath . pop ( )
55 const leafRe = new RegExp ( `^${ leafSlug } $` , 'i' )
6- const leafMatches = nodes . filter ( p => p . slug . match ( leafRe ) )
6+ const leafMatches = allNodes . filter ( p => p . slug . match ( leafRe ) )
77
88 if ( ! leafMatches . length ) {
99 return undefined
@@ -14,7 +14,7 @@ function findLinkedNode(nodes, linkPath) {
1414 }
1515
1616 if ( ! linkPath . length ) {
17- return undefined
17+ return findClosestNode ( sourceNode , leafMatches )
1818 }
1919
2020 const paths = linkPath . reverse ( )
@@ -29,6 +29,31 @@ function findLinkedNode(nodes, linkPath) {
2929 } )
3030}
3131
32+ function findClosestNode ( sourceNode , candidates ) {
33+ const sourceContext = [ ...sourceNode . context . items , sourceNode ]
34+ let bestMatch = candidates [ 0 ]
35+ let bestScore = - 1
36+ for ( const candidate of candidates ) {
37+ const candidateContext = candidate . context . items
38+ const maxDepth = Math . min (
39+ sourceContext . length , candidateContext . length
40+ )
41+ let score = 0
42+ for ( let i = 0 ; i < maxDepth ; i ++ ) {
43+ if ( sourceContext [ i ] . slug === candidateContext [ i ] . slug ) {
44+ score ++
45+ } else {
46+ break
47+ }
48+ }
49+ if ( score > bestScore ) {
50+ bestScore = score
51+ bestMatch = candidate
52+ }
53+ }
54+ return bestMatch
55+ }
56+
3257function addLinkBack ( sourceNode , targetNode , key ) {
3358 if ( sourceNode . schema ) {
3459 Object . keys ( sourceNode . schema . attributes || [ ] ) . forEach ( schemaKey => {
@@ -82,7 +107,7 @@ function resolveLinks(node, nodes) {
82107 if ( ! valueItem . linkPath ) {
83108 continue
84109 }
85- const linkedNode = findLinkedNode ( nodes , [ ...valueItem . linkPath ] )
110+ const linkedNode = findLinkedNode ( node , nodes , [ ...valueItem . linkPath ] )
86111 if ( linkedNode ) {
87112 node . addLink ( [ key , i ] , Object . assign ( { } , linkedNode ) )
88113 linkedNode . addLinkBack ( node , key )
@@ -92,7 +117,7 @@ function resolveLinks(node, nodes) {
92117 if ( ! value ?. linkPath ) {
93118 return
94119 }
95- const linkedNode = findLinkedNode ( nodes , [ ...value . linkPath ] )
120+ const linkedNode = findLinkedNode ( node , nodes , [ ...value . linkPath ] )
96121 if ( linkedNode ) {
97122 node . addLink ( [ key ] , Object . assign ( { } , linkedNode ) )
98123 linkedNode . addLinkBack ( node , key )
0 commit comments