this fixes #137 and #272

This commit is contained in:
gorhill 2014-10-07 08:59:35 -04:00
parent f417a3733e
commit a61975b798
15 changed files with 262 additions and 57 deletions

View File

@ -5,20 +5,7 @@
<title>µBlock — Your filters</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
<style>
div > p:first-child {
margin-top: 0;
}
div > p:last-child {
margin-bottom: 0;
}
.userFilters {
font-size: smaller;
width: 48em;
height: 40em;
white-space: nowrap;
}
</style>
<link rel="stylesheet" type="text/css" href="css/1p-filters.css">
</head>
<body>

View File

@ -279,6 +279,26 @@
"message":"Mitwirkende",
"description":"English: Contributors"
},
"aboutBackupDataButton" : {
"message": "Backup to file...",
"description": "English: Backup to file..."
},
"aboutRestoreDataButton" : {
"message": "Restore from file...",
"description": "English: Restore from file..."
},
"aboutResetDataButton" : {
"message": "Start from scratch...",
"description": "English: Start from scratch..."
},
"aboutRestoreDataConfirm" : {
"message": "All your settings will be overwritten using data backed up on {{time}}, and µBlock will restart.\n\nOverwrite all existing settings using backed up data?",
"description": "Message asking user to confirm restore"
},
"aboutResetDataConfirm" : {
"message": "All your settings will be erased, and µBlock will restart.\n\nReset µBlock to factory settings?",
"description": "Message asking user to confirm restore"
},
"errorCantConnectTo":{
"message":"Netzwerkfehler: Verbindung zu {{url}} nicht möglich",
"description":"English: Network error: unable to connect to {{url}}"

View File

@ -279,6 +279,26 @@
"message":"Contributors",
"description":"English: Contributors"
},
"aboutBackupDataButton" : {
"message": "Backup to file...",
"description": "English: Backup to file..."
},
"aboutRestoreDataButton" : {
"message": "Restore from file...",
"description": "English: Restore from file..."
},
"aboutResetDataButton" : {
"message": "Start from scratch...",
"description": "English: Start from scratch..."
},
"aboutRestoreDataConfirm" : {
"message": "All your settings will be overwritten using data backed up on {{time}}, and µBlock will restart.\n\nOverwrite all existing settings using backed up data?",
"description": "Message asking user to confirm restore"
},
"aboutResetDataConfirm" : {
"message": "All your settings will be erased, and µBlock will restart.\n\nReset µBlock to factory settings?",
"description": "Message asking user to confirm restore"
},
"errorCantConnectTo":{
"message":"Unable to connect to {{url}}",
"description":"English: Network error: unable to connect to {{url}}"

View File

@ -279,6 +279,26 @@
"message":"Contributeurs",
"description":"English: Contributors"
},
"aboutBackupDataButton" : {
"message": "Exporter vers un fichier",
"description": "English: Backup to file..."
},
"aboutRestoreDataButton" : {
"message": "Importer depuis un fichier",
"description": "English: Restore from file..."
},
"aboutResetDataButton" : {
"message": "Repartir à zéro",
"description": "English: Start from scratch..."
},
"aboutRestoreDataConfirm" : {
"message": "Vos paramètres seront remplacés par les données sauvegardées le {{time}}, puis µBlock redémarrera.\n\nProcéder à l'importation ?",
"description": "Message asking user to confirm restore"
},
"aboutResetDataConfirm" : {
"message": "Vos paramètres seront effacés, puis µBlock redémarrera.\n\nProcéder à la remise à zéro ?",
"description": "Message asking user to confirm restore"
},
"errorCantConnectTo":{
"message":"Erreur de connexion : {{url}}",
"description":"English: Network error: unable to connect to {{url}}"

View File

@ -5,18 +5,13 @@
<title>µBlock — About</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
<style>
ul {
padding-left: 1em;
padding-right: 1em;
}
</style>
<link rel="stylesheet" type="text/css" href="css/about.css">
</head>
<body>
<h2>µBlock <span id="aboutVersion"></span></h2>
<ul id="AboutUL">
<ul>
<li><a href="https://github.com/gorhill/uBlock/releases" data-i18n="aboutChangelog"></a>
<li><a href="https://github.com/gorhill/ublock" data-i18n="aboutCode"></a>
<li><span data-i18n="aboutContributors"></span>
@ -26,9 +21,19 @@ ul {
</ul>
</ul>
<div style="margin:3em 0;border-top:1px solid #ccc;"></div>
<div style="margin:1em 0 0 0;">
<p><button type="button" id="export" data-i18n="aboutBackupDataButton"></button>
<button type="button" id="import" data-i18n="aboutRestoreDataButton"></button>
<p>
<p><button type="button" id="reset" data-i18n="aboutResetDataButton">Start from scratch...</button>
</div>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>
<script src="js/messaging-client.js"></script>
<script src="js/about.js"></script>
</body>

13
css/1p-filters.css Normal file
View File

@ -0,0 +1,13 @@
div > p:first-child {
margin-top: 0;
}
div > p:last-child {
margin-bottom: 0;
}
.userFilters {
font-size: smaller;
width: 48em;
height: 40em;
white-space: nowrap;
text-align: left;
}

4
css/about.css Normal file
View File

@ -0,0 +1,4 @@
ul {
padding-__MSG_@@bidi_start_edge__: 1em;
margin-__MSG_@@bidi_start_edge__: 1em;
}

View File

@ -25,7 +25,9 @@ h2 + * {
a {
text-decoration: none;
}
button {
padding: 0.33em;
}
div > p:first-child {
margin-top: 0;
}
@ -36,18 +38,6 @@ div > p:last-child {
.para {
width: 40em;
}
.userFilters {
text-align: left;
}
#whitelist {
text-align: left;
}
ul#AboutUL {
padding-__MSG_@@bidi_start_edge__: 1em;
margin-__MSG_@@bidi_start_edge__: 1em;
}
.whatisthis {
margin: 0 0 0 8px;
border: 0;

16
css/whitelist.css Normal file
View File

@ -0,0 +1,16 @@
div > p:first-child {
margin-top: 0;
}
div > p:last-child {
margin-bottom: 0;
}
#whitelist {
font-size: smaller;
width: 48em;
height: 40em;
white-space: nowrap;
text-align: left;
}
#whitelist.bad {
background-color: #fee;
}

View File

@ -27,7 +27,83 @@ uDom.onLoad(function() {
/******************************************************************************/
messaging.start('about.js');
/******************************************************************************/
var exportToFile = function() {
var onUserDataReady = function(userData) {
chrome.downloads.download({
'url': 'data:text/plain,' + encodeURIComponent(JSON.stringify(userData)),
'filename': 'ublock-backup.txt',
'saveAs': true
});
};
messaging.ask({ what: 'getUserData' }, onUserDataReady);
};
/******************************************************************************/
var importFromFile = function() {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'text/plain');
var fileReaderOnLoadHandler = function() {
var userData;
try {
userData = JSON.parse(this.result);
}
catch (e) {
}
if ( userData === undefined ) {
return;
}
var time = new Date(userData.timeStamp);
var msg = chrome.i18n
.getMessage('aboutRestoreDataConfirm')
.replace('{{time}}', time.toLocaleString());
var proceed = window.confirm(msg);
if ( proceed ) {
messaging.tell({ what: 'restoreUserData', userData: userData });
}
};
var filePickerOnChangeHandler = function() {
input.removeEventListener('change', filePickerOnChangeHandler);
var file = this.files[0];
if ( !file ) {
return;
}
if ( file.type.indexOf('text') !== 0 ) {
return;
}
var fr = new FileReader();
fr.onload = fileReaderOnLoadHandler;
fr.readAsText(file);
};
input.addEventListener('change', filePickerOnChangeHandler);
input.click();
};
/******************************************************************************/
var resetUserData = function() {
var msg = chrome.i18n.getMessage('aboutResetDataConfirm');
var proceed = window.confirm(msg);
if ( proceed ) {
messaging.tell({ what: 'resetUserData' });
}
};
/******************************************************************************/
uDom('#aboutVersion').html(chrome.runtime.getManifest().version);
uDom('#export').on('click', exportToFile);
uDom('#import').on('click', importFromFile);
uDom('#reset').on('click', resetUserData);
/******************************************************************************/

View File

@ -633,9 +633,53 @@ var µb = µBlock;
/******************************************************************************/
var getUserData = function(callback) {
var onUserFiltersReady = function(details) {
callback({
'timeStamp': Date.now(),
'version': µb.manifest.version,
'userSettings': µb.userSettings,
'filterLists': µb.remoteBlacklists,
'netWhitelist': µb.stringFromWhitelist(µb.netWhitelist),
'userFilters': details.content
});
};
µb.assets.get('assets/user/filters.txt', onUserFiltersReady);
};
/******************************************************************************/
var restoreUserData = function(userData) {
var onUserFiltersSaved = function() {
µb.XAL.restart();
};
µb.destroySelfie();
µb.XAL.keyvalSetMany(userData.userSettings);
µb.XAL.keyvalSetOne('remoteBlacklists', userData.filterLists);
µb.XAL.keyvalSetOne('netWhitelist', userData.netWhitelist);
µb.assets.put('assets/user/filters.txt', userData.userFilters, onUserFiltersSaved);
};
/******************************************************************************/
var resetUserData = function() {
var onAllDone = function() {
µb.XAL.restart();
};
// Keep global counts, people can become quite attached to numbers
var onAllRemoved = function() {
µBlock.saveLocalSettings(onAllDone);
};
µb.XAL.keyvalRemoveAll(onAllRemoved);
};
/******************************************************************************/
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
case 'getUserData':
return getUserData(callback);
default:
break;
@ -645,6 +689,13 @@ var onMessage = function(request, sender, callback) {
var response;
switch ( request.what ) {
case 'restoreUserData':
restoreUserData(request.userData);
break;
case 'resetUserData':
resetUserData();
break;
default:
return µb.messaging.defaultHandler(request, sender, callback);

View File

@ -32,10 +32,11 @@
/******************************************************************************/
µBlock.saveLocalSettings = function() {
chrome.storage.local.set(this.localSettings, function() {
µBlock.getBytesInUse();
});
µBlock.saveLocalSettings = function(callback) {
if ( typeof callback !== 'function' ) {
callback = this.noopFunc;
}
chrome.storage.local.set(this.localSettings, callback);
};
/******************************************************************************/

View File

@ -265,6 +265,6 @@
}
if ( changed ) {
this.userSettings.dynamicFilteringSelfie = this.netFilteringEngine.selfieFromDynamicFilters();
this.XAL.keyValSetOne('dynamicFilteringSelfie', this.userSettings.dynamicFilteringSelfie);
this.XAL.keyvalSetOne('dynamicFilteringSelfie', this.userSettings.dynamicFilteringSelfie);
}
};

View File

@ -59,7 +59,7 @@ exports.injectScript = function(id, details) {
/******************************************************************************/
exports.keyValSetOne = function(key, val) {
exports.keyvalSetOne = function(key, val) {
var bin = {};
bin[key] = val;
chrome.storage.local.set(bin);
@ -67,6 +67,24 @@ exports.keyValSetOne = function(key, val) {
/******************************************************************************/
exports.keyvalSetMany = function(dict) {
chrome.storage.local.set(dict);
};
/******************************************************************************/
exports.keyvalRemoveAll = function(callback) {
chrome.storage.local.clear(callback);
};
/******************************************************************************/
exports.restart = function() {
chrome.runtime.reload();
};
/******************************************************************************/
return exports;
/******************************************************************************/

View File

@ -5,23 +5,7 @@
<title>µBlock — Whitelist</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
<style>
div > p:first-child {
margin-top: 0;
}
div > p:last-child {
margin-bottom: 0;
}
#whitelist {
font-size: smaller;
width: 48em;
height: 40em;
white-space: nowrap;
}
#whitelist.bad {
background-color: #fee;
}
</style>
<link rel="stylesheet" type="text/css" href="css/whitelist.css">
</head>
<body>