aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cakefile8
-rw-r--r--README.md6
-rw-r--r--content_scripts/link_hints.coffee2
-rw-r--r--lib/settings.coffee4
-rw-r--r--pages/options.coffee57
-rw-r--r--pages/options.css3
-rw-r--r--pages/options.html26
7 files changed, 97 insertions, 9 deletions
diff --git a/Cakefile b/Cakefile
index a106365a..d188ea12 100644
--- a/Cakefile
+++ b/Cakefile
@@ -77,6 +77,9 @@ task "package", "Builds a zip file for submission to the Chrome store. The outpu
spawn "rsync", rsyncOptions, false, true
spawn "zip", ["-r", "dist/vimium-#{vimium_version}.zip", "dist/vimium"], false, true
+ spawn "zip", "-r -FS dist/vimium-ff-#{vimium_version}.zip background_scripts Cakefile content_scripts CONTRIBUTING.md CREDITS icons lib
+ manifest.json MIT-LICENSE.txt pages README.md -x *.coffee -x Cakefile -x CREDITS -x *.md".split(/\s+/), false, true
+
# This builds a CRX that's distributable outside of the Chrome web store. Is this used by folks who fork
# Vimium and want to distribute their fork?
task "package-custom-crx", "build .crx file", ->
@@ -157,8 +160,3 @@ task "coverage", "generate coverage report", ->
source: (Utils.escapeHtml fs.readFileSync fname, 'utf-8').split '\n'
fs.writeFileSync 'jscoverage.json', JSON.stringify(result)
-
-task "zip", "build Firefox zip file in ../vimium.zip", ->
- spawn "zip", "-r -FS ../vimium.zip background_scripts Cakefile content_scripts CONTRIBUTING.md CREDITS icons lib
- manifest.json MIT-LICENSE.txt pages README.md -x *.coffee -x Cakefile -x CREDITS -x *.md".split /\s+/
-
diff --git a/README.md b/README.md
index 6368f67d..1896a662 100644
--- a/README.md
+++ b/README.md
@@ -168,9 +168,13 @@ PRs are welcome.
Release Notes
-------------
+In `master` (not yet released)
+
+- Backup and restore Vimium options (see the very bottom of the options page, below *Advanced Options*).
+
1.61 (2017-10-27)
-- For *filtered hints*, you can now now use alphabetical hint characters
+- For *filtered hints*, you can now use alphabetical hint characters
instead of digits; use `<Shift>` for hint characters.
- With `map R reload hard`, the reload command now asks Chrome to bypass its cache.
- You can now map `<c-[>` to a command (in which case it will not be treated as `Escape`).
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee
index 8b5bb8d9..38ac3b28 100644
--- a/content_scripts/link_hints.coffee
+++ b/content_scripts/link_hints.coffee
@@ -841,6 +841,8 @@ LocalHints =
if labelMap[element.id]
linkText = labelMap[element.id]
showLinkText = true
+ else if element.getAttribute("type")?.toLowerCase() == "file"
+ linkText = "Choose File"
else if element.type != "password"
linkText = element.value
if not linkText and 'placeholder' of element
diff --git a/lib/settings.coffee b/lib/settings.coffee
index 11cf7557..fd1ef268 100644
--- a/lib/settings.coffee
+++ b/lib/settings.coffee
@@ -202,7 +202,7 @@ Settings.init()
# Perform migration from old settings versions, if this is the background page.
if Utils.isBackgroundPage()
- Settings.onLoaded ->
+ Settings.applyMigrations = ->
unless Settings.get "settingsVersion"
# This is a new install. For some settings, we retain a legacy default behaviour for existing users but
# use a non-default behaviour for new users.
@@ -218,6 +218,8 @@ if Utils.isBackgroundPage()
# be removed after 1.58 has been out for sufficiently long.
Settings.nuke "copyNonDefaultsToChromeStorage-20150717"
+ Settings.onLoaded Settings.applyMigrations.bind Settings
+
root = exports ? (window.root ?= {})
root.Settings = Settings
extend window, root unless exports?
diff --git a/pages/options.coffee b/pages/options.coffee
index 035dd403..86b6122d 100644
--- a/pages/options.coffee
+++ b/pages/options.coffee
@@ -39,9 +39,14 @@ class Option
bgSettings.clear @field
@fetch()
+ @onSaveCallbacks: []
+ @onSave: (callback) ->
+ @onSaveCallbacks.push callback
+
# Static method.
@saveOptions: ->
Option.all.map (option) -> option.save()
+ callback() for callback in @onSaveCallbacks
# Abstract method; only implemented in sub-classes.
# Populate the option's DOM element (@element) with the setting's current value.
@@ -93,8 +98,10 @@ class ExclusionRulesOption extends Option
element
populateElement: (rules) ->
- for rule in rules
- @appendRule rule
+ # For the case of restoring a backup, we first have to remove existing rules.
+ exclusionRules = $ "exclusionRules"
+ exclusionRules.deleteRow 1 while exclusionRules.rows[1]
+ @appendRule rule for rule in rules
# Append a row for a new rule. Return the newly-added element.
appendRule: (rule) ->
@@ -323,6 +330,52 @@ document.addEventListener "DOMContentLoaded", ->
xhr.send()
+#
+# Backup and restore. "?" is for the tests."
+DomUtils?.documentReady ->
+ restoreSettingsVersion = null
+
+ populateBackupLinkUrl = ->
+ backup = settingsVersion: bgSettings.get "settingsVersion"
+ for option in Option.all
+ backup[option.field] = option.readValueFromElement()
+ # Create the blob in the background page so it isn't garbage collected when the page closes in FF.
+ bgWin = chrome.extension.getBackgroundPage()
+ blob = new bgWin.Blob [ JSON.stringify backup, null, 2 ]
+ $("backupLink").href = bgWin.URL.createObjectURL blob
+
+ $("backupLink").addEventListener "mousedown", populateBackupLinkUrl, true
+
+ $("chooseFile").addEventListener "change", (event) ->
+ document.activeElement?.blur()
+ files = event.target.files
+ if files.length == 1
+ file = files[0]
+ reader = new FileReader
+ reader.readAsText file
+ reader.onload = (event) ->
+ try
+ backup = JSON.parse reader.result
+ catch
+ alert "Failed to parse Vimium backup."
+ return
+
+ restoreSettingsVersion = backup["settingsVersion"] if "settingsVersion" of backup
+ for option in Option.all
+ if option.field of backup
+ option.populateElement backup[option.field]
+ option.onUpdated()
+
+ Option.onSave ->
+ # If we're restoring a backup, then restore the backed up settingsVersion.
+ if restoreSettingsVersion?
+ bgSettings.set "settingsVersion", restoreSettingsVersion
+ restoreSettingsVersion = null
+ # Reset the restore-backup input.
+ $("chooseFile").value = ""
+ # We need to apply migrations in case we are restoring an old backup.
+ bgSettings.applyMigrations()
+
# Exported for tests.
root = exports ? window
extend root, {Options, isVimiumOptionsPage: true}
diff --git a/pages/options.css b/pages/options.css
index 5e2a3dfc..dab342a3 100644
--- a/pages/options.css
+++ b/pages/options.css
@@ -231,3 +231,6 @@ input.pattern, input.passKeys, .exclusionHeaderText {
white-space: nowrap;
width: 110px;
}
+#backupLink {
+ cursor: pointer;
+}
diff --git a/pages/options.html b/pages/options.html
index 6312e450..bfdb9b53 100644
--- a/pages/options.html
+++ b/pages/options.html
@@ -316,6 +316,32 @@ b: http://b.com/?q=%s description
</tr>
-->
</tbody>
+ <tbody id='backupAndRestor'>
+ <tr>
+ <td colspan="2"><header>Backup and Restore</header></td>
+ </tr>
+ <tr>
+ <td class="caption">Backup</td>
+ <td>
+ <div class="help">
+ <div class="example">
+ </div>
+ </div>
+ <a id="backupLink" download="vimium-options.json">Click to download backup</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="caption">Restore</td>
+ <td>
+ <div class="help">
+ <div class="example">
+ Choose file, then click <i>Save Changes</i>, below, to confirm restore.
+ </div>
+ </div>
+ <input id="chooseFile" type="file" accept=".json" style="width: 200px;"/>
+ </td>
+ </tr>
+ </tbody>
</table>
</div>