From 9960e8f01ab8477151465af936d7cb14b84fb125 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 16:21:38 +0100 Subject: Combine sync.coffee with settings.coffee --- background_scripts/settings.coffee | 76 +++++++++++++++++++++++++++++++++++++- background_scripts/sync.coffee | 74 ------------------------------------- 2 files changed, 74 insertions(+), 76 deletions(-) delete mode 100644 background_scripts/sync.coffee (limited to 'background_scripts') diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index d23649ee..5442a1cf 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -1,8 +1,81 @@ # -# Used by all parts of Vimium to manipulate localStorage. +# * 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 + +# +# Used by all parts of Vimium to manipulate localStorage. +# + root.Settings = Settings = get: (key) -> if (key of localStorage) then JSON.parse(localStorage[key]) else @defaults[key] @@ -123,4 +196,3 @@ 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 - -- cgit v1.2.3 From 960ccc627c4e55a7bdc53eead255270d9504a8bf Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 16:35:58 +0100 Subject: Move Sync.storeAndPropagate to Settings.storeAndPropagate This function does nothing related to Sync, and only affects Settings. --- background_scripts/settings.coffee | 43 +++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index 5442a1cf..81bc8589 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -5,10 +5,6 @@ # * 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. # @@ -33,30 +29,12 @@ root.Sync = Sync = @storage.get null, (items) => unless chrome.runtime.lastError for own key, value of items - @storeAndPropagate key, value + Settings.storeAndPropagate key, value if @shouldSyncKey key # 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 + Settings.storeAndPropagate key, change?.newValue if @shouldSyncKey key # 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. @@ -112,6 +90,23 @@ root.Settings = Settings = performPostUpdateHook: (key, value) -> @postUpdateHooks[key] value if @postUpdateHooks[key] + # Only ever called from asynchronous synced-storage callbacks (fetchAsync and handleStorageUpdate). + storeAndPropagate: (key, value) -> + return unless key of @defaults + return if value and key of localStorage and localStorage[key] is value + defaultValue = @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 + @performPostUpdateHook key, JSON.parse(value) + else + # Key has been reset to default value at remote instance. + if key of localStorage + delete localStorage[key] + @performPostUpdateHook key, defaultValue + # options.coffee and options.html only handle booleans and strings; therefore all defaults must be booleans # or strings defaults: -- cgit v1.2.3 From 31873e39772c538cab418d03c244b4cac1addba0 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 17:07:16 +0100 Subject: Remove all direct calls to Sync, stop exporting it This stops Sync from being referred to from anywhere except settings.coffee and settings_test.coffee. --- background_scripts/main.coffee | 2 +- background_scripts/settings.coffee | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index a13d9d98..edcdf3b2 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 index 81bc8589..44676ad7 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -14,7 +14,7 @@ # root = exports ? window -root.Sync = Sync = +Sync = storage: chrome.storage.sync doNotSync: ["settingsVersion", "previousVersion"] @@ -55,6 +55,7 @@ root.Sync = Sync = # root.Settings = Settings = + init: -> Sync.init() get: (key) -> if (key of localStorage) then JSON.parse(localStorage[key]) else @defaults[key] @@ -178,6 +179,9 @@ root.Settings = Settings = settingsVersion: Utils.getCurrentVersion() +# Export Sync via Settings for tests. +root.Settings.Sync = Sync + # We use settingsVersion to coordinate any necessary schema changes. if Utils.compareVersions("1.42", Settings.get("settingsVersion")) != -1 -- cgit v1.2.3 From d7a0daf5fa2c0a3302a8fc6b9fa0744cfa17ab42 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 19:29:39 +0100 Subject: Move registration of postUpdateHooks to the corresponding source files This completely decouples settings.coffee from all other background source files, so that it can (eventually) also be used in the frontend. --- background_scripts/commands.coffee | 6 ++++++ background_scripts/exclusions.coffee | 4 ++++ background_scripts/settings.coffee | 13 +++---------- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index abfbd9e2..5857665c 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -359,5 +359,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/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/settings.coffee b/background_scripts/settings.coffee index 44676ad7..6b33d239 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -75,17 +75,10 @@ root.Settings = Settings = 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 + # For settings which require action when their value changes, add hooks to this object, to be called from + # options/options.coffee (when the options page is saved), and by Settings.storeAndPropagate (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: {} # postUpdateHooks convenience wrapper performPostUpdateHook: (key, value) -> -- cgit v1.2.3 From bfe304932b13eb1bfe65662490d3d6b830eefec7 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 19:58:10 +0100 Subject: Only perform settings migration in the background page --- background_scripts/settings.coffee | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index 6b33d239..607264a2 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -175,16 +175,18 @@ root.Settings = Settings = # Export Sync via Settings for tests. root.Settings.Sync = Sync - -# 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 []) +# Perform migration from old settings versions, if this is the background page. +if Utils.isBackgroundPage() + + # 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 []) -- cgit v1.2.3 From 0c12810c4c49ade77a1c8a8b3172857e19eb01f0 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 27 Apr 2015 20:08:11 +0100 Subject: Move settings.coffee from background_scripts/ to lib/ --- background_scripts/settings.coffee | 192 ------------------------------------- 1 file changed, 192 deletions(-) delete mode 100644 background_scripts/settings.coffee (limited to 'background_scripts') diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee deleted file mode 100644 index 607264a2..00000000 --- a/background_scripts/settings.coffee +++ /dev/null @@ -1,192 +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. -# -# 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 -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 - Settings.storeAndPropagate key, value if @shouldSyncKey key - - # Asynchronous message from synced storage. - handleStorageUpdate: (changes, area) -> - for own key, change of changes - Settings.storeAndPropagate key, change?.newValue if @shouldSyncKey key - - # 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 - -# -# Used by all parts of Vimium to manipulate localStorage. -# - -root.Settings = Settings = - init: -> Sync.init() - 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 to this object, to be called from - # options/options.coffee (when the options page is saved), and by Settings.storeAndPropagate (when an - # update propagates from chrome.storage.sync). - postUpdateHooks: {} - - # postUpdateHooks convenience wrapper - performPostUpdateHook: (key, value) -> - @postUpdateHooks[key] value if @postUpdateHooks[key] - - # Only ever called from asynchronous synced-storage callbacks (fetchAsync and handleStorageUpdate). - storeAndPropagate: (key, value) -> - return unless key of @defaults - return if value and key of localStorage and localStorage[key] is value - defaultValue = @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 - @performPostUpdateHook key, JSON.parse(value) - else - # Key has been reset to default value at remote instance. - if key of localStorage - delete localStorage[key] - @performPostUpdateHook key, defaultValue - - # 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() - -# Export Sync via Settings for tests. -root.Settings.Sync = Sync - -# Perform migration from old settings versions, if this is the background page. -if Utils.isBackgroundPage() - - # 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 []) -- cgit v1.2.3