diff options
author | gorhill <rhill@raymondhill.net> | 2015-03-06 23:36:09 -0500 |
---|---|---|
committer | gorhill <rhill@raymondhill.net> | 2015-03-06 23:36:09 -0500 |
commit | d8b949ecbe42fa651a402cdbe8e0cda976ed4297 (patch) | |
tree | d35defd0abb41351a7c78cd1323b1e1eb91b6f9b | |
parent | e861ff00ca8bd566de086e114a3950ae183747b9 (diff) | |
download | uBlock-d8b949ecbe42fa651a402cdbe8e0cda976ed4297.zip uBlock-d8b949ecbe42fa651a402cdbe8e0cda976ed4297.tar.gz uBlock-d8b949ecbe42fa651a402cdbe8e0cda976ed4297.tar.bz2 |
this fixes #932
-rw-r--r-- | src/_locales/en/messages.json | 12 | ||||
-rw-r--r-- | src/js/background.js | 7 | ||||
-rw-r--r-- | src/js/messaging.js | 72 | ||||
-rw-r--r-- | src/js/settings.js | 86 | ||||
-rw-r--r-- | src/js/start.js | 15 | ||||
-rw-r--r-- | src/js/storage.js | 6 | ||||
-rw-r--r-- | src/settings.html | 38 |
7 files changed, 177 insertions, 59 deletions
diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 2fdc432..816bdbb 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -235,6 +235,18 @@ "message":"Enable experimental features (<a href='https:\/\/github.com\/gorhill\/uBlock\/wiki\/Experimental-features'>About<\/a>)", "description":"English: Enable experimental features" }, + "settingsStorageUsed":{ + "message":"Storage used: {{value}} bytes", + "description":"English: Storage used: {{}} bytes" + }, + "settingsLastRestorePrompt":{ + "message":"Last restore:", + "description":"English: Last restore:" + }, + "settingsLastBackupPrompt":{ + "message":"Last backup:", + "description":"English: Last backup:" + }, "3pListsOfBlockedHostsPrompt":{ "message":"{{netFilterCount}} network filters + {{cosmeticFilterCount}} cosmetic filters from:", "description":"English: {{netFilterCount}} network filters + {{cosmeticFilterCount}} cosmetic filters from:" diff --git a/src/js/background.js b/src/js/background.js index da7dad1..1419a43 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -92,6 +92,13 @@ return { selfieMagic: 'spqmeuaftfra' }, + restoreBackupSettings: { + lastRestoreFile: '', + lastRestoreTime: 0, + lastBackupFile: '', + lastBackupTime: 0 + }, + // EasyList, EasyPrivacy and many others have an 4-day update period, // as per list headers. updateAssetsEvery: 97 * oneHour, diff --git a/src/js/messaging.js b/src/js/messaging.js index e818b35..72b51f8 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -954,24 +954,58 @@ var µb = µBlock; /******************************************************************************/ -var getUserData = function(callback) { - var onUserFiltersReady = function(details) { +var getLocalData = function(callback) { + var onStorageInfoReady = function(bytesInUse) { + var o = µb.restoreBackupSettings; callback({ - 'timeStamp': Date.now(), - 'version': vAPI.app.version, - 'userSettings': µb.userSettings, - 'filterLists': µb.remoteBlacklists, - 'netWhitelist': µb.stringFromWhitelist(µb.netWhitelist), - 'userFilters': details.content + storageUsed: bytesInUse, + lastRestoreFile: o.lastRestoreFile, + lastRestoreTime: o.lastRestoreTime, + lastBackupFile: o.lastBackupFile, + lastBackupTime: o.lastBackupTime }); }; + + µb.getBytesInUse(onStorageInfoReady); +}; + +/******************************************************************************/ + +var backupUserData = function(callback) { + var onUserFiltersReady = function(details) { + var userData = { + timeStamp: Date.now(), + version: vAPI.app.version, + userSettings: µb.userSettings, + filterLists: µb.remoteBlacklists, + netWhitelist: µb.stringFromWhitelist(µb.netWhitelist), + userFilters: details.content + }; + var now = new Date(); + var filename = vAPI.i18n('aboutBackupFilename') + .replace('{{datetime}}', now.toLocaleString()) + .replace(/ +/g, '_'); + + vAPI.download({ + 'url': 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(userData, null, ' ')), + 'filename': filename + }); + + µb.restoreBackupSettings.lastBackupFile = filename; + µb.restoreBackupSettings.lastBackupTime = Date.now(); + µb.XAL.keyvalSetMany(µb.restoreBackupSettings); + + getLocalData(callback); + }; + µb.assets.get('assets/user/filters.txt', onUserFiltersReady); }; /******************************************************************************/ -var restoreUserData = function(userData) { - var countdown = 5; +var restoreUserData = function(request) { + var userData = request.userData; + var countdown = 6; var onCountdown = function() { countdown -= 1; if ( countdown === 0 ) { @@ -987,6 +1021,13 @@ var restoreUserData = function(userData) { µb.XAL.keyvalSetOne('remoteBlacklists', userData.filterLists, onCountdown); µb.XAL.keyvalSetOne('netWhitelist', userData.netWhitelist, onCountdown); µb.assets.put('assets/user/filters.txt', userData.userFilters, onCountdown); + + µb.XAL.keyvalSetMany({ + lastRestoreFile: request.file || '', + lastRestoreTime: Date.now(), + lastBackupFile: '', + lastBackupTime: 0 + }, onCountdown); }; // If we are going to restore all, might as well wipe out clean local @@ -999,7 +1040,7 @@ var restoreUserData = function(userData) { var resetUserData = function() { µb.XAL.keyvalRemoveAll(); // Keep global counts, people can become quite attached to numbers - µBlock.saveLocalSettings(); + µb.saveLocalSettings(); vAPI.app.restart(); }; @@ -1008,8 +1049,11 @@ var resetUserData = function() { var onMessage = function(request, sender, callback) { // Async switch ( request.what ) { - case 'getUserData': - return getUserData(callback); + case 'backupUserData': + return backupUserData(callback); + + case 'getLocalData': + return getLocalData(callback); default: break; @@ -1020,7 +1064,7 @@ var onMessage = function(request, sender, callback) { switch ( request.what ) { case 'restoreUserData': - restoreUserData(request.userData); + restoreUserData(request); break; case 'resetUserData': diff --git a/src/js/settings.js b/src/js/settings.js index cf9981b..ddd8bb0 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -33,27 +33,16 @@ var messager = vAPI.messaging.channel('settings.js'); /******************************************************************************/ -var exportToFile = function() { - var onUserDataReady = function(userData) { - if (!userData) { - return; - } - var now = new Date(); - var filename = vAPI.i18n('aboutBackupFilename') - .replace('{{datetime}}', now.toLocaleString()) - .replace(/ +/g, '_'); - vAPI.download({ - 'url': 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(userData, null, ' ')), - 'filename': filename - }); - }; - - messager.send({ what: 'getUserData' }, onUserDataReady); -}; - -/******************************************************************************/ - var handleImportFilePicker = function() { + var file = this.files[0]; + if ( file === undefined || file.name === '' ) { + return; + } + if ( file.type.indexOf('text') !== 0 ) { + return; + } + var filename = file.name; + var fileReaderOnLoadHandler = function() { var userData; try { @@ -80,20 +69,17 @@ var handleImportFilePicker = function() { } var time = new Date(userData.timeStamp); var msg = vAPI.i18n('aboutRestoreDataConfirm') - .replace('{{time}}', time.toLocaleString()); + .replace('{{time}}', time.toLocaleString()); var proceed = window.confirm(msg); if ( proceed ) { - messager.send({ what: 'restoreUserData', userData: userData }); + messager.send({ + what: 'restoreUserData', + userData: userData, + file: filename + }); } }; - var file = this.files[0]; - if ( file === undefined || file.name === '' ) { - return; - } - if ( file.type.indexOf('text') !== 0 ) { - return; - } var fr = new FileReader(); fr.onload = fileReaderOnLoadHandler; fr.readAsText(file); @@ -112,6 +98,47 @@ var startImportFilePicker = function() { /******************************************************************************/ +var exportToFile = function() { + messager.send({ what: 'backupUserData' }, onLocalDataReceived); +}; + +/******************************************************************************/ + +var onLocalDataReceived = function(details) { + uDom('#localData > ul > li:nth-of-type(1)').text( + vAPI.i18n('settingsStorageUsed').replace('{{value}}', details.storageUsed.toLocaleString()) + ); + + var elem, dt; + var timeOptions = { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + timeZoneName: 'short' + }; + var lastBackupFile = details.lastBackupFile || ''; + if ( lastBackupFile !== '' ) { + dt = new Date(details.lastBackupTime); + uDom('#localData > ul > li:nth-of-type(2) > ul > li:nth-of-type(1)').text(dt.toLocaleString('fullwide', timeOptions)); + uDom('#localData > ul > li:nth-of-type(2) > ul > li:nth-of-type(2)').text(lastBackupFile); + uDom('#localData > ul > li:nth-of-type(2)').css('display', ''); + } + + var lastRestoreFile = details.lastRestoreFile || ''; + elem = uDom('#localData > p:nth-of-type(3)'); + if ( lastRestoreFile !== '' ) { + dt = new Date(details.lastRestoreTime); + uDom('#localData > ul > li:nth-of-type(3) > ul > li:nth-of-type(1)').text(dt.toLocaleString('fullwide', timeOptions)); + uDom('#localData > ul > li:nth-of-type(3) > ul > li:nth-of-type(2)').text(lastRestoreFile); + uDom('#localData > ul > li:nth-of-type(3)').css('display', ''); + } +}; + +/******************************************************************************/ + var resetUserData = function() { var msg = vAPI.i18n('aboutResetDataConfirm'); var proceed = window.confirm(msg); @@ -175,6 +202,7 @@ var onUserSettingsReceived = function(details) { uDom.onLoad(function() { messager.send({ what: 'userSettings' }, onUserSettingsReceived); + messager.send({ what: 'getLocalData' }, onLocalDataReceived); }); /******************************************************************************/ diff --git a/src/js/start.js b/src/js/start.js index bca966b..b1c82f8 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -143,12 +143,6 @@ var onUserSettingsReady = function(fetched) { /******************************************************************************/ -var onLocalSettingsReady = function(fetched) { - fromFetch(µb.localSettings, fetched); -}; - -/******************************************************************************/ - // Housekeeping, as per system setting changes var onSystemSettingsReady = function(fetched) { @@ -170,11 +164,11 @@ var onSystemSettingsReady = function(fetched) { /******************************************************************************/ var onFirstFetchReady = function(fetched) { - // Order is important -- do not change: onSystemSettingsReady(fetched); - onLocalSettingsReady(fetched); + fromFetch(µb.localSettings, fetched); onUserSettingsReady(fetched); + fromFetch(µb.restoreBackupSettings, fetched); onNetWhitelistReady(fetched.netWhitelist); onVersionReady(fetched.version); @@ -191,6 +185,10 @@ var onFirstFetchReady = function(fetched) { var fetchableProps = { 'compiledMagic': '', + 'lastRestoreFile': '', + 'lastRestoreTime': 0, + 'lastBackupFile': '', + 'lastBackupTime': 0, 'netWhitelist': '', 'selfie': null, 'selfieMagic': '', @@ -222,6 +220,7 @@ var fromFetch = function(to, fetched) { toFetch(µb.localSettings, fetchableProps); toFetch(µb.userSettings, fetchableProps); +toFetch(µb.restoreBackupSettings, fetchableProps); vAPI.storage.get(fetchableProps, onFirstFetchReady); diff --git a/src/js/storage.js b/src/js/storage.js index 0c41411..478f3a2 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -25,9 +25,13 @@ /******************************************************************************/ -µBlock.getBytesInUse = function() { +µBlock.getBytesInUse = function(callback) { + if ( typeof callback !== 'function' ) { + callback = this.noopFunc; + } var getBytesInUseHandler = function(bytesInUse) { µBlock.storageUsed = bytesInUse; + callback(bytesInUse); }; vAPI.storage.getBytesInUse(null, getBytesInUseHandler); }; diff --git a/src/settings.html b/src/settings.html index fe37653..e52cbd7 100644 --- a/src/settings.html +++ b/src/settings.html @@ -7,9 +7,21 @@ <link rel="stylesheet" type="text/css" href="css/dashboard-common.css"> <style> ul { - list-style-type: none; padding-left: 1em; } +li { + margin-top: 0.25em; + } +ul#userSettings { + list-style-type: none; + } +#localData > ul > li { + margin-top: 1em; + } +#localData > ul > li > ul > li:nth-of-type(2) { + font-family: monospace; + font-size: small; + } #experimental-enabled { margin-top: 1em; } @@ -18,24 +30,36 @@ ul { <body> -<ul> +<ul id="userSettings"> <li><input id="collapse-blocked" type="checkbox"><label data-i18n="settingsCollapseBlockedPrompt" for="collapse-blocked"></label> <li><input id="icon-badge" type="checkbox"><label data-i18n="settingsIconBadgePrompt" for="icon-badge"></label> <li><input id="context-menu-enabled" type="checkbox"><label data-i18n="settingsContextMenuPrompt" for="context-menu-enabled"></label> <li><input id="advanced-user-enabled" type="checkbox"><label data-i18n="settingsAdvancedUserPrompt" for="advanced-user-enabled"></label> - <!-- <li><input id="experimental-enabled" type="checkbox" disabled><label data-i18n="settingsExperimentalPrompt" for="experimental-enabled"></label> --> -</ul> + </ul> -<div style="margin:3em 0;border-top:1px solid #ccc;"></div> +<div id="localData" style="margin: 0 1em;"> + <div style="margin: 2.5em 0; border-top: 1px solid #ccc;"></div> + <ul> + <li> + <li style="display: none;"><span data-i18n="settingsLastBackupPrompt"></span><ul> + <li> + <li> + </ul> + <li style="display: none;"><span data-i18n="settingsLastRestorePrompt"></span><ul> + <li> + <li> + </ul> + </ul> + </div> -<div style="margin:1em 0 0 1em;"> +<div style="margin: 2.5em 1em;"> <p><button type="button" id="export" data-i18n="aboutBackupDataButton"></button>  <button type="button" id="import" data-i18n="aboutRestoreDataButton"></button> <input id="restoreFilePicker" type="file" accept="text/plain" class="hiddenFileInput"> <p> <p><button type="button" id="reset" data-i18n="aboutResetDataButton"></button> -</div> + </div> <script src="js/vapi-common.js"></script> <script src="js/vapi-client.js"></script> |