diff options
| author | Phil Crosby | 2014-06-14 05:05:16 -0700 |
|---|---|---|
| committer | Phil Crosby | 2014-06-14 05:05:16 -0700 |
| commit | d674b10c38e1d9d6cf230391a23107ef53b82282 (patch) | |
| tree | 47c50bf7f2467e5a6b3b0564e5eec7a62129c108 | |
| parent | f42690b1578de0b874048579354a17c251f567dd (diff) | |
| parent | a18ad484f2fdc0019c15d94405c915f8bfe6d76f (diff) | |
| download | vimium-d674b10c38e1d9d6cf230391a23107ef53b82282.tar.bz2 | |
Merge pull request #1058 from mijoharas/custom_search_engines
Custom search engines
| -rw-r--r-- | background_scripts/completion.coffee | 22 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 2 | ||||
| -rw-r--r-- | background_scripts/settings.coffee | 21 | ||||
| -rw-r--r-- | pages/options.coffee | 4 | ||||
| -rw-r--r-- | pages/options.html | 27 | ||||
| -rw-r--r-- | tests/unit_tests/completion_test.coffee | 14 | ||||
| -rw-r--r-- | tests/unit_tests/settings_test.coffee | 9 |
7 files changed, 96 insertions, 3 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 07f97322..b0ab4b88 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -267,6 +267,27 @@ class TabCompleter computeRelevancy: (suggestion) -> RankingUtils.wordRelevancy(suggestion.queryTerms, suggestion.url, suggestion.title) +# A completer which will return your search engines +class SearchEngineCompleter + searchEngines: {} + + filter: (queryTerms, onComplete) -> + searchEngineMatch = this.getSearchEngineMatches(queryTerms[0]) + suggestions = [] + if searchEngineMatch + searchEngineMatch = searchEngineMatch.replace(/%s/g, queryTerms[1..].join(" ")) + suggestion = new Suggestion(queryTerms, "search", searchEngineMatch, queryTerms[0] + ": " + queryTerms[1..].join(" "), @computeRelevancy) + suggestions.push(suggestion) + onComplete(suggestions) + + computeRelevancy: -> 1 + + refresh: -> + this.searchEngines = root.Settings.getSearchEngines() + + getSearchEngineMatches: (queryTerm) -> + this.searchEngines[queryTerm] + # A completer which calls filter() on many completers, aggregates the results, ranks them, and returns the top # 10. Queries from the vomnibar frontend script come through a multi completer. class MultiCompleter @@ -513,6 +534,7 @@ root.MultiCompleter = MultiCompleter root.HistoryCompleter = HistoryCompleter root.DomainCompleter = DomainCompleter root.TabCompleter = TabCompleter +root.SearchEngineCompleter = SearchEngineCompleter root.HistoryCache = HistoryCache root.RankingUtils = RankingUtils root.RegexpCache = RegexpCache diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 0511303a..3b7670d4 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -24,9 +24,11 @@ completionSources = history: new HistoryCompleter() domains: new DomainCompleter() tabs: new TabCompleter() + seachEngines: new SearchEngineCompleter() completers = omni: new MultiCompleter([ + completionSources.seachEngines, completionSources.bookmarks, completionSources.history, completionSources.domains]) diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index c26da5a4..175f3262 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -32,10 +32,28 @@ root.Settings = Settings = root.Commands.parseCustomKeyMappings value root.refreshCompletionKeysAfterMappingSave() + searchEngines: (value) -> + root.Settings.parseSearchEngines value + # postUpdateHooks convenience wrapper performPostUpdateHook: (key, value) -> @postUpdateHooks[key] value if @postUpdateHooks[key] + # Here we have our functions that parse the search engines + # this is a map that we use to store our search engines for use. + searchEnginesMap: {} + + # this parses the search engines settings and clears the old searchEngines and sets the new one + parseSearchEngines: (searchEnginesText) -> + @searchEnginesMap = {} + # find the split pairs by first splitting by line then splitting on the first `: ` + split_pairs = ( pair.split( /: (.+)/, 2) for pair in searchEnginesText.split( /\n/ ) when pair[0] != "#" ) + @searchEnginesMap[a[0]] = a[1] for a in split_pairs + @searchEnginesMap + getSearchEngines: -> + this.parseSearchEngines(@get("searchEngines") || "") if Object.keys(@searchEnginesMap).length == 0 + @searchEnginesMap + # options.coffee and options.html only handle booleans and strings; therefore all defaults must be booleans # or strings defaults: @@ -78,9 +96,12 @@ root.Settings = Settings = nextPatterns: "next,more,>,\u2192,\xbb,\u226b,>>" # default/fall back search engine searchUrl: "http://www.google.com/search?q=" + # put in an example search engine + searchEngines: "w: http://www.wikipedia.org/w/index.php?title=Special:Search&search=%s" settingsVersion: Utils.getCurrentVersion() + # We use settingsVersion to coordinate any necessary schema changes. if Utils.compareVersions("1.42", Settings.get("settingsVersion")) != -1 Settings.set("scrollStepSize", parseFloat Settings.get("scrollStepSize")) diff --git a/pages/options.coffee b/pages/options.coffee index 34696f68..d73d8f15 100644 --- a/pages/options.coffee +++ b/pages/options.coffee @@ -4,9 +4,9 @@ bgSettings = chrome.extension.getBackgroundPage().Settings editableFields = [ "scrollStepSize", "excludedUrls", "linkHintCharacters", "linkHintNumbers", "userDefinedLinkHintCss", "keyMappings", "filterLinkHints", "previousPatterns", - "nextPatterns", "hideHud", "regexFindMode", "searchUrl"] + "nextPatterns", "hideHud", "regexFindMode", "searchUrl", "searchEngines"] -canBeEmptyFields = ["excludedUrls", "keyMappings", "userDefinedLinkHintCss"] +canBeEmptyFields = ["excludedUrls", "keyMappings", "userDefinedLinkHintCss", "searchEngines"] document.addEventListener "DOMContentLoaded", -> populateOptions() diff --git a/pages/options.html b/pages/options.html index 8c7c007a..5450a774 100644 --- a/pages/options.html +++ b/pages/options.html @@ -122,6 +122,10 @@ width: 100%; min-height: 135px; } + textarea#searchEngines { + width: 100%; + min-height: 135px; + } input#previousPatterns, input#nextPatterns { width: 100%; } @@ -330,12 +334,33 @@ unmapAll <td verticalAlign="top"> <div class="help"> <div class="example"> - Set which search engine is used when searching from the Vomnibar (examples: "http://duckduckgo.com/?q=", "http://www.google.com/search?q="). + Set which search engine is used when searching from the Vomnibar (examples: "http://duckduckgo.com/?q="). </div> </div> <input id="searchUrl" type="text" /> </td> </tr> + <tr> + <td class="caption">Search Engines</td> + <td verticalAlign="top"> + <div class="help"> + <div class="example"> + Allow customised search engines the format is `token: http://address.com/q?=%s` + <br/> + token must not contain a colon. + <br/> + comments are allowed and start with '#' + <br/> + all `%s` will be replaced with the query string + <br/> + for a list of default and extra search engines please see <a href="https://gist.github.com/mhauserr/1918ecd63393a9cb23c4">here</a> + <br/> + to subsequently search for something just type token follewed by your search terms + </div> + </div> + <textarea id="searchEngines"></textarea> + </td> + </tr> </tbody> </table> diff --git a/tests/unit_tests/completion_test.coffee b/tests/unit_tests/completion_test.coffee index 165bad46..02a741d5 100644 --- a/tests/unit_tests/completion_test.coffee +++ b/tests/unit_tests/completion_test.coffee @@ -229,6 +229,20 @@ context "tab completer", assert.arrayEqual ["tab2.com"], results.map (tab) -> tab.url assert.arrayEqual [2], results.map (tab) -> tab.tabId +context "search engines", + setup -> + searchEngines = "foo: bar?q=%s\n# comment\nbaz: qux?q=%s" + Settings.set 'searchEngines', searchEngines + @completer = new SearchEngineCompleter() + # note, I couldn't just call @completer.refresh() here as I couldn't set root.Settings without errors + # workaround is below, would be good for someone that understands the testing system better than me to improve + @completer.searchEngines = Settings.getSearchEngines() + + should "return search engine suggestion", -> + results = filterCompleter(@completer, ["foo", "hello"]) + assert.arrayEqual ["bar?q=hello"], results.map (result) -> result.url + assert.arrayEqual ["foo: hello"], results.map (result) -> result.title + context "suggestions", should "escape html in page titles", -> suggestion = new Suggestion(["queryterm"], "tab", "url", "title <span>", returns(1)) diff --git a/tests/unit_tests/settings_test.coffee b/tests/unit_tests/settings_test.coffee index 25bb3628..1283497c 100644 --- a/tests/unit_tests/settings_test.coffee +++ b/tests/unit_tests/settings_test.coffee @@ -70,5 +70,14 @@ context "settings", chrome.storage.sync.set { scrollStepSize: JSON.stringify(message) } assert.equal message, Sync.message + should "set search engines, retrieve them correctly and check that it has been parsed correctly", -> + searchEngines = "foo: bar?q=%s\n# comment\nbaz: qux?q=%s" + parsedSearchEngines = {"foo": "bar?q=%s", "baz": "qux?q=%s"} + Settings.set 'searchEngines', searchEngines + assert.equal(searchEngines, Settings.get('searchEngines')) + result = Settings.getSearchEngines() + assert.isTrue(parsedSearchEngines["foo"] == result["foo"] && + parsedSearchEngines["baz"] == result["baz"] && Object.keys(result).length == 2) + should "sync a key which is not a known setting (without crashing)", -> chrome.storage.sync.set { notASetting: JSON.stringify("notAUsefullValue") } |
