aboutsummaryrefslogtreecommitdiffstats
path: root/background_scripts
diff options
context:
space:
mode:
authorStephen Blott2015-05-10 09:49:09 +0100
committerStephen Blott2015-05-10 09:55:14 +0100
commit146957c9dae54c31ce4676b5a4b60a0000c05487 (patch)
treeb40e0185da068e9f5250f837104e99bce7c132ac /background_scripts
parent1a337a261a6dd6deffa836cbd949bb036e103f36 (diff)
downloadvimium-146957c9dae54c31ce4676b5a4b60a0000c05487.tar.bz2
Search completion; use cached suggestions synchronously.
Diffstat (limited to 'background_scripts')
-rw-r--r--background_scripts/completion.coffee49
-rw-r--r--background_scripts/completion_engines.coffee30
2 files changed, 57 insertions, 22 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee
index c529f376..4f0401f0 100644
--- a/background_scripts/completion.coffee
+++ b/background_scripts/completion.coffee
@@ -406,6 +406,18 @@ class SearchEngineCompleter
query = queryTerms.join " "
haveCompletionEngine = CompletionEngines.haveCompletionEngine searchUrl
+ # Relevancy:
+ # - Relevancy does not depend upon the actual suggestion (so, it does not depend upon word
+ # relevancy). We assume that the completion engine has already factored that in. Also, completion
+ # engines often handle spelling mistakes, in which case we wouldn't find the query terms in the
+ # suggestion anyway.
+ # - The relavancy is higher if the query term is longer. The idea is that search suggestions are more
+ # likely to be relevant if, after typing some number of characters, the user hasn't yet found
+ # a useful suggestion from another completer.
+ # - Scores are weighted such that they retain the order provided by the completion engine.
+ characterCount = query.length - queryTerms.length + 1
+ relavancy = 0.6 * (Math.min(characterCount, 10.0)/10.0)
+
# This distinguishes two very different kinds of vomnibar baviours, the newer bahviour (true) and the
# legacy behavior (false). We retain the latter for the default search engine, and for custom search
# engines for which we do not have a completion engine.
@@ -440,8 +452,30 @@ class SearchEngineCompleter
# Do not use this entry for vomnibar completion.
highlightCommonMatches: false
- # Post suggestions and bail if there is no prospect of adding further suggestions.
- if queryTerms.length == 0 or not haveCompletionEngine
+ mkSuggestion = do ->
+ (suggestion) ->
+ new Suggestion
+ queryTerms: queryTerms
+ type: description
+ url: Utils.createSearchUrl suggestion, searchUrl
+ title: suggestion
+ relevancy: relavancy *= 0.9
+ highlightTerms: false
+ insertText: suggestion
+ # Do use this entry for vomnibar completion.
+ highlightCommonMatches: true
+
+ # If we have cached suggestions, then we can bundle them immediately (otherwise we'll have to do an HTTP
+ # request, which we do asynchronously). This is a synchronous call (for cached suggestions only)
+ # because no callback is provided.
+ cachedSuggestions = CompletionEngines.complete searchUrl, queryTerms
+
+ # Post suggestions and bail if we already have all of the suggestions, or if there is no prospect of
+ # adding further suggestions.
+ if queryTerms.length == 0 or cachedSuggestions? or not haveCompletionEngine
+ if cachedSuggestions?
+ console.log "using cached suggestions"
+ suggestions.push cachedSuggestions.map(mkSuggestion)...
return onComplete suggestions, { filter }
# Post any initial suggestion, and then deliver suggestions from completion engines as a continuation
@@ -450,17 +484,6 @@ class SearchEngineCompleter
filter: filter
continuation: (existingSuggestions, onComplete) =>
suggestions = []
- # Relevancy:
- # - Relevancy does not depend upon the actual suggestion (so, it does not depend upon word
- # relevancy). We assume that the completion engine has already factored that in. Also, completion
- # engines often handle spelling mistakes, in which case we wouldn't find the query terms in the
- # suggestion anyway.
- # - The relavancy is higher if the query term is longer. The idea is that search suggestions are more
- # likely to be relevant if, after typing some number of characters, the user hasn't yet found
- # a useful suggestion from another completer.
- # - Scores are weighted such that they retain the order provided by the completion engine.
- characterCount = query.length - queryTerms.length + 1
- relavancy = 0.6 * (Math.min(characterCount, 10.0)/10.0)
if 0 < existingSuggestions.length
existingSuggestionsMinScore = existingSuggestions[existingSuggestions.length-1].relevancy
diff --git a/background_scripts/completion_engines.coffee b/background_scripts/completion_engines.coffee
index 425ff47e..51799971 100644
--- a/background_scripts/completion_engines.coffee
+++ b/background_scripts/completion_engines.coffee
@@ -161,10 +161,16 @@ CompletionEngines =
# - queryTerms are the query terms.
# - callback will be applied to a list of suggestion strings (which may be an empty list, if anything goes
# wrong).
- complete: (searchUrl, queryTerms, callback) ->
+ complete: (searchUrl, queryTerms, callback = null) ->
@mostRecentHandler = null
query = queryTerms.join ""
+ # If no callback is provided, then we're to provide suggestions only if we can do so synchronously (ie.
+ # from a cache). In this case we return the results and don't call callback. Return null if we cannot
+ # service the request synchronously.
+ returnResultsOnlyFromCache = not callback?
+ callback ?= (suggestions) -> suggestions
+
# We don't complete single characters: the results are usually useless.
return callback [] unless 1 < query.length
@@ -179,16 +185,20 @@ CompletionEngines =
completionCacheKey = searchUrl + junk + queryTerms.map((s) -> s.toLowerCase()).join junk
@completionCache ?= new SimpleCache 60 * 60 * 1000, 2000 # One hour, 2000 entries.
if @completionCache.has completionCacheKey
- # We add a short delay, even for a cache hit. This avoids an ugly flicker when the additional
- # suggestions are posted.
- Utils.setTimeout 75, =>
- console.log "hit", completionCacheKey if @debug
- callback @completionCache.get completionCacheKey
- return
+ if returnResultsOnlyFromCache
+ return @completionCache.get completionCacheKey
+ else
+ # We add a short delay, even for a cache hit. This avoids an ugly flicker when the additional
+ # suggestions are posted.
+ Utils.setTimeout 75, =>
+ console.log "hit", completionCacheKey if @debug
+ callback @completionCache.get completionCacheKey
+ return
if @mostRecentQuery? and @mostRecentSuggestions?
- # If the user appears to be typing a continuation of the characters in all of the most recent query,
- # then we can re-use the results of the previous query.
+ # If the user appears to be typing a continuation of the characters of the most recent query, and those
+ # characters are also common to all of the most recent suggestions, then we can re-use the previous
+ # suggestions.
reusePreviousSuggestions = do (query) =>
query = queryTerms.join(" ").toLowerCase()
return false unless 0 == query.indexOf @mostRecentQuery.toLowerCase()
@@ -201,6 +211,8 @@ CompletionEngines =
@mostRecentQuery = queryTerms.join " "
return callback @completionCache.set completionCacheKey, @mostRecentSuggestions
+ return null if returnResultsOnlyFromCache
+
fetchSuggestions = (engine, callback) =>
url = engine.getUrl queryTerms
query = queryTerms.join(" ").toLowerCase()