From a39bd536b5f1187174e47b0cf938b529114a5458 Mon Sep 17 00:00:00 2001 From: gorhill Date: Fri, 24 Oct 2014 11:13:46 -0400 Subject: [PATCH] work on auto-update, backup/restore/reset --- src/about.html | 58 ++------ src/background.html | 1 + src/info.html | 4 +- src/js/about.js | 136 +++++------------- src/js/asset-updater.js | 224 ----------------------------- src/js/background.js | 12 +- src/js/hosts-files.js | 22 +-- src/js/info.js | 6 +- src/js/messaging-handlers.js | 63 +++++++- src/js/messaging.js | 2 +- src/js/pagestats.js | 16 +-- src/js/storage.js | 72 ++++++---- src/js/traffic.js | 5 +- src/js/updater.js | 105 ++++++++++++++ tools/_locales/de/messages.json | 150 +++---------------- tools/_locales/en/messages.json | 164 ++++----------------- tools/_locales/fr/messages.json | 152 +++----------------- tools/_locales/ru/messages.json | 150 +++---------------- tools/_locales/zh_CN/messages.json | 150 +++---------------- 19 files changed, 409 insertions(+), 1083 deletions(-) delete mode 100644 src/js/asset-updater.js create mode 100644 src/js/updater.js diff --git a/src/about.html b/src/about.html index efa0210..178242d 100644 --- a/src/about.html +++ b/src/about.html @@ -5,49 +5,6 @@ µMatrix — About - @@ -64,13 +21,20 @@ table td:first-child {

-

- +

+ -

-

+

+

+ + + + + + + diff --git a/src/background.html b/src/background.html index f0ea1d8..e681360 100644 --- a/src/background.html +++ b/src/background.html @@ -17,6 +17,7 @@ + diff --git a/src/info.html b/src/info.html index d208d10..f8b99d3 100644 --- a/src/info.html +++ b/src/info.html @@ -156,8 +156,8 @@ tr.unused {
- - + +
whenwhatwhere
<a>
whenwhatwhere
<a>
diff --git a/src/js/about.js b/src/js/about.js index 22bf593..4a14f67 100644 --- a/src/js/about.js +++ b/src/js/about.js @@ -19,7 +19,7 @@ Home: https://github.com/gorhill/uMatrix */ -/* global chrome, uDom */ +/* global chrome, messaging, uDom */ /******************************************************************************/ @@ -28,115 +28,54 @@ uDom.onLoad(function() { /******************************************************************************/ var backupUserDataToFile = function() { - var allUserData = { - timeStamp: Date.now(), - version: '', - userSettings: {}, - scopes: '', - remoteBlacklists: {}, - ubiquitousBlacklist: '', - ubiquitousWhitelist: '' - }; - - var userWhitelistReady = function(details) { - allUserData.ubiquitousWhitelist = details.content; + var userDataReady = function(userData) { chrome.downloads.download({ - 'url': 'data:text/plain,' + encodeURIComponent(JSON.stringify(allUserData)), - 'filename': 'umatrix-alluserdata-backup.txt', + 'url': 'data:text/plain,' + encodeURIComponent(JSON.stringify(userData)), + 'filename': uDom('[data-i18n="aboutBackupFilename"]').text(), 'saveAs': true }); }; - var userBlacklistReady = function(details) { - allUserData.ubiquitousBlacklist = details.content; - messaging.ask({ what: 'readUserUbiquitousAllowRules' }, userWhitelistReady); - }; - - var ruleDataReady = function(store) { - allUserData.version = store.version; - allUserData.scopes = store.scopes; - allUserData.remoteBlacklists = store.remoteBlacklists; - messaging.ask({ what: 'readUserUbiquitousBlockRules' }, userBlacklistReady); - }; - - var userSettingsReady = function(store) { - allUserData.userSettings = store; - chrome.storage.local.get(['version', 'scopes', 'remoteBlacklists'], ruleDataReady); - }; - - messaging.ask({ what: 'readUserSettings' }, userSettingsReady); + messaging.ask({ what: 'getAllUserData' }, userDataReady); }; /******************************************************************************/ function restoreUserDataFromFile() { - var restartCountdown = 4; - var doCountdown = function() { - restartCountdown -= 1; - if ( restartCountdown > 0 ) { - return; - } - chrome.runtime.reload(); - }; - - var restoreBackup = function(data) { - chrome.storage.local.set(data.userSettings, doCountdown); - var store = { - 'version': data.version, - 'scopes': data.scopes - }; - // This case may happen if data was backed up without the user having - // changed default selection of lists. - if ( data.remoteBlacklists !== undefined ) { - store.remoteBlacklists = data.remoteBlacklists; - } - chrome.storage.local.set(store, doCountdown); - messaging.ask({ - what: 'writeUserUbiquitousBlockRules', - content: data.ubiquitousBlacklist - }, - doCountdown - ); - messaging.ask({ - what: 'writeUserUbiquitousAllowRules', - content: data.ubiquitousWhitelist - }, - doCountdown - ); - }; - var validateBackup = function(s) { - var data; + var userData = null; try { - data = JSON.parse(s); + userData = JSON.parse(s); } catch (e) { - data = undefined; + userData = null; } - if ( typeof data !== 'object' || - typeof data.timeStamp !== 'number' || - typeof data.version !== 'string' || - typeof data.userSettings !== 'object' || - typeof data.scopes !== 'string' || - typeof data.ubiquitousBlacklist !== 'string' || - typeof data.ubiquitousWhitelist !== 'string' ) { - alert('File content is not valid backed up data.'); + if ( userData === null ) { + return null; } - return data; + if ( typeof userData !== 'object' || + typeof userData.version !== 'string' || + typeof userData.when !== 'number' || + typeof userData.settings !== 'object' || + typeof userData.rules !== 'string' || + typeof userData.hostsFiles !== 'object' ) { + return null; + } + return userData; }; var fileReaderOnLoadHandler = function() { - var data = validateBackup(this.result); - if ( !data ) { + var userData = validateBackup(this.result); + if ( !userData ) { + window.alert(uDom('[data-i18n="aboutRestoreError"]').text()); return; } - var time = new Date(data.timeStamp); - var msg = chrome.i18n - .getMessage('aboutUserDataRestoreConfirm') + var time = new Date(userData.when); + var msg = uDom('[data-i18n="aboutRestoreConfirm"]').text() .replace('{{time}}', time.toLocaleString()); var proceed = window.confirm(msg); if ( proceed ) { - restoreBackup(data); + messaging.tell({ what: 'restoreAllUserData', userData: userData }); } }; @@ -166,28 +105,25 @@ var startRestoreFilePicker = function() { /******************************************************************************/ var resetUserData = function() { - messaging.tell({ - what: 'gotoExtensionURL', - url: 'setup.html' - }); + var proceed = window.confirm(uDom('[data-i18n="aboutResetConfirm"]').text()); + if ( proceed ) { + messaging.tell({ what: 'resetAllUserData' }); + } }; /******************************************************************************/ -messaging.start('about.js'); - -/******************************************************************************/ - (function() { - uDom('#aboutVersion').html(chrome.runtime.getManifest().version); var renderStats = function(details) { - var template = chrome.i18n.getMessage('aboutStorageUsed'); - var percent = 0; - if ( details.storageQuota ) { - percent = (details.storageUsed / details.storageQuota * 100).toFixed(1); + uDom('#aboutVersion').html(details.version); + var template = uDom('[data-i18n="aboutStorageUsed"]').text(); + var storageUsed = '?'; + if ( typeof details.storageUsed === 'number' ) { + storageUsed = details.storageUsed.toLocaleString(); } - uDom('#aboutStorageUsed').html(template.replace('{{storageUsed}}', percent)); + uDom('#aboutStorageUsed').html(template.replace('{{storageUsed}}', storageUsed)); }; + messaging.start('about.js'); messaging.ask({ what: 'getSomeStats' }, renderStats); })(); diff --git a/src/js/asset-updater.js b/src/js/asset-updater.js deleted file mode 100644 index 9e37a1a..0000000 --- a/src/js/asset-updater.js +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - - µMatrix - a Chromium browser extension to black/white list requests. - Copyright (C) 2013 Raymond Hill - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see {http://www.gnu.org/licenses/}. - - Home: https://github.com/gorhill/uMatrix -*/ - -/* global chrome, µMatrix */ - -/******************************************************************************/ - -// Asset update manager - -µMatrix.assetUpdater = (function() { - -/******************************************************************************/ - -var getUpdateList = function(callback) { - var localChecksumsText = ''; - var remoteChecksumsText = ''; - - var compareChecksums = function() { - var parseChecksumsText = function(text) { - var result = {}; - var lines = text.split(/\n+/); - var i = lines.length; - var fields; - while ( i-- ) { - fields = lines[i].trim().split(/\s+/); - if ( fields.length !== 2 ) { - continue; - } - result[fields[1]] = fields[0]; - } - return result; - }; - if ( remoteChecksumsText === 'Error' || localChecksumsText === 'Error' ) { - remoteChecksumsText = localChecksumsText = ''; - } - var localAssetChecksums = parseChecksumsText(localChecksumsText); - var remoteAssetChecksums = parseChecksumsText(remoteChecksumsText); - - var toUpdate = {}; - var path; - for ( path in remoteAssetChecksums ) { - if ( !remoteAssetChecksums.hasOwnProperty(path) ) { - continue; - } - if ( localAssetChecksums[path] === undefined ) { - toUpdate[path] = { - status: 'Added', - remoteChecksum: remoteAssetChecksums[path], - localChecksum: '' - }; - continue; - } - if ( localAssetChecksums[path] === remoteAssetChecksums[path] ) { - toUpdate[path] = { - status: 'Unchanged', - remoteChecksum: remoteAssetChecksums[path], - localChecksum: localAssetChecksums[path] - }; - continue; - } - toUpdate[path] = { - status: 'Changed', - remoteChecksum: remoteAssetChecksums[path], - localChecksum: localAssetChecksums[path] - }; - } - for ( path in localAssetChecksums ) { - if ( !localAssetChecksums.hasOwnProperty(path) ) { - continue; - } - if ( remoteAssetChecksums[path] === undefined ) { - toUpdate[path] = { - status: 'Removed', - remoteChecksum: '', - localChecksum: localAssetChecksums[path] - }; - } - } - - callback({ 'list': toUpdate }); - }; - - var validateChecksums = function(details) { - if ( details.error || details.content === '' ) { - return 'Error'; - } - if ( /^(?:[0-9a-f]{32}\s+\S+(\s+|$))+/.test(details.content) ) { - return details.content; - } - return 'Error'; - }; - - var onLocalChecksumsLoaded = function(details) { - localChecksumsText = validateChecksums(details); - if ( remoteChecksumsText !== '' ) { - compareChecksums(); - } - }; - - var onRemoteChecksumsLoaded = function(details) { - remoteChecksumsText = validateChecksums(details); - if ( localChecksumsText !== '' ) { - compareChecksums(); - } - }; - - µMatrix.assets.getRemote('assets/checksums.txt', onRemoteChecksumsLoaded); - µMatrix.assets.get('assets/checksums.txt', onLocalChecksumsLoaded); -}; - -/******************************************************************************/ - -// If `list` is null, it will be fetched internally. - -var update = function(list, callback) { - var assetChangedCount = 0; - var assetProcessedCount; - var updatedAssetChecksums = []; - - var onCompleted = function() { - var details = { - what: 'allLocalAssetsUpdated', - changedCount: assetChangedCount - }; - callback(details); - µMatrix.messaging.announce(details); - }; - - var doCountdown = function() { - assetProcessedCount -= 1; - if ( assetProcessedCount > 0 ) { - return; - } - µMatrix.assets.put( - 'assets/checksums.txt', - updatedAssetChecksums.join('\n'), - onCompleted - ); - chrome.storage.local.set({ 'assetsUpdateTimestamp': Date.now() }); - }; - - var assetUpdated = function(details) { - var path = details.path; - var entry = list[path]; - if ( details.error ) { - updatedAssetChecksums.push(entry.localChecksum + ' ' + path); - } else { - updatedAssetChecksums.push(entry.remoteChecksum + ' ' + path); - assetChangedCount += 1; - } - doCountdown(); - }; - - var processList = function() { - assetProcessedCount = Object.keys(list).length; - if ( assetProcessedCount === 0 ) { - onCompleted(); - return; - } - var entry; - var details = { path: '', md5: '' }; - for ( var path in list ) { - if ( list.hasOwnProperty(path) === false ) { - continue; - } - entry = list[path]; - if ( entry.status === 'Added' || entry.status === 'Changed' ) { - details.path = path; - details.md5 = entry.remoteChecksum; - µMatrix.assets.update(details, assetUpdated); - continue; - } - if ( entry.status === 'Unchanged' ) { - updatedAssetChecksums.push(entry.localChecksum + ' ' + path); - } - doCountdown(); - } - }; - - var listLoaded = function(details) { - list = details.list; - processList(); - }; - - if ( list ) { - processList(); - } else { - getUpdateList(listLoaded); - } -}; - -/******************************************************************************/ - -// Export API - -return { - 'getList': getUpdateList, - 'update': update -}; - -/******************************************************************************/ - -})(); - -/******************************************************************************/ - diff --git a/src/js/background.js b/src/js/background.js index 6b81cf3..aea3a9a 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -27,6 +27,13 @@ var µMatrix = (function() { /******************************************************************************/ +var oneSecond = 1000; +var oneMinute = 60 * oneSecond; +var oneHour = 60 * oneMinute; +var oneDay = 24 * oneHour; + +/******************************************************************************/ + var defaultUserAgentStrings = [ '# http://www.useragentstring.com/pages/Chrome/', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36', @@ -40,6 +47,7 @@ var getDefaultUserAgentStrings = function() { return defaultUserAgentStrings.join('\n'); }; +/******************************************************************************/ return { manifest: chrome.runtime.getManifest(), @@ -73,7 +81,9 @@ return { }, clearBrowserCacheCycle: 0, - updateAssetsEvery: 5 * 24 * 60 * 60 * 1000, + updateAssetsEvery: 11 * oneDay + 1 * oneHour + 1 * oneMinute + 1 * oneSecond, + firstUpdateAfter: 11 * oneMinute, + nextUpdateAfter: 11 * oneHour, projectServerRoot: 'https://raw.githubusercontent.com/gorhill/umatrix/master/', // permanent hosts files diff --git a/src/js/hosts-files.js b/src/js/hosts-files.js index 4a1065a..0dfa0ed 100644 --- a/src/js/hosts-files.js +++ b/src/js/hosts-files.js @@ -162,23 +162,23 @@ var renderBlacklists = function() { hasCachedContent = false; // Visually split the filter lists in two groups: built-in and external - var html = []; + var htmlBuiltin = []; + var htmlExternal = []; var hostsPaths = Object.keys(details.available); - var hostsEntry; - for ( i = 0; i < hostsPaths.length; i++ ) { - hostsPath = hostsPaths[i]; - hostsEntry = details.available[hostsPath]; - if ( !hostsEntry.external ) { - html.push(htmlFromLeaf(hostsPath, hostsEntry)); - } - } - for ( i = 0; i < hostsPaths.length; i++ ) { + var hostsPath, hostsEntry; + for ( var i = 0; i < hostsPaths.length; i++ ) { hostsPath = hostsPaths[i]; hostsEntry = details.available[hostsPath]; if ( hostsEntry.external ) { - html.push(htmlFromLeaf(hostsPath, hostsEntry)); + htmlExternal.push(htmlFromLeaf(hostsPath, hostsEntry)); + } else { + htmlBuiltin.push(htmlFromLeaf(hostsPath, hostsEntry)); } } + if ( htmlExternal.length !== 0 ) { + htmlBuiltin.push('
  •  '); + } + var html = htmlBuiltin.concat(htmlExternal); uDom('#listsOfBlockedHostsPrompt').text( chrome.i18n.getMessage('hostsFilesStats') diff --git a/src/js/info.js b/src/js/info.js index c18e022..dc9ee0c 100644 --- a/src/js/info.js +++ b/src/js/info.js @@ -231,12 +231,8 @@ function renderRequestRow(row, request) { a.css('display', 'none'); } - // reason of why block, if available - $(cells[3]).text('\u00a0'); - $(cells[3]).removeAttr('data-tip'); - // request URL - $(cells[4]).text(request.url); + $(cells[3]).text(request.url); } /*----------------------------------------------------------------------------*/ diff --git a/src/js/messaging-handlers.js b/src/js/messaging-handlers.js index 7c4f3d2..3a5139e 100644 --- a/src/js/messaging-handlers.js +++ b/src/js/messaging-handlers.js @@ -630,14 +630,45 @@ var onMessage = function(request, sender, callback) { (function() { -var onMessage = function(request, sender, callback) { - var µm = µMatrix; +var µm = µMatrix; +/******************************************************************************/ + +var restoreUserData = function(userData) { + var countdown = 3; + var onCountdown = function() { + countdown -= 1; + if ( countdown === 0 ) { + µm.XAL.restart(); + } + }; + + var onAllRemoved = function() { + // Be sure to adjust `countdown` if adding/removing anything below + µm.XAL.keyvalSetMany(userData.settings, onCountdown); + µm.XAL.keyvalSetOne('userMatrix', userData.rules, onCountdown); + µm.XAL.keyvalSetOne('liveHostsFiles', userData.hostsFiles, onCountdown); + }; + + // If we are going to restore all, might as well wipe out clean local + // storage + µm.XAL.keyvalRemoveAll(onAllRemoved); +}; + +/******************************************************************************/ + +var resetUserData = function() { + var onAllRemoved = function() { + µm.XAL.restart(); + }; + µm.XAL.keyvalRemoveAll(onAllRemoved); +}; + +/******************************************************************************/ + +var onMessage = function(request, sender, callback) { // Async switch ( request.what ) { - case 'readUserSettings': - return chrome.storage.local.get(µm.userSettings, callback); - default: break; } @@ -646,13 +677,33 @@ var onMessage = function(request, sender, callback) { var response; switch ( request.what ) { + case 'getAllUserData': + response = { + app: 'µMatrix', + version: µm.manifest.version, + when: Date.now(), + settings: µm.userSettings, + rules: µm.pMatrix.toString(), + hostsFiles: µm.liveHostsFiles + }; + break; + case 'getSomeStats': response = { + version: µm.manifest.version, storageQuota: µm.storageQuota, storageUsed: µm.storageUsed }; break; + case 'restoreAllUserData': + restoreUserData(request.userData); + break; + + case 'resetAllUserData': + resetUserData(); + break; + default: return µm.messaging.defaultHandler(request, sender, callback); } @@ -662,6 +713,8 @@ var onMessage = function(request, sender, callback) { µMatrix.messaging.listen('about.js', onMessage); +/******************************************************************************/ + })(); /******************************************************************************/ diff --git a/src/js/messaging.js b/src/js/messaging.js index c8ac45a..d9d13c6 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -166,7 +166,7 @@ function defaultHandler(request, sender, callback) { break; case 'reloadHostsFiles': - µm.reloadHostsFiles(request.switches); + µm.reloadHostsFiles(request.switches, request.update); break; case 'userSettings': diff --git a/src/js/pagestats.js b/src/js/pagestats.js index 2e19fd0..9b36a4c 100644 --- a/src/js/pagestats.js +++ b/src/js/pagestats.js @@ -20,6 +20,7 @@ */ /* global chrome, µMatrix */ +/* jshint bitwise: false */ /******************************************************************************* @@ -156,7 +157,6 @@ var LogEntry = function() { this.type = ''; this.when = 0; this.block = false; - this.reason = ''; }; var logEntryJunkyard = []; @@ -300,7 +300,7 @@ PageRequestStats.prototype.typeFromRequestKey = typeFromRequestKey; /******************************************************************************/ -PageRequestStats.prototype.createEntryIfNotExists = function(url, type, block) { +PageRequestStats.prototype.createEntryIfNotExists = function(url, type) { var reqKey = makeRequestKey(url, type); if ( this.requests[reqKey] ) { return false; @@ -347,7 +347,7 @@ PageRequestStats.prototype.resizeLogBuffer = function(size) { /******************************************************************************/ -PageRequestStats.prototype.logRequest = function(url, type, block, reason) { +PageRequestStats.prototype.logRequest = function(url, type, block) { var buffer = this.ringBuffer; var len = buffer.length; if ( !len ) { @@ -362,7 +362,6 @@ PageRequestStats.prototype.logRequest = function(url, type, block, reason) { logEntry.type = type; logEntry.when = Date.now(); logEntry.block = block; - logEntry.reason = reason; this.ringBufferPointer = ((pointer + 1) % len) | 0; }; @@ -495,10 +494,7 @@ PageStore.prototype.dispose = function() { /******************************************************************************/ -// rhill 2014-03-11: If `block` !== false, then block.toString() may return -// user legible information about the reason for the block. - -PageStore.prototype.recordRequest = function(type, url, block, reason) { +PageStore.prototype.recordRequest = function(type, url, block) { // TODO: this makes no sense, I forgot why I put this here. if ( !this ) { // console.error('HTTP Switchboard> PageStore.recordRequest(): no pageStats'); @@ -523,7 +519,7 @@ PageStore.prototype.recordRequest = function(type, url, block, reason) { this.perLoadAllowedRequestCount++; } - this.requests.logRequest(url, type, block, reason); + this.requests.logRequest(url, type, block); if ( !this.requests.createEntryIfNotExists(url, type, block) ) { return; @@ -544,7 +540,7 @@ PageStore.prototype.recordRequest = function(type, url, block, reason) { // rhill 2014-03-12: disregard blocking operations which do not originate // from matrix evaluation, or else this can cause a useless reload of the // page if something important was blocked through ABP filtering. - if ( block !== false && reason === undefined ) { + if ( block !== false ) { this.state[type + '|' + hostname] = true; } diff --git a/src/js/storage.js b/src/js/storage.js index 8751308..fb4469d 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -24,8 +24,9 @@ /******************************************************************************/ µMatrix.getBytesInUse = function() { + var µm = this; var getBytesInUseHandler = function(bytesInUse) { - µMatrix.storageUsed = bytesInUse; + µm.storageUsed = bytesInUse; }; chrome.storage.local.getBytesInUse(null, getBytesInUseHandler); }; @@ -33,14 +34,21 @@ /******************************************************************************/ µMatrix.saveUserSettings = function() { - chrome.storage.local.set(this.userSettings, function() { - µMatrix.getBytesInUse(); - }); + chrome.storage.local.set( + this.userSettings, + this.getBytesInUse.bind(this) + ); }; /******************************************************************************/ -µMatrix.loadUserSettings = function() { +µMatrix.loadUserSettings = function(callback) { + var µm = this; + + if ( typeof callback !== 'function' ) { + callback = this.noopFunc; + } + var settingsLoaded = function(store) { // console.log('storage.js > loaded user settings'); @@ -51,19 +59,13 @@ } else if ( store.smartAutoReload === false ) { store.smartAutoReload = 'none'; } - // https://github.com/gorhill/httpswitchboard/issues/250 - if ( typeof store.autoCreateSiteScope === 'boolean' ) { - store.autoCreateScope = store.autoCreateSiteScope ? 'site' : ''; - delete store.autoCreateSiteScope; - } - // https://github.com/gorhill/httpswitchboard/issues/299 - // No longer needed. - delete store.subframeFgColor; - µMatrix.userSettings = store; + µm.userSettings = store; // https://github.com/gorhill/httpswitchboard/issues/344 - µMatrix.userAgentSpoofer.shuffle(); + µm.userAgentSpoofer.shuffle(); + + callback(µm.userSettings); }; chrome.storage.local.get(this.userSettings, settingsLoaded); @@ -319,7 +321,7 @@ // `switches` contains the preset blacklists for which the switch must be // revisited. -µMatrix.reloadHostsFiles = function(switches) { +µMatrix.reloadHostsFiles = function(switches, update) { var liveHostsFiles = this.liveHostsFiles; // Toggle switches @@ -334,19 +336,22 @@ // Save switch states chrome.storage.local.set( { 'liveHostsFiles': liveHostsFiles }, - this.loadHostsFiles.bind(this) + this.loadUpdatableAssets.bind(this, update) ); }; /******************************************************************************/ -µMatrix.loadPublicSuffixList = function() { +µMatrix.loadPublicSuffixList = function(callback) { + if ( typeof callback !== 'function' ) { + callback = this.noopFunc; + } + var applyPublicSuffixList = function(details) { - // TODO: Not getting proper suffix list is a bit serious, I think - // the extension should be force-restarted if it occurs.. if ( !details.error ) { publicSuffixList.parse(details.content, punycode.toASCII); } + callback(); }; this.assets.get( 'assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat', @@ -358,9 +363,14 @@ // Load updatable assets -µMatrix.loadUpdatableAssets = function() { - this.loadHostsFiles(); +µMatrix.loadUpdatableAssets = function(forceUpdate) { + this.assets.autoUpdate = forceUpdate === true; + this.assets.autoUpdateDelay = this.updateAssetsEvery; + if ( forceUpdate ) { + this.updater.restart(); + } this.loadPublicSuffixList(); + this.loadHostsFiles(); }; /******************************************************************************/ @@ -368,10 +378,20 @@ // Load all µMatrix.load = function() { - this.loadUserSettings(); - this.loadMatrix(); - this.loadUpdatableAssets(); + var µm = this; + // User settings are in memory + var onUserSettingsReady = function(settings) { + // Never auto-update at boot time + µm.loadUpdatableAssets(false); + + // Setup auto-updater, earlier if auto-upate is enabled, later if not + if ( settings.autoUpdate ) { + µm.updater.restart(µm.firstUpdateAfter); + } + }; + + this.loadUserSettings(onUserSettingsReady); + this.loadMatrix(); this.getBytesInUse(); }; - diff --git a/src/js/traffic.js b/src/js/traffic.js index 15b1ea5..2576788 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -288,7 +288,6 @@ var processRequest = function(µm, details) { // Block request? var block = µm.mustBlock(µm.scopeFromURL(pageURL), requestHostname, requestType); - var reason; // Record request. // https://github.com/gorhill/httpswitchboard/issues/342 @@ -296,7 +295,7 @@ var processRequest = function(µm, details) { // processing has already been performed, and that a synthetic URL has // been constructed for logging purpose. Use this synthetic URL if // it is available. - pageStats.recordRequest(requestType, details.µmRequestURL || requestURL, block, false); + pageStats.recordRequest(requestType, details.µmRequestURL || requestURL, block); // whitelisted? if ( !block ) { @@ -883,7 +882,7 @@ chrome.webRequest.onBeforeRequest.addListener( [ "blocking" ] ); -console.log('µMatrix > Beginning to intercept net requests at %s', (new Date()).toISOString()); +//console.log('µMatrix > Beginning to intercept net requests at %s', (new Date()).toISOString()); chrome.webRequest.onBeforeSendHeaders.addListener( onBeforeSendHeadersHandler, diff --git a/src/js/updater.js b/src/js/updater.js new file mode 100644 index 0000000..1bb300d --- /dev/null +++ b/src/js/updater.js @@ -0,0 +1,105 @@ +/******************************************************************************* + + µMatrix - a Chromium browser extension to black/white list requests. + Copyright (C) 2014 Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uMatrix +*/ + +/* global µMatrix */ + +/******************************************************************************/ + +// Automatic update of non-user assets +// https://github.com/gorhill/httpswitchboard/issues/334 + +µMatrix.updater = (function() { + +/******************************************************************************/ + +var µm = µMatrix; + +var jobCallback = function() { + // Simpler to fire restart here, and safe given how far this will happen + // in the future. + restart(); + + // If auto-update is disabled, check again in a while. + if ( µm.userSettings.autoUpdate !== true ) { + return; + } + + var onMetadataReady = function(metadata) { + // Check PSL + var mdEntry = metadata[µm.pslPath]; + if ( mdEntry.repoObsolete ) { + µm.loadUpdatableAssets(true); + return; + } + // Check used hosts files + var hostsFiles = µm.liveHostsFiles; + for ( var path in hostsFiles ) { + if ( hostsFiles.hasOwnProperty(path) === false ) { + continue; + } + if ( hostsFiles[path].off ) { + continue; + } + if ( metadata.hasOwnProperty(path) === false ) { + continue; + } + mdEntry = metadata[path]; + if ( mdEntry.cacheObsolete || mdEntry.repoObsolete ) { + µm.loadUpdatableAssets(true); + return; + } + } + + // console.log('updater.js > all is up to date'); + }; + + µm.assets.metadata(onMetadataReady); +}; + +// https://www.youtube.com/watch?v=cIrGQD84F1g + +/******************************************************************************/ + +var restart = function(after) { + if ( after === undefined ) { + after = µm.nextUpdateAfter; + } + + µm.asyncJobs.add( + 'autoUpdateAssets', + null, + jobCallback, + after, + false + ); +}; + +/******************************************************************************/ + +return { + restart: restart +}; + +/******************************************************************************/ + +})(); + +/******************************************************************************/ diff --git a/tools/_locales/de/messages.json b/tools/_locales/de/messages.json index 8535986..99c2fa7 100644 --- a/tools/_locales/de/messages.json +++ b/tools/_locales/de/messages.json @@ -483,143 +483,37 @@ "message": "Deine Daten", "description": "English: Your data" }, - "aboutUserDataBackupButton" : { - "message": "Backup in eine Datei...", + "aboutBackupButton" : { + "message": "Backup to file...", "description": "English: Backup all..." }, - "aboutUserDataRestoreButton" : { - "message": "Aus einer Datei wiederherstellen...", + "aboutBackupFilename" : { + "message": "all-my-umatrix-data.txt", + "description": "all-my-umatrix-data.txt" + }, + "aboutRestoreButton" : { + "message": "Restore from file...", "description": "English: Restore all..." }, - "aboutUserDataOr" : { - "message": "... oder ...", - "description": "English: ... or ..." - }, - "aboutUserDataResetButton" : { - "message": "Fange von ganz vorne an ...", - "description": "English: Start from scratch..." - }, - "aboutUserDataRestoreConfirm" : { - "message": "Alle deine Einstellungen und Regeln werden überschrieben\nmit Daten gesichert am {{time}},\nund µMatrix wird neu starten.\n\nSollen alle existierenden Daten mit Backup-Daten überschrieben werden?", + "aboutRestoreConfirm" : { + "message": "All your settings will be overwritten using data backed up on {{time}}, and µMatrix will restart.\n\nOverwrite all existing settings using backed up data?", "description": "Message asking user to confirm restore" }, - "aboutExtensionDataHeader" : { - "message": "Externe Ressourcen dieser Erweiterung", - "description": "English: Extension data" + "aboutRestoreError" : { + "message": "The data could not be read or is invalid", + "description": "" }, - "aboutAssetsUpdatePrompt" : { - "message": "Von µMatrix benutzte externe Ressourcen können hier upgedatet werden, ohne auf eine neue Version dieser Erweiterung warten zu müssen. Diese Ressourcen werden bezogen vom Github Repository dieses Projekts.", - "description": "Short descriptive text of the update feature" + "aboutOr" : { + "message": "... or ...", + "description": "English: ... or ..." }, - "aboutAssetsUpdateColPath" : { - "message": "Pfad", - "description": "Path column header" + "aboutResetButton" : { + "message": "Reset to default settings", + "description": "English: Reset to default settings" }, - "aboutAssetsUpdateColStatus" : { - "message": "Status", - "description": "Status column header" - }, - "aboutAssetsUpdateGetListError" : { - "message": "Ein Fehler ist aufgetreten. Ist XHR blockiert für raw2.github.com?", - "description": "Successful outcome of clicking 'update' button" - }, - "aboutAssetsUpdateStatusAdded" : { - "message": "Hinzufügen", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusChanged" : { - "message": "Neue Version verfügbar", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusUnchanged" : { - "message": "Up-to-date", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusRemoved" : { - "message": "Entfernen", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateButton" : { - "message": "Update", - "description": "Update button" - }, - "aboutAssetsUpdatingButton" : { - "message": "Updating...", - "description": "Updating..." - }, - - - "setupPagePrompt" : { - "message": "

    µMatrix ist hochgradig konfigurierbar: Die Einstellungen können fast beliebig gesetzt werden zwischen den beiden Extremen “alles blockieren” und “nichts blockieren”.

    Je höher die Sicherheit, desto höher die Wahrscheinlichkeit, dass Webseiten “nicht funktionieren”, d.h. sie werden nicht gerendert und/oder verhalten sich nicht wie gewünscht. Daher bedeutet höhere Sicherheit auch mehr notwendige Interventionen durch den Benutzer, damit vertrauenswürdige Webseiten wieder “funktionieren”.

    Hier kannst du ein Profil wählen, das am besten zu dem passt, wie du gedenkst, µMatrix zu benutzen. Bitte berücksichtige, dass diese Profile lediglich einen Startpunkt repräsentieren, den du später beliebig an deine Vorstellungen anpassen kannst .", - "description": "Appears at the top of the setup page" - }, - "setupBlockAllAllowExceptionally" : { - "message": "Blockiere alles / erlaube ausnahmsweise", - "description": "English: Block all / allow exceptionally" - }, - "setupAllowAllBlockExceptionally" : { - "message": "Erlaube alles / blockiere ausnahmsweise", - "description": "English: Allow all / block exceptionally" - }, - "setupAdBlocker" : { - "message": "Benutzen als Werbeblocker", - "description": "English: Ad blocker-like" - }, - "setupNoScript" : { - "message": "Verhalten wie NoScript", - "description": "English: NoScript-like" - }, - "setupRequestPolicy" : { - "message": "Verhalten wie RequestPolicy", - "description": "English: RequestPolicy-like" - }, - "setupBlockNothingReportAll" : { - "message": "Blockiere nichts / melde alles", - "description": "English: Block nothing / report everything" - }, - "setupSecurity" : { - "message": "Sicherheit:", - "description": "English: Security:" - }, - "setupBreakage" : { - "message": "Bruchgefahr:", - "description": "English: Breakage:" - }, - "setupVeryHigh" : { - "message": "sehr hoch", - "description": "English: very high" - }, - "setupHigh" : { - "message": "hoch", - "description": "English: high" - }, - "setupMediumHigh" : { - "message": "mittel - hoch", - "description": "English: medium high" - }, - "setupMedium" : { - "message": "mittel", - "description": "English: medium" - }, - "setupMediumLow" : { - "message": "mittel - niedrig", - "description": "English: medium low" - }, - "setupLow" : { - "message": "niedrig", - "description": "English: low" - }, - "setupVeryLow" : { - "message": "sehr niedrig", - "description": "English: very low" - }, - "setupNone" : { - "message": "gar nicht", - "description": "English: none" - }, - "setupRestoreConfirm" : { - "message": "Alle deine Einstellungen und Regeln werden überschrieben\nund µMatrix wird neu starten.\n\nAlle existierenden Daten überschreiben?", - "description": "English: All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?" + "aboutResetConfirm" : { + "message": "Caution! this will also remove all your custom settings. Are you sure you want to proceed?", + "description": "Message asking user to confirm reset" }, diff --git a/tools/_locales/en/messages.json b/tools/_locales/en/messages.json index 56cdb0f..94ba644 100644 --- a/tools/_locales/en/messages.json +++ b/tools/_locales/en/messages.json @@ -460,12 +460,12 @@ "aboutChangelog" : { - "message": "Change log", - "description": "English: Change log" + "message": "Change log", + "description": "English: Change log" }, "aboutStorageUsed" : { - "message": "Storage used: {{storageUsed}}%", - "description": "English: Storage used: {{storageUsed}}%" + "message": "Storage used: {{storageUsed}} bytes", + "description": "English: Storage used: {{storageUsed}} bytes" }, "aboutDoc" : { "message": "Documentation", @@ -476,154 +476,48 @@ "description": "English: Permissions" }, "aboutCode" : { - "message": "Source code (GPLv3)", - "description": "English: Source code (GPLv3)" + "message": "Source code (GPLv3)", + "description": "English: Source code (GPLv3)" }, "aboutCredits" : { - "message": "Credits", - "description": "English: Credits" + "message": "Credits", + "description": "English: Credits" }, "aboutUserDataHeader" : { "message": "Your data", "description": "English: Your data" }, - "aboutUserDataBackupButton" : { + "aboutBackupButton" : { "message": "Backup to file...", "description": "English: Backup all..." }, - "aboutUserDataRestoreButton" : { + "aboutBackupFilename" : { + "message": "all-my-umatrix-data.txt", + "description": "all-my-umatrix-data.txt" + }, + "aboutRestoreButton" : { "message": "Restore from file...", "description": "English: Restore all..." }, - "aboutUserDataOr" : { + "aboutRestoreConfirm" : { + "message": "All your settings will be overwritten using data backed up on {{time}}, and µMatrix will restart.\n\nOverwrite all existing settings using backed up data?", + "description": "Message asking user to confirm restore" + }, + "aboutRestoreError" : { + "message": "The data could not be read or is invalid", + "description": "" + }, + "aboutOr" : { "message": "... or ...", "description": "English: ... or ..." }, - "aboutUserDataResetButton" : { - "message": "Start from scratch...", - "description": "English: Start from scratch..." + "aboutResetButton" : { + "message": "Reset to default settings", + "description": "English: Reset to default settings" }, - "aboutUserDataRestoreConfirm" : { - "message": "All your settings and rules will be overwritten\nusing data backed up on {{time}},\nand µMatrix will restart.\n\nOverwrite all existing data using backed up data?", - "description": "Message asking user to confirm restore" - }, - "aboutExtensionDataHeader" : { - "message": "Extension data", - "description": "English: Extension data" - }, - "aboutAssetsUpdatePrompt" : { - "message": "µMatrix assets can be updated here without having to wait for the next release of the extension. These assets are pulled from the project's Github repository.", - "description": "Short descriptive text of the update feature" - }, - "aboutAssetsUpdateColPath" : { - "message": "Path", - "description": "Path column header" - }, - "aboutAssetsUpdateColStatus" : { - "message": "Status", - "description": "Status column header" - }, - "aboutAssetsUpdateGetListError" : { - "message": "An error occurred. Is XHR blocked for raw2.github.com?", - "description": "Successful outcome of clicking 'update' button" - }, - "aboutAssetsUpdateStatusAdded" : { - "message": "To add", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusChanged" : { - "message": "New version available", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusUnchanged" : { - "message": "Up to date", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusRemoved" : { - "message": "To remove", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateButton" : { - "message": "Update", - "description": "Update button" - }, - "aboutAssetsUpdatingButton" : { - "message": "Updating...", - "description": "Updating..." - }, - - - "setupPagePrompt" : { - "message": "

    µMatrix is highly configurable: it can be set anywhere between “block everything” and “block nothing”.

    The higher the security, the more likely web pages will be “broken”, i.e. will not render and/or behave as intended. Thus, higher security also means more intervention required from the user in order to “unbreak” those web pages which a user trust.

    Here you can pick a profile which best matches how you plan to use µMatrix. Consider these a starting point, as you can customize at will afterward.", - "description": "Appears at the top of the setup page" - }, - "setupBlockAllAllowExceptionally" : { - "message": "Block all / allow exceptionally", - "description": "English: Block all / allow exceptionally" - }, - "setupAllowAllBlockExceptionally" : { - "message": "Allow all / block exceptionally", - "description": "English: Allow all / block exceptionally" - }, - "setupAdBlocker" : { - "message": "Ad blocker-like", - "description": "English: Ad blocker-like" - }, - "setupNoScript" : { - "message": "NoScript-like", - "description": "English: NoScript-like" - }, - "setupRequestPolicy" : { - "message": "RequestPolicy-like", - "description": "English: RequestPolicy-like" - }, - "setupBlockNothingReportAll" : { - "message": "Block nothing / report everything", - "description": "English: Block nothing / report everything" - }, - "setupSecurity" : { - "message": "Security:", - "description": "English: Security:" - }, - "setupBreakage" : { - "message": "Breakage:", - "description": "English: Breakage:" - }, - "setupVeryHigh" : { - "message": "very high", - "description": "English: very high" - }, - "setupHigh" : { - "message": "high", - "description": "English: high" - }, - "setupMediumHigh" : { - "message": "medium high", - "description": "English: medium high" - }, - "setupMedium" : { - "message": "medium", - "description": "English: medium" - }, - "setupMediumLow" : { - "message": "medium low", - "description": "English: medium low" - }, - "setupLow" : { - "message": "low", - "description": "English: low" - }, - "setupVeryLow" : { - "message": "very low", - "description": "English: very low" - }, - "setupNone" : { - "message": "none", - "description": "English: none" - }, - "setupRestoreConfirm" : { - "message": "All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?", - "description": "English: All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?" + "aboutResetConfirm" : { + "message": "Caution! this will also remove all your custom settings. Are you sure you want to proceed?", + "description": "Message asking user to confirm reset" }, diff --git a/tools/_locales/fr/messages.json b/tools/_locales/fr/messages.json index 6c6b68b..5fe1bb9 100644 --- a/tools/_locales/fr/messages.json +++ b/tools/_locales/fr/messages.json @@ -483,143 +483,37 @@ "message": "Vos réglages", "description": "English: Your data" }, - "aboutUserDataBackupButton" : { - "message": "Exporter vers un fichier", - "description": "English: Backup to file..." + "aboutBackupButton" : { + "message": "Backup to file...", + "description": "English: Backup all..." }, - "aboutUserDataRestoreButton" : { - "message": "Importer depuis un fichier", - "description": "English: Restore from file..." + "aboutBackupFilename" : { + "message": "all-my-umatrix-data.txt", + "description": "all-my-umatrix-data.txt" }, - "aboutUserDataOr" : { - "message": "Ou alors vous pouvez...", - "description": "English: ... or ..." + "aboutRestoreButton" : { + "message": "Restore from file...", + "description": "English: Restore all..." }, - "aboutUserDataResetButton" : { - "message": "Repartir à zéro", - "description": "English: Start from scratch..." - }, - "aboutUserDataRestoreConfirm" : { - "message": "Vos paramètres et vos règles seront remplacés\npar les données sauvegardées le {{time}},\n puis µMatrix redémarrera.\n\nProcéder à l'importation ?", + "aboutRestoreConfirm" : { + "message": "All your settings will be overwritten using data backed up on {{time}}, and µMatrix will restart.\n\nOverwrite all existing settings using backed up data?", "description": "Message asking user to confirm restore" }, - "aboutExtensionDataHeader" : { - "message": "Données de l'extension", - "description": "English: Extension data" + "aboutRestoreError" : { + "message": "The data could not be read or is invalid", + "description": "" }, - "aboutAssetsUpdatePrompt" : { - "message": "Les éléments dynamiques, comprenant entre autres listes d'hôtes à bloquer et recettes prédéfinies, peuvent être mis à jour ici sans avoir à attendre la prochaine version de µMatrix. Le processus s'effectue à partir de la page du projet sur Github.", - "description": "Short descriptive text of the update feature" + "aboutOr" : { + "message": "... or ...", + "description": "English: ... or ..." }, - "aboutAssetsUpdateColPath" : { - "message": "Élément dynamique", - "description": "Path column header" + "aboutResetButton" : { + "message": "Reset to default settings", + "description": "English: Reset to default settings" }, - "aboutAssetsUpdateColStatus" : { - "message": "État", - "description": "Status column header" - }, - "aboutAssetsUpdateGetListError" : { - "message": "Une erreur est survenue. Veuillez vous assurer que les requêtes de type XHR ne soient pas bloquées pour raw2.github.com", - "description": "Successful outcome of clicking 'update' button" - }, - "aboutAssetsUpdateStatusAdded" : { - "message": "À ajouter", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusChanged" : { - "message": "Nouvelle version disponible", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusUnchanged" : { - "message": "À jour", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusRemoved" : { - "message": "À supprimer", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateButton" : { - "message": "Mettre à jour", - "description": "Update button" - }, - "aboutAssetsUpdatingButton" : { - "message": "Mise à jour en cours...", - "description": "Updating..." - }, - - - "setupPagePrompt" : { - "message": "

    µMatrix est hautement personnalisable : il peut être paramétré pour faire du “Blocage total” comme du “Blocage inactif”.

    Plus les pages Web sont sécurisées, plus elles risquent d'être “compromises”, c'est-à-dire qu'elles n'auront pas un rendu/comportement attendu. Ainsi, une sécurité forte implique plus d'interventions de la part de l'utilisateur pour “faire remarcher” les pages Web jugées fiables par l'utilisateur.

    Ici, vous pouvez choisir un profil correspondant le mieux à votre intention d'utiliser µMatrix. Pensez cela comme un point de départ, paramétrable à volonté par la suite !", - "description": "Appears at the top of the setup page" - }, - "setupBlockAllAllowExceptionally" : { - "message": "Blocage total / Permissions exceptionnelles", - "description": "English: Block all / allow exceptionally" - }, - "setupAllowAllBlockExceptionally" : { - "message": "Permission totale / Blocage exceptionnel", - "description": "English: Allow all / block exceptionally" - }, - "setupAdBlocker" : { - "message": "Façon Adblock", - "description": "English: Ad blocker-like" - }, - "setupNoScript" : { - "message": "Façon NoScript", - "description": "English: NoScript-like" - }, - "setupRequestPolicy" : { - "message": "Façon RequestPolicy", - "description": "English: RequestPolicy-like" - }, - "setupBlockNothingReportAll" : { - "message": "Blocage inactif / Tout rapporter", - "description": "English: Block nothing / report everything" - }, - "setupSecurity" : { - "message": "Sécurité :", - "description": "English: Security:" - }, - "setupBreakage" : { - "message": "Compromission :", - "description": "English: Breakage:" - }, - "setupVeryHigh" : { - "message": "Très élevée", - "description": "English: very high" - }, - "setupHigh" : { - "message": "Élevée", - "description": "English: high" - }, - "setupMediumHigh" : { - "message": "Assez élevée", - "description": "English: medium high" - }, - "setupMedium" : { - "message": "Moyenne", - "description": "English: medium" - }, - "setupMediumLow" : { - "message": "Assez faible", - "description": "English: medium low" - }, - "setupLow" : { - "message": "Faible", - "description": "English: low" - }, - "setupVeryLow" : { - "message": "Très faible", - "description": "English: very low" - }, - "setupNone" : { - "message": "Inexistante", - "description": "English: none" - }, - "setupRestoreConfirm" : { - "message": "Tous vos paramètres et toutes vos règles seront remplacés\net µMatrix va redémarrer.\n\nRemplacer les données existantes ?", - "description": "English: All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?" + "aboutResetConfirm" : { + "message": "Caution! this will also remove all your custom settings. Are you sure you want to proceed?", + "description": "Message asking user to confirm reset" }, diff --git a/tools/_locales/ru/messages.json b/tools/_locales/ru/messages.json index c0cb4bd..edc6751 100644 --- a/tools/_locales/ru/messages.json +++ b/tools/_locales/ru/messages.json @@ -483,143 +483,37 @@ "message": "Ваши настройки", "description": "English: Your data" }, - "aboutUserDataBackupButton" : { - "message": "Сохранить в файл...", + "aboutBackupButton" : { + "message": "Backup to file...", "description": "English: Backup all..." }, - "aboutUserDataRestoreButton" : { - "message": "Восстановить из файла...", + "aboutBackupFilename" : { + "message": "all-my-umatrix-data.txt", + "description": "all-my-umatrix-data.txt" + }, + "aboutRestoreButton" : { + "message": "Restore from file...", "description": "English: Restore all..." }, - "aboutUserDataOr" : { - "message": "... или ...", - "description": "English: ... or ..." - }, - "aboutUserDataResetButton" : { - "message": "Запустить настройку с нуля...", - "description": "English: Start from scratch..." - }, - "aboutUserDataRestoreConfirm" : { - "message": "Все ваши настройки и правила будет перезаписаны\nданными от {{time}},\nи µMatrix перезапустится.\n\nПерезаписать все существующие данные резервной копией?", + "aboutRestoreConfirm" : { + "message": "All your settings will be overwritten using data backed up on {{time}}, and µMatrix will restart.\n\nOverwrite all existing settings using backed up data?", "description": "Message asking user to confirm restore" }, - "aboutExtensionDataHeader" : { - "message": "Данные расширения", - "description": "English: Extension data" + "aboutRestoreError" : { + "message": "The data could not be read or is invalid", + "description": "" }, - "aboutAssetsUpdatePrompt" : { - "message": "µMatrix подписки могут быть обновлены здесь вручную, если не хотите ждать новой версии расширения. Они загружаются из Github хранилища.", - "description": "Short descriptive text of the update feature" + "aboutOr" : { + "message": "... or ...", + "description": "English: ... or ..." }, - "aboutAssetsUpdateColPath" : { - "message": "Путь", - "description": "Path column header" + "aboutResetButton" : { + "message": "Reset to default settings", + "description": "English: Reset to default settings" }, - "aboutAssetsUpdateColStatus" : { - "message": "Состояние", - "description": "Status column header" - }, - "aboutAssetsUpdateGetListError" : { - "message": "Произошла ошибка. XHR заблокирован для raw2.github.com?", - "description": "Successful outcome of clicking 'update' button" - }, - "aboutAssetsUpdateStatusAdded" : { - "message": "Добавить", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusChanged" : { - "message": "Доступно обновление", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusUnchanged" : { - "message": "Обновлений не найдено", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusRemoved" : { - "message": "Для удаления", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateButton" : { - "message": "Обновить", - "description": "Update button" - }, - "aboutAssetsUpdatingButton" : { - "message": "Обновление...", - "description": "Updating..." - }, - - - "setupPagePrompt" : { - "message": "

    µMatrix можно гибко настроить: в любом месте можно уставновить “блокирование всего” и “ничего не блокировать”.

    Чем выше безопасность, тем больше вероятность “поломки” сайтов, это означает, что сайт будет загружаться не полностью или вести себя не так, как задумавал создатель. Поэтому скорее всего потребуется вмешательство пользователя, чтобы “починить” эти страницы, которым пользователь доверяет, разрешив в матрице данные необходимые для нормальной работы сайта.

    Здесь вы можете выбрать готовый профиль, как будет работать µMatrix. Можно считать это начальной настройкой т.к. дальше их можно дополнять для конкретных сайтов отдельно.", - "description": "Appears at the top of the setup page" - }, - "setupBlockAllAllowExceptionally" : { - "message": "Блокировать все / разрешать исключения", - "description": "English: Block all / allow exceptionally" - }, - "setupAllowAllBlockExceptionally" : { - "message": "Разрешить все / блокировать исключения", - "description": "English: Allow all / block exceptionally" - }, - "setupAdBlocker" : { - "message": "Как блокировщик рекламы", - "description": "English: Ad blocker-like" - }, - "setupNoScript" : { - "message": "Как блокировщик скриптов", - "description": "English: NoScript-like" - }, - "setupRequestPolicy" : { - "message": "Как политика запросов", - "description": "English: RequestPolicy-like" - }, - "setupBlockNothingReportAll" : { - "message": "Ничего не блокировать / докладывать обо всем", - "description": "English: Block nothing / report everything" - }, - "setupSecurity" : { - "message": "Безопасность:", - "description": "English: Security:" - }, - "setupBreakage" : { - "message": "Вероятность неправильного отображения сайта::", - "description": "English: Breakage:" - }, - "setupVeryHigh" : { - "message": "очень высокая", - "description": "English: very high" - }, - "setupHigh" : { - "message": "высокая", - "description": "English: high" - }, - "setupMediumHigh" : { - "message": "выше среднего", - "description": "English: medium high" - }, - "setupMedium" : { - "message": "средняя", - "description": "English: medium" - }, - "setupMediumLow" : { - "message": "ниже среднего", - "description": "English: medium low" - }, - "setupLow" : { - "message": "низкая", - "description": "English: low" - }, - "setupVeryLow" : { - "message": "очень низкая", - "description": "English: very low" - }, - "setupNone" : { - "message": "ни влияет", - "description": "English: none" - }, - "setupRestoreConfirm" : { - "message": "Все ваши правила и настройки будут перезаписаны\nи µMatrix перезапустится.\n\nПерезаписать существующие настройки?", - "description": "English: All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?" + "aboutResetConfirm" : { + "message": "Caution! this will also remove all your custom settings. Are you sure you want to proceed?", + "description": "Message asking user to confirm reset" }, diff --git a/tools/_locales/zh_CN/messages.json b/tools/_locales/zh_CN/messages.json index 082ae0d..73be8a0 100644 --- a/tools/_locales/zh_CN/messages.json +++ b/tools/_locales/zh_CN/messages.json @@ -483,143 +483,37 @@ "message": "您的数据", "description": "English: Your data" }, - "aboutUserDataBackupButton" : { - "message": "备份到文件...", + "aboutBackupButton" : { + "message": "Backup to file...", "description": "English: Backup all..." }, - "aboutUserDataRestoreButton" : { - "message": "从文件恢复...", + "aboutBackupFilename" : { + "message": "all-my-umatrix-data.txt", + "description": "all-my-umatrix-data.txt" + }, + "aboutRestoreButton" : { + "message": "Restore from file...", "description": "English: Restore all..." }, - "aboutUserDataOr" : { - "message": "... 或者 ...", - "description": "English: ... or ..." - }, - "aboutUserDataResetButton" : { - "message": "从头来过……", - "description": "English: Start from scratch..." - }, - "aboutUserDataRestoreConfirm" : { - "message": "所有您的设置和规则将被覆盖,\n使用备份于{{time}}时的数据,\n随后µMatrix将会重启。\n\n是否要使用备份数据覆盖所有现存数据?", + "aboutRestoreConfirm" : { + "message": "All your settings will be overwritten using data backed up on {{time}}, and µMatrix will restart.\n\nOverwrite all existing settings using backed up data?", "description": "Message asking user to confirm restore" }, - "aboutExtensionDataHeader" : { - "message": "扩展数据", - "description": "English: Extension data" + "aboutRestoreError" : { + "message": "The data could not be read or is invalid", + "description": "" }, - "aboutAssetsUpdatePrompt" : { - "message": "µMatrix使用的资源可以在这里进行升级,而不必等到扩展的下一个发行版。这些资源是拉取自本项目的Github代码托管库。", - "description": "Short descriptive text of the update feature" + "aboutOr" : { + "message": "... or ...", + "description": "English: ... or ..." }, - "aboutAssetsUpdateColPath" : { - "message": "路径", - "description": "Path column header" + "aboutResetButton" : { + "message": "Reset to default settings", + "description": "English: Reset to default settings" }, - "aboutAssetsUpdateColStatus" : { - "message": "状态", - "description": "Status column header" - }, - "aboutAssetsUpdateGetListError" : { - "message": "有一个错误发生。raw2.github.comXHR是否被屏蔽?", - "description": "Successful outcome of clicking 'update' button" - }, - "aboutAssetsUpdateStatusAdded" : { - "message": "将被添加", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusChanged" : { - "message": "有新版本", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusUnchanged" : { - "message": "已是最新", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateStatusRemoved" : { - "message": "将被移除", - "description": "Displayed in the status column for each entry" - }, - "aboutAssetsUpdateButton" : { - "message": "马上更新", - "description": "Update button" - }, - "aboutAssetsUpdatingButton" : { - "message": "正在更新...", - "description": "Updating..." - }, - - - "setupPagePrompt" : { - "message": "

    µMatrix是高度可配置的:它可以被设置为“屏蔽所有”和“完全不屏蔽”间的任何状态。

    安全性越高,网页破损的可能性也就越高,即不能如设想的一样渲染或运作。因此,更高的安全性也意味着需要更多来自用户的介入,来“修复”那些用户信任的网页。

    这里您可以选择一个最适合您使用µMatrix计划的设定档。您只需把这当作一个起点,因为您之后仍可随意自行定制。", - "description": "Appears at the top of the setup page" - }, - "setupBlockAllAllowExceptionally" : { - "message": "屏蔽所有 / 允许例外", - "description": "English: Block all / allow exceptionally" - }, - "setupAllowAllBlockExceptionally" : { - "message": "允许所有 / 屏蔽例外", - "description": "English: Allow all / block exceptionally" - }, - "setupAdBlocker" : { - "message": "类似Adblock Plus", - "description": "English: Ad blocker-like" - }, - "setupNoScript" : { - "message": "类似NoScript", - "description": "English: NoScript-like" - }, - "setupRequestPolicy" : { - "message": "类似RequestPolicy", - "description": "English: RequestPolicy-like" - }, - "setupBlockNothingReportAll" : { - "message": "完全不屏蔽 / 报告所有", - "description": "English: Block nothing / report everything" - }, - "setupSecurity" : { - "message": "安全性:", - "description": "English: Security:" - }, - "setupBreakage" : { - "message": "不兼容性:", - "description": "English: Breakage:" - }, - "setupVeryHigh" : { - "message": "非常高", - "description": "English: very high" - }, - "setupHigh" : { - "message": "高", - "description": "English: high" - }, - "setupMediumHigh" : { - "message": "中高", - "description": "English: medium high" - }, - "setupMedium" : { - "message": "中等", - "description": "English: medium" - }, - "setupMediumLow" : { - "message": "中低", - "description": "English: medium low" - }, - "setupLow" : { - "message": "低", - "description": "English: low" - }, - "setupVeryLow" : { - "message": "非常低", - "description": "English: very low" - }, - "setupNone" : { - "message": "无", - "description": "English: none" - }, - "setupRestoreConfirm" : { - "message": "所有您的设置和规则将被覆盖,\n然后µMatrix将会重启。\n\n是否要覆盖所有现存数据?", - "description": "English: All your settings and rules will be overwritten\nand µMatrix will restart.\n\nOverwrite all existing data?" + "aboutResetConfirm" : { + "message": "Caution! this will also remove all your custom settings. Are you sure you want to proceed?", + "description": "Message asking user to confirm reset" },