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 - | 
