diff options
Diffstat (limited to 'background_scripts')
| -rw-r--r-- | background_scripts/commands.coffee | 6 | ||||
| -rw-r--r-- | background_scripts/completion_engines.coffee | 60 | ||||
| -rw-r--r-- | background_scripts/exclusions.coffee | 4 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 2 | ||||
| -rw-r--r-- | background_scripts/settings.coffee | 126 | ||||
| -rw-r--r-- | background_scripts/sync.coffee | 74 |
6 files changed, 42 insertions, 230 deletions
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index fa5354df..bf892c1a 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -343,5 +343,11 @@ commandDescriptions = Commands.init() +# Register postUpdateHook for keyMappings setting. +Settings.postUpdateHooks["keyMappings"] = (value) -> + Commands.clearKeyMappingsAndSetDefaults() + Commands.parseCustomKeyMappings value + refreshCompletionKeysAfterMappingSave() + root = exports ? window root.Commands = Commands diff --git a/background_scripts/completion_engines.coffee b/background_scripts/completion_engines.coffee index 189f66f3..f15e6db4 100644 --- a/background_scripts/completion_engines.coffee +++ b/background_scripts/completion_engines.coffee @@ -21,12 +21,11 @@ # A base class for common regexp-based matching engines. class RegexpEngine - constructor: (@regexps) -> + constructor: (args...) -> @regexps = args.map (regexp) -> new RegExp regexp match: (searchUrl) -> Utils.matchesAnyRegexp @regexps, searchUrl # Several Google completion engines package XML responses in this way. class GoogleXMLRegexpEngine extends RegexpEngine - doNotCache: false # true (disbaled, experimental) parse: (xhr) -> for suggestion in xhr.responseXML.getElementsByTagName "suggestion" continue unless suggestion = suggestion.getAttribute "data" @@ -34,31 +33,47 @@ class GoogleXMLRegexpEngine extends RegexpEngine class Google extends GoogleXMLRegexpEngine # Example search URL: http://www.google.com/search?q=%s - constructor: -> - super [ - # We match the major English-speaking TLDs. - new RegExp "^https?://[a-z]+\.google\.(com|ie|co\.uk|ca|com\.au)/" - new RegExp "localhost/cgi-bin/booky" # Only for smblott. - ] + constructor: (regexps = null) -> + super regexps ? "^https?://[a-z]+\.google\.(com|ie|co\.uk|ca|com\.au)/" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "http://suggestqueries.google.com/complete/search?ss_protocol=legace&client=toolbar&q=%s" +# A wrapper class for Google completions. This adds prefix terms to the query, and strips those terms from +# the resulting suggestions. For example, for Google Maps, we add "map of" as a prefix, then strip "map of" +# from the resulting suggestions. +class GoogleWithPrefix + constructor: (prefix, args...) -> + @engine = new Google args... + @prefix = "#{prefix.trim()} " + @queryTerms = @prefix.split /\s+/ + match: (args...) -> @engine.match args... + getUrl: (queryTerms) -> @engine.getUrl [ @queryTerms..., queryTerms... ] + parse: (xhr) -> + @engine.parse(xhr) + .filter (suggestion) => suggestion.startsWith @prefix + .map (suggestion) => suggestion[@prefix.length..].ltrim() + +# For Google Maps, we add the prefix "map of" to the query, and send it to Google's general search engine, +# then strip "map of" from the resulting suggestions. +class GoogleMaps extends GoogleWithPrefix + # Example search URL: https://www.google.com/maps?q=%s + constructor: -> super "map of", "https?://[a-z]+\.google\.(com|ie|co\.uk|ca|com\.au)/maps" + class Youtube extends GoogleXMLRegexpEngine # Example search URL: http://www.youtube.com/results?search_query=%s constructor: -> - super [ new RegExp "^https?://[a-z]+\.youtube\.com/results" ] + super "^https?://[a-z]+\.youtube\.com/results" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "http://suggestqueries.google.com/complete/search?client=youtube&ds=yt&xml=t&q=%s" class Wikipedia extends RegexpEngine - doNotCache: false # true (disbaled, experimental) # Example search URL: http://www.wikipedia.org/w/index.php?title=Special:Search&search=%s constructor: -> - super [ new RegExp "^https?://[a-z]+\.wikipedia\.org/" ] + super "^https?://[a-z]+\.wikipedia\.org/" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, @@ -67,28 +82,15 @@ class Wikipedia extends RegexpEngine parse: (xhr) -> JSON.parse(xhr.responseText)[1] -## Does not work... -## class GoogleMaps extends RegexpEngine -## # Example search URL: https://www.google.com/maps/search/%s -## constructor: -> -## super [ new RegExp "^https?://www\.google\.com/maps/search/" ] -## -## getUrl: (queryTerms) -> -## "https://www.google.com/s?tbm=map&fp=1&gs_ri=maps&source=hp&suggest=p&authuser=0&hl=en&pf=p&tch=1&ech=2&q=#{Utils.createSearchQuery queryTerms}" -## -## parse: (xhr) -> -## data = JSON.parse xhr.responseText -## [] - class Bing extends RegexpEngine # Example search URL: https://www.bing.com/search?q=%s - constructor: -> super [ new RegExp "^https?://www\.bing\.com/search" ] + constructor: -> super "^https?://www\.bing\.com/search" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "http://api.bing.com/osjson.aspx?query=%s" parse: (xhr) -> JSON.parse(xhr.responseText)[1] class Amazon extends RegexpEngine # Example search URL: http://www.amazon.com/s/?field-keywords=%s - constructor: -> super [ new RegExp "^https?://www\.amazon\.(com|co.uk|ca|com.au)/s/" ] + constructor: -> super "^https?://www\.amazon\.(com|co.uk|ca|com.au)/s/" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "https://completion.amazon.com/search/complete?method=completion&search-alias=aps&client=amazon-search-ui&mkt=1&q=%s" @@ -96,15 +98,14 @@ class Amazon extends RegexpEngine class DuckDuckGo extends RegexpEngine # Example search URL: https://duckduckgo.com/?q=%s - constructor: -> super [ new RegExp "^https?://([a-z]+\.)?duckduckgo\.com/" ] - getUrl: (queryTerms) -> + constructor: -> super "^https?://([a-z]+\.)?duckduckgo\.com/" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "https://duckduckgo.com/ac/?q=%s" parse: (xhr) -> suggestion.phrase for suggestion in JSON.parse xhr.responseText class Webster extends RegexpEngine # Example search URL: http://www.merriam-webster.com/dictionary/%s - constructor: -> super [ new RegExp "^https?://www.merriam-webster.com/dictionary/" ] + constructor: -> super "^https?://www.merriam-webster.com/dictionary/" getUrl: (queryTerms) -> Utils.createSearchUrl queryTerms, "http://www.merriam-webster.com/autocomplete?query=%s" parse: (xhr) -> JSON.parse(xhr.responseText).suggestions @@ -120,6 +121,7 @@ class DummyCompletionEngine # Note: Order matters here. CompletionEngines = [ Youtube + GoogleMaps Google DuckDuckGo Wikipedia diff --git a/background_scripts/exclusions.coffee b/background_scripts/exclusions.coffee index 5ec76e2a..21342d61 100644 --- a/background_scripts/exclusions.coffee +++ b/background_scripts/exclusions.coffee @@ -73,3 +73,7 @@ if not Settings.has("exclusionRules") and Settings.has("excludedUrls") # We'll keep a backup of the "excludedUrls" setting, just in case. Settings.set("excludedUrlsBackup", Settings.get("excludedUrls")) if not Settings.has("excludedUrlsBackup") Settings.clear("excludedUrls") + +# Register postUpdateHook for exclusionRules setting. +Settings.postUpdateHooks["exclusionRules"] = (value) -> + Exclusions.postUpdateHook value diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index e7a1f82c..99a5672b 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -744,5 +744,5 @@ chrome.windows.getAll { populate: true }, (windows) -> chrome.tabs.sendMessage(tab.id, { name: "getScrollPosition" }, createScrollPositionHandler()) # Start pulling changes from synchronized storage. -Sync.init() +Settings.init() showUpgradeMessage() diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee deleted file mode 100644 index d23649ee..00000000 --- a/background_scripts/settings.coffee +++ /dev/null @@ -1,126 +0,0 @@ -# -# Used by all parts of Vimium to manipulate localStorage. -# - -root = exports ? window -root.Settings = Settings = - get: (key) -> - if (key of localStorage) then JSON.parse(localStorage[key]) else @defaults[key] - - set: (key, value) -> - # Don't store the value if it is equal to the default, so we can change the defaults in the future - if (value == @defaults[key]) - @clear(key) - else - jsonValue = JSON.stringify value - localStorage[key] = jsonValue - Sync.set key, jsonValue - - clear: (key) -> - if @has key - delete localStorage[key] - Sync.clear key - - has: (key) -> key of localStorage - - # For settings which require action when their value changes, add hooks here called from - # options/options.coffee (when the options page is saved), and from background_scripts/sync.coffee (when an - # update propagates from chrome.storage.sync). - postUpdateHooks: - keyMappings: (value) -> - root.Commands.clearKeyMappingsAndSetDefaults() - root.Commands.parseCustomKeyMappings value - root.refreshCompletionKeysAfterMappingSave() - - exclusionRules: (value) -> - root.Exclusions.postUpdateHook value - - # postUpdateHooks convenience wrapper - performPostUpdateHook: (key, value) -> - @postUpdateHooks[key] value if @postUpdateHooks[key] - - # options.coffee and options.html only handle booleans and strings; therefore all defaults must be booleans - # or strings - defaults: - scrollStepSize: 60 - smoothScroll: true - keyMappings: "# Insert your preferred key mappings here." - linkHintCharacters: "sadfjklewcmpgh" - linkHintNumbers: "0123456789" - filterLinkHints: false - hideHud: false - userDefinedLinkHintCss: - """ - div > .vimiumHintMarker { - /* linkhint boxes */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFF785), - color-stop(100%,#FFC542)); - border: 1px solid #E3BE23; - } - - div > .vimiumHintMarker span { - /* linkhint text */ - color: black; - font-weight: bold; - font-size: 12px; - } - - div > .vimiumHintMarker > .matchingCharacter { - } - """ - # Default exclusion rules. - exclusionRules: - [ - # Disable Vimium on Gmail. - { pattern: "http*://mail.google.com/*", passKeys: "" } - ] - - # NOTE: If a page contains both a single angle-bracket link and a double angle-bracket link, then in - # most cases the single bracket link will be "prev/next page" and the double bracket link will be - # "first/last page", so we put the single bracket first in the pattern string so that it gets searched - # for first. - - # "\bprev\b,\bprevious\b,\bback\b,<,←,«,≪,<<" - previousPatterns: "prev,previous,back,<,\u2190,\xab,\u226a,<<" - # "\bnext\b,\bmore\b,>,→,»,≫,>>" - nextPatterns: "next,more,>,\u2192,\xbb,\u226b,>>" - # default/fall back search engine - searchUrl: "https://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 Wikipedia" - "" - "# More examples." - "#" - "# (Vimium has built-in completion for these.)" - "#" - "# g: http://www.google.com/search?q=%s Google" - "# l: http://www.google.com/search?q=%s&btnI I'm feeling lucky..." - "# y: http://www.youtube.com/results?search_query=%s Youtube" - "# b: https://www.bing.com/search?q=%s Bing" - "# d: https://duckduckgo.com/?q=%s DuckDuckGo" - "# az: http://www.amazon.com/s/?field-keywords=%s Amazon" - "#" - "# Another example (for Vimium does not have completion)." - "#" - "# m: https://www.google.com/maps/search/%s Google Maps" - ].join "\n" - newTabUrl: "chrome://newtab" - grabBackFocus: false - - 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")) -Settings.set("settingsVersion", Utils.getCurrentVersion()) - -# Migration (after 1.49, 2015/2/1). -# Legacy setting: findModeRawQuery (a string). -# New setting: findModeRawQueryList (a list of strings), now stored in chrome.storage.local (not localStorage). -chrome.storage.local.get "findModeRawQueryList", (items) -> - unless chrome.runtime.lastError or items.findModeRawQueryList - rawQuery = Settings.get "findModeRawQuery" - chrome.storage.local.set findModeRawQueryList: (if rawQuery then [ rawQuery ] else []) - diff --git a/background_scripts/sync.coffee b/background_scripts/sync.coffee deleted file mode 100644 index d0d501d3..00000000 --- a/background_scripts/sync.coffee +++ /dev/null @@ -1,74 +0,0 @@ -# -# * Sync.set() and Sync.clear() propagate local changes to chrome.storage.sync. -# * Sync.handleStorageUpdate() listens for changes to chrome.storage.sync and propagates those -# changes to localStorage and into vimium's internal state. -# * Sync.fetchAsync() polls chrome.storage.sync at startup, similarly propagating -# changes to localStorage and into vimium's internal state. -# -# Changes are propagated into vimium's state using the same mechanism -# (Settings.performPostUpdateHook) that is used when options are changed on -# the options page. -# -# The effect is best-effort synchronization of vimium options/settings between -# chrome/vimium instances. -# -# NOTE: -# Values handled within this module are ALWAYS already JSON.stringifed, so -# they're always non-empty strings. -# - -root = exports ? window -root.Sync = Sync = - - storage: chrome.storage.sync - doNotSync: ["settingsVersion", "previousVersion"] - - # This is called in main.coffee. - init: -> - chrome.storage.onChanged.addListener (changes, area) -> Sync.handleStorageUpdate changes, area - @fetchAsync() - - # Asynchronous fetch from synced storage, called only at startup. - fetchAsync: -> - @storage.get null, (items) => - unless chrome.runtime.lastError - for own key, value of items - @storeAndPropagate key, value - - # Asynchronous message from synced storage. - handleStorageUpdate: (changes, area) -> - for own key, change of changes - @storeAndPropagate key, change?.newValue - - # Only ever called from asynchronous synced-storage callbacks (fetchAsync and handleStorageUpdate). - storeAndPropagate: (key, value) -> - return unless key of Settings.defaults - return if not @shouldSyncKey key - return if value and key of localStorage and localStorage[key] is value - defaultValue = Settings.defaults[key] - defaultValueJSON = JSON.stringify(defaultValue) - - if value and value != defaultValueJSON - # Key/value has been changed to non-default value at remote instance. - localStorage[key] = value - Settings.performPostUpdateHook key, JSON.parse(value) - else - # Key has been reset to default value at remote instance. - if key of localStorage - delete localStorage[key] - Settings.performPostUpdateHook key, defaultValue - - # Only called synchronously from within vimium, never on a callback. - # No need to propagate updates to the rest of vimium, that's already been done. - set: (key, value) -> - if @shouldSyncKey key - setting = {}; setting[key] = value - @storage.set setting - - # Only called synchronously from within vimium, never on a callback. - clear: (key) -> - @storage.remove key if @shouldSyncKey key - - # Should we synchronize this key? - shouldSyncKey: (key) -> key not in @doNotSync - |
