diff options
| author | Stephen Blott | 2015-05-06 07:40:46 +0100 | 
|---|---|---|
| committer | Stephen Blott | 2015-05-06 09:29:15 +0100 | 
| commit | 5752c0ead0a65fc2329515509f66e00bd6ee2f60 (patch) | |
| tree | 0cc13d0e924c0daf69312036f2dc1fe28aa84494 | |
| parent | 372e65d7b44c3f0ad3f522bd6b8c9cfacd693186 (diff) | |
| download | vimium-5752c0ead0a65fc2329515509f66e00bd6ee2f60.tar.bz2 | |
Search completion; more tweaks.
| -rw-r--r-- | background_scripts/completion.coffee | 37 | ||||
| -rw-r--r-- | background_scripts/completion_engines.coffee | 26 | ||||
| -rw-r--r-- | lib/utils.coffee | 11 | 
3 files changed, 42 insertions, 32 deletions
| diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 4ae0c44b..bffb9700 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -363,23 +363,22 @@ class SearchEngineCompleter      haveDescription = description? and 0 < description.length      description ||= "#{if custom then "custom " else ""}search" +    queryTerms = queryTerms[1..] if custom +    query = queryTerms.join " " + +    if queryTerms.length == 0 +      return onComplete suggestions +      # For custom search engines, we add an auto-selected suggestion.      if custom -      queryTerms = queryTerms[1..] -      query = queryTerms.join " "        suggestions.push new Suggestion          queryTerms: queryTerms          type: description -        url: searchUrl.replace /%s/g, Utils.createSearchQuery query.split /\s+/ -        title: if haveDescription then query else "#{keyword}:  #{query}" +        url: Utils.createSearchUrl queryTerms, searchUrl +        title: if haveDescription then query else "#{keyword}: #{query}"          relevancy: 1 -        autoSelect: true          highlightTerms: false -    else -      query = queryTerms.join " " - -    if queryTerms.length == 0 -      return onComplete suggestions +        autoSelect: true      onComplete suggestions, (existingSuggestions, onComplete) =>        suggestions = [] @@ -399,23 +398,22 @@ class SearchEngineCompleter        relavancy = 0.6 * (Math.min(characterCount, 10.0)/10.0)        if 0 < existingSuggestions.length -        existingSuggestionMinScore = existingSuggestions[existingSuggestions.length-1].relevancy -        if relavancy < existingSuggestionMinScore and MultiCompleter.maxResults <= existingSuggestions.length +        existingSuggestionsMinScore = existingSuggestions[existingSuggestions.length-1].relevancy +        if relavancy < existingSuggestionsMinScore and MultiCompleter.maxResults <= existingSuggestions.length            # No suggestion we propose will have a high enough relavancy to beat the existing suggestions, so bail            # immediately.            return onComplete [] -      CompletionEngines.complete searchUrl, queryTerms, (searchSuggestions = []) => -        for suggestion in searchSuggestions +      CompletionEngines.complete searchUrl, queryTerms, (completionSuggestions = []) => +        for suggestion in completionSuggestions            suggestions.push new Suggestion              queryTerms: queryTerms              type: description -            url: searchUrl.replace /%s/g, Utils.createSearchQuery suggestion.split /\s+/ +            url: Utils.createSearchUrl suggestion, searchUrl              title: suggestion -            relevancy: relavancy -            insertText: if custom then "#{keyword} #{suggestion}" else suggestion +            relevancy: relavancy *= 0.9              highlightTerms: false -          relavancy *= 0.9 +            insertText: if custom then "#{keyword} #{suggestion}" else suggestion          # We keep at least three suggestions (if possible) and at most six.  We keep more than three only if          # there are enough slots.  The idea is that these suggestions shouldn't wholly displace suggestions @@ -501,7 +499,8 @@ class MultiCompleter                @filterInProgress = false                if shouldRunContinuation                  continuation suggestions, (newSuggestions) => -                  onComplete @prepareSuggestions queryTerms, suggestions.concat newSuggestions +                  if 0 < newSuggestions.length +                    onComplete @prepareSuggestions queryTerms, suggestions.concat newSuggestions                else                  @filter @mostRecentQuery.queryTerms, @mostRecentQuery.onComplete if @mostRecentQuery diff --git a/background_scripts/completion_engines.coffee b/background_scripts/completion_engines.coffee index 0177806a..1386256f 100644 --- a/background_scripts/completion_engines.coffee +++ b/background_scripts/completion_engines.coffee @@ -116,6 +116,9 @@ completionEngines = [  CompletionEngines =    debug: true +  # The amount of time to wait for new completions before launching the HTTP request. +  delay: 250 +    get: (searchUrl, url, callback) ->      xhr = new XMLHttpRequest()      xhr.open "GET", url, true @@ -139,7 +142,7 @@ CompletionEngines =          engine = new engine()          return @engineCache.set searchUrl, engine if engine.match searchUrl -  # This is the main (actually, the only) entry point. +  # This is the main entry point.    #  - searchUrl is the search engine's URL, e.g. Settings.get("searchUrl"), or a custome search engine's URL.    #    This is only used as a key for determining the relevant completion engine.    #  - queryTerms are the queryTerms. @@ -169,34 +172,41 @@ CompletionEngines =      completionCacheKey = searchUrl + junk + queryTerms.join junk      @completionCache ?= new SimpleCache 60 * 60 * 1000, 2000 # One hour, 2000 entries.      if @completionCache.has completionCacheKey -      console.log "hit", completionCacheKey if @debug -      return callback @completionCache.get completionCacheKey +      # We add a short delay, even for a cache hit.  This avoids an ugly flicker when the additional +      # suggestions are posted.  It also makes the vomnibar behave similarly regardless of whether there's a +      # cache hit. +      Utils.setTimeout @delay, => +        console.log "hit", completionCacheKey if @debug +        callback @completionCache.get completionCacheKey +      return      fetchSuggestions = (callback) =>        engine = @lookupEngine searchUrl        url = engine.getUrl queryTerms -      console.log "get", url if @debug        query = queryTerms.join(" ").toLowerCase()        @get searchUrl, url, (xhr = null) =>          # Parsing the response may fail if we receive an unexpected or an unexpectedly-formatted response.  In -        # all cases, we fall back to the catch clause, below. +        # all cases, we fall back to the catch clause, below.  Therefore, we "fail safe" in the case of +        # incorrect or out-of-date completion engines.          try            suggestions = engine.parse xhr            # Make sure we really do have an iterable of strings.            suggestions = (suggestion for suggestion in suggestions when "string" == typeof suggestion)            # Filter out the query itself. It's not adding anything.            suggestions = (suggestion for suggestion in suggestions when suggestion.toLowerCase() != query) +          console.log "GET", url if @debug          catch            suggestions = [] -          # We cache failures, but remove them after just ten minutes.  This (it is hoped) avoids repeated -          # XMLHttpRequest failures over a short period of time. +          # We allow failures to be cached, but remove them after just ten minutes.  This (it is hoped) avoids +          # repeated unnecessary XMLHttpRequest failures over a short period of time.            removeCompletionCacheKey = => @completionCache.set completionCacheKey, null            setTimeout removeCompletionCacheKey, 10 * 60 * 1000 # Ten minutes. +          console.log "fail", url if @debug          callback suggestions      # We pause in case the user is still typing. -    Utils.setTimeout 200, handler = @mostRecentHandler = => +    Utils.setTimeout @delay, handler = @mostRecentHandler = =>        if handler != @mostRecentHandler # Bail if another completion has begun, or the user is typing.          console.log "bail", completionCacheKey if @debug          return callback [] diff --git a/lib/utils.coffee b/lib/utils.coffee index e97872f0..354d82f6 100644 --- a/lib/utils.coffee +++ b/lib/utils.coffee @@ -96,11 +96,12 @@ Utils =      query = query.split(/\s+/) if typeof(query) == "string"      query.map(encodeURIComponent).join "+" -  # Creates a search URL from the given :query. -  createSearchUrl: (query) -> -    # It would be better to pull the default search engine from chrome itself.  However, unfortunately chrome -    # does not provide an API for doing so. -    Settings.get("searchUrl") + @createSearchQuery query +  # Create a search URL from the given :query (using either the provided search URL, or the default one). +  # It would be better to pull the default search engine from chrome itself.  However, chrome does not provide +  # an API for doing so. +  createSearchUrl: (query, searchUrl = Settings.get("searchUrl")) -> +    searchUrl += "%s" unless 0 <= searchUrl.indexOf "%s" +    searchUrl.replace /%s/g, @createSearchQuery query    # Converts :string into a Google search if it's not already a URL. We don't bother with escaping characters    # as Chrome will do that for us. | 
