From a65d79b810cf4c165c2174ad9893db0ebcc9989f Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 27 May 2015 08:13:53 +0100 Subject: Custom-only: disable default search completion. --- background_scripts/completion.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 30a7b882..dc2c9360 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -464,7 +464,7 @@ class SearchEngineCompleter searchUrl: Settings.get "searchUrl" description: "search" - return onComplete [] unless custom or 0 < queryTerms.length + return onComplete [] unless custom factor = Math.max 0.0, Math.min 1.0, Settings.get "omniSearchWeight" haveCompletionEngine = (0.0 < factor or custom) and CompletionSearch.haveCompletionEngine searchUrl @@ -514,6 +514,8 @@ class SearchEngineCompleter highlightTerms: not haveCompletionEngine isSearchSuggestion: true + return onComplete [ primarySuggestion ], { filter } if queryTerms.length == 0 + mkSuggestion = (suggestion) => url = Utils.createSearchUrl suggestion, searchUrl @previousSuggestions[url] = new Suggestion -- cgit v1.2.3 From 9b9c26a42bffa88584d44526da5e14a5e546fa07 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 27 May 2015 08:23:01 +0100 Subject: Custom-only: always filter for the custom search engine. --- background_scripts/completion.coffee | 39 ++++++++++++------------------------ 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index dc2c9360..7a5f37bf 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -472,37 +472,24 @@ class SearchEngineCompleter # This filter is applied to all of the suggestions from all of the completers, after they have been # aggregated by the MultiCompleter. filter = (suggestions) -> - if custom and haveCompletionEngine - # We only accept suggestions: - # - from this completer, or - # - from other completers, but then only if their URL matches this search engine and matches this - # query (that is only if their URL could have been generated by this search engine). - suggestions.filter (suggestion) -> - suggestion.type == description or - # This is a suggestion for the same search engine. - (suggestion.url.startsWith(engine.searchUrlPrefix) and - # And the URL suffix (which must contain the query part) matches the current query. - RankingUtils.matches queryTerms, suggestion.url[engine.searchUrlPrefix.length..]) - - else if not custom - # Filter out any suggestion which is just what the user would get if they hit anyway. For - # example, don't offer "https://www.google.com/search?q=vimium" if the query is "vimium". - defaultUrl = Utils.createSearchUrl queryTerms, searchUrl - defaultQuery = queryTerms.join " " - suggestions.filter (suggestion) -> Utils.extractQuery(searchUrl, suggestion.url) != defaultQuery - else - suggestions + suggestions.filter (suggestion) -> + # We only keep suggestions which either *were* generated by this completion engine, or *could have + # been* generated by this completion engine. + suggestion.isSearchSuggestion or suggestion.isCustomSearch or Utils.extractQuery searchUrl, suggestion.url # If a previous suggestion still matches the query, then we keep it (even if the completion engine may not # return it for the current query). This allows the user to pick suggestions by typing fragments of their # text, without regard to whether the completion engine can complete the actual text of the query. previousSuggestions = - for url, suggestion of @previousSuggestions - continue unless RankingUtils.matches queryTerms, suggestion.title - # Reset various fields, they may not be correct wrt. the current query. - extend suggestion, relevancy: null, html: null, highlightTerms: true, queryTerms: queryTerms - suggestion.relevancy = null - suggestion + if queryTerms.length == 0 + [] + else + for url, suggestion of @previousSuggestions + continue unless RankingUtils.matches queryTerms, suggestion.title + # Reset various fields, they may not be correct wrt. the current query. + extend suggestion, relevancy: null, html: null, highlightTerms: true, queryTerms: queryTerms + suggestion.relevancy = null + suggestion primarySuggestion = new Suggestion queryTerms: queryTerms -- cgit v1.2.3 From e27da85676a9d62145ed7ef56e125de2e133ae10 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 27 May 2015 08:34:15 +0100 Subject: Custom-only: single-line completions for custom search engines. --- background_scripts/completion.coffee | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 7a5f37bf..3238f744 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -41,23 +41,32 @@ class Suggestion # or @relevancyFunction. @relevancy ?= @relevancyFunction this - generateHtml: -> + generateHtml: (request) -> return @html if @html relevancyHtml = if @showRelevancy then "#{@computeRelevancy()}" else "" insertTextClass = if @insertText then "vomnibarInsertText" else "vomnibarNoInsertText" insertTextIndicator = "↪" # A right hooked arrow. + @title = @insertText if @insertText and request.isCustomSearch # NOTE(philc): We're using these vimium-specific class names so we don't collide with the page's CSS. @html = - """ -
- #{insertTextIndicator}#{@type} - #{@highlightQueryTerms Utils.escapeHtml @title} -
-
- #{insertTextIndicator}#{@highlightUrlTerms Utils.escapeHtml @shortenUrl()} - #{relevancyHtml} -
- """ + if request.isCustomSearch + """ +
+ #{insertTextIndicator}#{@type} + #{@highlightQueryTerms Utils.escapeHtml @title} +
+ """ + else + """ +
+ #{insertTextIndicator}#{@type} + #{@highlightQueryTerms Utils.escapeHtml @title} +
+
+ #{insertTextIndicator}#{@highlightUrlTerms Utils.escapeHtml @shortenUrl()} + #{relevancyHtml} +
+ """ # Use neat trick to snatch a domain (http://stackoverflow.com/a/8498668). getUrlRoot: (url) -> @@ -419,6 +428,7 @@ class SearchEngineCompleter queryTerms: queryTerms[1..] keyword: keyword engine: engines[keyword] + isCustomSearch: true refresh: (port) -> @previousSuggestions = {} @@ -662,7 +672,7 @@ class MultiCompleter completer.postProcessSuggestions? request, suggestions for completer in @completers # Generate HTML for the remaining suggestions and return them. - suggestion.generateHtml() for suggestion in suggestions + suggestion.generateHtml request for suggestion in suggestions suggestions # Utilities which help us compute a relevancy score for a given item. -- cgit v1.2.3 From 0eae69d6cb9b37fe0a41c16888f8af85197e42aa Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 27 May 2015 09:27:07 +0100 Subject: Custom-only: verify match on query terms alone. --- background_scripts/completion.coffee | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 3238f744..7dbd2e61 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -484,8 +484,12 @@ class SearchEngineCompleter filter = (suggestions) -> suggestions.filter (suggestion) -> # We only keep suggestions which either *were* generated by this completion engine, or *could have - # been* generated by this completion engine. - suggestion.isSearchSuggestion or suggestion.isCustomSearch or Utils.extractQuery searchUrl, suggestion.url + # been* generated by this completion engine (and match the current query). + suggestion.isSearchSuggestion or suggestion.isCustomSearch or + ( + terms = Utils.extractQuery searchUrl, suggestion.url + terms and RankingUtils.matches queryTerms, terms + ) # If a previous suggestion still matches the query, then we keep it (even if the completion engine may not # return it for the current query). This allows the user to pick suggestions by typing fragments of their -- cgit v1.2.3 From b5d3c6e963cd32da41046a16f30307a655089f17 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 27 May 2015 09:29:04 +0100 Subject: Custom-only: fix comment. --- background_scripts/completion.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 7dbd2e61..40a7c8fd 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -483,8 +483,8 @@ class SearchEngineCompleter # aggregated by the MultiCompleter. filter = (suggestions) -> suggestions.filter (suggestion) -> - # We only keep suggestions which either *were* generated by this completion engine, or *could have - # been* generated by this completion engine (and match the current query). + # We only keep suggestions which either *were* generated by this search engine, or *could have + # been* generated by this search engine (and match the current query). suggestion.isSearchSuggestion or suggestion.isCustomSearch or ( terms = Utils.extractQuery searchUrl, suggestion.url -- cgit v1.2.3 From a3002fe93e6d9f69f7f12f3695becf307e59bb89 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 28 May 2015 10:11:33 +0100 Subject: Custom-only: strip non-custom search code. --- background_scripts/completion.coffee | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 40a7c8fd..6f0b9a73 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -420,7 +420,7 @@ class SearchEngineCompleter preprocessRequest: (request) -> @searchEngines.use (engines) => { queryTerms, query } = request - request.searchEngines = engines + extend request, searchEngines: engines, keywords: key for own key of engines keyword = queryTerms[0] # Note. For a keyword "w", we match "w search terms" and "w ", but not "w" on its own. if keyword and engines[keyword] and (1 < queryTerms.length or /\S\s/.test query) @@ -461,23 +461,13 @@ class SearchEngineCompleter filter: (request, onComplete) -> { queryTerms, query, engine } = request + return onComplete [] unless engine - { custom, searchUrl, description } = - if engine - { keyword, searchUrl, description } = engine - extend request, { searchUrl, customSearchMode: true } - custom: true - searchUrl: searchUrl - description: description - else - custom: false - searchUrl: Settings.get "searchUrl" - description: "search" - - return onComplete [] unless custom + { keyword, searchUrl, description } = engine + extend request, searchUrl, customSearchMode: true factor = Math.max 0.0, Math.min 1.0, Settings.get "omniSearchWeight" - haveCompletionEngine = (0.0 < factor or custom) and CompletionSearch.haveCompletionEngine searchUrl + haveCompletionEngine = CompletionSearch.haveCompletionEngine searchUrl # This filter is applied to all of the suggestions from all of the completers, after they have been # aggregated by the MultiCompleter. @@ -501,7 +491,7 @@ class SearchEngineCompleter for url, suggestion of @previousSuggestions continue unless RankingUtils.matches queryTerms, suggestion.title # Reset various fields, they may not be correct wrt. the current query. - extend suggestion, relevancy: null, html: null, highlightTerms: true, queryTerms: queryTerms + extend suggestion, relevancy: null, html: null, highlightTerms: false, queryTerms: queryTerms suggestion.relevancy = null suggestion @@ -511,8 +501,8 @@ class SearchEngineCompleter url: Utils.createSearchUrl queryTerms, searchUrl title: queryTerms.join " " relevancy: 1 - autoSelect: custom - highlightTerms: not haveCompletionEngine + autoSelect: true + highlightTerms: false isSearchSuggestion: true return onComplete [ primarySuggestion ], { filter } if queryTerms.length == 0 @@ -527,7 +517,7 @@ class SearchEngineCompleter insertText: suggestion highlightTerms: false highlightTermsExcludeUrl: true - isCustomSearch: custom + isCustomSearch: true relevancyFunction: @computeRelevancy relevancyData: factor @@ -535,12 +525,11 @@ class SearchEngineCompleter if haveCompletionEngine then CompletionSearch.complete searchUrl, queryTerms else null suggestions = previousSuggestions - suggestions.push primarySuggestion if custom - suggestions.push cachedSuggestions.map(mkSuggestion)... if custom and cachedSuggestions? + suggestions.push primarySuggestion + suggestions.push cachedSuggestions.map(mkSuggestion)... if cachedSuggestions? if queryTerms.length == 0 or cachedSuggestions? or not haveCompletionEngine # There is no prospect of adding further completions. - suggestions.push cachedSuggestions.map(mkSuggestion)... if cachedSuggestions? onComplete suggestions, { filter, continuation: null } else # Post the initial suggestions, but then deliver any further completions asynchronously, as a @@ -586,9 +575,6 @@ class SearchEngineCompleter # suggestion, then custom search-engine mode should be activated. suggestion.customSearchMode = engine.keyword suggestion.title ||= suggestion.insertText - # NOTE(smblott) The following is disabled: experimentation with UI. - # suggestion.highlightTermsExcludeUrl = true - # suggestion.type = engine.description ? "custom search history" break # A completer which calls filter() on many completers, aggregates the results, ranks them, and returns the top -- cgit v1.2.3 From ded18f3bb0eb8cf2e559ff44a46564fd002a4b33 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 28 May 2015 10:22:46 +0100 Subject: Custom-only: remove omniSearchWeightOption. This option is no longer needed, since we don't do search completion except for custom searches. --- background_scripts/completion.coffee | 10 +++++----- background_scripts/settings.coffee | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 6f0b9a73..aa7ed4bc 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -10,7 +10,7 @@ # - refresh(): (optional) refreshes the completer's data source (e.g. refetches the list of bookmarks). # - cancel(): (optional) cancels any pending, cancelable action. class Suggestion - showRelevancy: false # Set this to true to render relevancy when debugging the ranking scores. + showRelevancy: true # Set this to true to render relevancy when debugging the ranking scores. constructor: (@options) -> # Required options. @@ -54,6 +54,7 @@ class Suggestion
#{insertTextIndicator}#{@type} #{@highlightQueryTerms Utils.escapeHtml @title} + #{relevancyHtml}
""" else @@ -466,7 +467,7 @@ class SearchEngineCompleter { keyword, searchUrl, description } = engine extend request, searchUrl, customSearchMode: true - factor = Math.max 0.0, Math.min 1.0, Settings.get "omniSearchWeight" + factor = 0.5 haveCompletionEngine = CompletionSearch.haveCompletionEngine searchUrl # This filter is applied to all of the suggestions from all of the completers, after they have been @@ -519,7 +520,6 @@ class SearchEngineCompleter highlightTermsExcludeUrl: true isCustomSearch: true relevancyFunction: @computeRelevancy - relevancyData: factor cachedSuggestions = if haveCompletionEngine then CompletionSearch.complete searchUrl, queryTerms else null @@ -544,7 +544,7 @@ class SearchEngineCompleter # lowest-ranked suggestion from another completer (and there are already 10 suggestions), then # there's no need to query the completion engine. perfectRelevancyScore = @computeRelevancy new Suggestion - queryTerms: queryTerms, title: queryTerms.join(" "), relevancyData: factor + queryTerms: queryTerms, title: queryTerms.join " " if 10 <= suggestions.length and perfectRelevancyScore < suggestions[suggestions.length-1].relevancy console.log "skip (cannot make the grade):", suggestions.length, query if SearchEngineCompleter.debug @@ -560,7 +560,7 @@ class SearchEngineCompleter # scores here, and those provided by other completers. # - Relevancy depends only on the title (which is the search terms), and not on the URL. Suggestion.boostRelevancyScore 0.5, - relevancyData * RankingUtils.wordRelevancy queryTerms, title, title + 0.7 * RankingUtils.wordRelevancy queryTerms, title, title postProcessSuggestions: (request, suggestions) -> return unless request.searchEngines diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index 269b4a2c..d23649ee 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -43,7 +43,6 @@ root.Settings = Settings = # or strings defaults: scrollStepSize: 60 - omniSearchWeight: 0.4 smoothScroll: true keyMappings: "# Insert your preferred key mappings here." linkHintCharacters: "sadfjklewcmpgh" -- cgit v1.2.3 From 4b4fb7957e89adddcf454c56e902f2c3395eadbc Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 28 May 2015 10:26:22 +0100 Subject: Custom-only: ensure top-ranking completion is always in top slot. This ensures that can always be used to complete the top-ranking completion. --- background_scripts/completion.coffee | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index aa7ed4bc..8f8754f8 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -301,7 +301,7 @@ class DomainCompleter queryTerms: queryTerms type: "domain" url: domains[0]?[0] ? "" # This is the URL or an empty string, but not null. - relevancy: 1 + relevancy: 2.0 ].filter (s) -> 0 < s.url.length # Returns a list of domains of the form: [ [domain, relevancy], ... ] @@ -501,35 +501,38 @@ class SearchEngineCompleter type: description url: Utils.createSearchUrl queryTerms, searchUrl title: queryTerms.join " " - relevancy: 1 + relevancy: 2.0 autoSelect: true highlightTerms: false isSearchSuggestion: true return onComplete [ primarySuggestion ], { filter } if queryTerms.length == 0 - mkSuggestion = (suggestion) => - url = Utils.createSearchUrl suggestion, searchUrl - @previousSuggestions[url] = new Suggestion - queryTerms: queryTerms - type: description - url: url - title: suggestion - insertText: suggestion - highlightTerms: false - highlightTermsExcludeUrl: true - isCustomSearch: true - relevancyFunction: @computeRelevancy + mkSuggestion = do => + count = 0 + (suggestion) => + url = Utils.createSearchUrl suggestion, searchUrl + @previousSuggestions[url] = new Suggestion + queryTerms: queryTerms + type: description + url: url + title: suggestion + insertText: suggestion + highlightTerms: false + highlightTermsExcludeUrl: true + isCustomSearch: true + relevancy: if ++count == 1 then 1.0 else null + relevancyFunction: @computeRelevancy cachedSuggestions = if haveCompletionEngine then CompletionSearch.complete searchUrl, queryTerms else null suggestions = previousSuggestions suggestions.push primarySuggestion - suggestions.push cachedSuggestions.map(mkSuggestion)... if cachedSuggestions? if queryTerms.length == 0 or cachedSuggestions? or not haveCompletionEngine - # There is no prospect of adding further completions. + # There is no prospect of adding further completions, so we're done. + suggestions.push cachedSuggestions.map(mkSuggestion)... if cachedSuggestions? onComplete suggestions, { filter, continuation: null } else # Post the initial suggestions, but then deliver any further completions asynchronously, as a -- cgit v1.2.3 From a975ce087c4beac442e5cfaeb7fb0510e54c82a4 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 28 May 2015 10:32:46 +0100 Subject: Custom-only: remove now unnecessary optimisation. This optimisation is now unnecessary, because we will *always* show at least one completion suggestion in top spot. --- background_scripts/completion.coffee | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 8f8754f8..d8b946a1 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -10,7 +10,7 @@ # - refresh(): (optional) refreshes the completer's data source (e.g. refetches the list of bookmarks). # - cancel(): (optional) cancels any pending, cancelable action. class Suggestion - showRelevancy: true # Set this to true to render relevancy when debugging the ranking scores. + showRelevancy: false # Set this to true to render relevancy when debugging the ranking scores. constructor: (@options) -> # Required options. @@ -539,20 +539,7 @@ class SearchEngineCompleter # continuation. onComplete suggestions, filter: filter - continuation: (suggestions, onComplete) => - - # We can skip querying the completion engine if any new suggestions we propose will not score highly - # enough to make the list anyway. We construct a suggestion which perfectly matches the query, and - # ask the relevancy function what score it would get. If that score is less than the score of the - # lowest-ranked suggestion from another completer (and there are already 10 suggestions), then - # there's no need to query the completion engine. - perfectRelevancyScore = @computeRelevancy new Suggestion - queryTerms: queryTerms, title: queryTerms.join " " - - if 10 <= suggestions.length and perfectRelevancyScore < suggestions[suggestions.length-1].relevancy - console.log "skip (cannot make the grade):", suggestions.length, query if SearchEngineCompleter.debug - return onComplete [] - + continuation: (onComplete) => CompletionSearch.complete searchUrl, queryTerms, (suggestions = []) => console.log "fetched suggestions:", suggestions.length, query if SearchEngineCompleter.debug onComplete suggestions.map mkSuggestion @@ -632,7 +619,7 @@ class MultiCompleter if shouldRunContinuations jobs = new JobRunner continuations.map (continuation) -> (callback) -> - continuation suggestions, (newSuggestions) -> + continuation (newSuggestions) -> suggestions.push newSuggestions... callback() -- cgit v1.2.3 From 45157bc460494503ca2b90caa762e72d224a1ef3 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 28 May 2015 15:56:18 +0100 Subject: Custom-only: fix long-standing race condition. In omni mode, the vomnibar suggestions are updated asynchronously. Therefore, the contents of the primary custom search-engine suggestion may be behind the actual contents of the comnibar input. So, we reconstruct the custom search-engine query on "enter". (This fixes a long-standing race condition.) --- background_scripts/completion.coffee | 1 + 1 file changed, 1 insertion(+) (limited to 'background_scripts') diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index d8b946a1..60e5f1df 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -505,6 +505,7 @@ class SearchEngineCompleter autoSelect: true highlightTerms: false isSearchSuggestion: true + isPrimarySuggestion: true return onComplete [ primarySuggestion ], { filter } if queryTerms.length == 0 -- cgit v1.2.3