mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-06 19:02:30 +01:00
<https://github.com/gorhill/uBlock/issues/3436>: a new per-site switch has been added, no-scripting, which purpose is to wholly disable/enable javascript for a given site. This new switch has precedence over all other ways javascript can be disabled, including precedence over dynamic filtering rules. The popup panel will report the number of script resources which have been seen by uBO for the current page. There is a minor inaccuracy to be fixed regarding the count, and which fix requires to extend request journaling. <https://github.com/gorhill/uBlock/issues/308>: the `noscript` tags will now be respected when the new no-scripting switch is in effect on a given site. A default setting has been added to the _Settings_ pane to disable/enable globally the new no-script switch, such that one can work in default-deny mode regarding javascript execution. <https://github.com/uBlockOrigin/uBlock-issues/issues/155>: a new hidden setting, `requestJournalProcessPeriod`, has been added to allow controlling the delay before uBO internally process it's network request journal queue. Default to 1000 (milliseconds).
This commit is contained in:
parent
cae7484be1
commit
3c85c03194
@ -147,6 +147,14 @@
|
||||
"message":"Click to no longer block remote fonts on this site",
|
||||
"description":"Tooltip for the no-remote-fonts per-site switch"
|
||||
},
|
||||
"popupTipNoScripting1":{
|
||||
"message":"Click to wholly disable javascript on this site",
|
||||
"description":"Tooltip for the no-scripting per-site switch"
|
||||
},
|
||||
"popupTipNoScripting2":{
|
||||
"message":"Click to no longer wholly disable javascript on this site",
|
||||
"description":"Tooltip for the no-remote-fonts per-site switch"
|
||||
},
|
||||
"popupTipGlobalRules":{
|
||||
"message":"Global rules: this column is for rules which apply to all sites.",
|
||||
"description":"Tooltip when hovering the top-most cell of the global-rules column."
|
||||
@ -299,6 +307,10 @@
|
||||
"message":"Block remote fonts",
|
||||
"description": ""
|
||||
},
|
||||
"settingsNoScriptingPrompt":{
|
||||
"message":"Disable javascript",
|
||||
"description": "The default state for the per-site no-scripting switch"
|
||||
},
|
||||
"settingsNoCSPReportsPrompt":{
|
||||
"message":"Block CSP reports",
|
||||
"description": "background information: https://github.com/gorhill/uBlock/issues/3150"
|
||||
|
@ -49,8 +49,8 @@ input[type="checkbox"][disabled] + label {
|
||||
width: 40em;
|
||||
}
|
||||
.synopsis {
|
||||
font-size: small;
|
||||
opacity: 0.8;
|
||||
display: inline-block;
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
.whatisthis {
|
||||
margin: 0 0 0 8px;
|
||||
|
@ -146,28 +146,28 @@ body.off #switch .fa {
|
||||
#extraTools {
|
||||
background-color: #eee;
|
||||
border: 0;
|
||||
color: #aaa;
|
||||
color: #888;
|
||||
margin: 0.8em 0 0 0;
|
||||
padding: 4px 0;
|
||||
padding: 4px 0 4px 0.8em;
|
||||
text-align: center;
|
||||
}
|
||||
#extraTools > span {
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
margin: 0 0.4em;
|
||||
margin: 0 0.8em 0 0;
|
||||
position: relative;
|
||||
}
|
||||
#extraTools > span > span.badge {
|
||||
color: #222;
|
||||
bottom: -1px;
|
||||
bottom: -2px;
|
||||
font: x-small sans-serif;
|
||||
position: absolute;
|
||||
}
|
||||
body[dir="ltr"] #extraTools > span > span.badge {
|
||||
left: 100%;
|
||||
/* left: 100%; */
|
||||
}
|
||||
body[dir="rtl"] #extraTools > span > span.badge {
|
||||
right: 100%;
|
||||
/* right: 100%; */
|
||||
}
|
||||
#extraTools > span > span:last-of-type {
|
||||
color: #e00;
|
||||
|
@ -48,6 +48,7 @@ var µBlock = (function() { // jshint ignore:line
|
||||
ignoreScriptInjectFilters: false,
|
||||
manualUpdateAssetFetchPeriod: 500,
|
||||
popupFontSize: 'unset',
|
||||
requestJournalProcessPeriod: 1000,
|
||||
suspendTabsUntilReady: false,
|
||||
userResourcesLocation: 'unset'
|
||||
};
|
||||
|
@ -1284,6 +1284,11 @@ vAPI.domSurveyor = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
vAPI.messaging.send(
|
||||
'contentscript',
|
||||
{ what: 'shouldRenderNoscriptTags' }
|
||||
);
|
||||
|
||||
if ( vAPI.domWatcher instanceof Object ) {
|
||||
vAPI.domWatcher.start();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a Chromium browser extension to black/white list requests.
|
||||
Copyright (C) 2015-2018 Raymond Hill
|
||||
Copyright (C) 2015-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
|
||||
@ -42,7 +42,8 @@ var switchBitOffsets = {
|
||||
'no-cosmetic-filtering': 4,
|
||||
'no-remote-fonts': 6,
|
||||
'no-large-media': 8,
|
||||
'no-csp-reports': 10
|
||||
'no-csp-reports': 10,
|
||||
'no-scripting': 12,
|
||||
};
|
||||
|
||||
var switchStateToNameMap = {
|
||||
|
@ -84,9 +84,6 @@ var onMessage = function(request, sender, callback) {
|
||||
break;
|
||||
}
|
||||
|
||||
// The concatenation with the empty string ensure that the resulting value
|
||||
// is a string. This is important since tab id values are assumed to be
|
||||
// of string type.
|
||||
var tabId = sender && sender.tab ? sender.tab.id : 0;
|
||||
|
||||
// Sync
|
||||
@ -335,6 +332,7 @@ var popupDataFromTabId = function(tabId, tabTitle) {
|
||||
r.largeMediaCount = pageStore.largeMediaCount;
|
||||
r.noRemoteFonts = µb.hnSwitches.evaluateZ('no-remote-fonts', rootHostname);
|
||||
r.remoteFontCount = pageStore.remoteFontCount;
|
||||
r.noScripting = µb.hnSwitches.evaluateZ('no-scripting', rootHostname);
|
||||
} else {
|
||||
r.hostnameDict = {};
|
||||
r.firewallRules = getFirewallRules();
|
||||
@ -374,14 +372,6 @@ var onMessage = function(request, sender, callback) {
|
||||
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
case 'getPopupLazyData':
|
||||
pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||
if ( pageStore !== null ) {
|
||||
pageStore.hiddenElementCount = 0;
|
||||
µb.scriptlets.injectDeep(request.tabId, 'cosmetic-survey');
|
||||
}
|
||||
return;
|
||||
|
||||
case 'getPopupData':
|
||||
popupDataFromRequest(request, callback);
|
||||
return;
|
||||
@ -394,6 +384,15 @@ var onMessage = function(request, sender, callback) {
|
||||
var response;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'getPopupLazyData':
|
||||
pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||
if ( pageStore !== null ) {
|
||||
pageStore.hiddenElementCount = 0;
|
||||
pageStore.inlineScriptCount = 0;
|
||||
µb.scriptlets.injectDeep(request.tabId, 'dom-survey');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'hasPopupContentChanged':
|
||||
pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||
var lastModified = pageStore ? pageStore.contentLastModified : 0;
|
||||
@ -491,6 +490,22 @@ var onMessage = function(request, sender, callback) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'shouldRenderNoscriptTags':
|
||||
if ( pageStore === null ) { break; }
|
||||
let tabContext = µb.tabContextManager.lookup(tabId);
|
||||
if ( tabContext === null ) { break; }
|
||||
if ( pageStore.filterScripting(tabContext.rootHostname) ) {
|
||||
vAPI.tabs.injectScript(
|
||||
tabId,
|
||||
{
|
||||
file: '/js/scriptlets/noscript-spoof.js',
|
||||
frameId: frameId,
|
||||
runAt: 'document_end'
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'retrieveContentScriptParameters':
|
||||
if (
|
||||
pageStore === null ||
|
||||
@ -1233,23 +1248,22 @@ vAPI.messaging.listen('documentBlocked', onMessage);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var µb = µBlock;
|
||||
var broadcastTimers = Object.create(null);
|
||||
let µb = µBlock;
|
||||
let broadcastTimers = new Map();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var cosmeticallyFilteredElementCountChanged = function(tabId) {
|
||||
delete broadcastTimers[tabId + '-cosmeticallyFilteredElementCountChanged'];
|
||||
var domSurveyFinalReport = function(tabId) {
|
||||
broadcastTimers.delete(tabId + '-domSurveyReport');
|
||||
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) {
|
||||
return;
|
||||
}
|
||||
let pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) { return; }
|
||||
|
||||
vAPI.messaging.broadcast({
|
||||
what: 'cosmeticallyFilteredElementCountChanged',
|
||||
what: 'domSurveyFinalReport',
|
||||
tabId: tabId,
|
||||
count: pageStore.hiddenElementCount
|
||||
affectedElementCount: pageStore.hiddenElementCount,
|
||||
scriptCount: pageStore.scriptCount + pageStore.inlineScriptCount,
|
||||
});
|
||||
};
|
||||
|
||||
@ -1280,8 +1294,8 @@ var logCosmeticFilters = function(tabId, details) {
|
||||
/******************************************************************************/
|
||||
|
||||
var onMessage = function(request, sender, callback) {
|
||||
var tabId = sender && sender.tab ? sender.tab.id : 0;
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
let tabId = sender && sender.tab ? sender.tab.id : 0;
|
||||
let pageStore = µb.pageStoreFromTabId(tabId);
|
||||
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
@ -1293,15 +1307,20 @@ var onMessage = function(request, sender, callback) {
|
||||
var response;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'cosmeticallyFilteredElementCount':
|
||||
if ( pageStore !== null && request.filteredElementCount ) {
|
||||
case 'domSurveyTransientReport':
|
||||
if ( pageStore !== null ) {
|
||||
if ( request.filteredElementCount ) {
|
||||
pageStore.hiddenElementCount += request.filteredElementCount;
|
||||
var broadcastKey = tabId + '-cosmeticallyFilteredElementCountChanged';
|
||||
if ( broadcastTimers[broadcastKey] === undefined ) {
|
||||
broadcastTimers[broadcastKey] = vAPI.setTimeout(
|
||||
cosmeticallyFilteredElementCountChanged.bind(null, tabId),
|
||||
}
|
||||
if ( request.inlineScriptCount ) {
|
||||
pageStore.inlineScriptCount += request.inlineScriptCount;
|
||||
}
|
||||
let broadcastKey = tabId + '-domSurveyReport';
|
||||
if ( broadcastTimers.has(broadcastKey) === false ) {
|
||||
broadcastTimers.set(broadcastKey, vAPI.setTimeout(
|
||||
( ) => { domSurveyFinalReport(tabId); },
|
||||
250
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -290,6 +290,8 @@ PageStore.prototype.init = function(tabId, context) {
|
||||
this.perLoadAllowedRequestCount = 0;
|
||||
this.hiddenElementCount = ''; // Empty string means "unknown"
|
||||
this.remoteFontCount = 0;
|
||||
this.scriptCount = 0;
|
||||
this.inlineScriptCount = 0;
|
||||
this.popupBlockedCount = 0;
|
||||
this.largeMediaCount = 0;
|
||||
this.largeMediaTimer = null;
|
||||
@ -517,7 +519,10 @@ PageStore.prototype.journalAddRequest = function(hostname, result) {
|
||||
result === 1 ? 0x00000001 : 0x00010000
|
||||
);
|
||||
if ( this.journalTimer === null ) {
|
||||
this.journalTimer = vAPI.setTimeout(this.journalProcess.bind(this, true), 1000);
|
||||
this.journalTimer = vAPI.setTimeout(
|
||||
( ) => { this.journalProcess(true); },
|
||||
µb.hiddenSettings.requestJournalProcessPeriod
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -539,7 +544,10 @@ PageStore.prototype.journalAddRootFrame = function(type, url) {
|
||||
if ( this.journalTimer !== null ) {
|
||||
clearTimeout(this.journalTimer);
|
||||
}
|
||||
this.journalTimer = vAPI.setTimeout(this.journalProcess.bind(this, true), 1000);
|
||||
this.journalTimer = vAPI.setTimeout(
|
||||
( ) => { this.journalProcess(true); },
|
||||
µb.hiddenSettings.requestJournalProcessPeriod
|
||||
);
|
||||
};
|
||||
|
||||
PageStore.prototype.journalProcess = function(fromTimer) {
|
||||
@ -549,21 +557,20 @@ PageStore.prototype.journalProcess = function(fromTimer) {
|
||||
this.journalTimer = null;
|
||||
|
||||
var journal = this.journal,
|
||||
i, n = journal.length,
|
||||
hostname, count, hostnameCounts,
|
||||
n = journal.length,
|
||||
aggregateCounts = 0,
|
||||
now = Date.now(),
|
||||
pivot = this.journalLastCommitted || 0;
|
||||
|
||||
// Everything after pivot originates from current page.
|
||||
for ( i = pivot; i < n; i += 2 ) {
|
||||
hostname = journal[i];
|
||||
hostnameCounts = this.hostnameToCountMap.get(hostname);
|
||||
for ( let i = pivot; i < n; i += 2 ) {
|
||||
let hostname = journal[i];
|
||||
let hostnameCounts = this.hostnameToCountMap.get(hostname);
|
||||
if ( hostnameCounts === undefined ) {
|
||||
hostnameCounts = 0;
|
||||
this.contentLastModified = now;
|
||||
}
|
||||
count = journal[i+1];
|
||||
let count = journal[i+1];
|
||||
this.hostnameToCountMap.set(hostname, hostnameCounts + count);
|
||||
aggregateCounts += count;
|
||||
}
|
||||
@ -579,7 +586,7 @@ PageStore.prototype.journalProcess = function(fromTimer) {
|
||||
|
||||
// Everything before pivot does not originate from current page -- we still
|
||||
// need to bump global blocked/allowed counts.
|
||||
for ( i = 0; i < pivot; i += 2 ) {
|
||||
for ( let i = 0; i < pivot; i += 2 ) {
|
||||
aggregateCounts += journal[i+1];
|
||||
}
|
||||
if ( aggregateCounts !== 0 ) {
|
||||
@ -609,6 +616,13 @@ PageStore.prototype.filterRequest = function(context) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( requestType === 'script' ) {
|
||||
this.scriptCount += 1;
|
||||
if ( this.filterScripting(context.rootHostname) === 1 ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
var cacheableResult = this.cacheableResults[requestType] === true;
|
||||
|
||||
if ( cacheableResult ) {
|
||||
@ -706,6 +720,21 @@ PageStore.prototype.filterFont = function(context) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
PageStore.prototype.filterScripting = function(rootHostname) {
|
||||
if (
|
||||
this.getNetFilteringSwitch() === false ||
|
||||
µb.hnSwitches.evaluateZ('no-scripting', rootHostname) === false
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
if ( µb.logger.isEnabled() ) {
|
||||
this.logData = µb.hnSwitches.toLogData();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// The caller is responsible to check whether filtering is enabled or not.
|
||||
|
||||
PageStore.prototype.filterLargeMediaElement = function(size) {
|
||||
|
@ -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
|
||||
@ -161,6 +161,7 @@ var hashFromPopupData = function(reset) {
|
||||
hasher.push(uDom.nodeFromId('no-large-media').classList.contains('on'));
|
||||
hasher.push(uDom.nodeFromId('no-cosmetic-filtering').classList.contains('on'));
|
||||
hasher.push(uDom.nodeFromId('no-remote-fonts').classList.contains('on'));
|
||||
hasher.push(uDom.nodeFromId('no-scripting').classList.contains('on'));
|
||||
|
||||
var hash = hasher.join('');
|
||||
if ( reset ) {
|
||||
@ -438,6 +439,7 @@ var renderPopup = function() {
|
||||
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);
|
||||
|
||||
// Report blocked popup count on badge
|
||||
total = popupData.popupBlockedCount;
|
||||
@ -487,14 +489,13 @@ var renderPopup = function() {
|
||||
// Use tooltip for ARIA purpose.
|
||||
|
||||
var renderTooltips = function(selector) {
|
||||
var elem, text;
|
||||
for ( var entry of tooltipTargetSelectors ) {
|
||||
for ( let entry of tooltipTargetSelectors ) {
|
||||
if ( selector !== undefined && entry[0] !== selector ) { continue; }
|
||||
text = vAPI.i18n(
|
||||
let text = vAPI.i18n(
|
||||
entry[1].i18n +
|
||||
(uDom.nodeFromSelector(entry[1].state) === null ? '1' : '2')
|
||||
);
|
||||
elem = uDom.nodeFromSelector(entry[0]);
|
||||
let elem = uDom.nodeFromSelector(entry[0]);
|
||||
elem.setAttribute('aria-label', text);
|
||||
elem.setAttribute('data-tip', text);
|
||||
if ( selector !== undefined ) {
|
||||
@ -539,7 +540,14 @@ var tooltipTargetSelectors = new Map([
|
||||
state: '#no-remote-fonts.on',
|
||||
i18n: 'popupTipNoRemoteFonts'
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
'#no-scripting',
|
||||
{
|
||||
state: '#no-scripting.on',
|
||||
i18n: 'popupTipNoScripting'
|
||||
}
|
||||
],
|
||||
]);
|
||||
|
||||
/******************************************************************************/
|
||||
@ -627,10 +635,17 @@ var onPopupMessage = function(data) {
|
||||
if ( data.tabId !== popupData.tabId ) { return; }
|
||||
|
||||
switch ( data.what ) {
|
||||
case 'cosmeticallyFilteredElementCountChanged':
|
||||
var v = data.count || '';
|
||||
case 'domSurveyFinalReport':
|
||||
let count = data.affectedElementCount || '';
|
||||
uDom.nodeFromSelector('#no-cosmetic-filtering > span.badge')
|
||||
.textContent = typeof v === 'number' ? v.toLocaleString() : v;
|
||||
.textContent = typeof count === 'number' ?
|
||||
count.toLocaleString() :
|
||||
count;
|
||||
count = data.scriptCount || '';
|
||||
uDom.nodeFromSelector('#no-scripting > span.badge')
|
||||
.textContent = typeof count === 'number' ?
|
||||
count.toLocaleString() :
|
||||
count;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2015-2018 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
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
if ( typeof vAPI !== 'object' || !vAPI.domFilterer ) { return; }
|
||||
|
||||
vAPI.messaging.send(
|
||||
'scriptlets',
|
||||
{
|
||||
what: 'cosmeticallyFilteredElementCount',
|
||||
pageURL: window.location.href,
|
||||
filteredElementCount: vAPI.domFilterer.getFilteredElementCount()
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
DO NOT:
|
||||
- Remove the following code
|
||||
- Add code beyond the following code
|
||||
Reason:
|
||||
- https://github.com/gorhill/uBlock/pull/3721
|
||||
- uBO never uses the return value from injected content scripts
|
||||
|
||||
**/
|
||||
|
||||
void 0;
|
84
src/js/scriptlets/dom-survey.js
Normal file
84
src/js/scriptlets/dom-survey.js
Normal file
@ -0,0 +1,84 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2015-2018 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
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
if ( typeof vAPI !== 'object' ) { return; }
|
||||
|
||||
// https://github.com/gorhill/httpswitchboard/issues/25
|
||||
//
|
||||
// https://github.com/gorhill/httpswitchboard/issues/131
|
||||
// Looks for inline javascript also in at least one a[href] element.
|
||||
//
|
||||
// https://github.com/gorhill/uMatrix/issues/485
|
||||
// Mind "on..." attributes.
|
||||
//
|
||||
// https://github.com/gorhill/uMatrix/issues/924
|
||||
// Report inline styles.
|
||||
let inlineScriptCount = 0;
|
||||
if (
|
||||
document.querySelector('script:not([src])') !== null ||
|
||||
document.querySelector('script[src^="data:"]') !== null ||
|
||||
document.querySelector('script[src^="blob:"]') !== null ||
|
||||
document.querySelector('a[href^="javascript:"]') !== null ||
|
||||
document.querySelector('[onabort],[onblur],[oncancel],[oncanplay],[oncanplaythrough],[onchange],[onclick],[onclose],[oncontextmenu],[oncuechange],[ondblclick],[ondrag],[ondragend],[ondragenter],[ondragexit],[ondragleave],[ondragover],[ondragstart],[ondrop],[ondurationchange],[onemptied],[onended],[onerror],[onfocus],[oninput],[oninvalid],[onkeydown],[onkeypress],[onkeyup],[onload],[onloadeddata],[onloadedmetadata],[onloadstart],[onmousedown],[onmouseenter],[onmouseleave],[onmousemove],[onmouseout],[onmouseover],[onmouseup],[onwheel],[onpause],[onplay],[onplaying],[onprogress],[onratechange],[onreset],[onresize],[onscroll],[onseeked],[onseeking],[onselect],[onshow],[onstalled],[onsubmit],[onsuspend],[ontimeupdate],[ontoggle],[onvolumechange],[onwaiting],[onafterprint],[onbeforeprint],[onbeforeunload],[onhashchange],[onlanguagechange],[onmessage],[onoffline],[ononline],[onpagehide],[onpageshow],[onrejectionhandled],[onpopstate],[onstorage],[onunhandledrejection],[onunload],[oncopy],[oncut],[onpaste]') !== null
|
||||
) {
|
||||
inlineScriptCount = 1;
|
||||
}
|
||||
|
||||
let filteredElementCount = 0;
|
||||
if ( vAPI.domFilterer ) {
|
||||
filteredElementCount = vAPI.domFilterer.getFilteredElementCount();
|
||||
}
|
||||
|
||||
vAPI.messaging.send(
|
||||
'scriptlets',
|
||||
{
|
||||
what: 'domSurveyTransientReport',
|
||||
pageURL: window.location.href,
|
||||
filteredElementCount: filteredElementCount,
|
||||
inlineScriptCount: inlineScriptCount,
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
DO NOT:
|
||||
- Remove the following code
|
||||
- Add code beyond the following code
|
||||
Reason:
|
||||
- https://github.com/gorhill/uBlock/pull/3721
|
||||
- uBO never uses the return value from injected content scripts
|
||||
|
||||
**/
|
||||
|
||||
void 0;
|
83
src/js/scriptlets/noscript-spoof.js
Normal file
83
src/js/scriptlets/noscript-spoof.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
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
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
// Code below has been imported from uMatrix and modified to fit uBO:
|
||||
// https://github.com/gorhill/uMatrix/blob/3f8794dd899a05e066c24066c6c0a2515d5c60d2/src/js/contentscript.js#L464-L531
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uMatrix/issues/232
|
||||
// Force `display` property, Firefox is still affected by the issue.
|
||||
|
||||
(function() {
|
||||
let noscripts = document.querySelectorAll('noscript');
|
||||
if ( noscripts.length === 0 ) { return; }
|
||||
|
||||
let redirectTimer,
|
||||
reMetaContent = /^\s*(\d+)\s*;\s*url=(['"]?)([^'"]+)\2/i,
|
||||
reSafeURL = /^https?:\/\//;
|
||||
|
||||
let autoRefresh = function(root) {
|
||||
let meta = root.querySelector('meta[http-equiv="refresh"][content]');
|
||||
if ( meta === null ) { return; }
|
||||
let match = reMetaContent.exec(meta.getAttribute('content'));
|
||||
if ( match === null || match[3].trim() === '' ) { return; }
|
||||
let url = new URL(match[3], document.baseURI);
|
||||
if ( reSafeURL.test(url.href) === false ) { return; }
|
||||
redirectTimer = setTimeout(( ) => {
|
||||
location.assign(url.href);
|
||||
},
|
||||
parseInt(match[1], 10) * 1000 + 1
|
||||
);
|
||||
meta.parentNode.removeChild(meta);
|
||||
};
|
||||
|
||||
let morphNoscript = function(from) {
|
||||
if ( /^application\/(?:xhtml\+)?xml/.test(document.contentType) ) {
|
||||
let to = document.createElement('span');
|
||||
while ( from.firstChild !== null ) {
|
||||
to.appendChild(from.firstChild);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString(
|
||||
'<span>' + from.textContent + '</span>',
|
||||
'text/html'
|
||||
);
|
||||
return document.adoptNode(doc.querySelector('span'));
|
||||
};
|
||||
|
||||
for ( let noscript of noscripts ) {
|
||||
let parent = noscript.parentNode;
|
||||
if ( parent === null ) { continue; }
|
||||
let span = morphNoscript(noscript);
|
||||
span.style.setProperty('display', 'inline', 'important');
|
||||
if ( redirectTimer === undefined ) {
|
||||
autoRefresh(span);
|
||||
}
|
||||
parent.replaceChild(span, noscript);
|
||||
}
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
@ -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
|
||||
@ -912,6 +912,21 @@ var injectCSP = function(pageStore, details) {
|
||||
|
||||
let builtinDirectives = [];
|
||||
|
||||
context.requestType = 'script';
|
||||
if ( pageStore.filterScripting(context.rootHostname) === 1 ) {
|
||||
builtinDirectives.push("script-src *");
|
||||
if ( loggerEnabled === true ) {
|
||||
logger.writeOne(
|
||||
tabId,
|
||||
'net',
|
||||
pageStore.logData,
|
||||
'no-scripting',
|
||||
requestURL,
|
||||
context.rootHostname,
|
||||
context.pageHostname
|
||||
);
|
||||
}
|
||||
} else {
|
||||
context.requestType = 'inline-script';
|
||||
if ( pageStore.filterRequest(context) === 1 ) {
|
||||
builtinDirectives.push("script-src 'unsafe-eval' * blob: data:");
|
||||
@ -927,6 +942,7 @@ var injectCSP = function(pageStore, details) {
|
||||
context.pageHostname
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/1539
|
||||
// - Use a CSP to also forbid inline fonts if remote fonts are blocked.
|
||||
|
@ -286,6 +286,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||
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;
|
||||
return us;
|
||||
}
|
||||
@ -354,6 +355,11 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||
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) ) {
|
||||
this.saveHostnameSwitches();
|
||||
|
@ -38,6 +38,7 @@
|
||||
<span id="no-large-media" class="hnSwitch fa" role="button" aria-label tabindex="0"><span class="badge"></span><span><svg viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span></span>
|
||||
<span id="no-cosmetic-filtering" class="hnSwitch fa" role="button" aria-label tabindex="0"><span class="badge"></span><span><svg viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span></span>
|
||||
<span id="no-remote-fonts" class="hnSwitch fa" role="button" aria-label tabindex="0"><span class="badge"></span><span><svg viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span></span>
|
||||
<span id="no-scripting" class="hnSwitch fa" role="button" aria-label tabindex="0"><span class="badge"></span><span><svg viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span></span>
|
||||
</div>
|
||||
</div><!-- DO NOT REMOVE --><div class="tooltipContainer">
|
||||
<div id="firewallContainer" class="minimized">
|
||||
|
@ -30,6 +30,7 @@
|
||||
<li><input id="no-cosmetic-filtering" type="checkbox" data-setting-name="noCosmeticFiltering" data-setting-type="bool"><label data-i18n="settingsNoCosmeticFilteringPrompt" for="no-cosmetic-filtering"></label> <a class="fa info" href="https://github.com/gorhill/uBlock/wiki/Per-site-switches#no-cosmetic-filtering" target="_blank"></a>
|
||||
<li><input id="no-large-media" type="checkbox" data-setting-name="noLargeMedia" data-setting-type="bool"><label data-i18n="settingsNoLargeMediaPrompt" for="no-large-media"></label> <a class="fa info" href="https://github.com/gorhill/uBlock/wiki/Per-site-switches#no-large-media-elements" target="_blank"></a>
|
||||
<li><input id="no-remote-fonts" type="checkbox" data-setting-name="noRemoteFonts" data-setting-type="bool"><label data-i18n="settingsNoRemoteFontsPrompt" for="no-remote-fonts"></label> <a class="fa info" href="https://github.com/gorhill/uBlock/wiki/Per-site-switches#no-remote-fonts" target="_blank"></a>
|
||||
<li><input id="no-scripting" type="checkbox" data-setting-name="noScripting" data-setting-type="bool"><label data-i18n="settingsNoScriptingPrompt" for="no-scripting"></label> <a class="fa info" href="https://github.com/gorhill/uBlock/wiki/Per-site-switches#no-scripting" target="_blank"></a>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user