1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-06 09:37:12 +02:00
This commit is contained in:
gorhill 2015-03-25 19:28:22 -04:00
parent 6f155d55f8
commit a4b4bc98ff
10 changed files with 512 additions and 45 deletions

View File

@ -63,5 +63,8 @@
"http://*/*",
"https://*/*"
],
"short_name": "uBlock"
"short_name": "uBlock",
"web_accessible_resources": [
"document-blocked.html"
]
}

View File

@ -567,6 +567,26 @@
"message": "off",
"description": "Firefox-specific: appears as 'uBlock (off)'"
},
"docblockedPrompt1": {
"message": "uBlock has prevented the following page from loading:",
"description": "English: uBlock has prevented the following page from loading:"
},
"docblockedPrompt2": {
"message": "Because of the following filter",
"description": "English: Because of the following filter"
},
"docblockedBack": {
"message": "Go back",
"description": "English: Go back"
},
"docblockedClose": {
"message": "Close this window",
"description": "English: Close this window"
},
"docblockedProceed": {
"message": "Proceed at your own risk",
"description": "English: Proceed at your own risk"
},
"dummy":{
"message":"This entry must be the last one",
"description":"so we dont need to deal with comma for last entry"

49
src/document-blocked.html Normal file
View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
body {
font-size: large;
text-align: center;
}
.label {
margin-bottom: 2px;
}
.code {
background-color: rgba(0, 0, 0, 0.1);
display: inline-block;
font-family: monospace;
margin: 0;
padding: 2px 4px;
word-break: break-all;
}
a {
margin: 0 1em;
}
img {
height: 60vh;
left: 10vw;
opacity: 0.05;
pointer-events: none;
position: fixed;
bottom: 5vh;
width: 80vw;
}
</style>
</head>
<body>
<!-- http://commons.wikimedia.org/wiki/File:Caution_sign_used_on_roads_pn.svg
Public domain. I removed the shadow.
--><img src="img/Caution_sign_used_on_roads_pn.svg" />
<p data-i18n="docblockedPrompt1" class="label"></p><p class="what code"></p>
<p data-i18n="docblockedPrompt2" class="label"></p><p class="code" id="why"></p>
<p><a id="back" data-i18n="docblockedBack" href></a><a id="bye" data-i18n="docblockedClose" href></a></p>
<p data-i18n="docblockedProceed" class="label"></p><p class="code"><a id="yolo" class="what" href></a></p>
<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/document-blocked.js"></script>
</body>
</html>

View File

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
width="580.13672"
height="484.1875"
id="svg2904"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Caution_sign_used_on_roads_pn.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<sodipodi:namedview
inkscape:window-height="1030"
inkscape:window-width="1635"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:zoom="1.508"
inkscape:cx="293.52078"
inkscape:cy="253.98496"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:current-layer="svg2904"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-maximized="0" />
<metadata
id="metadata2950">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs2906">
<linearGradient
id="Grad1"
x1="41.194874"
y1="616.47717"
x2="118.93135"
y2="527.55511"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.556763,0,0,-4.315033,37.49756,2758.519)">
<stop
offset="0"
id="stop2909"
style="stop-color:#f2b600;stop-opacity:1;" />
<stop
offset="1"
id="stop2911"
style="stop-color:#f29600;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="Grad2"
x1="530.80951"
y1="486.63101"
x2="529.85413"
y2="487.53238"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.960006,0,0,0.960006,22.29079,4.4825252)">
<stop
offset="0"
id="stop2914"
style="stop-color:#d88500;stop-opacity:1;" />
<stop
offset="1"
id="stop2916"
style="stop-color:#fc3;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="Grad3"
x1="187.87357"
y1="224.59892"
x2="581.83746"
y2="483.10001"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.960006,0,0,0.960006,-530.75961,251.16687)">
<stop
offset="0"
id="stop2919"
style="stop-color:#ffd657;stop-opacity:1;" />
<stop
offset="1"
id="stop2921"
style="stop-color:#f2b600;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="Grad4"
x1="250.39845"
y1="101.53633"
x2="412.0943"
y2="264.54187"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.960006,0,0,0.960006,-532.08587,273.71329)">
<stop
offset="0"
id="stop2924"
style="stop-color:#fff1c5;stop-opacity:1;" />
<stop
offset="1"
id="stop2926"
style="stop-color:#fc3;stop-opacity:1;" />
</linearGradient>
<radialGradient
id="Grad5"
cx="512.86597"
cy="-10.558988"
r="179.55"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.14292e-8,1.531256,-0.876504,-2.165967e-5,462.7486,-245.0023)"
fx="512.86597"
fy="-10.558988">
<stop
offset="0"
stop-color="#ffffff"
id="stop2929" />
<stop
offset="0.5"
stop-color="#ffffff"
id="stop2931" />
<stop
offset="1"
stop-color="#d5d5d5"
id="stop2933" />
</radialGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#Grad1"
id="linearGradient3073"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.556763,0,0,-4.315033,47.077221,2766.2065)"
x1="41.194874"
y1="616.47717"
x2="118.93135"
y2="527.55511" />
<linearGradient
inkscape:collect="always"
xlink:href="#Grad1"
id="linearGradient3011"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.556763,0,0,-4.315033,37.49756,2758.519)"
x1="41.194874"
y1="616.47717"
x2="118.93135"
y2="527.55511" />
</defs>
<path
inkscape:connector-curvature="0"
d="m 266.00664,15.34815 c 0,0 -260.1615711,427.20245 -260.1615711,427.20245 -4.99203,8.1601 -4.99203,18.2402 0,26.4002 4.8960301,8.0641 14.1120801,13.1521 24.0961401,13.1521 l 520.323031,0 c 9.8881,0 19.1041,-5.088 24.0962,-13.1521 4.896,-8.16 4.896,-18.2401 0,-26.4002 L 314.19884,15.34815 c -4.992,-8.16005 -14.208,-13.248082 -24.0961,-13.248082 -9.8881,0 -19.1041,5.088032 -24.0961,13.248082 z"
style="fill:url(#linearGradient3011);stroke:#000000;stroke-width:4.19999981;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path2937" />
<path
inkscape:connector-curvature="0"
d="m 278.99868,452.85066 c -12.43866,-5.95746 -21.9115,-20.28215 -21.9115,-33.13415 0,-23.93002 25.00579,-41.95617 48.66461,-35.08124 15.96067,4.63812 26.80866,19.04141 26.67576,35.41846 -0.11343,13.91176 -6.13472,24.16004 -18.42527,31.36003 -9.40791,5.5111 -25.14823,6.15709 -35.0036,1.4369 z m 2.8271,-94.49217 c -1.55488,-0.85447 -5.21697,-3.82967 -8.13748,-6.61147 -10.20448,-9.71943 -10.19177,-9.63392 -16.84358,-113.63182 -5.91312,-92.44672 -5.96202,-93.8832 -3.42475,-100.52382 5.70796,-14.94056 18.42638,-21.48282 39.60333,-20.37181 13.46097,0.70636 23.82792,5.43359 30.56648,13.93842 5.75591,7.26436 7.00727,11.37103 7.00202,22.97663 -0.006,12.61148 -8.0619,167.26958 -9.20704,176.74725 -1.49934,12.41296 -8.74672,22.48635 -19.36924,26.92167 -6.07007,2.53478 -16.08611,2.81012 -20.18974,0.55495 z"
id="path2947" />
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -88,7 +88,7 @@ return {
// read-only
systemSettings: {
compiledMagic: 'intdliecolot',
compiledMagic: 'squafjaywuba',
selfieMagic: 'spqmeuaftfra'
},

View File

@ -0,0 +1,73 @@
/*******************************************************************************
uBlock - 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 messager = vAPI.messaging.channel('document-blocked.js');
var matches = /details=([^&]+)/.exec(window.location.search);
if ( matches === null ) {
return;
}
var details = JSON.parse(atob(matches[1]));
/******************************************************************************/
var yolo = function(ev) {
var onReady = function() {
window.location.replace(details.url);
};
messager.send({
what: 'temporarilyWhitelistDocument',
url: details.url
}, onReady);
ev.preventDefault();
};
/******************************************************************************/
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(); });
} else {
uDom('#back').css('display', 'none');
}
uDom('#bye').on('click', function() { window.close(); });
uDom('#yolo').attr('href', details.url)
.on('click', yolo);
})();
/******************************************************************************/

View File

@ -1204,6 +1204,43 @@ vAPI.messaging.listen('subscriber.js', onMessage);
})();
// https://www.youtube.com/watch?v=3_WcygKJP1k
/******************************************************************************/
/******************************************************************************/
// document-blocked.js
(function() {
'use strict';
/******************************************************************************/
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
default:
break;
}
// Sync
var response;
switch ( request.what ) {
case 'temporarilyWhitelistDocument':
µBlock.webRequest.temporarilyWhitelistDocument(request.url);
break;
default:
return vAPI.messaging.UNHANDLED;
}
callback(response);
};
vAPI.messaging.listen('document-blocked.js', onMessage);
/******************************************************************************/
})();
/******************************************************************************/

View File

@ -515,6 +515,12 @@ PageStore.prototype.reuse = function(rawURL, pageURL, context) {
// return this;
//}
// If the hostname changes, we can't merely just update the context.
var pageHostname = µb.URI.hostnameFromURI(pageURL);
if ( pageHostname !== this.pageHostname ) {
context = '';
}
// If URL changes without a page reload (more and more common), then we
// need to keep all that we collected for reuse. In particular, not
// doing so was causing a problem in `videos.foxnews.com`: clicking a
@ -523,10 +529,6 @@ PageStore.prototype.reuse = function(rawURL, pageURL, context) {
if ( context === 'tabUpdated' ) {
this.rawURL = rawURL;
this.pageURL = pageURL;
this.pageHostname = µb.URI.hostnameFromURI(pageURL);
this.pageDomain = µb.URI.domainFromHostname(this.pageHostname) || this.pageHostname;
this.rootHostname = this.pageHostname;
this.rootDomain = this.pageDomain;
// As part of https://github.com/gorhill/uBlock/issues/405
// URL changed, force a re-evaluation of filtering switch

View File

@ -54,15 +54,16 @@ var AnyParty = 0 << 2;
var FirstParty = 1 << 2;
var ThirdParty = 2 << 2;
var AnyType = 1 << 4;
var AnyType = 0 << 4;
var typeNameToTypeValue = {
'stylesheet': 2 << 4,
'image': 3 << 4,
'object': 4 << 4,
'script': 5 << 4,
'xmlhttprequest': 6 << 4,
'sub_frame': 7 << 4,
'other': 8 << 4,
'stylesheet': 1 << 4,
'image': 2 << 4,
'object': 3 << 4,
'script': 4 << 4,
'xmlhttprequest': 5 << 4,
'sub_frame': 6 << 4,
'other': 7 << 4,
'main_frame': 12 << 4,
'cosmetic-filtering': 13 << 4,
'inline-script': 14 << 4,
'popup': 15 << 4
@ -71,13 +72,9 @@ var typeOtherValue = typeNameToTypeValue.other;
// All network request types to bitmap
// bring origin to 0 (from 4 -- see typeNameToTypeValue)
// add 2 = number of left shift to use
// left-shift 1 by the above-calculated value
// subtract 4 to set all type bits, *except* for 2 lsb
// https://github.com/gorhill/uBlock/issues/723
// The 2 lsb *must* be zeroed
var allNetRequestTypesBitmap = (1 << (typeOtherValue >>> 4) + 2) - 4;
// subtract 1 to set all type bits
var allNetRequestTypesBitmap = (1 << (typeOtherValue >>> 4)) - 1;
var BlockAnyTypeAnyParty = BlockAction | AnyType | AnyParty;
var BlockAnyType = BlockAction | AnyType;
@ -100,6 +97,8 @@ var reURLPostHostnameAnchors = /[\/?#]/;
var pageHostnameRegister = '';
var requestHostnameRegister = '';
var filterRegister = null;
var categoryRegister = '';
/******************************************************************************/
@ -1192,6 +1191,7 @@ FilterParser.prototype.toNormalizedType = {
'xmlhttprequest': 'xmlhttprequest',
'subdocument': 'sub_frame',
'other': 'other',
'document': 'main_frame',
'elemhide': 'cosmetic-filtering',
'inline-script': 'inline-script',
'popup': 'popup'
@ -1227,10 +1227,10 @@ FilterParser.prototype.reset = function() {
// Be ready to handle multiple negated types
FilterParser.prototype.parseOptType = function(raw, not) {
var type = typeNameToTypeValue[this.toNormalizedType[raw]];
var typeBit = 1 << ((typeNameToTypeValue[this.toNormalizedType[raw]] >>> 4) - 1);
if ( !not ) {
this.types |= 1 << (type >>> 4);
this.types |= typeBit;
return;
}
@ -1239,7 +1239,7 @@ FilterParser.prototype.parseOptType = function(raw, not) {
this.types = allNetRequestTypesBitmap;
}
this.types &= ~(1 << (type >>> 4));
this.types &= ~typeBit;
};
/******************************************************************************/
@ -1283,10 +1283,22 @@ FilterParser.prototype.parseOptions = function(s) {
this.parseOptParty(not);
continue;
}
if ( opt === 'elemhide' && this.action === AllowAction ) {
this.parseOptType('elemhide', false);
this.action = BlockAction;
continue;
if ( opt === 'elemhide' ) {
if ( this.action !== AllowAction ) {
this.parseOptType('elemhide', false);
this.action = BlockAction;
continue;
}
this.unsupported = true;
break;
}
if ( opt === 'document' ) {
if ( this.action === BlockAction ) {
this.parseOptType('document', false);
continue;
}
this.unsupported = true;
break;
}
if ( this.toNormalizedType.hasOwnProperty(opt) ) {
this.parseOptType(opt, not);
@ -1743,9 +1755,20 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
party = parsed.firstParty ? FirstParty : ThirdParty;
}
var keyShard = parsed.action | parsed.important | party;
var type = parsed.types >>> 1 || 1; // bit 0 is unused; also, default to AnyType
var type = parsed.types;
if ( type === 0 ) {
out.push(
'n\v' +
this.makeCategoryKey(keyShard) + '\v' +
'.\v' +
parsed.f
);
return true;
}
var bitOffset = 1;
while ( type !== 0 ) {
do {
if ( type & 1 ) {
out.push(
'n\v' +
@ -1756,7 +1779,7 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
}
bitOffset += 1;
type >>>= 1;
}
} while ( type !== 0 );
return true;
};
@ -1845,9 +1868,19 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed, party, out, hostname) {
var bits = parsed.action | parsed.important | party;
var type = parsed.types >>> 1 || 1; // bit 0 is unused; also, default to AnyType
var type = parsed.types;
if ( type === 0 ) {
out.push(
'n\v' +
this.makeCategoryKey(bits) + '\v' +
parsed.token + '\v' +
filterClass.fid + '\v' +
filterClass.compile(parsed, hostname)
);
return;
}
var bitOffset = 1;
while ( type !== 0 ) {
do {
if ( type & 1 ) {
out.push(
'n\v' +
@ -1859,7 +1892,7 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
}
bitOffset += 1;
type >>>= 1;
}
} while ( type !== 0 );
};
/******************************************************************************/
@ -2008,7 +2041,11 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r
var party = isFirstParty(context.pageDomain, requestHostnameRegister) ? FirstParty : ThirdParty;
// Be prepared to support unknown types
var type = typeNameToTypeValue[requestType] || typeOtherValue;
var type = typeNameToTypeValue[requestType] || 0;
if ( type === 0 ) {
return '';
}
var categories = this.categories;
var bf = false, bucket;
@ -2069,7 +2106,7 @@ FilterContainer.prototype.matchString = function(context) {
// Use exact type match for anything beyond `other`
// Also, be prepared to support unknown types
var type = typeNameToTypeValue[context.requestType] || typeOtherValue;
if ( type > 8 << 4 ) {
if ( type > (7 << 4) ) {
return this.matchStringExactType(context, context.requestURL, context.requestType);
}

View File

@ -31,6 +31,8 @@
/******************************************************************************/
var exports = {};
// https://github.com/gorhill/uBlock/issues/1001
// This is to be used as last-resort fallback in case a tab is found to not
// be bound while network requests are fired for the tab.
@ -38,6 +40,9 @@
var mostRecentRootDocURLTimestamp = 0;
var mostRecentRootDocURL = '';
var documentWhitelists = Object.create(null);
/******************************************************************************/
// Intercept and filter web requests.
@ -165,26 +170,75 @@ var onBeforeRequest = function(details) {
// Do not use redirection, we need to block outright to be sure the request
// will not be made. There can be no such guarantee with redirection.
return { 'cancel': true };
return { cancel: true };
};
/******************************************************************************/
var onBeforeRootFrameRequest = function(details) {
mostRecentRootDocURL = requestURL;
mostRecentRootDocURLTimestamp = Date.now();
// Special handling for root document.
// https://github.com/gorhill/uBlock/issues/1001
// This must be executed regardless of whether the request is
// behind-the-scene
var µb = µBlock;
var requestURL = details.url;
var pageStore = µBlock.bindTabToPageStats(details.tabId, requestURL, 'beforeRequest');
if ( pageStore !== null ) {
pageStore.requestURL = requestURL;
pageStore.requestHostname = pageStore.pageHostname;
pageStore.requestType = 'main_frame';
pageStore.logRequest(pageStore, '');
var requestHostname = details.hostname;
var requestDomain = µb.URI.domainFromHostname(requestHostname);
var context = {
rootHostname: requestHostname,
rootDomain: requestDomain,
pageHostname: requestHostname,
pageDomain: requestDomain,
requestURL: requestURL,
requestHostname: requestHostname,
requestType: 'main_frame'
};
var result = '';
// Temporarily whitelisted?
var obsolete = documentWhitelists[requestHostname];
if ( obsolete !== undefined ) {
if ( obsolete > Date.now() ) {
result = 'da:*' + ' ' + requestHostname + ' doc allow';
} else {
delete documentWhitelists[requestHostname];
}
}
mostRecentRootDocURL = requestURL;
mostRecentRootDocURLTimestamp = Date.now();
// Filtering
if ( result === '' && µb.getNetFilteringSwitch(requestURL) ) {
if ( µb.userSettings.advancedUserEnabled ) {
var df = µb.sessionFirewall.evaluateCellZY(requestHostname, requestHostname, '*');
if ( df.mustBlockOrAllow() ) {
result = df.toFilterString();
}
}
if ( result === '' ) {
result = µb.staticNetFilteringEngine.matchString(context);
}
}
// Log
var pageStore = µb.bindTabToPageStats(details.tabId, requestURL, 'beforeRequest');
if ( pageStore ) {
pageStore.logRequest(context, result);
}
// Not blocked
if ( µb.isAllowResult(result) ) {
return;
}
// Blocked
var query = btoa(JSON.stringify({
url: requestURL,
why: result + '$document'
}));
return { redirectUrl: vAPI.getURL('document-blocked.html?details=') + query };
};
/******************************************************************************/
@ -348,6 +402,22 @@ vAPI.net.registerListeners();
/******************************************************************************/
exports.temporarilyWhitelistDocument = function(url) {
var µb = µBlock;
var hostname = µb.URI.hostnameFromURI(url);
if ( hostname === '' ) {
return;
}
documentWhitelists[hostname] = Date.now() + 60 * 1000;
};
/******************************************************************************/
return exports;
/******************************************************************************/
})();
/******************************************************************************/