1
0
Fork 0
mirror of https://github.com/gorhill/uMatrix.git synced 2024-06-26 10:01:08 +12:00

infrastructure work toward addressing #7, #36

This commit is contained in:
Raymond Hill 2014-11-18 00:18:04 -02:00
parent 0e23caeec4
commit 4aab150af3
4 changed files with 153 additions and 99 deletions

View file

@ -26,11 +26,11 @@
(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('matrix-off', 'localhost', true);
µm.pMatrix.setSwitch('chrome-extension-scheme', false); µm.pMatrix.setSwitch('matrix-off', 'chrome-extension-scheme', true);
µm.pMatrix.setSwitch('chrome-scheme', false); µm.pMatrix.setSwitch('matrix-off', 'chrome-scheme', true);
µm.pMatrix.setSwitch(µm.behindTheSceneScope, false); µm.pMatrix.setSwitch('matrix-off', µm.behindTheSceneScope, true);
µm.pMatrix.setSwitch('opera-scheme', false); µm.pMatrix.setSwitch('matrix-off', 'opera-scheme', true);
µm.pMatrix.setCell('*', '*', '*', µm.Matrix.Red); µm.pMatrix.setCell('*', '*', '*', µm.Matrix.Red);
µm.pMatrix.setCell('*', '*', 'doc', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'doc', µm.Matrix.Green);
µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green);
@ -179,23 +179,6 @@
/******************************************************************************/ /******************************************************************************/
µMatrix.getTemporaryMtxFiltering = function(srcHostname) {
return this.tMatrix.evaluateSwitchZ(srcHostname);
};
µMatrix.getPermanentMtxFiltering = function(srcHostname) {
return this.pMatrix.evaluateSwitchZ(srcHostname);
};
µMatrix.toggleTemporaryMtxFiltering = function(srcHostname, state) {
if ( state === undefined ) {
state = !this.getTemporaryMtxFiltering(srcHostname);
}
return this.tMatrix.toggleSwitch(srcHostname, state);
};
/******************************************************************************/
// Commit temporary permissions. // Commit temporary permissions.
µMatrix.commitPermissions = function(persist) { µMatrix.commitPermissions = function(persist) {

View file

@ -82,8 +82,16 @@ var nameToStateMap = {
}; };
var nameToSwitchMap = { var nameToSwitchMap = {
'on': true, 'true': true,
'off': false 'false': false,
'on': false, // backward compatibility
'off': true // backward compatibility
};
var switchBitOffsets = {
'matrix-off': 0,
'https-only': 2,
'ua-spoof-off': 4
}; };
/******************************************************************************/ /******************************************************************************/
@ -171,7 +179,7 @@ var extractFirstPartyDesDomain = function(srcHostname, desHostname) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.reset = function() { Matrix.prototype.reset = function() {
this.switchedOn = {}; this.switches = {};
this.rules = {}; this.rules = {};
this.rootValue = Matrix.GreenIndirect; this.rootValue = Matrix.GreenIndirect;
}; };
@ -193,12 +201,12 @@ Matrix.prototype.assign = function(other) {
} }
} }
// Remove switches not in other // Remove switches not in other
for ( k in this.switchedOn ) { for ( k in this.switches ) {
if ( this.switchedOn.hasOwnProperty(k) === false ) { if ( this.switches.hasOwnProperty(k) === false ) {
continue; continue;
} }
if ( other.switchedOn.hasOwnProperty(k) === false ) { if ( other.switches.hasOwnProperty(k) === false ) {
delete this.switchedOn[k]; delete this.switches[k];
} }
} }
// Add/change rules in other // Add/change rules in other
@ -209,11 +217,11 @@ Matrix.prototype.assign = function(other) {
this.rules[k] = other.rules[k]; this.rules[k] = other.rules[k];
} }
// Add/change switches in other // Add/change switches in other
for ( k in other.switchedOn ) { for ( k in other.switches ) {
if ( other.switchedOn.hasOwnProperty(k) === false ) { if ( other.switches.hasOwnProperty(k) === false ) {
continue; continue;
} }
this.switchedOn[k] = other.switchedOn[k]; this.switches[k] = other.switches[k];
} }
return this; return this;
}; };
@ -224,19 +232,20 @@ Matrix.prototype.assign = function(other) {
// If value is undefined, the switch is removed // If value is undefined, the switch is removed
Matrix.prototype.setSwitch = function(srcHostname, state) { Matrix.prototype.setSwitch = function(switchName, srcHostname, newState) {
if ( state !== undefined ) { var bitOffset = switchBitOffsets[switchName];
if ( this.switchedOn.hasOwnProperty(srcHostname) === false || this.switchedOn[srcHostname] !== state ) { if ( bitOffset === undefined ) {
this.switchedOn[srcHostname] = state; return false;
return true;
}
} else {
if ( this.switchedOn.hasOwnProperty(srcHostname) ) {
delete this.switchedOn[srcHostname];
return true;
}
} }
return false; var state = this.evaluateSwitch(switchName, srcHostname);
if ( newState === state ) {
return false;
}
var bits = this.switches[srcHostname] || 0;
bits &= ~(3 << bitOffset);
bits |= newState ? 1 << bitOffset : 3 << bitOffset;
this.switches[srcHostname] = bits;
return true;
}; };
/******************************************************************************/ /******************************************************************************/
@ -350,7 +359,7 @@ Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) { Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) {
// Matrix filtering switch // Matrix filtering switch
if ( this.evaluateSwitchZ(srcHostname) !== true ) { if ( this.evaluateSwitchZ('matrix-off', srcHostname) ) {
return Matrix.GreenIndirect; return Matrix.GreenIndirect;
} }
@ -465,45 +474,80 @@ Matrix.prototype.desHostnameFromRule = function(rule) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.toggleSwitch = function(srcHostname, newState) { Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) {
if ( newState === undefined ) { var bitOffset = switchBitOffsets[switchName];
newState = !this.evaluateSwitchZ(srcHostname); if ( bitOffset === undefined ) {
}
delete this.switchedOn[srcHostname];
var oldState = this.evaluateSwitchZ(srcHostname);
if ( newState === oldState ) {
return false; return false;
} }
this.switchedOn[srcHostname] = newState; var state = this.evaluateSwitchZ(switchName, srcHostname);
return true; if ( newState === state ) {
}; return false;
/******************************************************************************/
Matrix.prototype.evaluateSwitch = function(srcHostname) {
var b = this.switchedOn[srcHostname];
if ( b !== undefined ) {
return b;
} }
if ( newState === undefined ) {
newState = !state;
}
var bits = this.switches[srcHostname] || 0;
bits &= ~(3 << bitOffset);
if ( bits === 0 ) {
delete this.switches[srcHostname];
} else {
this.switches[srcHostname] = bits;
}
state = this.evaluateSwitchZ(switchName, srcHostname);
if ( state === newState ) {
return true;
}
bits |= newState ? 1 << bitOffset : 3 << bitOffset;
this.switches[srcHostname] = bits;
return true; return true;
}; };
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateSwitchZ = function(srcHostname) { // 0 = default state, which meaning depends on the switch
var b; // 1 = non-default state
// 3 = forced default state (to override a broader non-default state)
Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) {
var bits = this.switches[srcHostname] || 0;
if ( bits === 0 ) {
return false;
}
var bitOffset = switchBitOffsets[switchName];
if ( bitOffset === undefined ) {
return false;
}
bits = bits >> bitOffset & 3;
return bits === 1;
};
/******************************************************************************/
// 0 = default state, which meaning depends on the switch
// 1 = non-default state
// 3 = forced default state (to override a broader non-default state)
Matrix.prototype.evaluateSwitchZ = function(switchName, srcHostname) {
var bitOffset = switchBitOffsets[switchName];
if ( bitOffset === undefined ) {
return false;
}
var bits;
var s = srcHostname; var s = srcHostname;
for (;;) { for (;;) {
b = this.switchedOn[s]; bits = this.switches[s] || 0;
if ( b !== undefined ) { if ( bits !== 0 ) {
return b; bits = bits >> bitOffset & 3;
if ( bits !== 0 ) {
return bits === 1;
}
} }
s = toBroaderHostname(s); s = toBroaderHostname(s);
if ( s === '' ) { if ( s === '' ) {
break; break;
} }
} }
return true; return false;
}; };
/******************************************************************************/ /******************************************************************************/
@ -544,7 +588,7 @@ Matrix.prototype.extractAllDestinationHostnames = function() {
Matrix.prototype.toString = function() { Matrix.prototype.toString = function() {
var out = []; var out = [];
var rule, type, val; var rule, type, switchName, val;
var srcHostname, desHostname; var srcHostname, desHostname;
for ( rule in this.rules ) { for ( rule in this.rules ) {
if ( this.rules.hasOwnProperty(rule) === false ) { if ( this.rules.hasOwnProperty(rule) === false ) {
@ -568,12 +612,20 @@ Matrix.prototype.toString = function() {
); );
} }
} }
for ( srcHostname in this.switchedOn ) { for ( srcHostname in this.switches ) {
if ( this.switchedOn.hasOwnProperty(srcHostname) === false ) { if ( this.switches.hasOwnProperty(srcHostname) === false ) {
continue; continue;
} }
val = this.switchedOn[srcHostname] ? 'on' : 'off'; for ( switchName in switchBitOffsets ) {
out.push('matrix: ' + srcHostname + ' ' + val); if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
continue;
}
val = this.evaluateSwitch(switchName, srcHostname);
if ( val === false ) {
continue;
}
out.push(switchName + ': ' + srcHostname + ' ' + val);
}
} }
return out.sort().join('\n'); return out.sort().join('\n');
}; };
@ -586,6 +638,7 @@ Matrix.prototype.fromString = function(text, append) {
var lineBeg = 0, lineEnd; var lineBeg = 0, lineEnd;
var line, pos; var line, pos;
var fields, fieldVal; var fields, fieldVal;
var switchName;
var srcHostname = ''; var srcHostname = '';
var desHostname = ''; var desHostname = '';
var type, state; var type, state;
@ -611,7 +664,7 @@ Matrix.prototype.fromString = function(text, append) {
fields = line.split(/\s+/); fields = line.split(/\s+/);
// Less than 2 fields make no sense // Less than 2 fields makes no sense
if ( fields.length < 2 ) { if ( fields.length < 2 ) {
continue; continue;
} }
@ -638,12 +691,21 @@ Matrix.prototype.fromString = function(text, append) {
// `switch:` srcHostname state // `switch:` srcHostname state
// state = [`on`, `off`] // state = [`on`, `off`]
switchName = '';
pos = fieldVal.indexOf('switch:'); pos = fieldVal.indexOf('switch:');
if ( pos === -1 ) {
pos = fieldVal.indexOf('matrix:');
}
if ( pos !== -1 ) { if ( pos !== -1 ) {
fieldVal = 'matrix-off:';
} else {
pos = fieldVal.indexOf('matrix:');
if ( pos !== -1 ) {
fieldVal = 'matrix-off:';
}
}
pos = fieldVal.indexOf(':');
if ( pos !== -1 ) {
switchName = fieldVal.slice(0, pos);
}
if ( switchBitOffsets.hasOwnProperty(switchName) ) {
srcHostname = punycode.toASCII(fields[1]); srcHostname = punycode.toASCII(fields[1]);
// No state field: reject // No state field: reject
@ -656,7 +718,7 @@ Matrix.prototype.fromString = function(text, append) {
continue; continue;
} }
matrix.setSwitch(srcHostname, nameToSwitchMap[fieldVal]); matrix.setSwitch(switchName, srcHostname, nameToSwitchMap[fieldVal]);
continue; continue;
} }
@ -723,7 +785,7 @@ Matrix.prototype.fromString = function(text, append) {
Matrix.prototype.toSelfie = function() { Matrix.prototype.toSelfie = function() {
return { return {
magicId: magicId, magicId: magicId,
switchedOn: this.switchedOn, switches: this.switches,
rules: this.rules rules: this.rules
}; };
}; };
@ -731,7 +793,7 @@ Matrix.prototype.toSelfie = function() {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.fromSelfie = function(selfie) { Matrix.prototype.fromSelfie = function(selfie) {
this.switchedOn = selfie.switchedOn; this.switches = selfie.switches;
this.rules = selfie.rules; this.rules = selfie.rules;
}; };
@ -740,15 +802,20 @@ 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, thisVal, otherVal; var switchName, i, thisVal, otherVal;
for (;;) { for (;;) {
thisVal = this.evaluateSwitch(srcHostname); for ( switchName in switchBitOffsets ) {
otherVal = other.evaluateSwitch(srcHostname); if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
if ( thisVal !== otherVal ) { continue;
out.push({ }
'what': 'matrix', thisVal = this.evaluateSwitch(switchName, srcHostname);
'src': srcHostname otherVal = other.evaluateSwitch(switchName, srcHostname);
}); if ( thisVal !== otherVal ) {
out.push({
'what': switchName,
'src': srcHostname
});
}
} }
i = desHostnames.length; i = desHostnames.length;
while ( i-- ) { while ( i-- ) {
@ -786,16 +853,16 @@ Matrix.prototype.applyDiff = function(diff, from) {
var action, val; var action, val;
while ( i-- ) { while ( i-- ) {
action = diff[i]; action = diff[i];
if ( action.what === 'matrix' ) {
val = from.evaluateSwitch(action.src);
changed = this.setSwitch(action.src, val) || changed;
continue;
}
if ( action.what === 'rule' ) { if ( action.what === 'rule' ) {
val = from.evaluateCell(action.src, action.des, action.type); val = from.evaluateCell(action.src, action.des, action.type);
changed = this.setCell(action.src, action.des, action.type, val) || changed; changed = this.setCell(action.src, action.des, action.type, val) || changed;
continue; continue;
} }
if ( switchBitOffsets.hasOwnProperty(action.what) ) {
val = from.evaluateSwitch(action.what, action.src);
changed = this.setSwitch(action.what, action.src, val) || changed;
continue;
}
} }
return changed; return changed;
}; };

View file

@ -115,8 +115,8 @@ var matrixSnapshot = function(details) {
r.scope = r.domain; r.scope = r.domain;
} }
r.tSwitch = µm.tMatrix.evaluateSwitchZ(r.scope); r.tSwitch = µm.tMatrix.evaluateSwitchZ('matrix-off', r.scope);
r.pSwitch = µm.pMatrix.evaluateSwitchZ(r.scope); r.pSwitch = µm.pMatrix.evaluateSwitchZ('matrix-off', r.scope);
// These rows always exist // These rows always exist
r.rows['*'] = new RowSnapshot(r.scope, '*', '*'); r.rows['*'] = new RowSnapshot(r.scope, '*', '*');
@ -209,7 +209,11 @@ var onMessage = function(request, sender, callback) {
break; break;
case 'toggleMatrixSwitch': case 'toggleMatrixSwitch':
µm.tMatrix.toggleSwitch(request.srcHostname); µm.tMatrix.setSwitchZ(
'matrix-off',
request.srcHostname,
!µm.tMatrix.evaluateSwitchZ('matrix-off', request.srcHostname)
);
break; break;
case 'blacklistMatrixCell': case 'blacklistMatrixCell':

View file

@ -1020,10 +1020,10 @@ function updateMtxbutton() {
var masterSwitch = matrixSnapshot.tSwitch; var masterSwitch = matrixSnapshot.tSwitch;
var count = matrixSnapshot.blockedCount; var count = matrixSnapshot.blockedCount;
var button = uDom('#buttonMtxFiltering'); var button = uDom('#buttonMtxFiltering');
button.toggleClass('disabled', !masterSwitch); button.toggleClass('disabled', masterSwitch);
button.descendants('span.badge').text(count.toLocaleString()); button.descendants('span.badge').text(count.toLocaleString());
button.attr('data-tip', button.attr('data-tip').replace('{{count}}', count)); button.attr('data-tip', button.attr('data-tip').replace('{{count}}', count));
uDom('body').toggleClass('powerOff', !masterSwitch); uDom('body').toggleClass('powerOff', masterSwitch);
} }
function toggleMtxFiltering() { function toggleMtxFiltering() {