1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-02 23:57:10 +02:00
This commit is contained in:
gorhill 2015-03-08 11:06:36 -04:00
parent 252eb1b4dc
commit 8341fb2193
5 changed files with 110 additions and 139 deletions

View File

@ -71,6 +71,17 @@ vAPI.noTabId = '-1';
/******************************************************************************/
var onCreatedNavigationTarget = function(details) {
vAPI.tabs.onPopup({
openerTabId: details.sourceTabId,
openerURL: '',
targetURL: details.url,
targetTabId: details.tabId
});
};
/******************************************************************************/
vAPI.tabs.registerListeners = function() {
if ( typeof this.onNavigation === 'function' ) {
chrome.webNavigation.onCommitted.addListener(this.onNavigation);
@ -85,7 +96,7 @@ vAPI.tabs.registerListeners = function() {
}
if ( typeof this.onPopup === 'function' ) {
chrome.webNavigation.onCreatedNavigationTarget.addListener(this.onPopup);
chrome.webNavigation.onCreatedNavigationTarget.addListener(onCreatedNavigationTarget);
}
};
@ -493,15 +504,6 @@ vAPI.net.registerListeners = function() {
this.onBeforeRequest.extra
);
chrome.webRequest.onBeforeSendHeaders.addListener(
this.onBeforeSendHeaders.callback,
{
'urls': this.onBeforeSendHeaders.urls || ['<all_urls>'],
'types': this.onBeforeSendHeaders.types || []
},
this.onBeforeSendHeaders.extra
);
var onHeadersReceivedClient = this.onHeadersReceived.callback;
var onHeadersReceived = function(details) {
normalizeRequestDetails(details);
@ -515,6 +517,56 @@ vAPI.net.registerListeners = function() {
},
this.onHeadersReceived.extra
);
// Intercept root frame requests.
// This is where we identify and block popups early, whenever possible.
var onBeforeSendHeaders = function(details) {
// Do not block behind the scene requests.
if ( vAPI.isNoTabId(details.tabId) ) {
return;
}
// Only root document.
if ( details.parentFrameId !== -1 ) {
return;
}
var referrer = headerValue(details.requestHeaders, 'referer');
if ( referrer === '' ) {
return;
}
var result = vAPI.tabs.onPopup({
openerTabId: undefined,
openerURL: referrer,
targetTabId: details.tabId,
targetURL: details.url
});
if ( result ) {
return { 'cancel': true };
}
};
var headerValue = function(headers, name) {
var i = headers.length;
while ( i-- ) {
if ( headers[i].name.toLowerCase() === name ) {
return headers[i].value;
}
}
return '';
};
chrome.webRequest.onBeforeSendHeaders.addListener(
onBeforeSendHeaders,
{
'urls': [ 'http://*/*', 'https://*/*' ],
'types': [ 'main_frame' ]
},
[ 'blocking', 'requestHeaders' ]
);
};
/******************************************************************************/

View File

@ -1118,9 +1118,9 @@ var httpObserver = {
}
var result = vAPI.tabs.onPopup({
tabId: tabId,
sourceTabId: sourceTabId,
url: URI.asciiSpec
targetTabId: tabId,
openerTabId: sourceTabId,
targetURL: URI.asciiSpec
});
return result === true;

View File

@ -209,15 +209,15 @@
var url = e.url,
tabId = vAPI.tabs.getTabId(e.target);
var details = {
url: url,
tabId: tabId,
sourceTabId: vAPI.tabs.popupCandidate
targetURL: url,
targetTabId: tabId,
openerTabId: vAPI.tabs.popupCandidate
};
vAPI.tabs.popupCandidate = false;
if(vAPI.tabs.onPopup(details)) {
e.preventDefault();
if(vAPI.tabs.stack[details.sourceTabId]) {
vAPI.tabs.stack[details.sourceTabId].activate();
if(vAPI.tabs.stack[details.openerTabId]) {
vAPI.tabs.stack[details.openerTabId].activate();
}
}
}, true);
@ -663,9 +663,9 @@
}
else {
e.message = !vAPI.tabs.onPopup({
url: e.message.url,
tabId: 0,
sourceTabId: vAPI.tabs.getTabId(e.target)
targetURL: e.message.url,
targetTabId: 0,
openerTabId: vAPI.tabs.getTabId(e.target)
});
}
break;

View File

@ -37,6 +37,7 @@ var µb = µBlock;
// When the DOM content of root frame is loaded, this means the tab
// content has changed.
vAPI.tabs.onNavigation = function(details) {
if ( details.frameId !== 0 ) {
return;
@ -55,9 +56,12 @@ vAPI.tabs.onNavigation = function(details) {
}
};
/******************************************************************************/
// It may happen the URL in the tab changes, while the page's document
// stays the same (for instance, Google Maps). Without this listener,
// the extension icon won't be properly refreshed.
vAPI.tabs.onUpdated = function(tabId, changeInfo, tab) {
if ( !tab.url || tab.url === '' ) {
return;
@ -68,6 +72,8 @@ vAPI.tabs.onUpdated = function(tabId, changeInfo, tab) {
µb.bindTabToPageStats(tabId, changeInfo.url, 'tabUpdated');
};
/******************************************************************************/
vAPI.tabs.onClosed = function(tabId) {
if ( tabId < 0 ) {
return;
@ -75,28 +81,49 @@ vAPI.tabs.onClosed = function(tabId) {
µb.unbindTabFromPageStats(tabId);
};
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/297
vAPI.tabs.onPopup = function(details) {
//console.debug('vAPI.tabs.onPopup: url="%s"', details.url);
var pageStore = µb.pageStoreFromTabId(details.sourceTabId);
if ( !pageStore ) {
var pageStore = µb.pageStoreFromTabId(details.openerTabId);
var openerURL = details.openerURL || '';
if ( openerURL === '' && pageStore ) {
openerURL = pageStore.pageURL;
}
if ( openerURL === '' ) {
return;
}
var requestURL = details.url;
var µburi = µb.URI;
var openerHostname = µburi.hostnameFromURI(openerURL);
var openerDomain = µburi.domainFromHostname(openerHostname);
var context = {
pageHostname: openerHostname,
pageDomain: openerDomain,
rootHostname: openerHostname,
rootDomain: openerDomain
};
var targetURL = details.targetURL;
var result = '';
// https://github.com/gorhill/uBlock/issues/323
// If popup URL is whitelisted, do not block it
if ( µb.getNetFilteringSwitch(requestURL) ) {
result = µb.staticNetFilteringEngine.matchStringExactType(pageStore, requestURL, 'popup');
if ( µb.getNetFilteringSwitch(targetURL) ) {
result = µb.staticNetFilteringEngine.matchStringExactType(context, targetURL, 'popup');
}
// https://github.com/gorhill/uBlock/issues/91
if ( result !== '' ) {
if ( pageStore ) {
var context = {
requestURL: requestURL,
requestHostname: µb.URI.hostnameFromURI(requestURL),
requestURL: targetURL,
requestHostname: µb.URI.hostnameFromURI(targetURL),
requestType: 'popup'
};
pageStore.logRequest(context, result);
@ -110,10 +137,9 @@ vAPI.tabs.onPopup = function(details) {
// Blocked
// It is a popup, block and remove the tab.
µb.unbindTabFromPageStats(details.tabId);
vAPI.tabs.remove(details.tabId);
µb.unbindTabFromPageStats(details.targetTabId);
vAPI.tabs.remove(details.targetTabId);
// for Safari and Firefox
return true;
};

View File

@ -185,89 +185,6 @@ var onBeforeBehindTheSceneRequest = function(details) {
/******************************************************************************/
// Intercept root frame requests. This is where we identify and block popups.
var onBeforeSendHeaders = function(details) {
// TODO: I vaguely remember reading that when pre-fetch is enabled,
// the tab id could be -1, despite the request not really being a
// behind-the-scene request. If true, the test below would prevent
// the popup blocker from working. Need to check this.
//console.debug('traffic.js > onBeforeSendHeaders(): "%s" (%o) because "%s"', details.url, details, result);
// Do not block behind the scene requests.
var tabId = details.tabId;
if ( vAPI.isNoTabId(tabId) ) {
return;
}
// Only root document.
if ( details.parentFrameId !== -1 ) {
return;
}
var µb = µBlock;
var requestURL = details.url;
// Lookup the page store associated with this tab id.
var pageStore = µb.pageStoreFromTabId(tabId);
if ( !pageStore ) {
// This happens under normal circumstances in Opera.
return;
}
// Heuristic to determine whether we are dealing with a popup:
// - the page store is new (it's not a reused one)
// - the referrer is not nil
// Can't be a popup, the tab was in use previously.
if ( pageStore.previousPageURL !== '' ) {
return;
}
var referrer = headerValue(details.requestHeaders, 'referer');
if ( referrer === '' ) {
return;
}
// https://github.com/gorhill/uBlock/issues/323
if ( pageStore.getNetFilteringSwitch() === false ) {
return;
}
// TODO: I think I should test the switch of the referrer instead, not the
// switch of the popup. If so, that would require being able to lookup
// a page store from a URL. Have to keep in mind the same URL can appear
// in multiple tabs.
// https://github.com/gorhill/uBlock/issues/67
// We need to pass the details of the page which opened this popup,
// so that the `third-party` option works.
// Create a synthetic context based on the referrer.
var µburi = µb.URI;
var referrerHostname = µburi.hostnameFromURI(referrer);
var pageDetails = {
pageHostname: referrerHostname,
pageDomain: µburi.domainFromHostname(referrerHostname)
};
pageDetails.rootHostname = pageDetails.pageHostname;
pageDetails.rootDomain = pageDetails.pageDomain;
//console.debug('traffic.js > Referrer="%s"', referrer);
var result = µb.staticNetFilteringEngine.matchStringExactType(pageDetails, requestURL, 'popup');
// Not blocked?
if ( µb.isAllowResult(result) ) {
return;
}
// It is a popup, block and remove the tab.
µb.unbindTabFromPageStats(tabId);
vAPI.tabs.remove(tabId);
return { 'cancel': true };
};
/******************************************************************************/
// To handle `inline-script`.
var onHeadersReceived = function(details) {
@ -343,18 +260,6 @@ var onHeadersReceived = function(details) {
/******************************************************************************/
var headerValue = function(headers, name) {
var i = headers.length;
while ( i-- ) {
if ( headers[i].name.toLowerCase() === name ) {
return headers[i].value;
}
}
return '';
};
/******************************************************************************/
var headerStartsWith = function(headers, prefix) {
var i = headers.length;
while ( i-- ) {
@ -386,18 +291,6 @@ vAPI.net.onBeforeRequest = {
callback: onBeforeRequest
};
vAPI.net.onBeforeSendHeaders = {
urls: [
'http://*/*',
'https://*/*'
],
types: [
"main_frame"
],
extra: [ 'blocking', 'requestHeaders' ],
callback: onBeforeSendHeaders
};
vAPI.net.onHeadersReceived = {
urls: [
'http://*/*',