mirror of https://github.com/gorhill/uBlock.git
fix #2859
This commit is contained in:
parent
3ef4005f63
commit
6d34a52179
|
@ -127,7 +127,8 @@ var proceedPermanent = function() {
|
|||
name: 'no-strict-blocking',
|
||||
hostname: getTargetHostname(),
|
||||
deep: true,
|
||||
state: true
|
||||
state: true,
|
||||
persist: true
|
||||
},
|
||||
proceedToURL
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2014-2018 Raymond Hill
|
||||
Copyright (C) 2014-present Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -67,12 +67,12 @@ var differ;
|
|||
// ... and modified as needed.
|
||||
|
||||
var updateOverlay = (function() {
|
||||
var reFilter;
|
||||
var mode = {
|
||||
let reFilter;
|
||||
let mode = {
|
||||
token: function(stream) {
|
||||
if ( reFilter !== undefined ) {
|
||||
reFilter.lastIndex = stream.pos;
|
||||
var match = reFilter.exec(stream.string);
|
||||
let match = reFilter.exec(stream.string);
|
||||
if ( match !== null ) {
|
||||
if ( match.index === stream.pos ) {
|
||||
stream.pos += match[0].length || 1;
|
||||
|
@ -100,35 +100,38 @@ var updateOverlay = (function() {
|
|||
// - Minimum amount of text updated
|
||||
|
||||
var rulesToDoc = function(clearHistory) {
|
||||
for ( var key in unfilteredRules ) {
|
||||
for ( let key in unfilteredRules ) {
|
||||
if ( unfilteredRules.hasOwnProperty(key) === false ) { continue; }
|
||||
var doc = unfilteredRules[key].doc;
|
||||
var rules = filterRules(key);
|
||||
if ( doc.lineCount() === 1 && doc.getValue() === '' || rules.length === 0 ) {
|
||||
let doc = unfilteredRules[key].doc;
|
||||
let rules = filterRules(key);
|
||||
if (
|
||||
doc.lineCount() === 1 && doc.getValue() === '' ||
|
||||
rules.length === 0
|
||||
) {
|
||||
doc.setValue(rules.length !== 0 ? rules.join('\n') : '');
|
||||
continue;
|
||||
}
|
||||
if ( differ === undefined ) { differ = new diff_match_patch(); }
|
||||
var beforeText = doc.getValue();
|
||||
var afterText = rules.join('\n');
|
||||
var diffs = differ.diff_main(beforeText, afterText);
|
||||
let beforeText = doc.getValue();
|
||||
let afterText = rules.join('\n');
|
||||
let diffs = differ.diff_main(beforeText, afterText);
|
||||
doc.startOperation();
|
||||
var i = diffs.length,
|
||||
let i = diffs.length,
|
||||
iedit = beforeText.length;
|
||||
while ( i-- ) {
|
||||
var diff = diffs[i];
|
||||
let diff = diffs[i];
|
||||
if ( diff[0] === 0 ) {
|
||||
iedit -= diff[1].length;
|
||||
continue;
|
||||
}
|
||||
var end = doc.posFromIndex(iedit);
|
||||
let end = doc.posFromIndex(iedit);
|
||||
if ( diff[0] === 1 ) {
|
||||
doc.replaceRange(diff[1], end, end);
|
||||
continue;
|
||||
}
|
||||
/* diff[0] === -1 */
|
||||
iedit -= diff[1].length;
|
||||
var beg = doc.posFromIndex(iedit);
|
||||
let beg = doc.posFromIndex(iedit);
|
||||
doc.replaceRange('', beg, end);
|
||||
}
|
||||
doc.endOperation();
|
||||
|
@ -143,11 +146,11 @@ var rulesToDoc = function(clearHistory) {
|
|||
/******************************************************************************/
|
||||
|
||||
var filterRules = function(key) {
|
||||
var rules = unfilteredRules[key].rules;
|
||||
var filter = uDom('#ruleFilter input').val();
|
||||
let rules = unfilteredRules[key].rules;
|
||||
let filter = uDom.nodeFromSelector('#ruleFilter input').value;
|
||||
if ( filter !== '' ) {
|
||||
rules = rules.slice();
|
||||
var i = rules.length;
|
||||
let i = rules.length;
|
||||
while ( i-- ) {
|
||||
if ( rules[i].indexOf(filter) === -1 ) {
|
||||
rules.splice(i, 1);
|
||||
|
@ -160,16 +163,23 @@ var filterRules = function(key) {
|
|||
/******************************************************************************/
|
||||
|
||||
var renderRules = (function() {
|
||||
var firstVisit = true;
|
||||
let firstVisit = true;
|
||||
let reIsSwitchRule = /^[a-z-]+: /;
|
||||
|
||||
// Switches always listed at the top.
|
||||
let customSort = (a, b) => {
|
||||
let aIsSwitch = reIsSwitchRule.test(a);
|
||||
if ( reIsSwitchRule.test(b) === aIsSwitch ) {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
return aIsSwitch ? -1 : 1;
|
||||
};
|
||||
|
||||
return function(details) {
|
||||
details.hnSwitches.sort();
|
||||
details.permanentRules.sort();
|
||||
details.sessionRules.sort();
|
||||
unfilteredRules.orig.rules =
|
||||
details.hnSwitches.concat(details.permanentRules);
|
||||
unfilteredRules.edit.rules =
|
||||
details.hnSwitches.concat(details.sessionRules);
|
||||
details.permanentRules.sort(customSort);
|
||||
details.sessionRules.sort(customSort);
|
||||
unfilteredRules.orig.rules = details.permanentRules;
|
||||
unfilteredRules.edit.rules = details.sessionRules;
|
||||
rulesToDoc(firstVisit);
|
||||
if ( firstVisit ) {
|
||||
firstVisit = false;
|
||||
|
@ -206,20 +216,19 @@ mergeView.options.revertChunk = function(
|
|||
) {
|
||||
// https://github.com/gorhill/uBlock/issues/3611
|
||||
if ( document.body.getAttribute('dir') === 'rtl' ) {
|
||||
var tmp;
|
||||
tmp = from; from = to; to = tmp;
|
||||
let tmp = from; from = to; to = tmp;
|
||||
tmp = fromStart; fromStart = toStart; toStart = tmp;
|
||||
tmp = fromEnd; fromEnd = toEnd; toEnd = tmp;
|
||||
}
|
||||
if ( typeof fromStart.ch !== 'number' ) { fromStart.ch = 0; }
|
||||
if ( fromEnd.ch !== 0 ) { fromEnd.line += 1; }
|
||||
var toAdd = from.getRange(
|
||||
let toAdd = from.getRange(
|
||||
{ line: fromStart.line, ch: 0 },
|
||||
{ line: fromEnd.line, ch: 0 }
|
||||
);
|
||||
if ( typeof toStart.ch !== 'number' ) { toStart.ch = 0; }
|
||||
if ( toEnd.ch !== 0 ) { toEnd.line += 1; }
|
||||
var toRemove = to.getRange(
|
||||
let toRemove = to.getRange(
|
||||
{ line: toStart.line, ch: 0 },
|
||||
{ line: toEnd.line, ch: 0 }
|
||||
);
|
||||
|
@ -229,12 +238,12 @@ mergeView.options.revertChunk = function(
|
|||
/******************************************************************************/
|
||||
|
||||
function handleImportFilePicker() {
|
||||
var fileReaderOnLoadHandler = function() {
|
||||
let fileReaderOnLoadHandler = function() {
|
||||
if ( typeof this.result !== 'string' || this.result === '' ) { return; }
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/757
|
||||
// Support RequestPolicy rule syntax
|
||||
var result = this.result;
|
||||
var matches = /\[origins-to-destinations\]([^\[]+)/.exec(result);
|
||||
let result = this.result;
|
||||
let matches = /\[origins-to-destinations\]([^\[]+)/.exec(result);
|
||||
if ( matches && matches.length === 2 ) {
|
||||
result = matches[1].trim()
|
||||
.replace(/\|/g, ' ')
|
||||
|
@ -242,10 +251,10 @@ function handleImportFilePicker() {
|
|||
}
|
||||
applyDiff(false, result, '');
|
||||
};
|
||||
var file = this.files[0];
|
||||
let file = this.files[0];
|
||||
if ( file === undefined || file.name === '' ) { return; }
|
||||
if ( file.type.indexOf('text') !== 0 ) { return; }
|
||||
var fr = new FileReader();
|
||||
let fr = new FileReader();
|
||||
fr.onload = fileReaderOnLoadHandler;
|
||||
fr.readAsText(file);
|
||||
}
|
||||
|
@ -253,7 +262,7 @@ function handleImportFilePicker() {
|
|||
/******************************************************************************/
|
||||
|
||||
var startImportFilePicker = function() {
|
||||
var input = document.getElementById('importFilePicker');
|
||||
let input = document.getElementById('importFilePicker');
|
||||
// Reset to empty string, this will ensure an change event is properly
|
||||
// triggered if the user pick a file, even if it is the same as the last
|
||||
// one picked.
|
||||
|
@ -264,7 +273,7 @@ var startImportFilePicker = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
function exportUserRulesToFile() {
|
||||
var filename = vAPI.i18n('rulesDefaultFileName')
|
||||
let filename = vAPI.i18n('rulesDefaultFileName')
|
||||
.replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString())
|
||||
.replace(/ +/g, '_');
|
||||
vAPI.download({
|
||||
|
@ -279,14 +288,14 @@ function exportUserRulesToFile() {
|
|||
/******************************************************************************/
|
||||
|
||||
var onFilterChanged = (function() {
|
||||
var timer,
|
||||
let timer,
|
||||
overlay = null,
|
||||
last = '';
|
||||
|
||||
var process = function() {
|
||||
let process = function() {
|
||||
timer = undefined;
|
||||
if ( mergeView.editor().isClean(cleanEditToken) === false ) { return; }
|
||||
var filter = uDom('#ruleFilter input').val();
|
||||
let filter = uDom.nodeFromSelector('#ruleFilter input').value;
|
||||
if ( filter === last ) { return; }
|
||||
last = filter;
|
||||
if ( overlay !== null ) {
|
||||
|
@ -311,12 +320,12 @@ var onFilterChanged = (function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var onTextChanged = (function() {
|
||||
var timer;
|
||||
let timer;
|
||||
|
||||
var process = function(now) {
|
||||
let process = function(now) {
|
||||
timer = undefined;
|
||||
var isClean = mergeView.editor().isClean(cleanEditToken);
|
||||
var diff = document.getElementById('diff');
|
||||
let isClean = mergeView.editor().isClean(cleanEditToken);
|
||||
let diff = document.getElementById('diff');
|
||||
if (
|
||||
now &&
|
||||
isClean === false &&
|
||||
|
@ -331,7 +340,7 @@ var onTextChanged = (function() {
|
|||
'disabled',
|
||||
isClean
|
||||
);
|
||||
var input = document.querySelector('#ruleFilter input');
|
||||
let input = document.querySelector('#ruleFilter input');
|
||||
if ( isClean ) {
|
||||
input.removeAttribute('disabled');
|
||||
CodeMirror.commands.save = undefined;
|
||||
|
@ -350,15 +359,15 @@ var onTextChanged = (function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var revertAllHandler = function() {
|
||||
var toAdd = [], toRemove = [];
|
||||
var left = mergeView.leftOriginal(),
|
||||
let toAdd = [], toRemove = [];
|
||||
let left = mergeView.leftOriginal(),
|
||||
edit = mergeView.editor();
|
||||
for ( var chunk of mergeView.leftChunks() ) {
|
||||
var addedLines = left.getRange(
|
||||
for ( let chunk of mergeView.leftChunks() ) {
|
||||
let addedLines = left.getRange(
|
||||
{ line: chunk.origFrom, ch: 0 },
|
||||
{ line: chunk.origTo, ch: 0 }
|
||||
);
|
||||
var removedLines = edit.getRange(
|
||||
let removedLines = edit.getRange(
|
||||
{ line: chunk.editFrom, ch: 0 },
|
||||
{ line: chunk.editTo, ch: 0 }
|
||||
);
|
||||
|
@ -371,15 +380,15 @@ var revertAllHandler = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var commitAllHandler = function() {
|
||||
var toAdd = [], toRemove = [];
|
||||
var left = mergeView.leftOriginal(),
|
||||
let toAdd = [], toRemove = [];
|
||||
let left = mergeView.leftOriginal(),
|
||||
edit = mergeView.editor();
|
||||
for ( var chunk of mergeView.leftChunks() ) {
|
||||
var addedLines = edit.getRange(
|
||||
for ( let chunk of mergeView.leftChunks() ) {
|
||||
let addedLines = edit.getRange(
|
||||
{ line: chunk.editFrom, ch: 0 },
|
||||
{ line: chunk.editTo, ch: 0 }
|
||||
);
|
||||
var removedLines = left.getRange(
|
||||
let removedLines = left.getRange(
|
||||
{ line: chunk.origFrom, ch: 0 },
|
||||
{ line: chunk.origTo, ch: 0 }
|
||||
);
|
||||
|
@ -392,16 +401,16 @@ var commitAllHandler = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var editSaveHandler = function() {
|
||||
var editor = mergeView.editor();
|
||||
var editText = editor.getValue().trim();
|
||||
let editor = mergeView.editor();
|
||||
let editText = editor.getValue().trim();
|
||||
if ( editText === cleanEditText ) {
|
||||
onTextChanged(true);
|
||||
return;
|
||||
}
|
||||
if ( differ === undefined ) { differ = new diff_match_patch(); }
|
||||
var toAdd = [], toRemove = [];
|
||||
var diffs = differ.diff_main(cleanEditText, editText);
|
||||
for ( var diff of diffs ) {
|
||||
let toAdd = [], toRemove = [];
|
||||
let diffs = differ.diff_main(cleanEditText, editText);
|
||||
for ( let diff of diffs ) {
|
||||
if ( diff[0] === 1 ) {
|
||||
toAdd.push(diff[1]);
|
||||
} else if ( diff[0] === -1 ) {
|
||||
|
|
|
@ -107,45 +107,59 @@ Matrix.prototype.assign = function(other) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
Matrix.prototype.copyRules = function(other, srcHostname, desHostnames) {
|
||||
|
||||
Matrix.prototype.copyRules = function(from, srcHostname, desHostnames) {
|
||||
// Specific types
|
||||
var bits = other.rules.get('* *');
|
||||
if ( bits !== undefined ) {
|
||||
this.rules.set('* *', bits);
|
||||
} else {
|
||||
this.rules.delete('* *');
|
||||
let thisBits = this.rules.get('* *');
|
||||
let fromBits = from.rules.get('* *');
|
||||
if ( fromBits !== thisBits ) {
|
||||
if ( fromBits !== undefined ) {
|
||||
this.rules.set('* *', fromBits);
|
||||
} else {
|
||||
this.rules.delete('* *');
|
||||
}
|
||||
this.changed = true;
|
||||
}
|
||||
var key = srcHostname + ' *';
|
||||
bits = other.rules.get(key);
|
||||
if ( bits !== undefined ) {
|
||||
this.rules.set(key, bits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
|
||||
let key = srcHostname + ' *';
|
||||
thisBits = this.rules.get(key);
|
||||
fromBits = from.rules.get(key);
|
||||
if ( fromBits !== thisBits ) {
|
||||
if ( fromBits !== undefined ) {
|
||||
this.rules.set(key, fromBits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
}
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
// Specific destinations
|
||||
for ( var desHostname in desHostnames ) {
|
||||
for ( let desHostname in desHostnames ) {
|
||||
if ( desHostnames.hasOwnProperty(desHostname) === false ) { continue; }
|
||||
key = '* ' + desHostname;
|
||||
bits = other.rules.get(key);
|
||||
if ( bits !== undefined ) {
|
||||
this.rules.set(key, bits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
thisBits = this.rules.get(key);
|
||||
fromBits = from.rules.get(key);
|
||||
if ( fromBits !== thisBits ) {
|
||||
if ( fromBits !== undefined ) {
|
||||
this.rules.set(key, fromBits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
}
|
||||
this.changed = true;
|
||||
}
|
||||
key = srcHostname + ' ' + desHostname ;
|
||||
bits = other.rules.get(key);
|
||||
if ( bits !== undefined ) {
|
||||
this.rules.set(key, bits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
thisBits = this.rules.get(key);
|
||||
fromBits = from.rules.get(key);
|
||||
if ( fromBits !== thisBits ) {
|
||||
if ( fromBits !== undefined ) {
|
||||
this.rules.set(key, fromBits);
|
||||
} else {
|
||||
this.rules.delete(key);
|
||||
}
|
||||
this.changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.changed = true;
|
||||
|
||||
return true;
|
||||
return this.changed;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -80,17 +80,54 @@ HnSwitches.prototype.reset = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.assign = function(from) {
|
||||
// Remove rules not in other
|
||||
for ( let hn of this.switches.keys() ) {
|
||||
if ( from.switches.has(hn) === false ) {
|
||||
this.switches.delete(hn);
|
||||
this.changed = true;
|
||||
}
|
||||
}
|
||||
// Add/change rules in other
|
||||
for ( let [hn, bits] of from.switches ) {
|
||||
if ( this.switches.get(hn) !== bits ) {
|
||||
this.switches.set(hn, bits);
|
||||
this.changed = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.copyRules = function(from, srcHostname) {
|
||||
let thisBits = this.switches.get(srcHostname);
|
||||
let fromBits = from.switches.get(srcHostname);
|
||||
if ( fromBits !== thisBits ) {
|
||||
if ( fromBits !== undefined ) {
|
||||
this.switches.set(srcHostname, fromBits);
|
||||
} else {
|
||||
this.switches.delete(srcHostname);
|
||||
}
|
||||
this.changed = true;
|
||||
}
|
||||
return this.changed;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.hasSameRules = function(other, srcHostname) {
|
||||
return this.switches.get(srcHostname) === other.switches.get(srcHostname);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// If value is undefined, the switch is removed
|
||||
|
||||
HnSwitches.prototype.toggle = function(switchName, hostname, newVal) {
|
||||
var bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) {
|
||||
return false;
|
||||
}
|
||||
if ( newVal === this.evaluate(switchName, hostname) ) {
|
||||
return false;
|
||||
}
|
||||
var bits = this.switches.get(hostname) || 0;
|
||||
let bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) { return false; }
|
||||
if ( newVal === this.evaluate(switchName, hostname) ) { return false; }
|
||||
let bits = this.switches.get(hostname) || 0;
|
||||
bits &= ~(3 << bitOffset);
|
||||
bits |= newVal << bitOffset;
|
||||
if ( bits === 0 ) {
|
||||
|
@ -105,18 +142,14 @@ HnSwitches.prototype.toggle = function(switchName, hostname, newVal) {
|
|||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.toggleOneZ = function(switchName, hostname, newState) {
|
||||
var bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) {
|
||||
return false;
|
||||
}
|
||||
var state = this.evaluateZ(switchName, hostname);
|
||||
if ( newState === state ) {
|
||||
return false;
|
||||
}
|
||||
let bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) { return false; }
|
||||
let state = this.evaluateZ(switchName, hostname);
|
||||
if ( newState === state ) { return false; }
|
||||
if ( newState === undefined ) {
|
||||
newState = !state;
|
||||
}
|
||||
var bits = this.switches.get(hostname) || 0;
|
||||
let bits = this.switches.get(hostname) || 0;
|
||||
bits &= ~(3 << bitOffset);
|
||||
if ( bits === 0 ) {
|
||||
this.switches.delete(hostname);
|
||||
|
@ -138,17 +171,11 @@ HnSwitches.prototype.toggleBranchZ = function(switchName, targetHostname, newSta
|
|||
|
||||
// Turn off all descendant switches, they will inherit the state of the
|
||||
// branch's origin.
|
||||
var targetLen = targetHostname.length;
|
||||
for ( var hostname of this.switches.keys() ) {
|
||||
if ( hostname === targetHostname ) {
|
||||
continue;
|
||||
}
|
||||
if ( hostname.length <= targetLen ) {
|
||||
continue;
|
||||
}
|
||||
if ( hostname.endsWith(targetHostname) === false ) {
|
||||
continue;
|
||||
}
|
||||
let targetLen = targetHostname.length;
|
||||
for ( let hostname of this.switches.keys() ) {
|
||||
if ( hostname === targetHostname ) { continue; }
|
||||
if ( hostname.length <= targetLen ) { continue; }
|
||||
if ( hostname.endsWith(targetHostname) === false ) { continue; }
|
||||
if ( hostname.charAt(hostname.length - targetLen - 1) !== '.' ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -174,11 +201,11 @@ HnSwitches.prototype.toggleZ = function(switchName, hostname, deep, newState) {
|
|||
// 2 = forced default state (to override a broader non-default state)
|
||||
|
||||
HnSwitches.prototype.evaluate = function(switchName, hostname) {
|
||||
var bits = this.switches.get(hostname);
|
||||
let bits = this.switches.get(hostname);
|
||||
if ( bits === undefined ) {
|
||||
return 0;
|
||||
}
|
||||
var bitOffset = switchBitOffsets[switchName];
|
||||
let bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -188,7 +215,7 @@ HnSwitches.prototype.evaluate = function(switchName, hostname) {
|
|||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.evaluateZ = function(switchName, hostname) {
|
||||
var bitOffset = switchBitOffsets[switchName];
|
||||
let bitOffset = switchBitOffsets[switchName];
|
||||
if ( bitOffset === undefined ) {
|
||||
this.r = 0;
|
||||
return false;
|
||||
|
@ -223,14 +250,14 @@ HnSwitches.prototype.toLogData = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.toArray = function() {
|
||||
var out = [],
|
||||
let out = [],
|
||||
toUnicode = punycode.toUnicode;
|
||||
for ( var hostname of this.switches.keys() ) {
|
||||
for ( let hostname of this.switches.keys() ) {
|
||||
for ( var switchName in switchBitOffsets ) {
|
||||
if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
|
||||
continue;
|
||||
}
|
||||
var val = this.evaluate(switchName, hostname);
|
||||
let val = this.evaluate(switchName, hostname);
|
||||
if ( val === 0 ) { continue; }
|
||||
if ( hostname.indexOf('xn--') !== -1 ) {
|
||||
hostname = toUnicode(hostname);
|
||||
|
@ -248,7 +275,7 @@ HnSwitches.prototype.toString = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
HnSwitches.prototype.fromString = function(text, append) {
|
||||
var lineIter = new µBlock.LineIterator(text);
|
||||
let lineIter = new µBlock.LineIterator(text);
|
||||
if ( append !== true ) { this.reset(); }
|
||||
while ( lineIter.eot() === false ) {
|
||||
this.addFromRuleParts(lineIter.next().trim().split(/\s+/));
|
||||
|
@ -270,7 +297,7 @@ HnSwitches.prototype.validateRuleParts = function(parts) {
|
|||
|
||||
HnSwitches.prototype.addFromRuleParts = function(parts) {
|
||||
if ( this.validateRuleParts(parts) !== undefined ) {
|
||||
var switchName = parts[0].slice(0, -1);
|
||||
let switchName = parts[0].slice(0, -1);
|
||||
if ( switchBitOffsets.hasOwnProperty(switchName) ) {
|
||||
this.toggle(switchName, parts[1], nameToSwitchStateMap[parts[2]]);
|
||||
return true;
|
||||
|
@ -297,6 +324,7 @@ return HnSwitches;
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.hnSwitches = new µBlock.HnSwitches();
|
||||
µBlock.sessionSwitches = new µBlock.HnSwitches();
|
||||
µBlock.permanentSwitches = new µBlock.HnSwitches();
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -279,9 +279,10 @@ var getFirewallRules = function(srcHostname, desHostnames) {
|
|||
/******************************************************************************/
|
||||
|
||||
var popupDataFromTabId = function(tabId, tabTitle) {
|
||||
var tabContext = µb.tabContextManager.mustLookup(tabId),
|
||||
let tabContext = µb.tabContextManager.mustLookup(tabId),
|
||||
rootHostname = tabContext.rootHostname;
|
||||
var r = {
|
||||
|
||||
let r = {
|
||||
advancedUserEnabled: µb.userSettings.advancedUserEnabled,
|
||||
appName: vAPI.app.name,
|
||||
appVersion: vAPI.app.version,
|
||||
|
@ -305,7 +306,7 @@ var popupDataFromTabId = function(tabId, tabTitle) {
|
|||
tooltipsDisabled: µb.userSettings.tooltipsDisabled
|
||||
};
|
||||
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
let pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore ) {
|
||||
// https://github.com/gorhill/uBlock/issues/2105
|
||||
// Be sure to always include the current page's hostname -- it might
|
||||
|
@ -325,23 +326,30 @@ var popupDataFromTabId = function(tabId, tabTitle) {
|
|||
r.contentLastModified = pageStore.contentLastModified;
|
||||
r.firewallRules = getFirewallRules(rootHostname, r.hostnameDict);
|
||||
r.canElementPicker = µb.URI.isNetworkURI(r.rawURL);
|
||||
r.noPopups = µb.hnSwitches.evaluateZ('no-popups', rootHostname);
|
||||
r.noPopups = µb.sessionSwitches.evaluateZ('no-popups', rootHostname);
|
||||
r.popupBlockedCount = pageStore.popupBlockedCount;
|
||||
r.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', rootHostname);
|
||||
r.noLargeMedia = µb.hnSwitches.evaluateZ('no-large-media', rootHostname);
|
||||
r.noCosmeticFiltering = µb.sessionSwitches.evaluateZ('no-cosmetic-filtering', rootHostname);
|
||||
r.noLargeMedia = µb.sessionSwitches.evaluateZ('no-large-media', rootHostname);
|
||||
r.largeMediaCount = pageStore.largeMediaCount;
|
||||
r.noRemoteFonts = µb.hnSwitches.evaluateZ('no-remote-fonts', rootHostname);
|
||||
r.noRemoteFonts = µb.sessionSwitches.evaluateZ('no-remote-fonts', rootHostname);
|
||||
r.remoteFontCount = pageStore.remoteFontCount;
|
||||
r.noScripting = µb.hnSwitches.evaluateZ('no-scripting', rootHostname);
|
||||
r.noScripting = µb.sessionSwitches.evaluateZ('no-scripting', rootHostname);
|
||||
} else {
|
||||
r.hostnameDict = {};
|
||||
r.firewallRules = getFirewallRules();
|
||||
}
|
||||
r.matrixIsDirty = !µb.sessionFirewall.hasSameRules(
|
||||
|
||||
r.matrixIsDirty = µb.sessionFirewall.hasSameRules(
|
||||
µb.permanentFirewall,
|
||||
rootHostname,
|
||||
r.hostnameDict
|
||||
);
|
||||
) === false;
|
||||
if ( r.matrixIsDirty === false ) {
|
||||
r.matrixIsDirty = µb.sessionSwitches.hasSameRules(
|
||||
µb.permanentSwitches,
|
||||
rootHostname
|
||||
) === false;
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
|
@ -409,18 +417,41 @@ var onMessage = function(request, sender, callback) {
|
|||
request.srcHostname,
|
||||
request.desHostnames
|
||||
);
|
||||
µb.sessionSwitches.copyRules(
|
||||
µb.permanentSwitches,
|
||||
request.srcHostname
|
||||
);
|
||||
// https://github.com/gorhill/uBlock/issues/188
|
||||
µb.cosmeticFilteringEngine.removeFromSelectorCache(request.srcHostname, 'net');
|
||||
µb.cosmeticFilteringEngine.removeFromSelectorCache(
|
||||
request.srcHostname,
|
||||
'net'
|
||||
);
|
||||
response = popupDataFromTabId(request.tabId);
|
||||
break;
|
||||
|
||||
case 'saveFirewallRules':
|
||||
µb.permanentFirewall.copyRules(
|
||||
µb.sessionFirewall,
|
||||
request.srcHostname,
|
||||
request.desHostnames
|
||||
);
|
||||
µb.savePermanentFirewallRules();
|
||||
if (
|
||||
µb.permanentFirewall.copyRules(
|
||||
µb.sessionFirewall,
|
||||
request.srcHostname,
|
||||
request.desHostnames
|
||||
)
|
||||
) {
|
||||
µb.savePermanentFirewallRules();
|
||||
}
|
||||
if (
|
||||
µb.permanentSwitches.copyRules(
|
||||
µb.sessionSwitches,
|
||||
request.srcHostname
|
||||
)
|
||||
) {
|
||||
µb.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'toggleHostnameSwitch':
|
||||
µb.toggleHostnameSwitch(request);
|
||||
response = popupDataFromTabId(request.tabId);
|
||||
break;
|
||||
|
||||
case 'toggleFirewallRule':
|
||||
|
@ -745,7 +776,7 @@ var backupUserData = function(callback) {
|
|||
netWhitelist: µb.stringFromWhitelist(µb.netWhitelist),
|
||||
dynamicFilteringString: µb.permanentFirewall.toString(),
|
||||
urlFilteringString: µb.permanentURLFiltering.toString(),
|
||||
hostnameSwitchesString: µb.hnSwitches.toString(),
|
||||
hostnameSwitchesString: µb.permanentSwitches.toString(),
|
||||
userFilters: ''
|
||||
};
|
||||
|
||||
|
@ -880,44 +911,55 @@ var getLists = function(callback) {
|
|||
|
||||
var getRules = function() {
|
||||
return {
|
||||
permanentRules: µb.permanentFirewall.toArray().concat(
|
||||
µb.permanentURLFiltering.toArray()
|
||||
),
|
||||
sessionRules: µb.sessionFirewall.toArray().concat(
|
||||
µb.sessionURLFiltering.toArray()
|
||||
),
|
||||
hnSwitches: µb.hnSwitches.toArray()
|
||||
permanentRules:
|
||||
µb.permanentFirewall.toArray().concat(
|
||||
µb.permanentSwitches.toArray(),
|
||||
µb.permanentURLFiltering.toArray()
|
||||
),
|
||||
sessionRules:
|
||||
µb.sessionFirewall.toArray().concat(
|
||||
µb.sessionSwitches.toArray(),
|
||||
µb.sessionURLFiltering.toArray()
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
var modifyRuleset = function(details) {
|
||||
var swRuleset = µb.hnSwitches,
|
||||
hnRuleset, urlRuleset;
|
||||
let swRuleset, hnRuleset, urlRuleset;
|
||||
if ( details.permanent ) {
|
||||
swRuleset = µb.permanentSwitches;
|
||||
hnRuleset = µb.permanentFirewall;
|
||||
urlRuleset = µb.permanentURLFiltering;
|
||||
} else {
|
||||
swRuleset = µb.sessionSwitches;
|
||||
hnRuleset = µb.sessionFirewall;
|
||||
urlRuleset = µb.sessionURLFiltering;
|
||||
}
|
||||
var toRemove = new Set(details.toRemove.trim().split(/\s*[\n\r]+\s*/));
|
||||
var rule, parts, _;
|
||||
for ( rule of toRemove ) {
|
||||
let toRemove = new Set(details.toRemove.trim().split(/\s*[\n\r]+\s*/));
|
||||
for ( let rule of toRemove ) {
|
||||
if ( rule === '' ) { continue; }
|
||||
parts = rule.split(/\s+/);
|
||||
_ = hnRuleset.removeFromRuleParts(parts) ||
|
||||
swRuleset.removeFromRuleParts(parts) ||
|
||||
urlRuleset.removeFromRuleParts(parts);
|
||||
let parts = rule.split(/\s+/);
|
||||
if ( hnRuleset.removeFromRuleParts(parts) === false ) {
|
||||
if ( swRuleset.removeFromRuleParts(parts) === false ) {
|
||||
urlRuleset.removeFromRuleParts(parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
var toAdd = new Set(details.toAdd.trim().split(/\s*[\n\r]+\s*/));
|
||||
for ( rule of toAdd ) {
|
||||
let toAdd = new Set(details.toAdd.trim().split(/\s*[\n\r]+\s*/));
|
||||
for ( let rule of toAdd ) {
|
||||
if ( rule === '' ) { continue; }
|
||||
parts = rule.split(/\s+/);
|
||||
_ = hnRuleset.addFromRuleParts(parts) ||
|
||||
swRuleset.addFromRuleParts(parts) ||
|
||||
urlRuleset.addFromRuleParts(parts);
|
||||
let parts = rule.split(/\s+/);
|
||||
if ( hnRuleset.addFromRuleParts(parts) === false ) {
|
||||
if ( swRuleset.addFromRuleParts(parts) === false ) {
|
||||
urlRuleset.addFromRuleParts(parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( details.permanent ) {
|
||||
if ( swRuleset.changed ) {
|
||||
µb.saveHostnameSwitches();
|
||||
swRuleset.changed = false;
|
||||
}
|
||||
if ( hnRuleset.changed ) {
|
||||
µb.savePermanentFirewallRules();
|
||||
hnRuleset.changed = false;
|
||||
|
@ -927,10 +969,6 @@ var modifyRuleset = function(details) {
|
|||
urlRuleset.changed = false;
|
||||
}
|
||||
}
|
||||
if ( swRuleset.changed ) {
|
||||
µb.saveHostnameSwitches();
|
||||
swRuleset.changed = false;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -297,7 +297,7 @@ PageStore.prototype.init = function(tabId, context) {
|
|||
this.netFilteringCache = NetFilteringResultCache.factory();
|
||||
this.internalRedirectionCount = 0;
|
||||
|
||||
this.noCosmeticFiltering = µb.hnSwitches.evaluateZ(
|
||||
this.noCosmeticFiltering = µb.sessionSwitches.evaluateZ(
|
||||
'no-cosmetic-filtering',
|
||||
tabContext.rootHostname
|
||||
) === true;
|
||||
|
@ -309,7 +309,7 @@ PageStore.prototype.init = function(tabId, context) {
|
|||
µb.logger.writeOne(
|
||||
tabId,
|
||||
'cosmetic',
|
||||
µb.hnSwitches.toLogData(),
|
||||
µb.sessionSwitches.toLogData(),
|
||||
'dom',
|
||||
tabContext.rawURL,
|
||||
this.tabHostname,
|
||||
|
@ -677,9 +677,9 @@ PageStore.prototype.collapsibleResources = {
|
|||
/******************************************************************************/
|
||||
|
||||
PageStore.prototype.filterCSPReport = function(context) {
|
||||
if ( µb.hnSwitches.evaluateZ('no-csp-reports', context.requestHostname) ) {
|
||||
if ( µb.sessionSwitches.evaluateZ('no-csp-reports', context.requestHostname) ) {
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
this.logData = µb.hnSwitches.toLogData();
|
||||
this.logData = µb.sessionSwitches.toLogData();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -708,9 +708,9 @@ PageStore.prototype.filterFont = function(context) {
|
|||
if ( context.requestType === 'font' ) {
|
||||
this.remoteFontCount += 1;
|
||||
}
|
||||
if ( µb.hnSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||
if ( µb.sessionSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
this.logData = µb.hnSwitches.toLogData();
|
||||
this.logData = µb.sessionSwitches.toLogData();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -725,12 +725,12 @@ PageStore.prototype.filterScripting = function(rootHostname, netFiltering) {
|
|||
}
|
||||
if (
|
||||
netFiltering === false ||
|
||||
µb.hnSwitches.evaluateZ('no-scripting', rootHostname) === false
|
||||
µb.sessionSwitches.evaluateZ('no-scripting', rootHostname) === false
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
this.logData = µb.hnSwitches.toLogData();
|
||||
this.logData = µb.sessionSwitches.toLogData();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
@ -745,7 +745,7 @@ PageStore.prototype.filterLargeMediaElement = function(size) {
|
|||
if ( Date.now() < this.allowLargeMediaElementsUntil ) {
|
||||
return 0;
|
||||
}
|
||||
if ( µb.hnSwitches.evaluateZ('no-large-media', this.tabHostname) !== true ) {
|
||||
if ( µb.sessionSwitches.evaluateZ('no-large-media', this.tabHostname) !== true ) {
|
||||
return 0;
|
||||
}
|
||||
if ( (size >>> 10) < µb.userSettings.largeMediaSize ) {
|
||||
|
@ -761,7 +761,7 @@ PageStore.prototype.filterLargeMediaElement = function(size) {
|
|||
}
|
||||
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
this.logData = µb.hnSwitches.toLogData();
|
||||
this.logData = µb.sessionSwitches.toLogData();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -391,6 +391,30 @@ var renderPrivacyExposure = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
let updateHnSwitches = function() {
|
||||
uDom.nodeFromId('no-popups').classList.toggle(
|
||||
'on',
|
||||
popupData.noPopups === true
|
||||
);
|
||||
uDom.nodeFromId('no-large-media').classList.toggle(
|
||||
'on', popupData.noLargeMedia === true
|
||||
);
|
||||
uDom.nodeFromId('no-cosmetic-filtering').classList.toggle(
|
||||
'on',
|
||||
popupData.noCosmeticFiltering === true
|
||||
);
|
||||
uDom.nodeFromId('no-remote-fonts').classList.toggle(
|
||||
'on',
|
||||
popupData.noRemoteFonts === true
|
||||
);
|
||||
uDom.nodeFromId('no-scripting').classList.toggle(
|
||||
'on',
|
||||
popupData.noScripting === true
|
||||
);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Assume everything has to be done incrementally.
|
||||
|
||||
var renderPopup = function() {
|
||||
|
@ -435,11 +459,7 @@ var renderPopup = function() {
|
|||
renderPrivacyExposure();
|
||||
|
||||
// Extra tools
|
||||
uDom.nodeFromId('no-popups').classList.toggle('on', popupData.noPopups === true);
|
||||
uDom.nodeFromId('no-large-media').classList.toggle('on', popupData.noLargeMedia === true);
|
||||
uDom.nodeFromId('no-cosmetic-filtering').classList.toggle('on', popupData.noCosmeticFiltering === true);
|
||||
uDom.nodeFromId('no-remote-fonts').classList.toggle('on', popupData.noRemoteFonts === true);
|
||||
uDom.nodeFromId('no-scripting').classList.toggle('on', popupData.noScripting === true);
|
||||
updateHnSwitches();
|
||||
|
||||
// Report blocked popup count on badge
|
||||
total = popupData.popupBlockedCount;
|
||||
|
@ -458,7 +478,7 @@ var renderPopup = function() {
|
|||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/470
|
||||
// This must be done here, to be sure the popup is resized properly
|
||||
var dfPaneVisible = popupData.dfEnabled;
|
||||
let dfPaneVisible = popupData.dfEnabled;
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/1068
|
||||
// Remember the last state of the firewall pane. This allows to
|
||||
|
@ -774,14 +794,13 @@ var mouseleaveCellHandler = function() {
|
|||
|
||||
var setFirewallRule = function(src, des, type, action, persist) {
|
||||
// This can happen on pages where uBlock does not work
|
||||
if ( typeof popupData.pageHostname !== 'string' || popupData.pageHostname === '' ) {
|
||||
if (
|
||||
typeof popupData.pageHostname !== 'string' ||
|
||||
popupData.pageHostname === ''
|
||||
) {
|
||||
return;
|
||||
}
|
||||
var onFirewallRuleChanged = function(response) {
|
||||
cachePopupData(response);
|
||||
updateAllFirewallCells();
|
||||
hashFromPopupData();
|
||||
};
|
||||
|
||||
messaging.send(
|
||||
'popupPanel',
|
||||
{
|
||||
|
@ -794,14 +813,18 @@ var setFirewallRule = function(src, des, type, action, persist) {
|
|||
action: action,
|
||||
persist: persist
|
||||
},
|
||||
onFirewallRuleChanged
|
||||
response => {
|
||||
cachePopupData(response);
|
||||
updateAllFirewallCells();
|
||||
hashFromPopupData();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var unsetFirewallRuleHandler = function(ev) {
|
||||
var cell = uDom(this);
|
||||
let cell = uDom(ev.target);
|
||||
setFirewallRule(
|
||||
cell.attr('data-src') === '/' ? '*' : popupData.pageHostname,
|
||||
cell.attr('data-des'),
|
||||
|
@ -815,13 +838,11 @@ var unsetFirewallRuleHandler = function(ev) {
|
|||
/******************************************************************************/
|
||||
|
||||
var setFirewallRuleHandler = function(ev) {
|
||||
var hotspot = uDom(this);
|
||||
var cell = hotspot.ancestors('[data-src]');
|
||||
if ( cell.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
var action = 0;
|
||||
var hotspotId = hotspot.attr('id');
|
||||
let hotspot = uDom(ev.target);
|
||||
let cell = hotspot.ancestors('[data-src]');
|
||||
if ( cell.length === 0 ) { return; }
|
||||
let action = 0;
|
||||
let hotspotId = hotspot.attr('id');
|
||||
if ( hotspotId === 'dynaAllow' ) {
|
||||
action = 2;
|
||||
} else if ( hotspotId === 'dynaNoop' ) {
|
||||
|
@ -885,9 +906,9 @@ var toggleMinimize = function(ev) {
|
|||
return;
|
||||
}
|
||||
|
||||
popupData.firewallPaneMinimized = uDom.nodeFromId('firewallContainer')
|
||||
.classList
|
||||
.toggle('minimized');
|
||||
popupData.firewallPaneMinimized =
|
||||
uDom.nodeFromId('firewallContainer').classList.toggle('minimized');
|
||||
|
||||
messaging.send(
|
||||
'popupPanel',
|
||||
{
|
||||
|
@ -916,11 +937,6 @@ var saveFirewallRules = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var revertFirewallRules = function() {
|
||||
var onFirewallRuleChanged = function(response) {
|
||||
cachePopupData(response);
|
||||
updateAllFirewallCells();
|
||||
hashFromPopupData();
|
||||
};
|
||||
messaging.send(
|
||||
'popupPanel',
|
||||
{
|
||||
|
@ -929,7 +945,12 @@ var revertFirewallRules = function() {
|
|||
desHostnames: popupData.hostnameDict,
|
||||
tabId: popupData.tabId
|
||||
},
|
||||
onFirewallRuleChanged
|
||||
response => {
|
||||
cachePopupData(response);
|
||||
updateAllFirewallCells();
|
||||
updateHnSwitches();
|
||||
hashFromPopupData();
|
||||
}
|
||||
);
|
||||
uDom.nodeFromId('firewallContainer').classList.remove('dirty');
|
||||
};
|
||||
|
@ -937,8 +958,8 @@ var revertFirewallRules = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var toggleHostnameSwitch = function(ev) {
|
||||
var target = ev.currentTarget;
|
||||
var switchName = target.getAttribute('id');
|
||||
let target = ev.currentTarget;
|
||||
let switchName = target.getAttribute('id');
|
||||
if ( !switchName ) { return; }
|
||||
target.classList.toggle('on');
|
||||
messaging.send(
|
||||
|
@ -948,11 +969,16 @@ var toggleHostnameSwitch = function(ev) {
|
|||
name: switchName,
|
||||
hostname: popupData.pageHostname,
|
||||
state: target.classList.contains('on'),
|
||||
tabId: popupData.tabId
|
||||
tabId: popupData.tabId,
|
||||
persist: popupData.dfEnabled === false || ev.ctrlKey || ev.metaKey
|
||||
},
|
||||
response => {
|
||||
cachePopupData(response);
|
||||
updateAllFirewallCells();
|
||||
hashFromPopupData();
|
||||
}
|
||||
);
|
||||
renderTooltips('#' + switchName);
|
||||
hashFromPopupData();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -42,7 +42,8 @@ vAPI.app.onShutdown = function() {
|
|||
µb.permanentFirewall.reset();
|
||||
µb.sessionURLFiltering.reset();
|
||||
µb.permanentURLFiltering.reset();
|
||||
µb.hnSwitches.reset();
|
||||
µb.sessionSwitches.reset();
|
||||
µb.permanentSwitches.reset();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -124,52 +125,11 @@ var onVersionReady = function(lastVersion) {
|
|||
// release. This will be done only for release versions of Firefox.
|
||||
if (
|
||||
vAPI.webextFlavor.soup.has('firefox') &&
|
||||
/(b|rc)\d+$/.test(vAPI.app.version) === false
|
||||
vAPI.webextFlavor.soup.has('devbuild') === false
|
||||
) {
|
||||
µb.redirectEngine.invalidateResourcesSelfie();
|
||||
}
|
||||
|
||||
// From 1.15.19b9 and above, the `behind-the-scene` scope is no longer
|
||||
// whitelisted by default, and network requests from that scope will be
|
||||
// subject to filtering by default.
|
||||
//
|
||||
// Following code is to remove the `behind-the-scene` scope when updating
|
||||
// from a version older than 1.15.19b9.
|
||||
// This will apply only to webext versions of uBO, as the following would
|
||||
// certainly cause too much breakage in Firefox legacy given that uBO can
|
||||
// see ALL network requests.
|
||||
// Remove when everybody is beyond 1.15.19b8.
|
||||
(function patch1015019008(s) {
|
||||
if ( vAPI.firefox !== undefined ) { return; }
|
||||
var match = /^(\d+)\.(\d+)\.(\d+)(?:\D+(\d+))?/.exec(s);
|
||||
if ( match === null ) { return; }
|
||||
var v =
|
||||
parseInt(match[1], 10) * 1000 * 1000 * 1000 +
|
||||
parseInt(match[2], 10) * 1000 * 1000 +
|
||||
parseInt(match[3], 10) * 1000 +
|
||||
(match[4] ? parseInt(match[4], 10) : 0);
|
||||
if ( /rc\d+$/.test(s) ) { v += 100; }
|
||||
if ( v > 1015019008 ) { return; }
|
||||
if ( µb.getNetFilteringSwitch('http://behind-the-scene/') ) { return; }
|
||||
var fwRules = [
|
||||
'behind-the-scene * * noop',
|
||||
'behind-the-scene * image noop',
|
||||
'behind-the-scene * 3p noop',
|
||||
'behind-the-scene * inline-script noop',
|
||||
'behind-the-scene * 1p-script noop',
|
||||
'behind-the-scene * 3p-script noop',
|
||||
'behind-the-scene * 3p-frame noop'
|
||||
].join('\n');
|
||||
µb.sessionFirewall.fromString(fwRules, true);
|
||||
µb.permanentFirewall.fromString(fwRules, true);
|
||||
µb.savePermanentFirewallRules();
|
||||
µb.hnSwitches.fromString([
|
||||
'no-large-media: behind-the-scene false'
|
||||
].join('\n'), true);
|
||||
µb.saveHostnameSwitches();
|
||||
µb.toggleNetFilteringSwitch('http://behind-the-scene/', '', true);
|
||||
})(lastVersion);
|
||||
|
||||
vAPI.storage.set({ version: vAPI.app.version });
|
||||
};
|
||||
|
||||
|
@ -206,7 +166,8 @@ var onUserSettingsReady = function(fetched) {
|
|||
µb.sessionFirewall.assign(µb.permanentFirewall);
|
||||
µb.permanentURLFiltering.fromString(fetched.urlFilteringString);
|
||||
µb.sessionURLFiltering.assign(µb.permanentURLFiltering);
|
||||
µb.hnSwitches.fromString(fetched.hostnameSwitchesString);
|
||||
µb.permanentSwitches.fromString(fetched.hostnameSwitchesString);
|
||||
µb.sessionSwitches.assign(µb.permanentSwitches);
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/1892
|
||||
// For first installation on a battery-powered device, disable generic
|
||||
|
@ -295,7 +256,8 @@ var onSelectedFilterListsLoaded = function() {
|
|||
].join('\n'),
|
||||
'urlFilteringString': '',
|
||||
'hostnameSwitchesString': [
|
||||
'no-large-media: behind-the-scene false'
|
||||
'no-large-media: behind-the-scene false',
|
||||
'no-scripting: behind-the-scene false'
|
||||
].join('\n'),
|
||||
'lastRestoreFile': '',
|
||||
'lastRestoreTime': 0,
|
||||
|
|
|
@ -64,14 +64,6 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.keyvalSetOne = function(key, val, callback) {
|
||||
var bin = {};
|
||||
bin[key] = val;
|
||||
vAPI.storage.set(bin, callback || this.noopFunc);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.saveLocalSettings = (function() {
|
||||
let saveAfter = 4 * 60 * 1000;
|
||||
|
||||
|
@ -206,25 +198,33 @@
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.savePermanentFirewallRules = function() {
|
||||
this.keyvalSetOne('dynamicFilteringString', this.permanentFirewall.toString());
|
||||
vAPI.storage.set({
|
||||
dynamicFilteringString: this.permanentFirewall.toString()
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.savePermanentURLFilteringRules = function() {
|
||||
this.keyvalSetOne('urlFilteringString', this.permanentURLFiltering.toString());
|
||||
vAPI.storage.set({
|
||||
urlFilteringString: this.permanentURLFiltering.toString()
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.saveHostnameSwitches = function() {
|
||||
this.keyvalSetOne('hostnameSwitchesString', this.hnSwitches.toString());
|
||||
vAPI.storage.set({
|
||||
hostnameSwitchesString: this.permanentSwitches.toString()
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.saveWhitelist = function() {
|
||||
this.keyvalSetOne('netWhitelist', this.stringFromWhitelist(this.netWhitelist));
|
||||
vAPI.storage.set({
|
||||
netWhitelist: this.stringFromWhitelist(this.netWhitelist)
|
||||
});
|
||||
this.netWhitelistModifyTime = Date.now();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2014-2018 Raymond Hill
|
||||
Copyright (C) 2014-present Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -610,10 +610,10 @@ vAPI.tabs.onPopupUpdated = (function() {
|
|||
// popunders.
|
||||
if (
|
||||
popupType === 'popup' &&
|
||||
µb.hnSwitches.evaluateZ('no-popups', openerHostname)
|
||||
µb.sessionSwitches.evaluateZ('no-popups', openerHostname)
|
||||
) {
|
||||
logData = {
|
||||
raw: 'no-popups: ' + µb.hnSwitches.z + ' true',
|
||||
raw: 'no-popups: ' + µb.sessionSwitches.z + ' true',
|
||||
result: 1,
|
||||
source: 'switch'
|
||||
};
|
||||
|
|
|
@ -246,10 +246,10 @@ var onBeforeRootFrameRequest = function(details) {
|
|||
}
|
||||
|
||||
// Permanently unrestricted?
|
||||
if ( result === 0 && µb.hnSwitches.evaluateZ('no-strict-blocking', requestHostname) ) {
|
||||
if ( result === 0 && µb.sessionSwitches.evaluateZ('no-strict-blocking', requestHostname) ) {
|
||||
result = 2;
|
||||
if ( logEnabled === true ) {
|
||||
logData = { engine: 'u', result: 2, raw: 'no-strict-blocking: ' + µb.hnSwitches.z + ' true' };
|
||||
if ( logEnabled ) {
|
||||
logData = { engine: 'u', result: 2, raw: 'no-strict-blocking: ' + µb.sessionSwitches.z + ' true' };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2014-2018 Raymond Hill
|
||||
Copyright (C) 2014-present Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -278,22 +278,20 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.changeUserSettings = function(name, value) {
|
||||
var us = this.userSettings;
|
||||
let us = this.userSettings;
|
||||
|
||||
// Return all settings if none specified.
|
||||
if ( name === undefined ) {
|
||||
us = JSON.parse(JSON.stringify(us));
|
||||
us.noCosmeticFiltering = this.hnSwitches.evaluate('no-cosmetic-filtering', '*') === 1;
|
||||
us.noLargeMedia = this.hnSwitches.evaluate('no-large-media', '*') === 1;
|
||||
us.noRemoteFonts = this.hnSwitches.evaluate('no-remote-fonts', '*') === 1;
|
||||
us.noScripting = this.hnSwitches.evaluate('no-scripting', '*') === 1;
|
||||
us.noCSPReports = this.hnSwitches.evaluate('no-csp-reports', '*') === 1;
|
||||
us.noCosmeticFiltering = this.sessionSwitches.evaluate('no-cosmetic-filtering', '*') === 1;
|
||||
us.noLargeMedia = this.sessionSwitches.evaluate('no-large-media', '*') === 1;
|
||||
us.noRemoteFonts = this.sessionSwitches.evaluate('no-remote-fonts', '*') === 1;
|
||||
us.noScripting = this.sessionSwitches.evaluate('no-scripting', '*') === 1;
|
||||
us.noCSPReports = this.sessionSwitches.evaluate('no-csp-reports', '*') === 1;
|
||||
return us;
|
||||
}
|
||||
|
||||
if ( typeof name !== 'string' || name === '' ) {
|
||||
return;
|
||||
}
|
||||
if ( typeof name !== 'string' || name === '' ) { return; }
|
||||
|
||||
if ( value === undefined ) {
|
||||
return us[name];
|
||||
|
@ -312,7 +310,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
}
|
||||
|
||||
// Change -- but only if the user setting actually exists.
|
||||
var mustSave = us.hasOwnProperty(name) && value !== us[name];
|
||||
let mustSave = us.hasOwnProperty(name) && value !== us[name];
|
||||
if ( mustSave ) {
|
||||
us[name] = value;
|
||||
}
|
||||
|
@ -341,27 +339,29 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
}
|
||||
break;
|
||||
case 'noCosmeticFiltering':
|
||||
if ( this.hnSwitches.toggle('no-cosmetic-filtering', '*', value ? 1 : 0) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
case 'noLargeMedia':
|
||||
if ( this.hnSwitches.toggle('no-large-media', '*', value ? 1 : 0) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
case 'noRemoteFonts':
|
||||
if ( this.hnSwitches.toggle('no-remote-fonts', '*', value ? 1 : 0) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
case 'noScripting':
|
||||
if ( this.hnSwitches.toggle('no-scripting', '*', value ? 1 : 0) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
case 'noCSPReports':
|
||||
if ( this.hnSwitches.toggle('no-csp-reports', '*', value ? 1 : 0) ) {
|
||||
let switchName;
|
||||
switch ( name ) {
|
||||
case 'noCosmeticFiltering':
|
||||
switchName = 'no-cosmetic-filtering'; break;
|
||||
case 'noLargeMedia':
|
||||
switchName = 'no-large-media'; break;
|
||||
case 'noRemoteFonts':
|
||||
switchName = 'no-remote-fonts'; break;
|
||||
case 'noScripting':
|
||||
switchName = 'no-scripting'; break;
|
||||
case 'noCSPReports':
|
||||
switchName = 'no-csp-reports'; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ( switchName === undefined ) { break; }
|
||||
let switchState = value ? 1 : 0;
|
||||
this.sessionSwitches.toggle(switchName, '*', switchState);
|
||||
if ( this.permanentSwitches.toggle(switchName, '*', switchState) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
break;
|
||||
|
@ -429,7 +429,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
// (but not really) redundant rules led to this issue.
|
||||
|
||||
µBlock.toggleFirewallRule = function(details) {
|
||||
var requestType = details.requestType;
|
||||
let requestType = details.requestType;
|
||||
|
||||
if ( details.action !== 0 ) {
|
||||
this.sessionFirewall.setCell(details.srcHostname, details.desHostname, requestType, details.action);
|
||||
|
@ -451,7 +451,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
// Flush all cached `net` cosmetic filters if we are dealing with a
|
||||
// collapsible type: any of the cached entries could be a resource on the
|
||||
// target page.
|
||||
var srcHostname = details.srcHostname;
|
||||
let srcHostname = details.srcHostname;
|
||||
if (
|
||||
(srcHostname !== '*') &&
|
||||
(requestType === '*' || requestType === 'image' || requestType === '3p' || requestType === '3p-frame')
|
||||
|
@ -466,22 +466,17 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.toggleURLFilteringRule = function(details) {
|
||||
var changed = this.sessionURLFiltering.setRule(
|
||||
let changed = this.sessionURLFiltering.setRule(
|
||||
details.context,
|
||||
details.url,
|
||||
details.type,
|
||||
details.action
|
||||
);
|
||||
|
||||
if ( !changed ) {
|
||||
return;
|
||||
}
|
||||
if ( changed === false ) { return; }
|
||||
|
||||
this.cosmeticFilteringEngine.removeFromSelectorCache(details.context, 'net');
|
||||
|
||||
if ( !details.persist ) {
|
||||
return;
|
||||
}
|
||||
if ( details.persist !== true ) { return; }
|
||||
|
||||
changed = this.permanentURLFiltering.setRule(
|
||||
details.context,
|
||||
|
@ -498,9 +493,13 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.toggleHostnameSwitch = function(details) {
|
||||
if ( this.hnSwitches.toggleZ(details.name, details.hostname, !!details.deep, details.state) ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
let changed = this.sessionSwitches.toggleZ(
|
||||
details.name,
|
||||
details.hostname,
|
||||
!!details.deep,
|
||||
details.state
|
||||
);
|
||||
if ( changed === false ) { return; }
|
||||
|
||||
// Take action if needed
|
||||
switch ( details.name ) {
|
||||
|
@ -517,6 +516,18 @@ var matchBucket = function(url, hostname, bucket, start) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( details.persist !== true ) { return; }
|
||||
|
||||
changed = this.permanentSwitches.toggleZ(
|
||||
details.name,
|
||||
details.hostname,
|
||||
!!details.deep,
|
||||
details.state
|
||||
);
|
||||
if ( changed ) {
|
||||
this.saveHostnameSwitches();
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue