| 556 | } |
| 557 | |
| 558 | async filter(request) { |
| 559 | const { queryTerms } = request; |
| 560 | |
| 561 | const keyword = queryTerms[0]; |
| 562 | const queryTermsWithoutKeyword = queryTerms.slice(1); |
| 563 | |
| 564 | const userSearchEngine = userSearchEngines.keywordToEngine[keyword]; |
| 565 | if (!userSearchEngine) return []; |
| 566 | |
| 567 | const searchUrl = userSearchEngine.url; |
| 568 | |
| 569 | const completions = await completionSearch.complete(searchUrl, queryTermsWithoutKeyword); |
| 570 | |
| 571 | const makeSuggestion = (query) => { |
| 572 | const url = UrlUtils.createSearchUrl(query, searchUrl); |
| 573 | return new Suggestion({ |
| 574 | queryTerms, |
| 575 | description: userSearchEngine.description, |
| 576 | url, |
| 577 | title: query, |
| 578 | searchUrl, |
| 579 | highlightTerms: false, |
| 580 | isCustomSearch: true, |
| 581 | relevancy: null, |
| 582 | relevancyFunction: this.computeRelevancy, |
| 583 | }); |
| 584 | }; |
| 585 | |
| 586 | const suggestions = completions.map((completion) => { |
| 587 | const s = makeSuggestion(completion); |
| 588 | s.insertText = completion; |
| 589 | return s; |
| 590 | }); |
| 591 | |
| 592 | if (suggestions[0]) suggestions[0].relevancy = 1.0; |
| 593 | |
| 594 | // This is a suggestion which contains the user's query. It's the "search for exactly what I |
| 595 | // just typed" option. It should always appear first in the list. |
| 596 | const primarySuggestion = makeSuggestion(queryTermsWithoutKeyword.join(" ")); |
| 597 | primarySuggestion.relevancy = 2; |
| 598 | primarySuggestion.isPrimarySuggestion = true; |
| 599 | primarySuggestion.autoSelect = true; |
| 600 | suggestions.unshift(primarySuggestion); |
| 601 | |
| 602 | return suggestions; |
| 603 | } |
| 604 | |
| 605 | computeRelevancy({ queryTerms, title }) { |
| 606 | // Tweaks: |