mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-26 18:10:39 +12:00
new way of handling blocked documents
This commit is contained in:
parent
e751a5403b
commit
ddaa948cf4
|
@ -572,6 +572,22 @@
|
||||||
"description": "Message asking user to confirm reset"
|
"description": "Message asking user to confirm reset"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"mainBlockedPrompt1": {
|
||||||
|
"message": "uMatrix has prevented the following page from loading:",
|
||||||
|
"description": "English: uMatrix has prevented the following page from loading:"
|
||||||
|
},
|
||||||
|
"mainBlockedPrompt2": {
|
||||||
|
"message": "Because of the following rule",
|
||||||
|
"description": "English: Because of the following rule"
|
||||||
|
},
|
||||||
|
"mainBlockedBack" : {
|
||||||
|
"message": "Go back",
|
||||||
|
"description": "English: Go back"
|
||||||
|
},
|
||||||
|
"mainBlockedClose" : {
|
||||||
|
"message": "Close",
|
||||||
|
"description": "English: Close"
|
||||||
|
},
|
||||||
|
|
||||||
"commandRevertAll" : {
|
"commandRevertAll" : {
|
||||||
"message": "Remove all temporary changes",
|
"message": "Remove all temporary changes",
|
||||||
|
|
|
@ -123,8 +123,6 @@ return {
|
||||||
behindTheSceneScope: 'behind-the-scene',
|
behindTheSceneScope: 'behind-the-scene',
|
||||||
|
|
||||||
// Commonly encountered strings
|
// Commonly encountered strings
|
||||||
chromeExtensionURLPrefix: 'chrome-extension://',
|
|
||||||
noopCSSURL: vAPI.getURL('css/noop.css'),
|
|
||||||
fontCSSURL: vAPI.getURL('css/fonts/Roboto_Condensed/RobotoCondensed-Regular.ttf'),
|
fontCSSURL: vAPI.getURL('css/fonts/Roboto_Condensed/RobotoCondensed-Regular.ttf'),
|
||||||
|
|
||||||
noopFunc: function(){},
|
noopFunc: function(){},
|
||||||
|
|
76
src/js/main-blocked.js
Normal file
76
src/js/main-blocked.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
µMatrix - a browser extension to block requests.
|
||||||
|
Copyright (C) 2015 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global uDom */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var details = {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var matches = /details=([^&]+)/.exec(window.location.search);
|
||||||
|
if ( matches === null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
details = JSON.parse(atob(matches[1]));
|
||||||
|
})();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uDom('.what').text(details.url);
|
||||||
|
uDom('#why').text(details.why.slice(3));
|
||||||
|
|
||||||
|
if ( window.history.length > 1 ) {
|
||||||
|
uDom('#back').on('click', function() { window.history.back(); });
|
||||||
|
uDom('#bye').css('display', 'none');
|
||||||
|
} else {
|
||||||
|
uDom('#bye').on('click', function() { window.close(); });
|
||||||
|
uDom('#back').css('display', 'none');
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// See if the target hostname is still blacklisted, and if not, navigate to it.
|
||||||
|
|
||||||
|
var messager = vAPI.messaging.channel('main-blocked.js');
|
||||||
|
|
||||||
|
messager.send({
|
||||||
|
what: 'mustBlock',
|
||||||
|
scope: details.hn,
|
||||||
|
hostname: details.hn,
|
||||||
|
type: 'doc'
|
||||||
|
}, function(response) {
|
||||||
|
if ( response === false ) {
|
||||||
|
window.location.replace(details.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
|
@ -71,6 +71,14 @@ function onMessage(request, sender, callback) {
|
||||||
µm.utils.gotoURL(request);
|
µm.utils.gotoURL(request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'mustBlock':
|
||||||
|
response = µm.mustBlock(
|
||||||
|
request.scope,
|
||||||
|
request.hostname,
|
||||||
|
request.type
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'reloadHostsFiles':
|
case 'reloadHostsFiles':
|
||||||
µm.reloadHostsFiles();
|
µm.reloadHostsFiles();
|
||||||
break;
|
break;
|
||||||
|
@ -168,7 +176,7 @@ var matrixSnapshot = function(tabId, details) {
|
||||||
|
|
||||||
// Allow examination of behind-the-scene requests
|
// Allow examination of behind-the-scene requests
|
||||||
if (
|
if (
|
||||||
tabContext.rawURL.lastIndexOf(vAPI.getURL(''), 0) === 0 ||
|
tabContext.rawURL.lastIndexOf(vAPI.getURL('dashboard.html'), 0) === 0 ||
|
||||||
tabContext.rawURL === µm.behindTheSceneURL
|
tabContext.rawURL === µm.behindTheSceneURL
|
||||||
) {
|
) {
|
||||||
tabId = µm.behindTheSceneTabId;
|
tabId = µm.behindTheSceneTabId;
|
||||||
|
|
|
@ -49,6 +49,20 @@ var µm = µMatrix;
|
||||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
||||||
return 'http://behind-the-scene/';
|
return 'http://behind-the-scene/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the URL is that of our "blocked page" document, return the URL of
|
||||||
|
// the blocked page.
|
||||||
|
if ( pageURL.lastIndexOf(vAPI.getURL('main-blocked.html'), 0) === 0 ) {
|
||||||
|
var matches = /main-blocked\.html\?details=([^&]+)/.exec(pageURL);
|
||||||
|
if ( matches && matches.length === 2 ) {
|
||||||
|
try {
|
||||||
|
var details = JSON.parse(atob(matches[1]));
|
||||||
|
pageURL = details.url;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var uri = this.URI.set(pageURL);
|
var uri = this.URI.set(pageURL);
|
||||||
var scheme = uri.scheme;
|
var scheme = uri.scheme;
|
||||||
if ( scheme === 'https' || scheme === 'http' ) {
|
if ( scheme === 'https' || scheme === 'http' ) {
|
||||||
|
@ -453,13 +467,6 @@ vAPI.tabs.registerListeners();
|
||||||
return this.pageStores[tabId];
|
return this.pageStores[tabId];
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/303
|
|
||||||
// Don't rebind pages blocked by µMatrix.
|
|
||||||
var blockedRootFramePrefix = this.webRequest.blockedRootFramePrefix;
|
|
||||||
if ( tabContext.rawURL.lastIndexOf(blockedRootFramePrefix, 0) === 0 ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var normalURL = tabContext.normalURL;
|
var normalURL = tabContext.normalURL;
|
||||||
var pageStore = this.pageStores[tabId] || null;
|
var pageStore = this.pageStores[tabId] || null;
|
||||||
|
|
||||||
|
|
|
@ -33,65 +33,6 @@
|
||||||
// The `id='uMatrix'` is important, it allows µMatrix to detect whether a
|
// The `id='uMatrix'` is important, it allows µMatrix to detect whether a
|
||||||
// specific data URI originates from itself.
|
// specific data URI originates from itself.
|
||||||
|
|
||||||
var rootFrameReplacement = [
|
|
||||||
'<!DOCTYPE html><html id="uMatrix">',
|
|
||||||
'<head>',
|
|
||||||
'<meta charset="utf-8" />',
|
|
||||||
'<style>',
|
|
||||||
'@font-face {',
|
|
||||||
'font-family:httpsb;',
|
|
||||||
'font-style:normal;',
|
|
||||||
'font-weight:400;',
|
|
||||||
'src: local("httpsb"),url("', µMatrix.fontCSSURL, '") format("truetype");',
|
|
||||||
'}',
|
|
||||||
'body {',
|
|
||||||
'margin:0;',
|
|
||||||
'border:0;',
|
|
||||||
'padding:0;',
|
|
||||||
'font:15px httpsb,sans-serif;',
|
|
||||||
'width:100%;',
|
|
||||||
'height:100%;',
|
|
||||||
'background-color:transparent;',
|
|
||||||
'background-size:10px 10px;',
|
|
||||||
'background-image:',
|
|
||||||
'repeating-linear-gradient(',
|
|
||||||
'-45deg,',
|
|
||||||
'rgba(204,0,0,0.5),rgba(204,0,0,0.5) 24%,',
|
|
||||||
'transparent 26%,transparent 49%,',
|
|
||||||
'rgba(204,0,0,0.5) 51%,rgba(204,0,0,0.5) 74%,',
|
|
||||||
'transparent 76%,transparent',
|
|
||||||
');',
|
|
||||||
'text-align: center;',
|
|
||||||
'}',
|
|
||||||
'#p {',
|
|
||||||
'margin:8px;',
|
|
||||||
'padding:4px;',
|
|
||||||
'display:inline-block;',
|
|
||||||
'background-color:white;',
|
|
||||||
'}',
|
|
||||||
'#t {',
|
|
||||||
'margin:2px;',
|
|
||||||
'border:0;',
|
|
||||||
'padding:0 2px;',
|
|
||||||
'display:inline-block;',
|
|
||||||
'}',
|
|
||||||
'#t b {',
|
|
||||||
'padding:0 4px;',
|
|
||||||
'background-color:#eee;',
|
|
||||||
'font-weight:normal;',
|
|
||||||
'}',
|
|
||||||
'</style>',
|
|
||||||
'<link href="{{cssURL}}?url={{originalURL}}&hostname={{hostname}}&t={{now}}" rel="stylesheet" type="text/css">',
|
|
||||||
'<title>Blocked by μMatrix</title>',
|
|
||||||
'</head>',
|
|
||||||
'<body>',
|
|
||||||
'<div id="p">',
|
|
||||||
'<div id="t"><b>{{hostname}}</b> blocked by μMatrix</div>',
|
|
||||||
'</div>',
|
|
||||||
'</body>',
|
|
||||||
'</html>'
|
|
||||||
].join('');
|
|
||||||
|
|
||||||
var subFrameReplacement = [
|
var subFrameReplacement = [
|
||||||
'<!DOCTYPE html>',
|
'<!DOCTYPE html>',
|
||||||
'<html>',
|
'<html>',
|
||||||
|
@ -152,43 +93,6 @@ var subFrameReplacement = [
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// If it is HTTP Switchboard's root frame replacement URL, verify that
|
|
||||||
// the page that was blacklisted is still blacklisted, and if not,
|
|
||||||
// redirect to the previously blacklisted page.
|
|
||||||
|
|
||||||
var onBeforeChromeExtensionRequestHandler = function(details) {
|
|
||||||
var requestURL = details.url;
|
|
||||||
|
|
||||||
// console.debug('onBeforeChromeExtensionRequestHandler()> "%s": %o', details.url, details);
|
|
||||||
|
|
||||||
// rhill 2013-12-10: Avoid regex whenever a faster indexOf() can be used:
|
|
||||||
// here we can use fast indexOf() as a first filter -- which is executed
|
|
||||||
// for every single request (so speed matters).
|
|
||||||
var matches = requestURL.match(/url=([^&]+)&hostname=([^&]+)/);
|
|
||||||
if ( !matches ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
var pageURL = decodeURIComponent(matches[1]);
|
|
||||||
var pageHostname = decodeURIComponent(matches[2]);
|
|
||||||
|
|
||||||
// Blacklisted as per matrix?
|
|
||||||
if ( µm.mustBlock(µm.scopeFromURL(pageURL), pageHostname, 'doc') ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
µMatrix.asyncJobs.add(
|
|
||||||
'gotoURL-' + details.tabId,
|
|
||||||
{ tabId: details.tabId, url: pageURL },
|
|
||||||
µm.utils.gotoURL,
|
|
||||||
200,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Intercept and filter web requests according to white and black lists.
|
// Intercept and filter web requests according to white and black lists.
|
||||||
|
|
||||||
var onBeforeRootFrameRequestHandler = function(details) {
|
var onBeforeRootFrameRequestHandler = function(details) {
|
||||||
|
@ -199,7 +103,7 @@ var onBeforeRootFrameRequestHandler = function(details) {
|
||||||
µm.tabContextManager.push(tabId, requestURL);
|
µm.tabContextManager.push(tabId, requestURL);
|
||||||
|
|
||||||
var tabContext = µm.tabContextManager.mustLookup(tabId);
|
var tabContext = µm.tabContextManager.mustLookup(tabId);
|
||||||
var pageStore = µm.bindTabToPageStats(tabId, 'weak');
|
var pageStore = µm.bindTabToPageStats(tabId);
|
||||||
|
|
||||||
// Disallow request as per matrix?
|
// Disallow request as per matrix?
|
||||||
var block = µm.mustBlock(tabContext.rootHostname, details.hostname, 'doc');
|
var block = µm.mustBlock(tabContext.rootHostname, details.hostname, 'doc');
|
||||||
|
@ -215,19 +119,15 @@ var onBeforeRootFrameRequestHandler = function(details) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blocked
|
// Blocked
|
||||||
|
var query = btoa(JSON.stringify({
|
||||||
|
url: requestURL,
|
||||||
|
hn: details.hostname,
|
||||||
|
why: '?'
|
||||||
|
}));
|
||||||
|
|
||||||
// If it's a blacklisted frame, redirect to frame.html
|
vAPI.tabs.replace(tabId, vAPI.getURL('main-blocked.html?details=') + query);
|
||||||
// rhill 2013-11-05: The root frame contains a link to noop.css, this
|
|
||||||
// allows to later check whether the root frame has been unblocked by the
|
|
||||||
// user, in which case we are able to force a reload using a redirect.
|
|
||||||
var html = rootFrameReplacement;
|
|
||||||
html = html.replace('{{cssURL}}', µm.noopCSSURL);
|
|
||||||
html = html.replace(/{{hostname}}/g, encodeURIComponent(requestHostname));
|
|
||||||
html = html.replace('{{originalURL}}', encodeURIComponent(requestURL));
|
|
||||||
html = html.replace('{{now}}', String(Date.now()));
|
|
||||||
var dataURI = 'data:text/html;base64,' + btoa(html);
|
|
||||||
|
|
||||||
return { 'redirectUrl': dataURI };
|
return { cancel: true };
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -258,11 +158,6 @@ var onBeforeRequestHandler = function(details) {
|
||||||
|
|
||||||
var requestURL = details.url;
|
var requestURL = details.url;
|
||||||
|
|
||||||
// Is it µMatrix's noop css file?
|
|
||||||
if ( requestType === 'css' && requestURL.lastIndexOf(µm.noopCSSURL, 0) === 0 ) {
|
|
||||||
return onBeforeChromeExtensionRequestHandler(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore non-http schemes
|
// Ignore non-http schemes
|
||||||
if ( requestScheme.indexOf('http') !== 0 ) {
|
if ( requestScheme.indexOf('http') !== 0 ) {
|
||||||
return;
|
return;
|
||||||
|
@ -603,8 +498,7 @@ var requestTypeNormalizer = {
|
||||||
vAPI.net.onBeforeRequest = {
|
vAPI.net.onBeforeRequest = {
|
||||||
urls: [
|
urls: [
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
"https://*/*",
|
"https://*/*"
|
||||||
"chrome-extension://*/*"
|
|
||||||
],
|
],
|
||||||
extra: [ 'blocking' ],
|
extra: [ 'blocking' ],
|
||||||
callback: onBeforeRequestHandler
|
callback: onBeforeRequestHandler
|
||||||
|
@ -641,7 +535,6 @@ var start = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blockedRootFramePrefix: 'data:text/html;base64,' + btoa(rootFrameReplacement).slice(0, 80),
|
|
||||||
start: start
|
start: start
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
72
src/main-blocked.html
Normal file
72
src/main-blocked.html
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<link rel="stylesheet" href="css/common.css" type="text/css">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: large;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
body > div {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
}
|
||||||
|
body > div > p {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
body > div > p:first-child {
|
||||||
|
margin: 1.5em 0 0 0;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
display: inline-block;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: large;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 2px 4px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0 1em 0.25em 1em;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
#warningSign {
|
||||||
|
margin: 1e, 0;
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#warningSign > span {
|
||||||
|
color: #f2a500;
|
||||||
|
font-size: 180px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="warningSign"><span class="fa"></span></div>
|
||||||
|
<div>
|
||||||
|
<p data-i18n="mainBlockedPrompt1"></p>
|
||||||
|
<p class="what code"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div>
|
||||||
|
<p data-i18n="mainBlockedPrompt2"></p>
|
||||||
|
<p id="why" class="code"></p>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p><button id="back" data-i18n="mainBlockedBack" type="button"></button>
|
||||||
|
<button id="bye" data-i18n="mainBlockedClose" type="button"></button></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/vapi-common.js"></script>
|
||||||
|
<script src="js/vapi-client.js"></script>
|
||||||
|
<script src="js/udom.js"></script>
|
||||||
|
<script src="js/i18n.js"></script>
|
||||||
|
<script src="js/main-blocked.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue