@@ -1202,28 +1202,42 @@ function initSearch(rawSearchIndex) {
12021202 * @param {Row } row
12031203 * @param {QueryElement } elem - The element from the parsed query.
12041204 * @param {integer } typeFilter
1205+ * @param {Array<integer> } skipPositions - Do not return one of these positions.
12051206 *
1206- * @return {integer } - Returns an edit distance to the best match. If there is no
1207- * match, returns `maxEditDistance + 1`.
1207+ * @return {dist: integer, position: integer } - Returns an edit distance to the best match.
1208+ * If there is no match, returns
1209+ * `maxEditDistance + 1` and position: -1.
12081210 */
1209- function findArg ( row , elem , typeFilter , maxEditDistance ) {
1211+ function findArg ( row , elem , typeFilter , maxEditDistance , skipPositions ) {
12101212 let dist = maxEditDistance + 1 ;
1213+ let position = - 1 ;
12111214
12121215 if ( row && row . type && row . type . inputs && row . type . inputs . length > 0 ) {
1216+ let i = 0 ;
12131217 for ( const input of row . type . inputs ) {
1214- if ( ! typePassesFilter ( typeFilter , input . ty ) ) {
1218+ if ( ! typePassesFilter ( typeFilter , input . ty ) ||
1219+ skipPositions . indexOf ( i ) !== - 1 ) {
1220+ i += 1 ;
12151221 continue ;
12161222 }
1217- dist = Math . min (
1218- dist ,
1219- checkType ( input , elem , parsedQuery . literalSearch , maxEditDistance )
1223+ const typeDist = checkType (
1224+ input ,
1225+ elem ,
1226+ parsedQuery . literalSearch ,
1227+ maxEditDistance
12201228 ) ;
1221- if ( dist === 0 ) {
1222- return 0 ;
1229+ if ( typeDist === 0 ) {
1230+ return { dist : 0 , position : i } ;
1231+ }
1232+ if ( typeDist < dist ) {
1233+ dist = typeDist ;
1234+ position = i ;
12231235 }
1236+ i += 1 ;
12241237 }
12251238 }
1226- return parsedQuery . literalSearch ? maxEditDistance + 1 : dist ;
1239+ dist = parsedQuery . literalSearch ? maxEditDistance + 1 : dist ;
1240+ return { dist, position} ;
12271241 }
12281242
12291243 /**
@@ -1232,29 +1246,43 @@ function initSearch(rawSearchIndex) {
12321246 * @param {Row } row
12331247 * @param {QueryElement } elem - The element from the parsed query.
12341248 * @param {integer } typeFilter
1249+ * @param {Array<integer> } skipPositions - Do not return one of these positions.
12351250 *
1236- * @return {integer } - Returns an edit distance to the best match. If there is no
1237- * match, returns `maxEditDistance + 1`.
1251+ * @return {dist: integer, position: integer } - Returns an edit distance to the best match.
1252+ * If there is no match, returns
1253+ * `maxEditDistance + 1` and position: -1.
12381254 */
1239- function checkReturned ( row , elem , typeFilter , maxEditDistance ) {
1255+ function checkReturned ( row , elem , typeFilter , maxEditDistance , skipPositions ) {
12401256 let dist = maxEditDistance + 1 ;
1257+ let position = - 1 ;
12411258
12421259 if ( row && row . type && row . type . output . length > 0 ) {
12431260 const ret = row . type . output ;
1261+ let i = 0 ;
12441262 for ( const ret_ty of ret ) {
1245- if ( ! typePassesFilter ( typeFilter , ret_ty . ty ) ) {
1263+ if ( ! typePassesFilter ( typeFilter , ret_ty . ty ) ||
1264+ skipPositions . indexOf ( i ) !== - 1 ) {
1265+ i += 1 ;
12461266 continue ;
12471267 }
1248- dist = Math . min (
1249- dist ,
1250- checkType ( ret_ty , elem , parsedQuery . literalSearch , maxEditDistance )
1268+ const typeDist = checkType (
1269+ ret_ty ,
1270+ elem ,
1271+ parsedQuery . literalSearch ,
1272+ maxEditDistance
12511273 ) ;
1252- if ( dist === 0 ) {
1253- return 0 ;
1274+ if ( typeDist === 0 ) {
1275+ return { dist : 0 , position : i } ;
12541276 }
1277+ if ( typeDist < dist ) {
1278+ dist = typeDist ;
1279+ position = i ;
1280+ }
1281+ i += 1 ;
12551282 }
12561283 }
1257- return parsedQuery . literalSearch ? maxEditDistance + 1 : dist ;
1284+ dist = parsedQuery . literalSearch ? maxEditDistance + 1 : dist ;
1285+ return { dist, position} ;
12581286 }
12591287
12601288 function checkPath ( contains , ty , maxEditDistance ) {
@@ -1455,13 +1483,13 @@ function initSearch(rawSearchIndex) {
14551483 const fullId = row . id ;
14561484 const searchWord = searchWords [ pos ] ;
14571485
1458- const in_args = findArg ( row , elem , parsedQuery . typeFilter , maxEditDistance ) ;
1459- const returned = checkReturned ( row , elem , parsedQuery . typeFilter , maxEditDistance ) ;
1486+ const in_args = findArg ( row , elem , parsedQuery . typeFilter , maxEditDistance , [ ] ) ;
1487+ const returned = checkReturned ( row , elem , parsedQuery . typeFilter , maxEditDistance , [ ] ) ;
14601488
14611489 // path_dist is 0 because no parent path information is currently stored
14621490 // in the search index
1463- addIntoResults ( results_in_args , fullId , pos , - 1 , in_args , 0 , maxEditDistance ) ;
1464- addIntoResults ( results_returned , fullId , pos , - 1 , returned , 0 , maxEditDistance ) ;
1491+ addIntoResults ( results_in_args , fullId , pos , - 1 , in_args . dist , 0 , maxEditDistance ) ;
1492+ addIntoResults ( results_returned , fullId , pos , - 1 , returned . dist , 0 , maxEditDistance ) ;
14651493
14661494 if ( ! typePassesFilter ( parsedQuery . typeFilter , row . ty ) ) {
14671495 return ;
@@ -1534,12 +1562,20 @@ function initSearch(rawSearchIndex) {
15341562
15351563 // If the result is too "bad", we return false and it ends this search.
15361564 function checkArgs ( elems , callback ) {
1565+ const skipPositions = [ ] ;
15371566 for ( const elem of elems ) {
15381567 // There is more than one parameter to the query so all checks should be "exact"
1539- const dist = callback ( row , elem , NO_TYPE_FILTER , maxEditDistance ) ;
1568+ const { dist, position } = callback (
1569+ row ,
1570+ elem ,
1571+ NO_TYPE_FILTER ,
1572+ maxEditDistance ,
1573+ skipPositions
1574+ ) ;
15401575 if ( dist <= 1 ) {
15411576 nbDist += 1 ;
15421577 totalDist += dist ;
1578+ skipPositions . push ( position ) ;
15431579 } else {
15441580 return false ;
15451581 }
@@ -1597,9 +1633,17 @@ function initSearch(rawSearchIndex) {
15971633 row ,
15981634 elem ,
15991635 parsedQuery . typeFilter ,
1636+ maxEditDistance ,
1637+ [ ]
1638+ ) ;
1639+ addIntoResults (
1640+ results_others ,
1641+ row . id ,
1642+ i ,
1643+ - 1 ,
1644+ in_returned . dist ,
16001645 maxEditDistance
16011646 ) ;
1602- addIntoResults ( results_others , row . id , i , - 1 , in_returned , maxEditDistance ) ;
16031647 }
16041648 }
16051649 } else if ( parsedQuery . foundElems > 0 ) {
0 commit comments