mirror of https://github.com/gorhill/uBlock.git
this fixes #58
This commit is contained in:
parent
1bfc107cdf
commit
6050ab3959
|
@ -28,6 +28,17 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// fedcba9876543210
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | +---- party [0 - 7]
|
||||||
|
// | +---- type [0 - 15]
|
||||||
|
// +---- [BlockAction | AllowAction]
|
||||||
|
|
||||||
const BlockAction = 0 << 15;
|
const BlockAction = 0 << 15;
|
||||||
const AllowAction = 1 << 15;
|
const AllowAction = 1 << 15;
|
||||||
|
|
||||||
|
@ -74,7 +85,8 @@ var typeNameToTypeValue = {
|
||||||
'script': 5 << 11,
|
'script': 5 << 11,
|
||||||
'xmlhttprequest': 6 << 11,
|
'xmlhttprequest': 6 << 11,
|
||||||
'sub_frame': 7 << 11,
|
'sub_frame': 7 << 11,
|
||||||
'other': 8 << 11
|
'other': 8 << 11,
|
||||||
|
'popup': 9 << 11
|
||||||
};
|
};
|
||||||
|
|
||||||
// ABP filters: https://adblockplus.org/en/filters
|
// ABP filters: https://adblockplus.org/en/filters
|
||||||
|
@ -805,7 +817,8 @@ FilterParser.prototype.toNormalizedType = {
|
||||||
'script': 'script',
|
'script': 'script',
|
||||||
'xmlhttprequest': 'xmlhttprequest',
|
'xmlhttprequest': 'xmlhttprequest',
|
||||||
'subdocument': 'sub_frame',
|
'subdocument': 'sub_frame',
|
||||||
'other': 'other'
|
'other': 'other',
|
||||||
|
'popup': 'popup'
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -955,7 +968,7 @@ FilterParser.prototype.parse = function(s) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( opt === 'popup' ) {
|
if ( opt === 'popup' ) {
|
||||||
this.elemHiding = true;
|
this.parseOptType('popup', not);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.unsupported = true;
|
this.unsupported = true;
|
||||||
|
|
|
@ -61,7 +61,6 @@ return {
|
||||||
},
|
},
|
||||||
|
|
||||||
pageStores: {},
|
pageStores: {},
|
||||||
pageStoreDump: {},
|
|
||||||
|
|
||||||
storageQuota: chrome.storage.local.QUOTA_BYTES,
|
storageQuota: chrome.storage.local.QUOTA_BYTES,
|
||||||
storageUsed: 0,
|
storageUsed: 0,
|
||||||
|
|
|
@ -60,6 +60,22 @@ function PageStore(tabId, pageURL) {
|
||||||
|
|
||||||
PageStore.prototype.init = function(tabId, pageURL) {
|
PageStore.prototype.init = function(tabId, pageURL) {
|
||||||
this.tabId = tabId;
|
this.tabId = tabId;
|
||||||
|
this.previousPageURL = '';
|
||||||
|
this.pageURL = pageURL;
|
||||||
|
this.pageHostname = µb.URI.hostnameFromURI(pageURL);
|
||||||
|
this.pageDomain = µb.URI.domainFromHostname(this.pageHostname);
|
||||||
|
this.perLoadBlockedRequestCount = 0;
|
||||||
|
this.perLoadAllowedRequestCount = 0;
|
||||||
|
this.blockedRequests = {};
|
||||||
|
this.allowedRequests = {};
|
||||||
|
this.disposeTime = 0;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
PageStore.prototype.reuse = function(pageURL) {
|
||||||
|
this.previousPageURL = this.pageURL;
|
||||||
this.pageURL = pageURL;
|
this.pageURL = pageURL;
|
||||||
this.pageHostname = µb.URI.hostnameFromURI(pageURL);
|
this.pageHostname = µb.URI.hostnameFromURI(pageURL);
|
||||||
this.pageDomain = µb.URI.domainFromHostname(this.pageHostname);
|
this.pageDomain = µb.URI.domainFromHostname(this.pageHostname);
|
||||||
|
|
41
js/tab.js
41
js/tab.js
|
@ -41,9 +41,15 @@
|
||||||
if ( !tab.url || tab.url === '' ) {
|
if ( !tab.url || tab.url === '' ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( changeInfo.url && µBlock.pageStores[tabId] ) {
|
var µb = µBlock;
|
||||||
µBlock.updateBadgeAsync(tabId);
|
if ( !changeInfo.url || !µb.pageStores[tabId] ) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
// If URL is unsupported scheme, unbind tab
|
||||||
|
if ( changeInfo.url && changeInfo.url.slice(0, 4) !== 'http' ) {
|
||||||
|
µb.unbindTabFromPageStats(tabId);
|
||||||
|
}
|
||||||
|
µb.updateBadgeAsync(tabId);
|
||||||
}
|
}
|
||||||
chrome.tabs.onUpdated.addListener(onTabUpdated);
|
chrome.tabs.onUpdated.addListener(onTabUpdated);
|
||||||
|
|
||||||
|
@ -92,32 +98,23 @@
|
||||||
µBlock.bindTabToPageStats = function(tabId, pageURL) {
|
µBlock.bindTabToPageStats = function(tabId, pageURL) {
|
||||||
this.updateBadgeAsync(tabId);
|
this.updateBadgeAsync(tabId);
|
||||||
|
|
||||||
// First unbind whatever page store is bound to the tab id.
|
|
||||||
this.unbindTabFromPageStats(tabId);
|
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/303
|
// https://github.com/gorhill/httpswitchboard/issues/303
|
||||||
// Normalize to a page-URL.
|
// Normalize page URL
|
||||||
pageURL = this.normalizePageURL(pageURL);
|
pageURL = this.normalizePageURL(pageURL);
|
||||||
|
|
||||||
// do not create stats store for urls which are of no interests
|
// Do not create a page store for URLs which are of no interests
|
||||||
if ( pageURL === '' ) {
|
if ( pageURL === '' ) {
|
||||||
|
this.unbindTabFromPageStats(tabId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bring back existing page store or create new one.
|
// Reuse page store if one exists: this allows to guess if a tab is
|
||||||
|
// a popup.
|
||||||
var pageStore = this.pageStores[tabId];
|
var pageStore = this.pageStores[tabId];
|
||||||
if ( !pageStore ) {
|
if ( pageStore ) {
|
||||||
var k = pageURL + ' ' + tabId;
|
pageStore.reuse(pageURL);
|
||||||
pageStore = this.pageStoreDump[k];
|
} else {
|
||||||
if ( pageStore ) {
|
|
||||||
delete this.pageStoreDump[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !pageStore ) {
|
|
||||||
pageStore = this.PageStore.factory(tabId, pageURL);
|
pageStore = this.PageStore.factory(tabId, pageURL);
|
||||||
pageStore.perLoadAllowedRequestCount =
|
|
||||||
pageStore.perLoadBlockedRequestCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log('µBlock> bindTabToPageStats(%d, "%s")', tabId, pageURL);
|
//console.log('µBlock> bindTabToPageStats(%d, "%s")', tabId, pageURL);
|
||||||
|
@ -127,12 +124,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.unbindTabFromPageStats = function(tabId) {
|
µBlock.unbindTabFromPageStats = function(tabId) {
|
||||||
var pageStore = this.pageStores[tabId];
|
|
||||||
if ( pageStore ) {
|
|
||||||
//pageStore.disposeTime = Date.now();
|
|
||||||
//this.pageStoreDump[pageStore.pageURL + ' ' + tabId] = pageStore;
|
|
||||||
//console.log('µBlock> unbindTabFromPageStats(%d)', tabId);
|
|
||||||
}
|
|
||||||
delete this.pageStores[tabId];
|
delete this.pageStores[tabId];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,58 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Intercept root frame requests. This is where we identify and block popups.
|
||||||
|
|
||||||
|
var onBeforeRootDocumentRequestHandler = function(tabId, details) {
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
// Ignore non-http schemes: I don't think this could ever happened
|
||||||
|
// because of filters at addListener() time... Will see.
|
||||||
|
var requestURL = details.url;
|
||||||
|
if ( requestURL.slice(0, 4) !== 'http' ) {
|
||||||
|
console.error('onBeforeRootDocumentRequestHandler(): Unexpected scheme!');
|
||||||
|
µb.unbindTabFromPageStats(tabId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup the page store associated with this tab id.
|
||||||
|
var pageStore = µb.bindTabToPageStats(tabId, requestURL);
|
||||||
|
if ( !pageStore ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Heuristic to determine whether we are dealing with a popup:
|
||||||
|
// - the page store is new (it's not a reused one)
|
||||||
|
|
||||||
|
// Can't be a popup, the tab was in use previously.
|
||||||
|
if ( pageStore.previousPageURL !== '' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var reason = false;
|
||||||
|
if ( µb.getNetFilteringSwitch(pageStore.pageHostname) ) {
|
||||||
|
reason = µb.abpFilters.matchString(
|
||||||
|
pageStore,
|
||||||
|
requestURL,
|
||||||
|
'popup',
|
||||||
|
µb.URI.hostnameFromURI(requestURL)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not blocked?
|
||||||
|
if ( reason === false || reason.slice(0, 2) === '@@' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is a popup, block and remove the tab.
|
||||||
|
µb.unbindTabFromPageStats(tabId);
|
||||||
|
chrome.tabs.remove(tabId);
|
||||||
|
|
||||||
|
return { 'cancel': true };
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
// Intercept and filter web requests according to white and black lists.
|
// Intercept and filter web requests according to white and black lists.
|
||||||
|
|
||||||
var onBeforeRequestHandler = function(details) {
|
var onBeforeRequestHandler = function(details) {
|
||||||
|
@ -40,24 +92,22 @@ var onBeforeRequestHandler = function(details) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var µb = µBlock;
|
// Special handling for root document.
|
||||||
var requestType = details.type;
|
var requestType = details.type;
|
||||||
|
|
||||||
// Never block root main doc.
|
|
||||||
if ( requestType === 'main_frame' && details.parentFrameId < 0 ) {
|
if ( requestType === 'main_frame' && details.parentFrameId < 0 ) {
|
||||||
µb.bindTabToPageStats(tabId, details.url);
|
return onBeforeRootDocumentRequestHandler(tabId, details);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignore non-http schemes: I don't think this could ever happened
|
||||||
|
// because of filters at addListener() time... Will see.
|
||||||
var requestURL = details.url;
|
var requestURL = details.url;
|
||||||
var µburi = µb.URI.set(details.url);
|
if ( requestURL.slice(0, 4) !== 'http' ) {
|
||||||
|
console.error('onBeforeRequestHandler(): Unexpected scheme!');
|
||||||
// Ignore non-http schemes
|
|
||||||
var requestScheme = µburi.scheme;
|
|
||||||
if ( requestScheme.indexOf('http') !== 0 ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
var µburi = µb.URI.set(requestURL);
|
||||||
var requestHostname = µburi.hostname;
|
var requestHostname = µburi.hostname;
|
||||||
var requestPath = µburi.path;
|
var requestPath = µburi.path;
|
||||||
|
|
||||||
|
@ -76,9 +126,7 @@ var onBeforeRequestHandler = function(details) {
|
||||||
|
|
||||||
var reason = false;
|
var reason = false;
|
||||||
if ( µb.getNetFilteringSwitch(pageStore.pageHostname) ) {
|
if ( µb.getNetFilteringSwitch(pageStore.pageHostname) ) {
|
||||||
//quickProfiler.start('abpFilters.matchString');
|
|
||||||
reason = µb.abpFilters.matchString(pageStore, requestURL, requestType, requestHostname);
|
reason = µb.abpFilters.matchString(pageStore, requestURL, requestType, requestHostname);
|
||||||
//quickProfiler.stop();
|
|
||||||
}
|
}
|
||||||
// Record what happened.
|
// Record what happened.
|
||||||
pageStore.recordRequest(requestType, requestURL, reason);
|
pageStore.recordRequest(requestType, requestURL, reason);
|
||||||
|
|
Loading…
Reference in New Issue