diff options
| author | Stephen Blott | 2015-05-08 17:28:09 +0100 |
|---|---|---|
| committer | Stephen Blott | 2015-05-08 17:28:09 +0100 |
| commit | 21db0f353257e5e7848d9d884ed93e717120e88d (patch) | |
| tree | 93232c0b97710cf19fe3938fe1d9bc2f73c296d2 | |
| parent | 82d25b5df76c8526d4ccb5352c0905cc28371199 (diff) | |
| download | vimium-21db0f353257e5e7848d9d884ed93e717120e88d.tar.bz2 | |
Search completion; search keyword on SPACE.
| -rw-r--r-- | background_scripts/completion.coffee | 20 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 14 | ||||
| -rw-r--r-- | pages/vomnibar.coffee | 74 |
3 files changed, 57 insertions, 51 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index ba19970f..dc5b2737 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -359,6 +359,13 @@ class SearchEngineCompleter cancel: -> CompletionEngines.cancel() + refresh: (port) -> + @searchEngines = SearchEngineCompleter.getSearchEngines() + # Let the vomnibar know the custom search engine keywords. + port.postMessage + handler: "customSearchEngineKeywords" + keywords: key for own key of @searchEngines + filter: (queryTerms, onComplete) -> suggestions = [] @@ -385,7 +392,7 @@ class SearchEngineCompleter # Always reset the selection to this suggestion on query change. The UX is weird otherwise. forceAutoSelect: true # Suppress the "w" from "w query terms" in the vomnibar input. - suppressLeadingQueryTerm: true + suppressLeadingKeyword: true # We filter out the empty strings late so that we can distinguish between, for example, "w" and "w ". queryTerms = queryTerms.filter (t) -> 0 < t.length @@ -436,9 +443,6 @@ class SearchEngineCompleter count = Math.min 6, Math.max 3, MultiCompleter.maxResults - existingSuggestions.length onComplete suggestions[...count] - refresh: -> - @searchEngines = SearchEngineCompleter.getSearchEngines() - getSearchEngineMatches: (queryTerms) -> (1 < queryTerms.length and @searchEngines[queryTerms[0]]) or {} @@ -473,11 +477,11 @@ class MultiCompleter constructor: (@completers) -> @maxResults = MultiCompleter.maxResults - refresh: -> - completer.refresh?() for completer in @completers + refresh: (port) -> + completer.refresh? port for completer in @completers - cancel: -> - completer.cancel?() for completer in @completers + cancel: (port) -> + completer.cancel? port for completer in @completers filter: do -> defaultCallbackOptions = diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 1a3281bf..34db5a20 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -60,15 +60,15 @@ completers = tabs: new MultiCompleter [completionSources.tabs] completionHandlers = - filter: (completer, args, port) -> - completer.filter args.queryTerms, (response) -> - port.postMessage extend args, response + filter: (completer, request, port) -> + completer.filter request.queryTerms, (response) -> + port.postMessage extend request, extend response, handler: "completions" - refresh: (completer) -> completer.refresh() - cancel: (completer) -> completer.cancel() + refresh: (completer, _, port) -> completer.refresh port + cancel: (completer, _, port) -> completer.cancel port -handleCompletions = (args, port) -> - completionHandlers[args.handler] completers[args.name], args, port +handleCompletions = (request, port) -> + completionHandlers[request.handler] completers[request.name], request, port chrome.runtime.onConnect.addListener (port, name) -> senderTabId = if port.sender.tab then port.sender.tab.id else null diff --git a/pages/vomnibar.coffee b/pages/vomnibar.coffee index b228a59b..3039075c 100644 --- a/pages/vomnibar.coffee +++ b/pages/vomnibar.coffee @@ -22,7 +22,7 @@ Vomnibar = completer = @getCompleter options.completer @vomnibarUI ?= new VomnibarUI() - completer.refresh() + completer.refresh @vomnibarUI @vomnibarUI.setInitialSelectionValue if options.selectFirst then 0 else -1 @vomnibarUI.setCompleter completer @vomnibarUI.setRefreshInterval options.refreshInterval @@ -44,6 +44,7 @@ class VomnibarUI setRefreshInterval: (@refreshInterval) -> setForceNewTab: (@forceNewTab) -> setCompleter: (@completer) -> @reset() + setKeywords: (@keywords) -> # The sequence of events when the vomnibar is hidden is as follows: # 1. Post a "hide" message to the host page. @@ -67,8 +68,9 @@ class VomnibarUI @completions = [] @previousAutoSelect = null @previousInputValue = null - @suppressedLeadingQueryTerm = null + @suppressedLeadingKeyword = null @selection = @initialSelectionValue + @keywords = [] updateSelection: -> # We retain global state here (previousAutoSelect) to tell if a search item (for which autoSelect is set) @@ -82,12 +84,9 @@ class VomnibarUI # For custom search engines, we suppress the leading term (e.g. the "w" of "w query terms") within the # vomnibar input. - if @suppressedLeadingQueryTerm? - @restoreSuppressedQueryTerm() - else if @completions[0]?.suppressLeadingQueryTerm - # We've been asked to suppress the leading query term, and it's not already suppressed. So suppress it. + if @completions[0]?.suppressLeadingKeyword and not @suppressedLeadingKeyword? queryTerms = @input.value.trim().split /\s+/ - @suppressedLeadingQueryTerm = queryTerms[0] + @suppressedLeadingKeyword = queryTerms[0] @input.value = queryTerms[1..].join " " # For suggestions from search-engine completion, we copy the suggested text into the input when selected, @@ -103,13 +102,6 @@ class VomnibarUI for i in [0...@completionList.children.length] @completionList.children[i].className = (if i == @selection then "vomnibarSelected" else "") - restoreSuppressedQueryTerm: -> - if @suppressedLeadingQueryTerm? - # If we have a suppressed term and the input is empty, then reinstate it. - if @input.value.length == 0 - @input.value = @suppressedLeadingQueryTerm - @suppressedLeadingQueryTerm = null - # # Returns the user's action ("up", "down", "enter", "dismiss", "delete" or null) based on their keypress. # We support the arrow keys and other shortcuts for moving, so this method hides that complexity. @@ -164,8 +156,9 @@ class VomnibarUI completion = @completions[@selection] @hide -> completion.performAction openInNewTab else if action == "delete" - if @input.value.length == 0 - @restoreSuppressedQueryTerm() + if @suppressedLeadingKeyword? and @input.value.length == 0 + @input.value = @suppressedLeadingKeyword + @suppressedLeadingKeyword = null @updateCompletions() else # Don't suppress the Delete. We want it to happen. @@ -177,7 +170,7 @@ class VomnibarUI true getInputValue: -> - (if @suppressedLeadingQueryTerm? then @suppressedLeadingQueryTerm + " " else "") + @input.value + (if @suppressedLeadingKeyword? then @suppressedLeadingKeyword + " " else "") + @input.value updateCompletions: (callback = null) -> @clearUpdateTimer() @@ -208,6 +201,11 @@ class VomnibarUI @updateTimer = null update: (updateSynchronously = false, callback = null) => + # If the query text is a custom search keyword, then we need to force a synchronous update (so that the + # interface is snappy). + if @keywords? and not @suppressedLeadingKeyword? + queryTerms = @input.value.ltrim().split /\s+/ + updateSynchronously ||= 1 < queryTerms.length and queryTerms[0] in @keywords if updateSynchronously @updateCompletions callback else if not @updateTimer? @@ -248,26 +246,30 @@ class BackgroundCompleter @reset() @port.onMessage.addListener (msg) => - # The result objects coming from the background page will be of the form: - # { html: "", type: "", url: "" } - # Type will be one of [tab, bookmark, history, domain, search], or a custom search engine description. - for result in msg.results - result.performAction = - if result.type == "tab" - @completionActions.switchToTab.curry result.tabId + switch msg.handler + when "customSearchEngineKeywords" + @lastUI.setKeywords msg.keywords + when "completions" + # The result objects coming from the background page will be of the form: + # { html: "", type: "", url: "" } + # Type will be one of [tab, bookmark, history, domain, search], or a custom search engine description. + for result in msg.results + result.performAction = + if result.type == "tab" + @completionActions.switchToTab.curry result.tabId + else + @completionActions.navigateToUrl.curry result.url + + # Cache the results (but only if the background completer tells us that it's ok to do so). + if msg.callerMayCacheResults + console.log "cache set:", msg.query if @debug + @cache.set msg.query, msg.results else - @completionActions.navigateToUrl.curry result.url - - # Cache the results (but only if the background completer tells us that it's ok to do so). - if msg.callerMayCacheResults - console.log "cache set:", msg.query if @debug - @cache.set msg.query, msg.results - else - console.log "not setting cache:", msg.query if @debug + console.log "not setting cache:", msg.query if @debug - # We ignore messages which arrive too late. - if msg.id == @messageId - @mostRecentCallback msg.results + # We ignore messages which arrive too late. + if msg.id == @messageId + @mostRecentCallback msg.results filter: (query, @mostRecentCallback) -> # We retain trailing whitespace so that we can tell the difference between "w" and "w " (for custom search @@ -286,7 +288,7 @@ class BackgroundCompleter query: query queryTerms: queryTerms - refresh: -> + refresh: (@lastUI) -> @reset() # Inform the background completer that we have a new vomnibar activation. @port.postMessage name: @name, handler: "refresh" |
