aboutsummaryrefslogtreecommitdiffstats
path: root/pages
diff options
context:
space:
mode:
Diffstat (limited to 'pages')
-rw-r--r--pages/options.coffee57
-rw-r--r--pages/options.css3
-rw-r--r--pages/options.html26
3 files changed, 84 insertions, 2 deletions
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>