Browse Source

literal "1st-party" row removes the need for auto-whitelist, strict blocking

pull/2/head
gorhill 10 years ago
parent
commit
78555a5b7c
  1. 20
      src/css/popup.css
  2. 2
      src/js/background.js
  3. 19
      src/js/commands.js
  4. 12
      src/js/httpsb.js
  5. 112
      src/js/matrix.js
  6. 3
      src/js/messaging-handlers.js
  7. 154
      src/js/popup.js
  8. 38
      src/js/profiler.js
  9. 23
      src/js/traffic.js
  10. 17
      src/settings.html
  11. 52
      tools/_locales/de/messages.json
  12. 52
      tools/_locales/en/messages.json
  13. 52
      tools/_locales/fr/messages.json
  14. 52
      tools/_locales/ru/messages.json
  15. 52
      tools/_locales/zh_CN/messages.json

20
src/css/popup.css

@ -340,7 +340,7 @@ body.tScopeNarrow #scopeCell {
.matrix .matGroup.g0 .matSection:first-child { .matrix .matGroup.g0 .matSection:first-child {
margin-top: 0; margin-top: 0;
} }
.matrix .matGroup.g3 .matSection:first-child {
.matrix .matGroup.g4 .matSection:first-child {
margin-top: 0; margin-top: 0;
} }
/* Collapsing of domains */ /* Collapsing of domains */
@ -358,7 +358,7 @@ body.tScopeNarrow #scopeCell {
} }
/* Collapsing of blacklisted */ /* Collapsing of blacklisted */
.matrix .g3Meta {
.matrix .g4Meta {
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
@ -368,29 +368,29 @@ body.tScopeNarrow #scopeCell {
opacity: 0.2; opacity: 0.2;
cursor: pointer; cursor: pointer;
} }
.matrix .g3Meta:hover {
.matrix .g4Meta:hover {
opacity: 0.4; opacity: 0.4;
} }
.matrix .g3Meta.g3Collapsed {
.matrix .g4Meta.g4Collapsed {
background: url('/img/matrix-group-show.png') no-repeat center top, background: url('/img/matrix-group-show.png') no-repeat center top,
url('/img/matrix-group-hline.png') repeat-x center top 3px; url('/img/matrix-group-hline.png') repeat-x center top 3px;
} }
.matrix .g3Meta.g3Collapsed ~ .matSection {
.matrix .g4Meta.g4Collapsed ~ .matSection {
display: none; display: none;
} }
body.powerOff .matrix .g3Meta.g3Collapsed ~ .matSection {
body.powerOff .matrix .g4Meta.g4Collapsed ~ .matSection {
display: block; display: block;
} }
.matrix .g3Meta ~ .matRow.ro {
.matrix .g4Meta ~ .matRow.ro {
display: none; display: none;
} }
.matrix .g3Meta.g3Collapsed ~ .matRow.ro {
.matrix .g4Meta.g4Collapsed ~ .matRow.ro {
display: block; display: block;
} }
body.powerOff .matrix .g3Meta.g3Collapsed ~ .matRow.ro {
body.powerOff .matrix .g4Meta.g4Collapsed ~ .matRow.ro {
display: none; display: none;
} }
.matrix .matGroup .g3Meta + *,.matrix .matGroup .g3Meta + * + * {
.matrix .matGroup .g4Meta + *,.matrix .matGroup .g4Meta + * + * {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }

2
src/js/background.js

@ -45,7 +45,6 @@ return {
manifest: chrome.runtime.getManifest(), manifest: chrome.runtime.getManifest(),
userSettings: { userSettings: {
autoWhitelistPageDomain: false,
clearBrowserCache: true, clearBrowserCache: true,
clearBrowserCacheAfter: 60, clearBrowserCacheAfter: 60,
colorBlindFriendly: false, colorBlindFriendly: false,
@ -67,7 +66,6 @@ return {
spoofUserAgentEvery: 5, spoofUserAgentEvery: 5,
spoofUserAgentWith: getDefaultUserAgentStrings(), spoofUserAgentWith: getDefaultUserAgentStrings(),
statsFilters: {}, statsFilters: {},
strictBlocking: true,
subframeColor: '#cc0000', subframeColor: '#cc0000',
subframeOpacity: 100 subframeOpacity: 100
}, },

19
src/js/commands.js

@ -25,22 +25,6 @@
/******************************************************************************/ /******************************************************************************/
var whitelistPageDomain = function(tabs) {
if ( tabs.length === 0 ) {
return;
}
var tab = tabs[0];
if ( !tab.url ) {
return;
}
var µm = µMatrix;
if ( µm.autoWhitelist1stPartyTemporarily(tab.url) ) {
µm.smartReloadTab(tab.id);
}
};
/******************************************************************************/
var whitelistAll = function(tabs) { var whitelistAll = function(tabs) {
if ( tabs.length === 0 ) { if ( tabs.length === 0 ) {
return; return;
@ -62,9 +46,6 @@ var onCommand = function(command) {
case 'revert-all': case 'revert-all':
µMatrix.revertAllRules(); µMatrix.revertAllRules();
break; break;
case 'whitelist-page-domain':
chrome.tabs.query({ active: true }, whitelistPageDomain);
break;
case 'whitelist-all': case 'whitelist-all':
chrome.tabs.query({ active: true }, whitelistAll); chrome.tabs.query({ active: true }, whitelistAll);
break; break;

12
src/js/httpsb.js

@ -26,6 +26,7 @@
(function() { (function() {
var µm = µMatrix; var µm = µMatrix;
µm.pMatrix = new µm.Matrix(); µm.pMatrix = new µm.Matrix();
µm.pMatrix.setSwitch('localhost', false);
µm.pMatrix.setSwitch('chrome-extension-scheme', false); µm.pMatrix.setSwitch('chrome-extension-scheme', false);
µm.pMatrix.setSwitch('chrome-scheme', false); µm.pMatrix.setSwitch('chrome-scheme', false);
µm.pMatrix.setSwitch(µm.behindTheSceneScope, false); µm.pMatrix.setSwitch(µm.behindTheSceneScope, false);
@ -34,6 +35,8 @@
µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green);
µm.pMatrix.setCell('*', '*', 'image', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'image', µm.Matrix.Green);
µm.pMatrix.setCell('*', '*', 'frame', µm.Matrix.Red); µm.pMatrix.setCell('*', '*', 'frame', µm.Matrix.Red);
µm.pMatrix.setCell('*', '1st-party', '*', µm.Matrix.Green);
µm.pMatrix.setCell('*', '1st-party', 'frame', µm.Matrix.Green);
µm.tMatrix = new µm.Matrix(); µm.tMatrix = new µm.Matrix();
µm.tMatrix.assign(µm.pMatrix); µm.tMatrix.assign(µm.pMatrix);
@ -90,15 +93,6 @@
} }
}; };
µMatrix.autoWhitelist1stPartyTemporarily = function(pageURL) {
var srcDomain = this.URI.domainFromURI(pageURL);
if ( this.tMatrix.evaluateCellZXY(srcDomain, srcDomain, '*') !== this.Matrix.RedIndirect ) {
return false;
}
this.tMatrix.whitelistCell(srcDomain, srcDomain, '*');
return true;
};
/******************************************************************************/ /******************************************************************************/
// Auto-whitelisting the `all` cell is a serious action, hence this will be // Auto-whitelisting the `all` cell is a serious action, hence this will be

112
src/js/matrix.js

@ -122,6 +122,36 @@ Matrix.toBroaderHostname = toBroaderHostname;
/******************************************************************************/ /******************************************************************************/
// Find out src-des relationship, using coarse-to-fine grained tests for
// speed. If desHostname is 1st-party to srcHostname, the domain is returned,
// otherwise the empty string.
var extractFirstPartyDesDomain = function(srcHostname, desHostname) {
if ( srcHostname === '*' || desHostname === '*' || desHostname === '1st-party' ) {
return '';
}
var srcLength = srcHostname.length;
var desLength = desHostname.length;
var len = srcLength < desLength ? srcLength : desLength;
if ( srcHostname.slice(-len) !== desHostname.slice(-len) ) {
return '';
}
var desDomain = µm.URI.domainFromHostname(desHostname);
if ( desDomain === '' ) {
return '';
}
var pos = srcLength - desDomain.length;
if ( pos < 0 || srcHostname.slice(pos) !== desDomain ) {
return '';
}
if ( pos !== 0 && srcHostname.charAt(pos - 1) !== '.' ) {
return '';
}
return desDomain;
};
/******************************************************************************/
Matrix.prototype.reset = function() { Matrix.prototype.reset = function() {
this.switchedOn = {}; this.switchedOn = {};
this.rules = {}; this.rules = {};
@ -274,12 +304,9 @@ Matrix.prototype.evaluateCell = function(srcHostname, desHostname, type) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) { Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
if ( this.evaluateSwitchZ(srcHostname) !== true ) {
return Matrix.Transparent;
}
var bitOffset = typeBitOffsets[type]; var bitOffset = typeBitOffsets[type];
var s = srcHostname; var s = srcHostname;
var v, pos;
var v;
for (;;) { for (;;) {
v = this.rules[s + ' ' + desHostname]; v = this.rules[s + ' ' + desHostname];
if ( v !== undefined ) { if ( v !== undefined ) {
@ -304,37 +331,91 @@ Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) { Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) {
// Matrix filtering switch
if ( this.evaluateSwitchZ(srcHostname) !== true ) {
return Matrix.GreenIndirect;
}
// Specific-hostname specific-type cell
var r = this.evaluateCellZ(srcHostname, desHostname, type); var r = this.evaluateCellZ(srcHostname, desHostname, type);
if ( r === 1 ) { return Matrix.RedDirect; } if ( r === 1 ) { return Matrix.RedDirect; }
if ( r === 2 ) { return Matrix.GreenDirect; } if ( r === 2 ) { return Matrix.GreenDirect; }
// Specific-hostname any-type cell
var rl = this.evaluateCellZ(srcHostname, desHostname, '*'); var rl = this.evaluateCellZ(srcHostname, desHostname, '*');
if ( rl === 1 ) { return Matrix.RedIndirect; } if ( rl === 1 ) { return Matrix.RedIndirect; }
var d = desHostname;
var pos; var pos;
var d = desHostname;
var firstPartDesDomain = extractFirstPartyDesDomain(srcHostname, desHostname);
// Ancestor cells, up to 1st-party destination domain
if ( firstPartDesDomain !== '' ) {
for (;;) {
if ( d === firstPartDesDomain ) {
break;
}
d = d.slice(d.indexOf('.') + 1);
// specific-hostname specific-type cell
r = this.evaluateCellZ(srcHostname, d, type);
if ( r === 1 ) { return Matrix.RedIndirect; }
if ( r === 2 ) { return Matrix.GreenIndirect; }
// Do not override narrower rule
if ( rl !== 2 ) {
rl = this.evaluateCellZ(srcHostname, d, '*');
if ( rl === 1 ) { return Matrix.RedIndirect; }
}
}
// 1st-party specific-type cell: it's a special row, it exists only in
// global scope.
r = this.evaluateCellZ('*', '1st-party', type);
if ( r === 1 ) { return Matrix.RedIndirect; }
if ( r === 2 ) { return Matrix.GreenIndirect; }
// Do not override narrower rule
if ( rl !== 2 ) {
rl = this.evaluateCellZ('*', '1st-party', '*');
if ( rl === 1 ) { return Matrix.RedIndirect; }
}
}
// Keep going, up to root
for (;;) { for (;;) {
pos = d.indexOf('.'); pos = d.indexOf('.');
if ( pos === -1 ) { if ( pos === -1 ) {
break; break;
} }
d = d.slice(pos + 1); d = d.slice(pos + 1);
// specific-hostname specific-type cell
r = this.evaluateCellZ(srcHostname, d, type); r = this.evaluateCellZ(srcHostname, d, type);
if ( r === 1 ) { return Matrix.RedIndirect; } if ( r === 1 ) { return Matrix.RedIndirect; }
if ( r === 2 ) { return Matrix.GreenIndirect; } if ( r === 2 ) { return Matrix.GreenIndirect; }
// Do not override narrower rule
if ( rl !== 2 ) { if ( rl !== 2 ) {
rl = this.evaluateCellZ(srcHostname, d, '*'); rl = this.evaluateCellZ(srcHostname, d, '*');
if ( rl === 1 ) { return Matrix.RedIndirect; } if ( rl === 1 ) { return Matrix.RedIndirect; }
} }
} }
// Any-hostname specific-type cells
r = this.evaluateCellZ(srcHostname, '*', type); r = this.evaluateCellZ(srcHostname, '*', type);
// Line below is strict-blocking
if ( r === 1 ) { return Matrix.RedIndirect; } if ( r === 1 ) { return Matrix.RedIndirect; }
// Narrower rule wins
if ( rl === 2 ) { return Matrix.GreenIndirect; } if ( rl === 2 ) { return Matrix.GreenIndirect; }
if ( r === 2 ) { return Matrix.GreenIndirect; } if ( r === 2 ) { return Matrix.GreenIndirect; }
// Any-hostname any-type cell
r = this.evaluateCellZ(srcHostname, '*', '*'); r = this.evaluateCellZ(srcHostname, '*', '*');
if ( r === 1 ) { return Matrix.RedIndirect; } if ( r === 1 ) { return Matrix.RedIndirect; }
if ( r === 2 ) { return Matrix.GreenIndirect; } if ( r === 2 ) { return Matrix.GreenIndirect; }
return this.rootValue; return this.rootValue;
}; };
// https://www.youtube.com/watch?v=4C5ZkwrnVfM
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) { Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) {
@ -368,24 +449,6 @@ Matrix.prototype.desHostnameFromRule = function(rule) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.extractZRules = function(srcHostname, desHostname, out) {
var s = srcHostname;
var rule, bitmap, pos;
for (;;) {
rule = s + ' ' + desHostname;
bitmap = this.rules[rule];
if ( bitmap !== undefined ) {
out[rule] = bitmap;
}
s = toBroaderHostname(s);
if ( s === '' ) {
break;
}
}
};
/******************************************************************************/
Matrix.prototype.toggleSwitch = function(srcHostname, newState) { Matrix.prototype.toggleSwitch = function(srcHostname, newState) {
if ( newState === undefined ) { if ( newState === undefined ) {
newState = !this.evaluateSwitchZ(srcHostname); newState = !this.evaluateSwitchZ(srcHostname);
@ -414,7 +477,6 @@ Matrix.prototype.evaluateSwitch = function(srcHostname) {
Matrix.prototype.evaluateSwitchZ = function(srcHostname) { Matrix.prototype.evaluateSwitchZ = function(srcHostname) {
var b; var b;
var s = srcHostname; var s = srcHostname;
var pos;
for (;;) { for (;;) {
b = this.switchedOn[s]; b = this.switchedOn[s];
if ( b !== undefined ) { if ( b !== undefined ) {
@ -639,7 +701,7 @@ Matrix.prototype.fromSelfie = function(selfie) {
Matrix.prototype.diff = function(other, srcHostname, desHostnames) { Matrix.prototype.diff = function(other, srcHostname, desHostnames) {
var out = []; var out = [];
var desHostname, type; var desHostname, type;
var i, pos, thisVal, otherVal;
var i, thisVal, otherVal;
for (;;) { for (;;) {
thisVal = this.evaluateSwitch(srcHostname); thisVal = this.evaluateSwitch(srcHostname);
otherVal = other.evaluateSwitch(srcHostname); otherVal = other.evaluateSwitch(srcHostname);

3
src/js/messaging-handlers.js

@ -118,8 +118,9 @@ var matrixSnapshot = function(details) {
r.tSwitch = µm.tMatrix.evaluateSwitchZ(r.scope); r.tSwitch = µm.tMatrix.evaluateSwitchZ(r.scope);
r.pSwitch = µm.pMatrix.evaluateSwitchZ(r.scope); r.pSwitch = µm.pMatrix.evaluateSwitchZ(r.scope);
// This one always exist
// These rows always exist
r.rows['*'] = new RowSnapshot(r.scope, '*', '*'); r.rows['*'] = new RowSnapshot(r.scope, '*', '*');
r.rows['1st-party'] = new RowSnapshot('*', '1st-party', '1st-party');
r.rowCount += 1; r.rowCount += 1;
var µmuri = µm.URI; var µmuri = µm.URI;

154
src/js/popup.js

@ -111,6 +111,7 @@ function updateMatrixSnapshot() {
/******************************************************************************/ /******************************************************************************/
// For display purpose, create four distinct groups of rows: // For display purpose, create four distinct groups of rows:
// 0th: literal "1st-party" row
// 1st: page domain's related // 1st: page domain's related
// 2nd: whitelisted // 2nd: whitelisted
// 3rd: graylisted // 3rd: graylisted
@ -147,36 +148,41 @@ function getGroupStats() {
} }
row = rows[hostname]; row = rows[hostname];
domain = row.domain; domain = row.domain;
// 1st-party always into group 0
if ( domain === pageDomain ) {
// literal "1st-party" row always into group 0
if ( hostname === '1st-party' ) {
domainToGroupMap[domain] = 0; domainToGroupMap[domain] = 0;
continue; continue;
} }
// 1st-party hostnames always into group 1
if ( domain === pageDomain ) {
domainToGroupMap[domain] = 1;
continue;
}
color = row.temporary[anyTypeOffset]; color = row.temporary[anyTypeOffset];
groupIndex = domainToGroupMap[domain] || 2; // anything overrides 2
// group 1: whitelisted (does not override 0)
groupIndex = domainToGroupMap[domain] || 3; // anything overrides 3
// group 2: whitelisted (does not override 0, 1)
if ( color === DarkGreen ) { if ( color === DarkGreen ) {
domainToGroupMap[domain] = 1;
domainToGroupMap[domain] = 2;
continue; continue;
} }
// group 3: blacklisted (does not override 0, 1)
// group 4: blacklisted (does not override 0, 1, 2)
if ( color === DarkRed ) { if ( color === DarkRed ) {
if ( groupIndex === 2 ) {
domainToGroupMap[domain] = 3;
if ( groupIndex === 3 ) {
domainToGroupMap[domain] = 4;
} }
continue; continue;
} }
// group 2: graylisted (does not override 0, 1, 3)
if ( groupIndex !== 2 ) {
// group 3: graylisted (does not override 0, 1, 2, 4)
if ( groupIndex !== 3 ) {
continue; continue;
} }
domainToGroupMap[domain] = 2;
domainToGroupMap[domain] = 3;
} }
// Second pass: put each domain in a group // Second pass: put each domain in a group
var groups = [ {}, {}, {}, {} ];
var groups = [ {}, {}, {}, {}, {} ];
var group; var group;
for ( hostname in rows ) { for ( hostname in rows ) {
if ( rows.hasOwnProperty(hostname) === false ) { if ( rows.hasOwnProperty(hostname) === false ) {
@ -305,7 +311,7 @@ function updateMatrixBehavior() {
var section, subdomainRows, j, subdomainRow; var section, subdomainRows, j, subdomainRow;
while ( i-- ) { while ( i-- ) {
section = sections.at(i); section = sections.at(i);
subdomainRows = section.descendants('.l2:not(.g3)');
subdomainRows = section.descendants('.l2:not(.g4)');
j = subdomainRows.length; j = subdomainRows.length;
while ( j-- ) { while ( j-- ) {
subdomainRow = subdomainRows.at(j); subdomainRow = subdomainRows.at(j);
@ -338,11 +344,12 @@ function handleFilter(button, leaning) {
// our parent cell knows who we are // our parent cell knows who we are
var cell = button.ancestors('div.matCell'); var cell = button.ancestors('div.matCell');
var type = cell.prop('reqType'); var type = cell.prop('reqType');
var hostname = cell.prop('hostname');
var desHostname = cell.prop('hostname');
var srcHostname = desHostname !== '1st-party' ? matrixSnapshot.scope : '*';
var request = { var request = {
what: getCellAction(hostname, type, leaning),
srcHostname: matrixSnapshot.scope,
desHostname: hostname,
what: getCellAction(desHostname, type, leaning),
srcHostname: srcHostname,
desHostname: desHostname,
type: type type: type
}; };
messaging.ask(request, updateMatrixSnapshot); messaging.ask(request, updateMatrixSnapshot);
@ -614,51 +621,21 @@ function hostnameCompare(a,b) {
/******************************************************************************/ /******************************************************************************/
function makeMatrixGroup0SectionDomain(domain) {
return makeMatrixRowDomain(domain)
.addClass('g0 l1');
}
function makeMatrixGroup0SectionSubomain(domain, subdomain) {
return makeMatrixRowSubdomain(domain, subdomain)
.addClass('g0 l2');
}
function makeMatrixGroup0SectionMetaDomain(domain) {
return makeMatrixMetaRowDomain(domain).addClass('g0 l1 meta');
function makeMatrixGroup0SectionDomain() {
return makeMatrixRowDomain('1st-party').addClass('g0 l1');
} }
function makeMatrixGroup0Section(hostnames) { function makeMatrixGroup0Section(hostnames) {
var domain = hostnames[0];
var domainDiv = createMatrixSection()
.toggleClass('collapsed', getCollapseState(domain))
.prop('domain', domain);
if ( hostnames.length > 1 ) {
makeMatrixGroup0SectionMetaDomain(domain)
.appendTo(domainDiv);
}
makeMatrixGroup0SectionDomain(domain)
.appendTo(domainDiv);
for ( var i = 1; i < hostnames.length; i++ ) {
makeMatrixGroup0SectionSubomain(domain, hostnames[i])
.appendTo(domainDiv);
}
var domainDiv = createMatrixSection().prop('domain', '1st-party');
makeMatrixGroup0SectionDomain().appendTo(domainDiv);
return domainDiv; return domainDiv;
} }
function makeMatrixGroup0(group) { function makeMatrixGroup0(group) {
var domains = Object.keys(group).sort(hostnameCompare);
if ( domains.length ) {
var groupDiv = createMatrixGroup().addClass('g0'); var groupDiv = createMatrixGroup().addClass('g0');
makeMatrixGroup0Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
.appendTo(groupDiv);
for ( var i = 1; i < domains.length; i++ ) {
makeMatrixGroup0Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
.appendTo(groupDiv);
}
makeMatrixGroup0Section().appendTo(groupDiv);
groupDiv.appendTo(matrixList); groupDiv.appendTo(matrixList);
} }
}
/******************************************************************************/ /******************************************************************************/
@ -682,7 +659,8 @@ function makeMatrixGroup1Section(hostnames) {
.toggleClass('collapsed', getCollapseState(domain)) .toggleClass('collapsed', getCollapseState(domain))
.prop('domain', domain); .prop('domain', domain);
if ( hostnames.length > 1 ) { if ( hostnames.length > 1 ) {
makeMatrixGroup1SectionMetaDomain(domain).appendTo(domainDiv);
makeMatrixGroup1SectionMetaDomain(domain)
.appendTo(domainDiv);
} }
makeMatrixGroup1SectionDomain(domain) makeMatrixGroup1SectionDomain(domain)
.appendTo(domainDiv); .appendTo(domainDiv);
@ -696,8 +674,7 @@ function makeMatrixGroup1Section(hostnames) {
function makeMatrixGroup1(group) { function makeMatrixGroup1(group) {
var domains = Object.keys(group).sort(hostnameCompare); var domains = Object.keys(group).sort(hostnameCompare);
if ( domains.length ) { if ( domains.length ) {
var groupDiv = createMatrixGroup()
.addClass('g1');
var groupDiv = createMatrixGroup().addClass('g1');
makeMatrixGroup1Section(Object.keys(group[domains[0]]).sort(hostnameCompare)) makeMatrixGroup1Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
.appendTo(groupDiv); .appendTo(groupDiv);
for ( var i = 1; i < domains.length; i++ ) { for ( var i = 1; i < domains.length; i++ ) {
@ -768,10 +745,18 @@ function makeMatrixGroup3SectionSubomain(domain, subdomain) {
.addClass('g3 l2'); .addClass('g3 l2');
} }
function makeMatrixGroup3SectionMetaDomain(domain) {
return makeMatrixMetaRowDomain(domain).addClass('g3 l1 meta');
}
function makeMatrixGroup3Section(hostnames) { function makeMatrixGroup3Section(hostnames) {
var domain = hostnames[0]; var domain = hostnames[0];
var domainDiv = createMatrixSection() var domainDiv = createMatrixSection()
.toggleClass('collapsed', getCollapseState(domain))
.prop('domain', domain); .prop('domain', domain);
if ( hostnames.length > 1 ) {
makeMatrixGroup3SectionMetaDomain(domain).appendTo(domainDiv);
}
makeMatrixGroup3SectionDomain(domain) makeMatrixGroup3SectionDomain(domain)
.appendTo(domainDiv); .appendTo(domainDiv);
for ( var i = 1; i < hostnames.length; i++ ) { for ( var i = 1; i < hostnames.length; i++ ) {
@ -782,21 +767,61 @@ function makeMatrixGroup3Section(hostnames) {
} }
function makeMatrixGroup3(group) { function makeMatrixGroup3(group) {
var domains = Object.keys(group).sort(hostnameCompare);
if ( domains.length) {
var groupDiv = createMatrixGroup()
.addClass('g3');
makeMatrixGroup3Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
.appendTo(groupDiv);
for ( var i = 1; i < domains.length; i++ ) {
makeMatrixGroup3Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
.appendTo(groupDiv);
}
groupDiv.appendTo(matrixList);
}
}
/******************************************************************************/
function makeMatrixGroup4SectionDomain(domain) {
return makeMatrixRowDomain(domain)
.addClass('g4 l1');
}
function makeMatrixGroup4SectionSubomain(domain, subdomain) {
return makeMatrixRowSubdomain(domain, subdomain)
.addClass('g4 l2');
}
function makeMatrixGroup4Section(hostnames) {
var domain = hostnames[0];
var domainDiv = createMatrixSection()
.prop('domain', domain);
makeMatrixGroup4SectionDomain(domain)
.appendTo(domainDiv);
for ( var i = 1; i < hostnames.length; i++ ) {
makeMatrixGroup4SectionSubomain(domain, hostnames[i])
.appendTo(domainDiv);
}
return domainDiv;
}
function makeMatrixGroup4(group) {
var domains = Object.keys(group).sort(hostnameCompare); var domains = Object.keys(group).sort(hostnameCompare);
if ( domains.length === 0 ) { if ( domains.length === 0 ) {
return; return;
} }
var groupDiv = createMatrixGroup().addClass('g3');
var groupDiv = createMatrixGroup().addClass('g4');
createMatrixSection() createMatrixSection()
.addClass('g3Meta')
.toggleClass('g3Collapsed', !!getUserSetting('popupHideBlacklisted'))
.addClass('g4Meta')
.toggleClass('g4Collapsed', !!getUserSetting('popupHideBlacklisted'))
.appendTo(groupDiv); .appendTo(groupDiv);
makeMatrixMetaRow(computeMatrixGroupMetaStats(group), 'g3')
makeMatrixMetaRow(computeMatrixGroupMetaStats(group), 'g4')
.appendTo(groupDiv); .appendTo(groupDiv);
makeMatrixGroup3Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
makeMatrixGroup4Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
.appendTo(groupDiv); .appendTo(groupDiv);
for ( var i = 1; i < domains.length; i++ ) { for ( var i = 1; i < domains.length; i++ ) {
makeMatrixGroup3Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
makeMatrixGroup4Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
.appendTo(groupDiv); .appendTo(groupDiv);
} }
groupDiv.appendTo(matrixList); groupDiv.appendTo(matrixList);
@ -823,6 +848,7 @@ var makeMenu = function() {
makeMatrixGroup1(groupStats[1]); makeMatrixGroup1(groupStats[1]);
makeMatrixGroup2(groupStats[2]); makeMatrixGroup2(groupStats[2]);
makeMatrixGroup3(groupStats[3]); makeMatrixGroup3(groupStats[3]);
makeMatrixGroup4(groupStats[4]);
endMatrixUpdate(); endMatrixUpdate();
initScopeCell(); initScopeCell();
@ -1120,10 +1146,10 @@ uDom.onLoad(function() {
uDom('body').on('click', '.dropdown-menu-button', dropDownMenuShow); uDom('body').on('click', '.dropdown-menu-button', dropDownMenuShow);
uDom('body').on('click', '.dropdown-menu-capture', dropDownMenuHide); uDom('body').on('click', '.dropdown-menu-capture', dropDownMenuHide);
uDom('#matList').on('click', '.g3Meta', function() {
uDom('#matList').on('click', '.g4Meta', function() {
var collapsed = uDom(this) var collapsed = uDom(this)
.toggleClass('g3Collapsed')
.hasClassName('g3Collapsed');
.toggleClass('g4Collapsed')
.hasClassName('g4Collapsed');
setUserSetting('popupHideBlacklisted', collapsed); setUserSetting('popupHideBlacklisted', collapsed);
}); });
}); });

38
src/js/profiler.js

@ -22,61 +22,41 @@
/******************************************************************************/ /******************************************************************************/
var quickProfiler = (function() { var quickProfiler = (function() {
/******************************************************************************/
var timer = performance; var timer = performance;
var time = 0; var time = 0;
var count = -3;
var count = 0;
var tstart = 0; var tstart = 0;
var lastlog = timer.now(); var lastlog = timer.now();
var prompt = ''; var prompt = '';
/******************************************************************************/
var reset = function() { var reset = function() {
time = 0; time = 0;
count = -3;
count = 0;
tstart = 0; tstart = 0;
}; };
/******************************************************************************/
var avg = function() { var avg = function() {
return count > 0 ? time / count : 0; return count > 0 ? time / count : 0;
}; };
/******************************************************************************/
var start = function(s) { var start = function(s) {
prompt = s || ''; prompt = s || '';
tstart = timer.now(); tstart = timer.now();
}; };
/******************************************************************************/
var stop = function() {
count += 1;
if ( count > 0 ) {
var stop = function(period) {
if ( period === undefined ) {
period = 10000;
}
var now = timer.now(); var now = timer.now();
count += 1;
time += (now - tstart); time += (now - tstart);
if ( (now - lastlog) > 10000 ) {
console.log('HTTP Switchboard() > %s: %s ms', prompt, avg().toFixed(3));
if ( (now - lastlog) >= period ) {
console.log('µMatrix> %s: %s ms (%d samples)', prompt, avg().toFixed(3), count);
lastlog = now; lastlog = now;
} }
}
}; };
/******************************************************************************/
return { return {
reset: reset, reset: reset,
start: start, start: start,
stop: stop stop: stop
}; };
/******************************************************************************/
})(); })();
/******************************************************************************/ /******************************************************************************/

23
src/js/traffic.js

@ -227,7 +227,6 @@ var onBeforeRootFrameRequestHandler = function(details) {
if ( tabId !== µm.behindTheSceneTabId ) { if ( tabId !== µm.behindTheSceneTabId ) {
µm.cookieHunter.recordPageCookies(pageStats); µm.cookieHunter.recordPageCookies(pageStats);
} }
// quickProfiler.stop();
return; return;
} }
@ -250,8 +249,6 @@ var onBeforeRootFrameRequestHandler = function(details) {
html = html.replace('{{now}}', String(Date.now())); html = html.replace('{{now}}', String(Date.now()));
var dataURI = 'data:text/html;base64,' + btoa(html); var dataURI = 'data:text/html;base64,' + btoa(html);
// quickProfiler.stop();
return { 'redirectUrl': dataURI }; return { 'redirectUrl': dataURI };
}; };
@ -342,8 +339,6 @@ var onBeforeRequestHandler = function(details) {
return; return;
} }
// quickProfiler.start('onBeforeRequest');
// console.debug('onBeforeRequestHandler()> "%s": %o', details.url, details); // console.debug('onBeforeRequestHandler()> "%s": %o', details.url, details);
var requestType = requestTypeNormalizer[details.type]; var requestType = requestTypeNormalizer[details.type];
@ -699,14 +694,9 @@ var onMainDocHeadersReceived = function(details) {
// console.debug('onMainDocHeadersReceived()> redirect "%s" to "%s"', requestURL, headers[i].value); // console.debug('onMainDocHeadersReceived()> redirect "%s" to "%s"', requestURL, headers[i].value);
} }
// rhill 2014-01-11: Auto-scope and/or auto-whitelist only when the
// `main_frame` object is really received (status = 200 OK), i.e. avoid
// redirection, because the final URL might differ. This ensures proper
// scope is looked-up before auto-site-scoping and/or auto-whitelisting.
// https://github.com/gorhill/httpswitchboard/issues/119
if ( details.statusLine.indexOf(' 200') > 0 ) {
// rhill 2014-01-15: Report redirects if any. // rhill 2014-01-15: Report redirects if any.
// https://github.com/gorhill/httpswitchboard/issues/112 // https://github.com/gorhill/httpswitchboard/issues/112
if ( details.statusLine.indexOf(' 200') > 0 ) {
var mainFrameStack = [requestURL]; var mainFrameStack = [requestURL];
var destinationURL = requestURL; var destinationURL = requestURL;
var sourceURL; var sourceURL;
@ -719,11 +709,6 @@ var onMainDocHeadersReceived = function(details) {
while ( destinationURL = mainFrameStack.pop() ) { while ( destinationURL = mainFrameStack.pop() ) {
pageStats.recordRequest('doc', destinationURL, false); pageStats.recordRequest('doc', destinationURL, false);
} }
// rhill 2013-12-23: Auto-whitelist page domain?
if ( µm.userSettings.autoWhitelistPageDomain ) {
µm.autoWhitelist1stPartyTemporarily(requestURL);
}
} }
// Evaluate // Evaluate
@ -871,6 +856,12 @@ var requestTypeNormalizer = {
/******************************************************************************/ /******************************************************************************/
chrome.webRequest.onBeforeRequest.addListener( chrome.webRequest.onBeforeRequest.addListener(
//function(details) {
// quickProfiler.start('onBeforeRequest');
// var r = onBeforeRequestHandler(details);
// quickProfiler.stop();
// return r;
//},
onBeforeRequestHandler, onBeforeRequestHandler,
{ {
"urls": [ "urls": [

17
src/settings.html

@ -52,23 +52,6 @@ ul > li {
&ensp;<span id="subframe-color-demo">&nbsp;</span> &ensp;<span id="subframe-color-demo">&nbsp;</span>
</ul> </ul>
<h2 data-i18n="settingsMatrixMoreSecurityHeader"></h2>
<ul>
<li>
<input id="strictBlocking" type="checkbox" data-range="bool"><span data-i18n="settingsStrictBlockingPrompt"></span>
<button class="whatisthis"></button>
<div class="whatisthis-expandable para" data-i18n="settingsStrictBlockingInfo"></div>
<li>
</ul>
<h2 data-i18n="settingsMatrixLessSecurityHeader"></h2>
<ul>
<li>
<input id="autoWhitelistPageDomain" type="checkbox" data-range="bool"><span data-i18n="settingsAutoWhitelistPrompt"></span>
<button class="whatisthis"></button>
<div class="whatisthis-expandable para" data-i18n="settingsAutoWhitelistHelp"></div>
</ul>
<h2 data-i18n="settingsMatrixConvenienceHeader"></h2> <h2 data-i18n="settingsMatrixConvenienceHeader"></h2>
<ul> <ul>
<li> <li>

52
tools/_locales/de/messages.json

@ -263,46 +263,10 @@
"message": "Mehr Sicherheit", "message": "Mehr Sicherheit",
"description": "..." "description": "..."
}, },
"settingsStrictBlockingPrompt": {
"message": "Striktes Blockieren aktivieren.",
"description": ""
},
"settingsStrictBlockingInfo": {
"message": "<p><strong><a href=\"https://github.com/gorhill/httpswitchboard/wiki/%22Strict-blocking%22-illustrated\">Striktes\nBlockieren</a></strong>,\neingeführt in <a href=\"https://github.com/gorhill/httpswitchboard/wiki/Change-log-0.0-to-0.5#036\">version 0.3.6</a>,\nbedeutet: Selbst\nwenn du einen spezifischen Hostnamen auf die Whitelist setzt, bleiben die Arten von Anfragen, die standardmäßig blockiert sind (<i>Plugins</i>,\n<i>Frames</i>, etc.), weiterhin auf der Blacklist. Für einige Benutzer ist das möglicherweise\nzu lästig, daher dieser Schalter.</p>\n<p><strong>Striktes Blockieren an</strong>: blockierte Arten von Anfragen (falls vorhanden)\nfür einen Hostnamen auf der Whitelist bleiben weiterhin auf der Blacklist (sofern du diese Arten von Anfragen für diesen Hostnamen nicht ausdrücklich erlaubst.)</p>\n<p><strong>Striktes Blockieren aus</strong>: blockierte Arten von Anfragen (falls vorhanden)\nfür einen Hostnamen auf der Whitelist sind erlaubt (sofern du diese Arten von Anfragen für diesen Hostnamen nicht ausdrücklich verbietest.)</p>",
"description": "To help user understand the purpose of strict blocking"
},
"settingsAutoCreateScopePrompt1": {
"message": "Automatisches Erzeugen eines temporären Geltungsbereichs auf ",
"description": "English: Auto create temporary"
},
"settingsAutoCreateDomainScope": {
"message": "Domain-Ebene",
"description": "English: domain-level"
},
"settingsAutoCreateSiteScope": {
"message": "Webseiten-Ebene",
"description": "English: site-level"
},
"settingsAutoCreateScopePrompt2": {
"message": " ",
"description": "English: scope"
},
"settingsAutoCreateScopeInfo": {
"message": "<p>Diese Option ermöglicht das automatische Erzeugen eines temporären Geltungsbereichs für eine besuchte Webseite, falls für diese noch kein Geltungsbereich definiert ist.</p><p>Das Benutzen von Domain- oder Webseiten-spezifischen Regeln hat viele Vorteile, vor allem der, dass diese Regeln in einer Art Sandbox eingesperrt werden - eine gute Angewohnheit für mehr Sicherheit.</p><p>Beispiel: Wenn du &ldquo;alles&rdquo; auf einer Webseite (www.example.com) erlaubst (also auf die Whitelist setzt), hat die Benutzung eines Geltungsbereichs auf Domain-Ebene zur Folge, dass diese extrem freizügige Regel tatsächlich nur für Webseiten dieser spezifischen Domain (example.com) gültig ist; hättest du stattdessen einen Globalen Geltungsbereich (&ldquo;&#x2217;&rdquo;) benutzt, würde diese extrem freizügige Regel für <i>alle</i> Webseiten gelten, d.h. du würdest damit das ganze Internet auf die Whitelist setzen.</p>",
"description": "English: see relevant messages.json file"
},
"settingsMatrixLessSecurityHeader" : { "settingsMatrixLessSecurityHeader" : {
"message": "Weniger Sicherheit", "message": "Weniger Sicherheit",
"description": "..." "description": "..."
}, },
"settingsAutoWhitelistPrompt": {
"message": "Auto-Whitelist: automatisches Hinzufügen von Domänen zur Whitelist.",
"description": ""
},
"settingsAutoWhitelistHelp": {
"message": "<p>Einige Benutzer möchten nicht andauernd Webseiten auf die Whitelist setzen müssen. Daher ermöglicht diese Einstellung, dass Domänen temporär automatisch zur Whitelist hinzugefügt werden. Dieses temporäre Auto-Whitelisting findet <b>nur</b> statt, wenn die Domäne auf der &ldquo;Greylist&rdquo; (=hellrote Zellen) ist, d.h. nicht explizit auf die Blacklist gesetzt wurde oder sich auf einer der externen Listen blockierter Hostnamen befindet.</p><p>Obwohl diese Einstellung unter Sicherheitsaspekten nicht empfehlenswert ist, wurde sie aufgrund entsprechender Benutzerwünsche hinzu gefügt -- lieber gebe ich Benutzern diese Option, als dass sie ganz auf die Benutzung dieser Erweiterung verzichten.</p><p>Sofern du diese Option benutzen willst, rate ich dazu, zumindest <b>frame</b> auf die Blacklist zu setzen und <b>Striktes Blockieren</b> zu aktivieren.</p>",
"description": "To help user understand the purpose of auto-whitelist"
},
"settingsMatrixConvenienceHeader" : { "settingsMatrixConvenienceHeader" : {
"message": "Komforteinstellungen", "message": "Komforteinstellungen",
"description": "English: Convenience" "description": "English: Convenience"
@ -327,22 +291,6 @@
"message": "Immer wenn du Änderungen in der Matrix durchführst, die die Anzeige und /oder das Verhalten einer oder mehrerer Seiten beeinflusst, wird <i>µMatrix</i> die betroffenen Seiten automatisch neu laden, sobald du die Matrix schließt.", "message": "Immer wenn du Änderungen in der Matrix durchführst, die die Anzeige und /oder das Verhalten einer oder mehrerer Seiten beeinflusst, wird <i>µMatrix</i> die betroffenen Seiten automatisch neu laden, sobald du die Matrix schließt.",
"description": "..." "description": "..."
}, },
"settingsMatrixCopyGlobalRulesIntoNewScopePrompt" : {
"message": "Kopiere alle Regeln aus dem Globalen Geltungsbereich in neu erstellte lokale Geltungsbereiche (d. h. auf Domain- oder Webseiten-Ebene).",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixCopyGlobalRulesIntoNewScopeHelp" : {
"message": "<p>Geltungsbereiche existieren in einer Art Sandbox, d. h. sie teilen keine Regeln untereinander, und das gilt auch für den Globalen Geltungsbereich: enger gefasste Geltungsbereiche sehen <b>nicht</b> die Regeln im Globalen Geltungsbereich.</p> <p>Von einigen Benutzern wird dies aber als Hindernis angesehen, da sie möchten, dass ihre globalen Regeln auch von enger gefassten Geltungsbereichen erkannt werden. Diese Option behebt dieses &ldquo;Manko&rdquo; indem sie erzwingt, dass alle globalen Regeln in neu erstellte enger gefasste Geltungsbereiche hineinkopiert werden.</p> <p>Bedenke aber, dass <b>alle</b> Regeln aus dem Globalen Geltungsbereich kopiert werden, einschließlich der Regeln, die möglicherweise irrelevant sind für die Webseite, für die der enger gefasste Geltungsbereich erstellt wurde. Dies kann daher zu &ldquo;aufgeblähten Regelwerken&rdquo; führen, falls im Globalen Geltungsbereich viele Regeln angelegt wurden.</p>",
"description": "English: ..."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt1" : {
"message": "Automatisches Löschen unbenutzter temporärer Geltungsbereiche.",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt2" : {
"message": "",
"description": "English:"
},
"settingsSubframeColor" : { "settingsSubframeColor" : {
"message": "Farbe blockierter Frames:", "message": "Farbe blockierter Frames:",
"description": "English: Blocked frames:&ensp;Color" "description": "English: Blocked frames:&ensp;Color"

52
tools/_locales/en/messages.json

@ -263,46 +263,10 @@
"message": "More security", "message": "More security",
"description": "..." "description": "..."
}, },
"settingsStrictBlockingPrompt": {
"message": "Enable strict blocking.",
"description": ""
},
"settingsStrictBlockingInfo": {
"message": "<p><strong><a href=\"https://github.com/gorhill/httpswitchboard/wiki/%22Strict-blocking%22-illustrated\">Strict\nblocking</a></strong>,\nintroduced in <a href=\"https://github.com/gorhill/httpswitchboard/wiki/Change-log-0.0-to-0.5#036\">version 0.3.6</a>,\nmeans that even\nif you whitelist a specific hostname, blacklisted type of requests (<i>plugins</i>,\n<i>frames</i>, etc.) will remain blacklisted. For some users this maybe\ntoo bothersome, hence this switch.</p>\n<p><strong>Strict blocking on</strong>: blacklisted types of request (if any)\nfor a whitelisted hostname are blocked (unless you explicitly whitelist\nspecifically these types of request for the whitelisted hostname.)</p>\n<p><strong>Strict blocking off</strong>: blacklisted types of request (if any)\nfor a whitelisted hostname are allowed (unless you explicitly blacklist\nspecifically these types of request for the whitelisted hostname.)</p>",
"description": "To help the user understand the purpose of strict blocking"
},
"settingsAutoCreateScopePrompt1": {
"message": "Auto create temporary",
"description": "English: Auto create temporary"
},
"settingsAutoCreateDomainScope": {
"message": "domain-level",
"description": "English: domain-level"
},
"settingsAutoCreateSiteScope": {
"message": "site-level",
"description": "English: site-level"
},
"settingsAutoCreateScopePrompt2": {
"message": "scope.",
"description": "English: scope"
},
"settingsAutoCreateScopeInfo": {
"message": "<p>This option enables the automatic creation of a temporary scope if no scope exists for a web site you visit.</p><p>There are many advantages to using domain- or site-scoped rules, one of them being the sandboxing of rules, a good habit for enhanced security.</p><p>For example, should you want to whitelist &ldquo;all&rdquo; for a web site (www.example.com), using a domain-level scope will limit this extremely permissive rule to only pages on that specific domain (example.com), while if used in the global scope (&ldquo;&#x2217;&rdquo;) the extremely permissive rule would apply to all pages on all web sites, i.e. the whitelisting of the whole internet.</p>",
"description": "English: see relevant messages.json file"
},
"settingsMatrixLessSecurityHeader" : { "settingsMatrixLessSecurityHeader" : {
"message": "Less security", "message": "Less security",
"description": "..." "description": "..."
}, },
"settingsAutoWhitelistPrompt": {
"message": "Auto whitelist page domain.",
"description": ""
},
"settingsAutoWhitelistHelp": {
"message": "<p>Some users do not like to constantly whitelist the domain of the page by default. This feature enables automatic temporary whitelisting of a page's whole domain whenever it is first loaded in the browser. The temporary auto-whitelisting will occur <b>only</b> if the page domain is currently graylisted.</p><p>Although it is not a recommended feature from a security perspective, it has been included due to popular demand -- I would rather give users this feature than see them give up completely on a blocker.</p><p>If you use this feature, I advise that you at least blacklist <b>frame</b> requests and turn on <b>strict blocking</b>.</p>",
"description": "To help user understand the purpose of auto-whitelist"
},
"settingsMatrixConvenienceHeader" : { "settingsMatrixConvenienceHeader" : {
"message": "Convenience", "message": "Convenience",
"description": "English: Convenience" "description": "English: Convenience"
@ -327,22 +291,6 @@
"message": "Whenever you make changes in the matrix which can affect the display and/or behavior of one or more pages, <i>µMatrix</i> will reload affected pages automatically when you close the matrix.", "message": "Whenever you make changes in the matrix which can affect the display and/or behavior of one or more pages, <i>µMatrix</i> will reload affected pages automatically when you close the matrix.",
"description": "..." "description": "..."
}, },
"settingsMatrixCopyGlobalRulesIntoNewScopePrompt" : {
"message": "Copy all rules from global scope into newly created local scopes.",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixCopyGlobalRulesIntoNewScopeHelp" : {
"message": "<p>Scopes are sandboxed, i.e. they do not share rules, and this also applies to the global scope: narrower scopes do not see rules in the global scope.</p> <p>Some users see this as an impediment, as they wish their global rules were seen by narrower scopes. This option allows to mitigate this &ldquo;shortcoming&rdquo; by forcing a copy of all global rules into a newly created narrower scope.</p> <p>Be mindful that <b>all</b> rules from the global scope are copied, including rules which could be irrelevant to the web site for which the scope was created. This could lead to &ldquo;rules bloat&rdquo; when there are many rules in the global scope.</p>",
"description": "English: ..."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt1" : {
"message": "Auto delete unused temporary scopes.",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt2" : {
"message": "",
"description": "English:"
},
"settingsSubframeColor" : { "settingsSubframeColor" : {
"message": "Blocked frames:&ensp;Color", "message": "Blocked frames:&ensp;Color",
"description": "English: Blocked frames:&ensp;Color" "description": "English: Blocked frames:&ensp;Color"

52
tools/_locales/fr/messages.json

@ -263,46 +263,10 @@
"message": "Sécurité renforcée", "message": "Sécurité renforcée",
"description": "..." "description": "..."
}, },
"settingsStrictBlockingPrompt": {
"message": "Activer le blocage strict",
"description": ""
},
"settingsStrictBlockingInfo": {
"message": "Introduit dans la <a href=\"https://github.com/gorhill/httpswitchboard/wiki/Change-log-0.0-to-0.5#036\">version 0.3.6</a>, le <strong><a href=\"https://github.com/gorhill/httpswitchboard/wiki/%22Strict-blocking%22-illustrated\">Blocage strict</a></strong> signifie que même si vous allouez un nom d'hôte spécifique, une requête restera bloquée si le type d'objet en question (plugins, iframes, etc) est lui-même bloqué; en d'autres termes, le blocage d'éléments de colonnes prime sur l'autorisation d'éléments de lignes. Le choix vous est proposé de l'activer ou non, car cela peut se montrer trop restrictif aux yeux de certains utilisateurs. Si l'option est activée, la requête est autorisée à condition que les nom d'hôte ET le type de requête soient autorisés. Si l'option n'est pas cochée, le nom d'hôte alloué suffit à autoriser la requête.",
"description": "To help user understand the purpose of strict blocking"
},
"settingsAutoCreateScopePrompt1": {
"message": "Créer automatiquement des contextes de règles à portée",
"description": "English: Auto create temporary"
},
"settingsAutoCreateDomainScope": {
"message": "domaine",
"description": "English: domain-level"
},
"settingsAutoCreateSiteScope": {
"message": "site",
"description": "English: site-level"
},
"settingsAutoCreateScopePrompt2": {
"message": "temporaires",
"description": "English: scope"
},
"settingsAutoCreateScopeInfo": {
"message": "<p>Cette option active la création automatique de contextes de règles à portée non globale si aucune règle n'existe pour le site web que vous visitez. Ainsi, les règles que vous définissez pour ce site ne s'appliqueront pas universellement, mais uniquement au domaine/site précis (selon votre choix).</p><p>Si cela peut se révéler légèrement contraignant dans certains cas, c'est également un bon moyen de renforcer votre sécurité.</p><p>Par exemple, si vous désirez mettre en liste blanche TOUS les éléments d'un site web (www.exemple.com), employer une règle à portée domaine/site limiterait cette règle trop permissive uniquement aux pages web en provenance du domaine/site exemple.com, tandis que si c'était employé à portée globale (&ldquo;&#x2217;&rdquo;), elle s'appliquerait partout, ce qui pourrait réduire votre sécurité.</p>",
"description": "..."
},
"settingsMatrixLessSecurityHeader" : { "settingsMatrixLessSecurityHeader" : {
"message": "Sécurité réduite", "message": "Sécurité réduite",
"description": "..." "description": "..."
}, },
"settingsAutoWhitelistPrompt": {
"message": "Mise en liste blanche automatique du domaine de la page visitée",
"description": ""
},
"settingsAutoWhitelistHelp": {
"message": "<p>Certains utilisateurs n'aiment pas devoir constamment mettre en liste blanche le domaine de la page visitée. Cette option permet de mettre automatiquement en liste blanche tout le domaine d'une page lors de son premier chargement dans le navigateur. Cette procédure automatique ne se produira <b>que</b> si le domaine de la page visitée est actuellement sur liste grise (c'est-à-dire ni sur liste blanche, ni sur liste noire).</p><p>Bien que d'un point de vue sécurité, il n'est pas recommandé d'utiliser cette fonctionnalité, elle a été incluse suite à une forte demande (il m'a paru plus pertinent de leur donner cette possibilité que d'abandonner l'utilisation de mon extension).</p><p>Si vous activez cette option, je vous recommande d'au moins mettre sur la liste noire du contexte global les requêtes de type <b>frame</b> et d'activer le <b>blocage strict</b>.</p>",
"description": "To help user understand the purpose of auto-whitelist"
},
"settingsMatrixConvenienceHeader" : { "settingsMatrixConvenienceHeader" : {
"message": "Ergonomie", "message": "Ergonomie",
"description": "English: Convenience" "description": "English: Convenience"
@ -327,22 +291,6 @@
"message": "Lorsque vous avez modifié des permissions susceptibles d'affecter l'apparence et/ou le comportement d'une page Web, l'extension rechargera automatiquement une ou plusieurs pages Web concernées (selon votre choix) en fermant la matrice. Si l'option Aucune page est sélectionnée, vous devrez actualiser la page Web vous-même pour appliquer les modifications", "message": "Lorsque vous avez modifié des permissions susceptibles d'affecter l'apparence et/ou le comportement d'une page Web, l'extension rechargera automatiquement une ou plusieurs pages Web concernées (selon votre choix) en fermant la matrice. Si l'option Aucune page est sélectionnée, vous devrez actualiser la page Web vous-même pour appliquer les modifications",
"description": "..." "description": "..."
}, },
"settingsMatrixCopyGlobalRulesIntoNewScopePrompt" : {
"message": "Copier toutes les règles du contexte global vers les nouveaux contextes à portée non globale",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixCopyGlobalRulesIntoNewScopeHelp" : {
"message": "<p>Chaque contexte est sandboxé, c'est-à-dire qu'elle ne partage pas ses règles avec les autres contextes, et cela vaut également pour le contexte global. Ainsi, un contexte restreint n'applique pas les règles du contexte global.</p> <p>Certaines personnes voient cela comme un obstacle, souhaitant que leurs règles du contexte global soient prises en compte dans des contextes restreints. Cette option permet d'atténuer ce &ldquo;défaut&rdquo; en forçant la copie de toutes les règles du contexte global dans un nouveau contexte restreint.</p> <p>Prenez conscience que <b>toutes</b> les règles du contexte global sont copiés, y compris des règles n'ayant pas de rapport avec le site Web pour lequel un nouveau contexte restreint a été créé. Cela pourrait conduire à un &ldquo;ballonnement de règles&rdquo; lorsqu'il a beaucoup de règles dans le contexte global.</p>",
"description": "English: ..."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt1" : {
"message": "Effacer automatiquement les règles de contextes non globaux inutilisées",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt2" : {
"message": "",
"description": "English:"
},
"settingsSubframeColor" : { "settingsSubframeColor" : {
"message": "Couleur pour les &lt;iframe&gt; bloquées :", "message": "Couleur pour les &lt;iframe&gt; bloquées :",
"description": "English: Blocked frames:&ensp;Color" "description": "English: Blocked frames:&ensp;Color"

52
tools/_locales/ru/messages.json

@ -263,46 +263,10 @@
"message": "Больше защиты", "message": "Больше защиты",
"description": "..." "description": "..."
}, },
"settingsStrictBlockingPrompt": {
"message": "Включить строгую блокировку.",
"description": ""
},
"settingsStrictBlockingInfo": {
"message": "<p><strong><a href=\"https://github.com/gorhill/httpswitchboard/wiki/%22Strict-blocking%22-illustrated\">Строгое\nблокирование</a></strong>,\nознокомиться на <a href=\"https://github.com/gorhill/httpswitchboard/wiki/Change-log-0.0-to-0.5#036\">версии 0.3.6</a>,\nозначает, что\nесли вы внесли сайт в белый список, заблокированые запросы: (<i>плагинов</i>,\n<i>фреймов</i>, и т.д.) будут в черном списке. Для некоторых пользователей это может быть\nнадоедливым, следовательно, нужен этот переключатель.</p>\n<p><strong>Строгие блокировки ВКЛ.</strong>: в черный список типов запросов (если любой)\nдля сайтов из белого списка будет блокированы (если явно не белый список\nспециально эти запросы для сайтов из белого списка.)</p>\n<p><strong>Строгие блокировки ВЫКЛ.</strong>: попавшие в черный список запросы (если любой)\nдля сайтов из белого списка разрешены (если вы явно не внесли эти запросы в ченый список для сайтов из белого списка.)</p>",
"description": "To help user understand the purpose of strict blocking"
},
"settingsAutoCreateScopePrompt1": {
"message": "Автоматически создавать временные",
"description": "English: Auto create temporary"
},
"settingsAutoCreateDomainScope": {
"message": "на уровне домена",
"description": "English: domain-level"
},
"settingsAutoCreateSiteScope": {
"message": "на уровне сайта",
"description": "English: site-level"
},
"settingsAutoCreateScopePrompt2": {
"message": "области.",
"description": "English: scope"
},
"settingsAutoCreateScopeInfo": {
"message": "<p>Эта опция позволяет автоматически создавать временные правила для новых сайтов.</p><p>There are many advantages to using domain- or site-scoped rules, one of them being the sandboxing of rules, a good habit for enhanced security.</p><p>For example, should you want to whitelist &ldquo;all&rdquo; for a web site (www.example.com), using a domain-level scope will limit this extremely permissive rule to only pages on that specific domain (example.com), while if used in the global scope (&ldquo;&#x2217;&rdquo;) the extremely permissive rule would apply to all pages on all web sites, i.e. the whitelisting of the whole internet.</p>",
"description": "English: see relevant messages.json file"
},
"settingsMatrixLessSecurityHeader" : { "settingsMatrixLessSecurityHeader" : {
"message": "Меньше защиты", "message": "Меньше защиты",
"description": "..." "description": "..."
}, },
"settingsAutoWhitelistPrompt": {
"message": "Автосоздание белых списков для домена.",
"description": ""
},
"settingsAutoWhitelistHelp": {
"message": "<p>Некоторые пользователи не любят добавлять домен текущей страницы в белый список по-умолчанию. Эта функция позволяет автоматически создавать временные белые списки из всей области страницы, когда она впервые загружается в браузере. The temporary auto-whitelisting will occur <b>only</b> если страница домена в серых списках.</p><p>Хотя включать эту опцию не рекомендуется, она была включена из-за удобства — я лучше включу её, нежели потеряю пользователей.</p><p>Если опция включена, рекомендуется включить блокировку <b>frame</b> запросов и <b>строгую блокировку</b>.</p>",
"description": "To help user understand the purpose of auto-whitelist"
},
"settingsMatrixConvenienceHeader" : { "settingsMatrixConvenienceHeader" : {
"message": "Удобство", "message": "Удобство",
"description": "English: Convenience" "description": "English: Convenience"
@ -327,22 +291,6 @@
"message": "Каждый раз, когда вы вносите изменения в матрицу, которые могут повлиять на отображение и/или поведение одной или нескольких страниц, <i>µMatrix</i> перезагрузит все затронутые страницы автоматически, после закрытия матрицы.", "message": "Каждый раз, когда вы вносите изменения в матрицу, которые могут повлиять на отображение и/или поведение одной или нескольких страниц, <i>µMatrix</i> перезагрузит все затронутые страницы автоматически, после закрытия матрицы.",
"description": "..." "description": "..."
}, },
"settingsMatrixCopyGlobalRulesIntoNewScopePrompt" : {
"message": "Копировать все правила из глобальной области во вновь создаваемые локальные области.",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixCopyGlobalRulesIntoNewScopeHelp" : {
"message": "<p>Области являются изолированными, т.е. они не придерживаются правил, и это также относится и к глобальной области видимости: более узкие области “не видят” правил в глобальной области.</p> <p>Некоторые пользователи видят в этом препятствие, как они хотят, чтобы их глобальные правила были замечены более узкие области. Эта опция позволяет смягчить этот “недостаток”, позволяя копировать правила глобальных областей, в новую созданную узкую область.</p> <p>Помните, что <b>все</b> правила, копируемые из глобальной области видимости могут иметь предназначение для веб-сайта, для которых область была создана. Это может привести к “Правилам наворотов”, когда есть много правил в глобальной области видимости.</p>",
"description": "English: ..."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt1" : {
"message": "Автоматически удалять временные области.",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt2" : {
"message": "",
"description": "English:"
},
"settingsSubframeColor" : { "settingsSubframeColor" : {
"message": "Цвет заблокированного фрейма:", "message": "Цвет заблокированного фрейма:",
"description": "English: Blocked frames:&ensp;Color" "description": "English: Blocked frames:&ensp;Color"

52
tools/_locales/zh_CN/messages.json

@ -263,46 +263,10 @@
"message": "增强安全性设置", "message": "增强安全性设置",
"description": "..." "description": "..."
}, },
"settingsStrictBlockingPrompt": {
"message": "启用严格屏蔽",
"description": ""
},
"settingsStrictBlockingInfo": {
"message": "<p><strong><a href=\"https://github.com/gorhill/httpswitchboard/wiki/%22Strict-blocking%22-illustrated\">严格屏蔽</a></strong>,导入于<a href=\"https://github.com/gorhill/httpswitchboard/wiki/Change-log-0.0-to-0.5#036\">0.3.6版</a>,意味着即使您把一个站点名加入了白名单,被加入黑名单的请求类型(<i>插件</i>、<i>子文档</i>等等)仍会保持被黑名单的状态。对部分用户来说这可能有点太麻烦,于是有了这个开关选项。</p><p><strong>开启严格屏蔽</strong>:对一个白名单中的站点名,被添加到黑名单的请求类型(如果有的话)将被屏蔽(除非您,为白名单中的站点名,明确地把这些特殊的请求类型加入到白名单中。)</p><p><strong>关闭严格屏蔽</strong>:对一个白名单中的站点名,被添加到黑名单的请求类型(如果有的话)将被允许(除非您,为白名单中的站点名,明确地把这些特殊的请求类型加入到黑名单中。)</p>",
"description": "To help the user understand the purpose of strict blocking"
},
"settingsAutoCreateScopePrompt1": {
"message": "自动添加临时",
"description": "English: Auto create temporary"
},
"settingsAutoCreateDomainScope": {
"message": "域名级",
"description": "English: domain-level"
},
"settingsAutoCreateSiteScope": {
"message": "站点级",
"description": "English: site-level"
},
"settingsAutoCreateScopePrompt2": {
"message": "作用域。",
"description": "English: scope"
},
"settingsAutoCreateScopeInfo": {
"message": "<p>这个选项开启临时作用域的自动创建,如果不存在适用于您访问的网站的作用域。</p><p>使用域名或站点级作用域的规则有许多的好处,其中之一是规则的沙盒化,这是一个增强安全性的好习惯。</p><p>例如,如果您想添加一个站点的“全部”请求到白名单(如www.example.com),使用一个域名级的作用域会把这条极其宽容的规则限制到那个特殊域名(example.com)的网页上。而如果运用到全局作用域(“*”)上,这条极其宽容的规则将被运用到所有网站的所有页面上,也就是说把整个互联网添加到白名单中。</p>",
"description": "English: see relevant messages.json file"
},
"settingsMatrixLessSecurityHeader" : { "settingsMatrixLessSecurityHeader" : {
"message": "减弱安全性设置", "message": "减弱安全性设置",
"description": "..." "description": "..."
}, },
"settingsAutoWhitelistPrompt": {
"message": "自动添加页面域名至白名单。",
"description": ""
},
"settingsAutoWhitelistHelp": {
"message": "<p>有些用户不喜欢要一直把页面的域名添加到默认的白名单。这项功能开启页面上所有域名的临时白名单自动添加,只要这个页面是第一次加载到浏览器。临时白名单自动添加<b>只会</b>发生在页面的域名当前处在灰名单里的情况下。</p><p>虽然从安全性的角度来说,这不是一项被推荐的功能,但它还是因为广泛的需求而被加入————比起看到他们完全放弃一个屏蔽工具,我更倾向于给予用户这项功能。</p><p>如果您使用这项功能,我建议您至少把<b>子文档</b>类型的请求添加到黑名单中,并且开启<b>严格屏蔽</b>。</p>",
"description": "To help user understand the purpose of auto-whitelist"
},
"settingsMatrixConvenienceHeader" : { "settingsMatrixConvenienceHeader" : {
"message": "便利设置", "message": "便利设置",
"description": "English: Convenience" "description": "English: Convenience"
@ -327,22 +291,6 @@
"message": "当您对过滤矩阵作出任何会影响一个或多个页面的显示或行为的变更时,<i>µMatrix</i> 会在您关闭过滤矩阵的显示后,自动重载受影响的页面。", "message": "当您对过滤矩阵作出任何会影响一个或多个页面的显示或行为的变更时,<i>µMatrix</i> 会在您关闭过滤矩阵的显示后,自动重载受影响的页面。",
"description": "..." "description": "..."
}, },
"settingsMatrixCopyGlobalRulesIntoNewScopePrompt" : {
"message": "拷贝所有全局作用域中的规则到新创建的局部作用域中。",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixCopyGlobalRulesIntoNewScopeHelp" : {
"message": "<p>作用域是沙盒化相互隔离的,即它们不共享规则,这对全局作用域来说也是适用的:局部作用域无法看到全局作用域中的规则。</p> <p>有些用户把这视为一种阻碍,因为他们希望他们的全局作用规则能被局部作用域所看到。这个选项使这个“短处”能得以缓和,通过强制把所以全局作用规则拷贝到一个新创建的局部作用域中来实现。</p> <p>请特别注意:<b>所有</b>来自全局作用域的规则都会被拷贝,包括那些可能和新创建作用域对应网站无关的规则。当全局作用域中有非常多的规则时,这可能会导致“规则膨胀”。</p>",
"description": "English: ..."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt1" : {
"message": "自动删除未使用的临时作用域。",
"description": "English: Auto delete unused temporary scopes."
},
"settingsMatrixDeleteUnusedTemporaryScopesPrompt2" : {
"message": "",
"description": "English:"
},
"settingsSubframeColor" : { "settingsSubframeColor" : {
"message": "被屏蔽子文档:颜色", "message": "被屏蔽子文档:颜色",
"description": "English: Blocked frames:&ensp;Color" "description": "English: Blocked frames:&ensp;Color"

Loading…
Cancel
Save