aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2015-05-08 17:28:09 +0100
committerStephen Blott2015-05-08 17:28:09 +0100
commit21db0f353257e5e7848d9d884ed93e717120e88d (patch)
tree93232c0b97710cf19fe3938fe1d9bc2f73c296d2
parent82d25b5df76c8526d4ccb5352c0905cc28371199 (diff)
downloadvimium-21db0f353257e5e7848d9d884ed93e717120e88d.tar.bz2
Search completion; search keyword on SPACE.
-rw-r--r--background_scripts/completion.coffee20
-rw-r--r--background_scripts/main.coffee14
-rw-r--r--pages/vomnibar.coffee74
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"