mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-09-29 08:41:11 +13:00
parent
0e23caeec4
commit
4aab150af3
4 changed files with 153 additions and 99 deletions
|
@ -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) {
|
||||||
|
|
203
src/js/matrix.js
203
src/js/matrix.js
|
@ -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 true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( this.switchedOn.hasOwnProperty(srcHostname) ) {
|
|
||||||
delete this.switchedOn[srcHostname];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
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,16 +802,21 @@ 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 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
thisVal = this.evaluateSwitch(switchName, srcHostname);
|
||||||
|
otherVal = other.evaluateSwitch(switchName, srcHostname);
|
||||||
if ( thisVal !== otherVal ) {
|
if ( thisVal !== otherVal ) {
|
||||||
out.push({
|
out.push({
|
||||||
'what': 'matrix',
|
'what': switchName,
|
||||||
'src': srcHostname
|
'src': srcHostname
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
i = desHostnames.length;
|
i = desHostnames.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
desHostname = desHostnames[i];
|
desHostname = desHostnames[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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue