mirror of https://github.com/gorhill/uBlock.git
Add keyboard support for toggling down blocking profile
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/371 By default, no specific keyboard shortcut is predefined, this will have to be assigned by the user. The command name in English is "Toggle blocking profile". The default behavior is to toggle down according to one of the following scenarios. a) If script execution is disabled through the no-scripting switch, the no-scripting switch will be locally toggled so as to allow script execution. The page will be automatically reloaded. b) If script execution is not blocked but the 3rd-party script and/or frame cells are blocked, local no-op rules will be set so as to no longer block 3rd-party scripts and/or frames. The page will be automatically reloaded. Given this, it may take more than one toggle down command to reach the lowest blocking profile, which is one where JavaScript execution is not blocked and 3rd-party scripts and frames resources block rules, if any, are bypassed with local no-op rules. TODO: At this point, I haven't yet decided whether toggling from the lowest profile should restore the original highest blocking profile.
This commit is contained in:
parent
d1df2b5e73
commit
693687fd74
|
@ -20,6 +20,9 @@
|
|||
},
|
||||
"launch-logger": {
|
||||
"description": "__MSG_popupTipLog__"
|
||||
},
|
||||
"toggle-blocking-profile": {
|
||||
"description": "__MSG_toggleBlockingProfile__"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
|
|
|
@ -607,7 +607,7 @@ vAPI.tabs.remove = function(tabId) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.tabs.reload = function(tabId, bypassCache) {
|
||||
vAPI.tabs.reload = function(tabId, bypassCache = false) {
|
||||
tabId = toChromiumTabId(tabId);
|
||||
if ( tabId === 0 ) { return; }
|
||||
|
||||
|
|
|
@ -963,6 +963,10 @@
|
|||
"message":"Copy to clipboard",
|
||||
"description":"Label for buttons used to copy something to the clipboard"
|
||||
},
|
||||
"toggleBlockingProfile":{
|
||||
"message":"Toggle blocking profile",
|
||||
"description":"Label for keyboard shortcut used to toggle blocking profile"
|
||||
},
|
||||
"dummy":{
|
||||
"message":"This entry must be the last one",
|
||||
"description":"so we dont need to deal with comma for last entry"
|
||||
|
|
|
@ -42,6 +42,7 @@ const µBlock = (function() { // jshint ignore:line
|
|||
autoUpdateAssetFetchPeriod: 120,
|
||||
autoUpdateDelayAfterLaunch: 180,
|
||||
autoUpdatePeriod: 7,
|
||||
blockingProfiles: '11111 11101 00001',
|
||||
cacheStorageAPI: 'unset',
|
||||
cacheStorageCompression: true,
|
||||
cacheControlForFirefox1376932: 'no-cache, no-store, must-revalidate',
|
||||
|
|
|
@ -26,43 +26,160 @@
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.canUseShortcuts = vAPI.commands instanceof Object;
|
||||
|
||||
µBlock.canUpdateShortcuts = µBlock.canUseShortcuts &&
|
||||
typeof vAPI.commands.update === 'function';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
if ( µBlock.canUseShortcuts === false ) { return; }
|
||||
(( ) => {
|
||||
|
||||
vAPI.commands.onCommand.addListener(function(command) {
|
||||
var µb = µBlock;
|
||||
// *****************************************************************************
|
||||
// start of local namespace
|
||||
|
||||
switch ( command ) {
|
||||
case 'launch-element-zapper':
|
||||
case 'launch-element-picker':
|
||||
vAPI.tabs.get(null, function(tab) {
|
||||
if ( tab instanceof Object === false ) { return; }
|
||||
µb.mouseEventRegister.x = µb.mouseEventRegister.y = -1;
|
||||
µb.elementPickerExec(tab.id, undefined, command === 'launch-element-zapper');
|
||||
});
|
||||
break;
|
||||
case 'launch-logger':
|
||||
vAPI.tabs.get(null, function(tab) {
|
||||
let hash = tab.url.startsWith(vAPI.getURL('')) ?
|
||||
'' :
|
||||
'#_+' + tab.id;
|
||||
µb.openNewTab({
|
||||
url: 'logger-ui.html' + hash,
|
||||
select: true,
|
||||
index: -1
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
if ( µBlock.canUseShortcuts === false ) { return; }
|
||||
|
||||
const toggleBlockingProfile = function(tab) {
|
||||
if (
|
||||
tab instanceof Object === false ||
|
||||
tab.id <= 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const µb = µBlock;
|
||||
const normalURL = µb.normalizePageURL(tab.id, tab.url);
|
||||
|
||||
if ( µb.getNetFilteringSwitch(normalURL) === false ) { return; }
|
||||
|
||||
const hn = µb.URI.hostnameFromURI(normalURL);
|
||||
|
||||
// Construct current blocking profile
|
||||
const ssw = µb.sessionSwitches;
|
||||
const sfw = µb.sessionFirewall;
|
||||
let currentProfile = 0;
|
||||
|
||||
if ( ssw.evaluateZ('no-scripting', hn) ) {
|
||||
currentProfile |= 0b00000010;
|
||||
}
|
||||
if ( µb.userSettings.advancedUserEnabled ) {
|
||||
if ( sfw.evaluateCellZY(hn, '*', '3p') === 1 ) {
|
||||
currentProfile |= 0b00000100;
|
||||
}
|
||||
if ( sfw.evaluateCellZY(hn, '*', '3p-script') === 1 ) {
|
||||
currentProfile |= 0b00001000;
|
||||
}
|
||||
if ( sfw.evaluateCellZY(hn, '*', '3p-frame') === 1 ) {
|
||||
currentProfile |= 0b00010000;
|
||||
}
|
||||
}
|
||||
|
||||
const profiles = [];
|
||||
for ( const s of µb.hiddenSettings.blockingProfiles.split(/\s+/) ) {
|
||||
const v = parseInt(s, 2);
|
||||
if ( isNaN(v) ) { continue; }
|
||||
profiles.push(v);
|
||||
}
|
||||
let newProfile;
|
||||
for ( const profile of profiles ) {
|
||||
if ( (currentProfile & profile & 0b11111110) !== currentProfile ) {
|
||||
newProfile = profile;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Reset to original blocking profile?
|
||||
if ( newProfile === undefined ) { return; }
|
||||
|
||||
if (
|
||||
(currentProfile & 0b00000010) !== 0 &&
|
||||
(newProfile & 0b00000010) === 0
|
||||
) {
|
||||
µb.toggleHostnameSwitch({
|
||||
name: 'no-scripting',
|
||||
hostname: hn,
|
||||
state: false,
|
||||
});
|
||||
}
|
||||
if ( µb.userSettings.advancedUserEnabled ) {
|
||||
if (
|
||||
(currentProfile & 0b00000100) !== 0 &&
|
||||
(newProfile & 0b00000100) === 0
|
||||
) {
|
||||
µb.toggleFirewallRule({
|
||||
srcHostname: hn,
|
||||
desHostname: '*',
|
||||
requestType: '3p',
|
||||
action: 3,
|
||||
});
|
||||
}
|
||||
if (
|
||||
(currentProfile & 0b00001000) !== 0 &&
|
||||
(newProfile & 0b00001000) === 0
|
||||
) {
|
||||
µb.toggleFirewallRule({
|
||||
srcHostname: hn,
|
||||
desHostname: '*',
|
||||
requestType: '3p-script',
|
||||
action: 3,
|
||||
});
|
||||
}
|
||||
if (
|
||||
(currentProfile & 0b00010000) !== 0 &&
|
||||
(newProfile & 0b00010000) === 0
|
||||
) {
|
||||
µb.toggleFirewallRule({
|
||||
srcHostname: hn,
|
||||
desHostname: '*',
|
||||
requestType: '3p-frame',
|
||||
action: 3,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( newProfile & 0b00000001 ) {
|
||||
vAPI.tabs.reload(tab.id);
|
||||
}
|
||||
};
|
||||
|
||||
vAPI.commands.onCommand.addListener(command => {
|
||||
const µb = µBlock;
|
||||
|
||||
switch ( command ) {
|
||||
case 'launch-element-picker':
|
||||
case 'launch-element-zapper':
|
||||
vAPI.tabs.get(null, tab => {
|
||||
if ( tab instanceof Object === false ) { return; }
|
||||
µb.mouseEventRegister.x = µb.mouseEventRegister.y = -1;
|
||||
µb.elementPickerExec(
|
||||
tab.id,
|
||||
undefined,
|
||||
command === 'launch-element-zapper'
|
||||
);
|
||||
});
|
||||
break;
|
||||
case 'launch-logger':
|
||||
vAPI.tabs.get(null, tab => {
|
||||
const hash = tab.url.startsWith(vAPI.getURL(''))
|
||||
? ''
|
||||
: `#_+${tab.id}`;
|
||||
µb.openNewTab({
|
||||
url: `logger-ui.html${hash}`,
|
||||
select: true,
|
||||
index: -1
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'toggle-blocking-profile':
|
||||
vAPI.tabs.get(null, toggleBlockingProfile);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// end of local namespace
|
||||
// *****************************************************************************
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
{
|
||||
|
||||
// *****************************************************************************
|
||||
// start of local namespace
|
||||
|
||||
{
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/405
|
||||
// Be more flexible with whitelist syntax
|
||||
|
||||
|
@ -451,20 +451,39 @@ const matchBucket = function(url, hostname, bucket, start) {
|
|||
// (but not really) redundant rules led to this issue.
|
||||
|
||||
µBlock.toggleFirewallRule = function(details) {
|
||||
let requestType = details.requestType;
|
||||
let { srcHostname, desHostname, requestType, action } = details;
|
||||
|
||||
if ( details.action !== 0 ) {
|
||||
this.sessionFirewall.setCell(details.srcHostname, details.desHostname, requestType, details.action);
|
||||
if ( action !== 0 ) {
|
||||
this.sessionFirewall.setCell(
|
||||
srcHostname,
|
||||
desHostname,
|
||||
requestType,
|
||||
action
|
||||
);
|
||||
} else {
|
||||
this.sessionFirewall.unsetCell(details.srcHostname, details.desHostname, requestType);
|
||||
this.sessionFirewall.unsetCell(
|
||||
srcHostname,
|
||||
desHostname,
|
||||
requestType
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/731#issuecomment-73937469
|
||||
if ( details.persist ) {
|
||||
if ( details.action !== 0 ) {
|
||||
this.permanentFirewall.setCell(details.srcHostname, details.desHostname, requestType, details.action);
|
||||
if ( action !== 0 ) {
|
||||
this.permanentFirewall.setCell(
|
||||
srcHostname,
|
||||
desHostname,
|
||||
requestType,
|
||||
action
|
||||
);
|
||||
} else {
|
||||
this.permanentFirewall.unsetCell(details.srcHostname, details.desHostname, requestType, details.action);
|
||||
this.permanentFirewall.unsetCell(
|
||||
srcHostname,
|
||||
desHostname,
|
||||
requestType,
|
||||
action
|
||||
);
|
||||
}
|
||||
this.savePermanentFirewallRules();
|
||||
}
|
||||
|
@ -473,10 +492,14 @@ const 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.
|
||||
let srcHostname = details.srcHostname;
|
||||
if (
|
||||
(srcHostname !== '*') &&
|
||||
(requestType === '*' || requestType === 'image' || requestType === '3p' || requestType === '3p-frame')
|
||||
(
|
||||
requestType === '*' ||
|
||||
requestType === 'image' ||
|
||||
requestType === '3p' ||
|
||||
requestType === '3p-frame'
|
||||
)
|
||||
) {
|
||||
srcHostname = '*';
|
||||
}
|
||||
|
@ -635,3 +658,5 @@ const matchBucket = function(url, hostname, bucket, start) {
|
|||
report: report
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue