mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-05 18:49:39 +02:00
Merge branch 'master' of https://github.com/gorhill/uBlock
This commit is contained in:
commit
e222ace6ef
@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
|
|
||||||
"name": "µBlock",
|
"name": "µBlock",
|
||||||
"version": "0.8.9.1",
|
"version": "0.8.9.2",
|
||||||
|
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"description": "__MSG_extShortDesc__",
|
"description": "__MSG_extShortDesc__",
|
||||||
|
@ -53,7 +53,6 @@ const contentObserver = {
|
|||||||
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
||||||
contentBaseURI: 'chrome://' + hostName + '/content/js/',
|
contentBaseURI: 'chrome://' + hostName + '/content/js/',
|
||||||
cpMessageName: hostName + ':shouldLoad',
|
cpMessageName: hostName + ':shouldLoad',
|
||||||
|
|
||||||
ignoredPopups: new WeakMap(),
|
ignoredPopups: new WeakMap(),
|
||||||
uniqueSandboxId: 1,
|
uniqueSandboxId: 1,
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ vAPI.tabs.get = function(tabId, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for internal use
|
// For internal use
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
@ -565,12 +565,14 @@ vAPI.tabs.get = function(tabId, callback) {
|
|||||||
|
|
||||||
var browser = getBrowserForTab(tab);
|
var browser = getBrowserForTab(tab);
|
||||||
var tabBrowser = getTabBrowser(win);
|
var tabBrowser = getTabBrowser(win);
|
||||||
var tabIndex = vAPI.fennec
|
var tabIndex, tabTitle;
|
||||||
? tabBrowser.tabs.indexOf(tab)
|
if ( vAPI.fennec ) {
|
||||||
: tabBrowser.browsers.indexOf(browser);
|
tabIndex = tabBrowser.tabs.indexOf(tab);
|
||||||
var tabTitle = vAPI.fennec
|
tabTitle = browser.contentTitle;
|
||||||
? browser.contentTitle
|
} else {
|
||||||
: tab.label;
|
tabIndex = tabBrowser.browsers.indexOf(browser);
|
||||||
|
tabTitle = tab.label;
|
||||||
|
}
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
id: tabId,
|
id: tabId,
|
||||||
@ -1022,14 +1024,7 @@ var httpObserver = {
|
|||||||
12: 'object',
|
12: 'object',
|
||||||
14: 'font'
|
14: 'font'
|
||||||
},
|
},
|
||||||
lastRequest: {
|
lastRequest: [{}, {}],
|
||||||
url: null,
|
|
||||||
type: null,
|
|
||||||
tabId: null,
|
|
||||||
frameId: null,
|
|
||||||
parentFrameId: null,
|
|
||||||
openerURL: null
|
|
||||||
},
|
|
||||||
|
|
||||||
get componentRegistrar() {
|
get componentRegistrar() {
|
||||||
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
@ -1134,13 +1129,13 @@ var httpObserver = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( result.redirectUrl ) {
|
/*if ( result.redirectUrl ) {
|
||||||
channel.redirectionLimit = 1;
|
channel.redirectionLimit = 1;
|
||||||
channel.redirectTo(
|
channel.redirectTo(
|
||||||
Services.io.newURI(result.redirectUrl, null, null)
|
Services.io.newURI(result.redirectUrl, null, null)
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@ -1159,13 +1154,6 @@ var httpObserver = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*[
|
|
||||||
type,
|
|
||||||
tabId,
|
|
||||||
sourceTabId - given if it was a popup,
|
|
||||||
frameId,
|
|
||||||
parentFrameId
|
|
||||||
]*/
|
|
||||||
channelData = channel.getProperty(this.REQDATAKEY);
|
channelData = channel.getProperty(this.REQDATAKEY);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
return;
|
return;
|
||||||
@ -1175,7 +1163,7 @@ var httpObserver = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (1 << channelData[0] & this.VALID_CSP_TARGETS) === 0 ) {
|
if ( (1 << channelData[4] & this.VALID_CSP_TARGETS) === 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1189,9 +1177,9 @@ var httpObserver = {
|
|||||||
|
|
||||||
result = vAPI.net.onHeadersReceived.callback({
|
result = vAPI.net.onHeadersReceived.callback({
|
||||||
hostname: URI.asciiHost,
|
hostname: URI.asciiHost,
|
||||||
parentFrameId: channelData[4],
|
parentFrameId: channelData[1],
|
||||||
responseHeaders: result ? [{name: topic, value: result}] : [],
|
responseHeaders: result ? [{name: topic, value: result}] : [],
|
||||||
tabId: channelData[1],
|
tabId: channelData[3],
|
||||||
url: URI.asciiSpec
|
url: URI.asciiSpec
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1208,13 +1196,36 @@ var httpObserver = {
|
|||||||
|
|
||||||
// http-on-opening-request
|
// http-on-opening-request
|
||||||
|
|
||||||
var lastRequest = this.lastRequest;
|
var lastRequest = this.lastRequest[0];
|
||||||
|
|
||||||
|
if ( lastRequest.url !== URI.spec ) {
|
||||||
|
if ( this.lastRequest[1].url === URI.spec ) {
|
||||||
|
lastRequest = this.lastRequest[1];
|
||||||
|
} else {
|
||||||
|
lastRequest.url = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( lastRequest.url === null ) {
|
if ( lastRequest.url === null ) {
|
||||||
this.handleRequest(channel, URI, {
|
lastRequest.type = channel.loadInfo && channel.loadInfo.contentPolicyType || 1;
|
||||||
|
result = this.handleRequest(channel, URI, {
|
||||||
tabId: vAPI.noTabId,
|
tabId: vAPI.noTabId,
|
||||||
type: channel.loadInfo && channel.loadInfo.contentPolicyType || 1
|
type: lastRequest.type
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ( result === true ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( channel instanceof Ci.nsIWritablePropertyBag === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carry data for behind-the-scene redirects
|
||||||
|
channel.setProperty(
|
||||||
|
this.REQDATAKEY,
|
||||||
|
[lastRequest.type, vAPI.noTabId, null, 0, -1]
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,34 +1233,11 @@ var httpObserver = {
|
|||||||
// the URL will be the same, so it could fall into an infinite loop
|
// the URL will be the same, so it could fall into an infinite loop
|
||||||
lastRequest.url = null;
|
lastRequest.url = null;
|
||||||
|
|
||||||
var sourceTabId = null;
|
if ( this.handleRequest(channel, URI, lastRequest) ) {
|
||||||
|
return;
|
||||||
// Popup candidate (only for main_frame type)
|
|
||||||
if ( lastRequest.openerURL ) {
|
|
||||||
for ( var tab of vAPI.tabs.getAll() ) {
|
|
||||||
var tabURI = tab.linkedBrowser.currentURI;
|
|
||||||
|
|
||||||
// Probably isn't the best method to identify the source tab
|
|
||||||
if ( tabURI.spec !== lastRequest.openerURL ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceTabId = vAPI.tabs.getTabId(tab);
|
|
||||||
|
|
||||||
if ( sourceTabId !== lastRequest.tabId ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceTabId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( this.handlePopup(channel.URI, lastRequest.tabId, sourceTabId) ) {
|
|
||||||
channel.cancel(this.ABORT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lastRequest.type === this.MAIN_FRAME && lastRequest.frameId === 0 ) {
|
if ( vAPI.fennec && lastRequest.type === this.MAIN_FRAME && lastRequest.frameId === 0 ) {
|
||||||
vAPI.tabs.onNavigation({
|
vAPI.tabs.onNavigation({
|
||||||
frameId: 0,
|
frameId: 0,
|
||||||
tabId: lastRequest.tabId,
|
tabId: lastRequest.tabId,
|
||||||
@ -1257,22 +1245,15 @@ var httpObserver = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this.handleRequest(channel, URI, lastRequest) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If request is not handled we may use the data in on-modify-request
|
// If request is not handled we may use the data in on-modify-request
|
||||||
if ( channel instanceof Ci.nsIWritablePropertyBag ) {
|
if ( channel instanceof Ci.nsIWritablePropertyBag ) {
|
||||||
channel.setProperty(
|
channel.setProperty(this.REQDATAKEY, [
|
||||||
this.REQDATAKEY,
|
lastRequest.frameId,
|
||||||
[
|
lastRequest.parentFrameId,
|
||||||
lastRequest.type,
|
lastRequest.sourceTabId,
|
||||||
lastRequest.tabId,
|
lastRequest.tabId,
|
||||||
sourceTabId,
|
lastRequest.type
|
||||||
lastRequest.frameId,
|
]);
|
||||||
lastRequest.parentFrameId
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1282,12 +1263,6 @@ var httpObserver = {
|
|||||||
|
|
||||||
// If error thrown, the redirect will fail
|
// If error thrown, the redirect will fail
|
||||||
try {
|
try {
|
||||||
// skip internal redirects?
|
|
||||||
/*if ( flags & 4 ) {
|
|
||||||
console.log('internal redirect skipped');
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var URI = newChannel.URI;
|
var URI = newChannel.URI;
|
||||||
|
|
||||||
if ( !URI.schemeIs('http') && !URI.schemeIs('https') ) {
|
if ( !URI.schemeIs('http') && !URI.schemeIs('https') ) {
|
||||||
@ -1298,21 +1273,18 @@ var httpObserver = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what if a behind-the-scene request is being redirected?
|
|
||||||
// This data is present only for tabbed requests, so if this throws,
|
|
||||||
// the redirection won't be evaluated and canceled (if necessary)
|
|
||||||
var channelData = oldChannel.getProperty(this.REQDATAKEY);
|
var channelData = oldChannel.getProperty(this.REQDATAKEY);
|
||||||
|
|
||||||
if ( this.handlePopup(URI, channelData[1], channelData[2]) ) {
|
if ( this.handlePopup(URI, channelData[3], channelData[2]) ) {
|
||||||
result = this.ABORT;
|
result = this.ABORT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var details = {
|
var details = {
|
||||||
type: channelData[0],
|
frameId: channelData[0],
|
||||||
tabId: channelData[1],
|
parentFrameId: channelData[1],
|
||||||
frameId: channelData[3],
|
tabId: channelData[3],
|
||||||
parentFrameId: channelData[4]
|
type: channelData[4]
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( this.handleRequest(newChannel, URI, details) ) {
|
if ( this.handleRequest(newChannel, URI, details) ) {
|
||||||
@ -1347,13 +1319,46 @@ vAPI.net.registerListeners = function() {
|
|||||||
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
||||||
var shouldLoadListener = function(e) {
|
var shouldLoadListener = function(e) {
|
||||||
var details = e.data;
|
var details = e.data;
|
||||||
|
var tabId = vAPI.tabs.getTabId(e.target);
|
||||||
|
var sourceTabId = null;
|
||||||
|
|
||||||
|
// Popup candidate
|
||||||
|
if ( details.openerURL ) {
|
||||||
|
for ( var tab of vAPI.tabs.getAll() ) {
|
||||||
|
var URI = tab.linkedBrowser.currentURI;
|
||||||
|
|
||||||
|
// Probably isn't the best method to identify the source tab
|
||||||
|
if ( URI.spec !== details.openerURL ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceTabId = vAPI.tabs.getTabId(tab);
|
||||||
|
|
||||||
|
if ( sourceTabId === tabId ) {
|
||||||
|
sourceTabId = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
URI = Services.io.newURI(details.url, null, null);
|
||||||
|
|
||||||
|
if ( httpObserver.handlePopup(URI, tabId, sourceTabId) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var lastRequest = httpObserver.lastRequest;
|
var lastRequest = httpObserver.lastRequest;
|
||||||
lastRequest.url = details.url;
|
lastRequest[1] = lastRequest[0];
|
||||||
lastRequest.type = details.type;
|
lastRequest[0] = {
|
||||||
lastRequest.tabId = vAPI.tabs.getTabId(e.target);
|
frameId: details.frameId,
|
||||||
lastRequest.frameId = details.frameId;
|
parentFrameId: details.parentFrameId,
|
||||||
lastRequest.parentFrameId = details.parentFrameId;
|
sourceTabId: sourceTabId,
|
||||||
lastRequest.openerURL = details.openerURL;
|
tabId: tabId,
|
||||||
|
type: details.type,
|
||||||
|
url: details.url
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
vAPI.messaging.globalMessageManager.addMessageListener(
|
vAPI.messaging.globalMessageManager.addMessageListener(
|
||||||
@ -1813,7 +1818,7 @@ vAPI.contextMenu.create = function(details, callback) {
|
|||||||
|
|
||||||
if ( gContextMenu.inFrame ) {
|
if ( gContextMenu.inFrame ) {
|
||||||
details.tagName = 'iframe';
|
details.tagName = 'iframe';
|
||||||
// Probably won't work with e01s
|
// Probably won't work with e10s
|
||||||
details.frameUrl = gContextMenu.focusedWindow.location.href;
|
details.frameUrl = gContextMenu.focusedWindow.location.href;
|
||||||
} else if ( gContextMenu.onImage ) {
|
} else if ( gContextMenu.onImage ) {
|
||||||
details.tagName = 'img';
|
details.tagName = 'img';
|
||||||
|
@ -27,6 +27,13 @@
|
|||||||
if(vAPI.vapiClientInjected) {
|
if(vAPI.vapiClientInjected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var safari;
|
||||||
|
if(typeof self.safari === "undefined") {
|
||||||
|
safari = self.top.safari;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
safari = self.safari;
|
||||||
|
}
|
||||||
vAPI.vapiClientInjected = true;
|
vAPI.vapiClientInjected = true;
|
||||||
vAPI.safari = true;
|
vAPI.safari = true;
|
||||||
vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
|
vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
|
||||||
@ -71,9 +78,6 @@
|
|||||||
listeners: {},
|
listeners: {},
|
||||||
requestId: 1,
|
requestId: 1,
|
||||||
setup: function() {
|
setup: function() {
|
||||||
if(typeof safari === "undefined") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.connector = function(msg) {
|
this.connector = function(msg) {
|
||||||
// messages from the background script are sent to every frame,
|
// messages from the background script are sent to every frame,
|
||||||
// so we need to check the vAPI.sessionId to accept only
|
// so we need to check the vAPI.sessionId to accept only
|
||||||
@ -107,9 +111,6 @@
|
|||||||
channelName: channelName,
|
channelName: channelName,
|
||||||
listener: typeof callback === 'function' ? callback : null,
|
listener: typeof callback === 'function' ? callback : null,
|
||||||
send: function(message, callback) {
|
send: function(message, callback) {
|
||||||
if(typeof safari === "undefined") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!vAPI.messaging.connector) {
|
if(!vAPI.messaging.connector) {
|
||||||
vAPI.messaging.setup();
|
vAPI.messaging.setup();
|
||||||
}
|
}
|
||||||
@ -236,7 +237,6 @@ return e.detail.url === false;\
|
|||||||
wo = open,\
|
wo = open,\
|
||||||
xo = XMLHttpRequest.prototype.open,\
|
xo = XMLHttpRequest.prototype.open,\
|
||||||
img = Image;\
|
img = Image;\
|
||||||
_noOP = function(){};\
|
|
||||||
Image = function() {\
|
Image = function() {\
|
||||||
var x = new img();\
|
var x = new img();\
|
||||||
Object.defineProperty(x, 'src', {\
|
Object.defineProperty(x, 'src', {\
|
||||||
@ -252,9 +252,9 @@ return x;\
|
|||||||
open = function(u) {\
|
open = function(u) {\
|
||||||
return block(u, 'popup') ? null : wo.apply(this, arguments);\
|
return block(u, 'popup') ? null : wo.apply(this, arguments);\
|
||||||
};\
|
};\
|
||||||
XMLHttpRequest.prototype.open = function(m, u, s) {\
|
XMLHttpRequest.prototype.open = function(m, u) {\
|
||||||
if(block(u, 'xmlhttprequest')) return {send: _noOP};\
|
if(block(u, 'xmlhttprequest')) {throw 'InvalidAccessError'; return;}\
|
||||||
else return xo.apply(this, arguments);\
|
else {xo.apply(this, arguments); return;}\
|
||||||
};";
|
};";
|
||||||
if(frameId === 0) {
|
if(frameId === 0) {
|
||||||
tmpScript += "\
|
tmpScript += "\
|
||||||
|
@ -85,7 +85,7 @@ return {
|
|||||||
|
|
||||||
// read-only
|
// read-only
|
||||||
systemSettings: {
|
systemSettings: {
|
||||||
compiledMagic: 'iolkecdtfsiy',
|
compiledMagic: 'fkaywfqahncj',
|
||||||
selfieMagic: 'spqmeuaftfra'
|
selfieMagic: 'spqmeuaftfra'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -93,25 +93,23 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var timer = window.performance || Date;
|
||||||
|
//var tStart = timer.now();
|
||||||
|
|
||||||
var queriedSelectors = {};
|
var queriedSelectors = {};
|
||||||
var injectedSelectors = {};
|
var injectedSelectors = {};
|
||||||
var classSelectors = null;
|
var lowGenericSelectors = [];
|
||||||
var idSelectors = null;
|
|
||||||
var highGenerics = null;
|
var highGenerics = null;
|
||||||
var contextNodes = [document];
|
var contextNodes = [document];
|
||||||
var nullArray = { push: function(){} };
|
var nullArray = { push: function(){} };
|
||||||
|
|
||||||
var retrieveGenericSelectors = function() {
|
var retrieveGenericSelectors = function() {
|
||||||
var selectors = classSelectors !== null ? Object.keys(classSelectors) : [];
|
if ( lowGenericSelectors.length !== 0 || highGenerics === null ) {
|
||||||
if ( idSelectors !== null ) {
|
//console.log('µBlock> ABP cosmetic filters: retrieving CSS rules using %d selectors', lowGenericSelectors.length);
|
||||||
selectors = selectors.concat(idSelectors);
|
|
||||||
}
|
|
||||||
if ( selectors.length > 0 || highGenerics === null ) {
|
|
||||||
//console.log('µBlock> ABP cosmetic filters: retrieving CSS rules using %d selectors', selectors.length);
|
|
||||||
messager.send({
|
messager.send({
|
||||||
what: 'retrieveGenericCosmeticSelectors',
|
what: 'retrieveGenericCosmeticSelectors',
|
||||||
pageURL: window.location.href,
|
pageURL: window.location.href,
|
||||||
selectors: selectors,
|
selectors: lowGenericSelectors,
|
||||||
highGenerics: highGenerics === null
|
highGenerics: highGenerics === null
|
||||||
},
|
},
|
||||||
retrieveHandler
|
retrieveHandler
|
||||||
@ -122,8 +120,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
} else {
|
} else {
|
||||||
otherRetrieveHandler(null);
|
otherRetrieveHandler(null);
|
||||||
}
|
}
|
||||||
idSelectors = null;
|
lowGenericSelectors = [];
|
||||||
classSelectors = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/452
|
// https://github.com/gorhill/uBlock/issues/452
|
||||||
@ -139,7 +136,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
var selectors = vAPI.hideCosmeticFilters;
|
var selectors = vAPI.hideCosmeticFilters;
|
||||||
if ( typeof selectors === 'object' ) {
|
if ( typeof selectors === 'object' ) {
|
||||||
injectedSelectors = selectors;
|
injectedSelectors = selectors;
|
||||||
hideElements(Object.keys(selectors).join(','));
|
//hideElements(Object.keys(selectors));
|
||||||
}
|
}
|
||||||
// Add exception filters into injected filters collection, in order
|
// Add exception filters into injected filters collection, in order
|
||||||
// to force them to be seen as "already injected".
|
// to force them to be seen as "already injected".
|
||||||
@ -158,6 +155,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
};
|
};
|
||||||
|
|
||||||
var otherRetrieveHandler = function(selectors) {
|
var otherRetrieveHandler = function(selectors) {
|
||||||
|
//var tStart = timer.now();
|
||||||
//console.debug('µBlock> contextNodes = %o', contextNodes);
|
//console.debug('µBlock> contextNodes = %o', contextNodes);
|
||||||
if ( selectors && selectors.highGenerics ) {
|
if ( selectors && selectors.highGenerics ) {
|
||||||
highGenerics = selectors.highGenerics;
|
highGenerics = selectors.highGenerics;
|
||||||
@ -196,6 +194,7 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
addStyleTag(hideSelectors);
|
addStyleTag(hideSelectors);
|
||||||
}
|
}
|
||||||
contextNodes.length = 0;
|
contextNodes.length = 0;
|
||||||
|
//console.debug('%f: uBlock: CSS injection time', timer.now() - tStart);
|
||||||
};
|
};
|
||||||
|
|
||||||
var retrieveHandler = firstRetrieveHandler;
|
var retrieveHandler = firstRetrieveHandler;
|
||||||
@ -206,10 +205,10 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
// - Injecting a style tag
|
// - Injecting a style tag
|
||||||
|
|
||||||
var addStyleTag = function(selectors) {
|
var addStyleTag = function(selectors) {
|
||||||
hideElements(selectors);
|
//hideElements(selectors);
|
||||||
var style = document.createElement('style');
|
var style = document.createElement('style');
|
||||||
// The linefeed before the style block is very important: do no remove!
|
// The linefeed before the style block is very important: do no remove!
|
||||||
style.appendChild(document.createTextNode(selectors.join(',\n') + '\n{display:none !important;}'));
|
style.appendChild(document.createTextNode(selectors.toString() + '\n{display:none !important;}'));
|
||||||
var parent = document.body || document.documentElement;
|
var parent = document.body || document.documentElement;
|
||||||
if ( parent ) {
|
if ( parent ) {
|
||||||
parent.appendChild(style);
|
parent.appendChild(style);
|
||||||
@ -349,12 +348,26 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
// requests to process high-high generics into as few requests as possible.
|
// requests to process high-high generics into as few requests as possible.
|
||||||
// The gain is *significant* on bloated pages.
|
// The gain is *significant* on bloated pages.
|
||||||
|
|
||||||
|
var processHighHighGenericsMisses = 8;
|
||||||
var processHighHighGenericsTimer = null;
|
var processHighHighGenericsTimer = null;
|
||||||
|
|
||||||
var processHighHighGenerics = function() {
|
var processHighHighGenerics = function() {
|
||||||
processHighHighGenericsTimer = null;
|
processHighHighGenericsTimer = null;
|
||||||
if ( injectedSelectors.hasOwnProperty('{{highHighGenerics}}') ) { return; }
|
if ( injectedSelectors.hasOwnProperty('{{highHighGenerics}}') ) {
|
||||||
if ( document.querySelector(highGenerics.hideHigh) === null ) { return; }
|
return;
|
||||||
|
}
|
||||||
|
//var tStart = timer.now();
|
||||||
|
if ( document.querySelector(highGenerics.hideHigh) === null ) {
|
||||||
|
//console.debug('%f: high-high generic test time', timer.now() - tStart);
|
||||||
|
processHighHighGenericsMisses -= 1;
|
||||||
|
// Too many misses for these nagging highly generic CSS rules,
|
||||||
|
// so we will just skip them from now on.
|
||||||
|
if ( processHighHighGenericsMisses === 0 ) {
|
||||||
|
injectedSelectors['{{highHighGenerics}}'] = true;
|
||||||
|
console.debug('high-high generic: apparently not needed...');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
injectedSelectors['{{highHighGenerics}}'] = true;
|
injectedSelectors['{{highHighGenerics}}'] = true;
|
||||||
// We need to filter out possible exception cosmetic filters from
|
// We need to filter out possible exception cosmetic filters from
|
||||||
// high-high generics selectors.
|
// high-high generics selectors.
|
||||||
@ -388,11 +401,8 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
if ( !nodes || !nodes.length ) {
|
if ( !nodes || !nodes.length ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( idSelectors === null ) {
|
|
||||||
idSelectors = [];
|
|
||||||
}
|
|
||||||
var qq = queriedSelectors;
|
var qq = queriedSelectors;
|
||||||
var ii = idSelectors;
|
var ll = lowGenericSelectors;
|
||||||
var node, v;
|
var node, v;
|
||||||
var i = nodes.length;
|
var i = nodes.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
@ -404,8 +414,8 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
v = v.trim();
|
v = v.trim();
|
||||||
if ( v === '' ) { continue; }
|
if ( v === '' ) { continue; }
|
||||||
v = '#' + v;
|
v = '#' + v;
|
||||||
if ( qq[v] ) { continue; }
|
if ( qq.hasOwnProperty(v) ) { continue; }
|
||||||
ii.push(v);
|
ll.push(v);
|
||||||
qq[v] = true;
|
qq[v] = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -417,11 +427,8 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
if ( !nodes || !nodes.length ) {
|
if ( !nodes || !nodes.length ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( classSelectors === null ) {
|
|
||||||
classSelectors = {};
|
|
||||||
}
|
|
||||||
var qq = queriedSelectors;
|
var qq = queriedSelectors;
|
||||||
var cc = classSelectors;
|
var ll = lowGenericSelectors;
|
||||||
var node, v, vv, j;
|
var node, v, vv, j;
|
||||||
var i = nodes.length;
|
var i = nodes.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
@ -433,8 +440,8 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
v = vv[j];
|
v = vv[j];
|
||||||
if ( typeof v !== 'string' ) { continue; }
|
if ( typeof v !== 'string' ) { continue; }
|
||||||
v = '.' + v;
|
v = '.' + v;
|
||||||
if ( qq[v] ) { continue; }
|
if ( qq.hasOwnProperty(v) ) { continue; }
|
||||||
cc[v] = true;
|
ll.push(v);
|
||||||
qq[v] = true;
|
qq[v] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,6 +453,8 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
classesFromNodeList(document.querySelectorAll('[class]'));
|
classesFromNodeList(document.querySelectorAll('[class]'));
|
||||||
retrieveGenericSelectors();
|
retrieveGenericSelectors();
|
||||||
|
|
||||||
|
//console.debug('%f: uBlock: survey time', timer.now() - tStart);
|
||||||
|
|
||||||
// Below this point is the code which takes care to observe changes in
|
// Below this point is the code which takes care to observe changes in
|
||||||
// the page and to add if needed relevant CSS rules as a result of the
|
// the page and to add if needed relevant CSS rules as a result of the
|
||||||
// changes.
|
// changes.
|
||||||
@ -528,7 +537,6 @@ var messager = vAPI.messaging.channel('contentscript-end.js');
|
|||||||
(function() {
|
(function() {
|
||||||
// https://github.com/gorhill/uBlock/issues/683
|
// https://github.com/gorhill/uBlock/issues/683
|
||||||
// Instead of a closure we use a map to remember the element to collapse
|
// Instead of a closure we use a map to remember the element to collapse
|
||||||
// or hide.
|
|
||||||
var filterRequestId = 1;
|
var filterRequestId = 1;
|
||||||
var filterRequests = {};
|
var filterRequests = {};
|
||||||
|
|
||||||
|
@ -1199,7 +1199,7 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.getFilterCount = function() {
|
FilterContainer.prototype.getFilterCount = function() {
|
||||||
return this.acceptedCount;
|
return this.acceptedCount - this.duplicateCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -59,6 +59,8 @@ var renderURL = function(url, filter) {
|
|||||||
.replace(/\?/g, '\\?')
|
.replace(/\?/g, '\\?')
|
||||||
.replace('||', '')
|
.replace('||', '')
|
||||||
.replace(/\^/g, '.')
|
.replace(/\^/g, '.')
|
||||||
|
.replace(/^\|/g, '^')
|
||||||
|
.replace(/\|$/g, '$')
|
||||||
.replace(/\*/g, '.*')
|
.replace(/\*/g, '.*')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ PageStore.prototype.disposeFrameStores = function() {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PageStore.prototype.getFrame = function(frameId) {
|
PageStore.prototype.getFrame = function(frameId) {
|
||||||
return this.frames[frameId];
|
return this.frames[frameId] || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -158,11 +158,11 @@ var onSystemSettingsReady = function(fetched) {
|
|||||||
mustSaveSystemSettings = true;
|
mustSaveSystemSettings = true;
|
||||||
}
|
}
|
||||||
if ( fetched.selfieMagic !== µb.systemSettings.selfieMagic ) {
|
if ( fetched.selfieMagic !== µb.systemSettings.selfieMagic ) {
|
||||||
fetched.selfie = null;
|
|
||||||
µb.destroySelfie();
|
|
||||||
mustSaveSystemSettings = true;
|
mustSaveSystemSettings = true;
|
||||||
}
|
}
|
||||||
if ( mustSaveSystemSettings ) {
|
if ( mustSaveSystemSettings ) {
|
||||||
|
fetched.selfie = null;
|
||||||
|
µb.destroySelfie();
|
||||||
vAPI.storage.set(µb.systemSettings, µb.noopFunc);
|
vAPI.storage.set(µb.systemSettings, µb.noopFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* jshint bitwise: false, esnext: true */
|
/* jshint bitwise: false, esnext: true, boss: true */
|
||||||
/* global µBlock */
|
/* global punycode, µBlock */
|
||||||
|
|
||||||
// Older Safari throws an exception for const when it's used with 'use strict'.
|
// Older Safari throws an exception for const when it's used with 'use strict'.
|
||||||
// 'use strict';
|
// 'use strict';
|
||||||
@ -88,9 +88,7 @@ const AllowAnyTypeAnyParty = AllowAction | AnyType | AnyParty;
|
|||||||
const AllowAnyType = AllowAction | AnyType;
|
const AllowAnyType = AllowAction | AnyType;
|
||||||
const AllowAnyParty = AllowAction | AnyParty;
|
const AllowAnyParty = AllowAction | AnyParty;
|
||||||
|
|
||||||
var reHostnameRule = /^[0-9a-z][0-9a-z.-]+[0-9a-z]$/;
|
var reHostnameRule = /^[0-9a-z][0-9a-z.-]*[0-9a-z]$/;
|
||||||
var reHostnameToken = /^[0-9a-z]+/g;
|
|
||||||
var reGoodToken = /[%0-9a-z]{2,}/g;
|
|
||||||
var reURLPostHostnameAnchors = /[\/?#]/;
|
var reURLPostHostnameAnchors = /[\/?#]/;
|
||||||
|
|
||||||
// ABP filters: https://adblockplus.org/en/filters
|
// ABP filters: https://adblockplus.org/en/filters
|
||||||
@ -168,6 +166,12 @@ var isFirstParty = function(firstPartyDomain, hostname) {
|
|||||||
return c === '.' || c === '';
|
return c === '.' || c === '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var strToRegex = function(prefix, s) {
|
||||||
|
var reStr = s.replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1')
|
||||||
|
.replace(/\*/g, '.*');
|
||||||
|
return new RegExp(prefix + reStr);
|
||||||
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Filters family tree:
|
Filters family tree:
|
||||||
@ -872,6 +876,51 @@ FilterSingleWildcardRightAnchoredHostname.fromSelfie = function(s) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Generic filter: hostname-anchored: it has that extra test to find out
|
||||||
|
// whether the start of the match falls within the hostname part of the
|
||||||
|
// URL.
|
||||||
|
|
||||||
|
var FilterGenericHnAnchored = function(s) {
|
||||||
|
this.s = s;
|
||||||
|
this.re = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.prototype.match = function(url) {
|
||||||
|
if ( this.re === null ) {
|
||||||
|
this.re = strToRegex('', this.s);
|
||||||
|
}
|
||||||
|
// Quick test first
|
||||||
|
if ( this.re.test(url) === false ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Valid only if begininning of match is within the hostname
|
||||||
|
// part of the url
|
||||||
|
var match = this.re.exec(url);
|
||||||
|
var pos = url.indexOf('://');
|
||||||
|
return pos !== -1 &&
|
||||||
|
reURLPostHostnameAnchors.test(url.slice(pos + 3, match.index)) === false;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.fid = FilterGenericHnAnchored.prototype.fid = '||_';
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.prototype.toString = function() {
|
||||||
|
return '||' + this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.prototype.toSelfie = function() {
|
||||||
|
return this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.compile = function(details) {
|
||||||
|
return details.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterGenericHnAnchored.fromSelfie = function(s) {
|
||||||
|
return new FilterGenericHnAnchored(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
// With many wildcards, a regex is best.
|
// With many wildcards, a regex is best.
|
||||||
|
|
||||||
// Ref: regex escaper taken from:
|
// Ref: regex escaper taken from:
|
||||||
@ -881,10 +930,13 @@ FilterSingleWildcardRightAnchoredHostname.fromSelfie = function(s) {
|
|||||||
var FilterManyWildcards = function(s, tokenBeg) {
|
var FilterManyWildcards = function(s, tokenBeg) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
this.re = new RegExp('^' + s.replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '.*'));
|
this.re = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterManyWildcards.prototype.match = function(url, tokenBeg) {
|
FilterManyWildcards.prototype.match = function(url, tokenBeg) {
|
||||||
|
if ( this.re === null ) {
|
||||||
|
this.re = strToRegex('^', this.s);
|
||||||
|
}
|
||||||
return this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
return this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -912,13 +964,18 @@ FilterManyWildcards.fromSelfie = function(s) {
|
|||||||
var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) {
|
var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
this.re = new RegExp('^' + s.replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '.*'));
|
this.re = null;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterManyWildcardsHostname.prototype.match = function(url, tokenBeg) {
|
FilterManyWildcardsHostname.prototype.match = function(url, tokenBeg) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
if ( pageHostnameRegister.slice(-this.hostname.length) !== this.hostname ) {
|
||||||
this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
return false;
|
||||||
|
}
|
||||||
|
if ( this.re === null ) {
|
||||||
|
this.re = strToRegex('^', this.s);
|
||||||
|
}
|
||||||
|
return this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterManyWildcardsHostname.fid = FilterManyWildcardsHostname.prototype.fid = '*+h';
|
FilterManyWildcardsHostname.fid = FilterManyWildcardsHostname.prototype.fid = '*+h';
|
||||||
@ -1316,6 +1373,9 @@ var getFilterClass = function(details) {
|
|||||||
var s = details.f;
|
var s = details.f;
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
if ( wcOffset !== -1 ) {
|
if ( wcOffset !== -1 ) {
|
||||||
|
if ( details.hostnameAnchored ) {
|
||||||
|
return FilterGenericHnAnchored;
|
||||||
|
}
|
||||||
if ( s.indexOf('*', wcOffset + 1) !== -1 ) {
|
if ( s.indexOf('*', wcOffset + 1) !== -1 ) {
|
||||||
return details.anchor === 0 ? FilterManyWildcards : null;
|
return details.anchor === 0 ? FilterManyWildcards : null;
|
||||||
}
|
}
|
||||||
@ -1388,47 +1448,6 @@ var getHostnameBasedFilterClass = function(details) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Given a string, find a good token. Tokens which are too generic, i.e. very
|
|
||||||
// common with a high probability of ending up as a miss, are not
|
|
||||||
// good. Avoid if possible. This has a *significant* positive impact on
|
|
||||||
// performance.
|
|
||||||
// These "bad tokens" are collated manually.
|
|
||||||
|
|
||||||
var badTokens = {
|
|
||||||
'com': true,
|
|
||||||
'http': true,
|
|
||||||
'https': true,
|
|
||||||
'icon': true,
|
|
||||||
'images': true,
|
|
||||||
'img': true,
|
|
||||||
'js': true,
|
|
||||||
'net': true,
|
|
||||||
'news': true,
|
|
||||||
'www': true
|
|
||||||
};
|
|
||||||
|
|
||||||
var findFirstGoodToken = function(s) {
|
|
||||||
reGoodToken.lastIndex = 0;
|
|
||||||
var matches;
|
|
||||||
while ( matches = reGoodToken.exec(s) ) {
|
|
||||||
if ( badTokens[matches[0]] === undefined ) {
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No good token found, just return the first token from left
|
|
||||||
reGoodToken.lastIndex = 0;
|
|
||||||
return reGoodToken.exec(s);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var findHostnameToken = function(s) {
|
|
||||||
reHostnameToken.lastIndex = 0;
|
|
||||||
return reHostnameToken.exec(s);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Trim leading/trailing char "c"
|
// Trim leading/trailing char "c"
|
||||||
|
|
||||||
var trimChar = function(s, c) {
|
var trimChar = function(s, c) {
|
||||||
@ -1690,6 +1709,50 @@ FilterParser.prototype.parse = function(raw) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Given a string, find a good token. Tokens which are too generic, i.e. very
|
||||||
|
// common with a high probability of ending up as a miss, are not
|
||||||
|
// good. Avoid if possible. This has a *significant* positive impact on
|
||||||
|
// performance.
|
||||||
|
// These "bad tokens" are collated manually.
|
||||||
|
|
||||||
|
var reHostnameToken = /^[0-9a-z]+/g;
|
||||||
|
var reGoodToken = /[%0-9a-z]{2,}/g;
|
||||||
|
|
||||||
|
var badTokens = {
|
||||||
|
'com': true,
|
||||||
|
'http': true,
|
||||||
|
'https': true,
|
||||||
|
'icon': true,
|
||||||
|
'images': true,
|
||||||
|
'img': true,
|
||||||
|
'js': true,
|
||||||
|
'net': true,
|
||||||
|
'news': true,
|
||||||
|
'www': true
|
||||||
|
};
|
||||||
|
|
||||||
|
var findFirstGoodToken = function(s) {
|
||||||
|
reGoodToken.lastIndex = 0;
|
||||||
|
var matches;
|
||||||
|
while ( matches = reGoodToken.exec(s) ) {
|
||||||
|
if ( badTokens.hasOwnProperty(matches[0]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( s.charAt(reGoodToken.lastIndex) === '*' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
// No good token found, just return the first token from left
|
||||||
|
reGoodToken.lastIndex = 0;
|
||||||
|
return reGoodToken.exec(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
var findHostnameToken = function(s) {
|
||||||
|
reHostnameToken.lastIndex = 0;
|
||||||
|
return reHostnameToken.exec(s);
|
||||||
|
};
|
||||||
|
|
||||||
FilterParser.prototype.makeToken = function() {
|
FilterParser.prototype.makeToken = function() {
|
||||||
if ( this.isRegex ) {
|
if ( this.isRegex ) {
|
||||||
this.token = '*';
|
this.token = '*';
|
||||||
@ -1698,7 +1761,8 @@ FilterParser.prototype.makeToken = function() {
|
|||||||
|
|
||||||
var matches;
|
var matches;
|
||||||
|
|
||||||
if ( this.hostnameAnchored ) {
|
// Hostname-anchored with no wildcard always have a token index of 0.
|
||||||
|
if ( this.hostnameAnchored && this.f.indexOf('*') === -1 ) {
|
||||||
matches = findHostnameToken(this.f);
|
matches = findHostnameToken(this.f);
|
||||||
if ( !matches || matches[0].length === 0 ) {
|
if ( !matches || matches[0].length === 0 ) {
|
||||||
return;
|
return;
|
||||||
@ -1799,7 +1863,8 @@ FilterContainer.prototype.factories = {
|
|||||||
'*+h': FilterManyWildcardsHostname,
|
'*+h': FilterManyWildcardsHostname,
|
||||||
'//': FilterRegex,
|
'//': FilterRegex,
|
||||||
'//h': FilterRegexHostname,
|
'//h': FilterRegexHostname,
|
||||||
'{h}': FilterHostnameDict
|
'{h}': FilterHostnameDict,
|
||||||
|
'||_': FilterGenericHnAnchored
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -288,7 +288,7 @@
|
|||||||
if ( µb.remoteBlacklists.hasOwnProperty(path) ) {
|
if ( µb.remoteBlacklists.hasOwnProperty(path) ) {
|
||||||
var entry = µb.remoteBlacklists[path];
|
var entry = µb.remoteBlacklists[path];
|
||||||
entry.entryCount = snfe.acceptedCount + cfe.acceptedCount - acceptedCount;
|
entry.entryCount = snfe.acceptedCount + cfe.acceptedCount - acceptedCount;
|
||||||
entry.entryUsedCount = entry.entryCount - snfe.duplicateCount - cfe.duplicateCount + duplicateCount;
|
entry.entryUsedCount = entry.entryCount - (snfe.duplicateCount + cfe.duplicateCount - duplicateCount);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,8 +100,13 @@ var onBeforeRequest = function(details) {
|
|||||||
//console.debug('traffic.js > onBeforeRequest(): ALLOW "%s" (%o) because "%s"', details.url, details, result);
|
//console.debug('traffic.js > onBeforeRequest(): ALLOW "%s" (%o) because "%s"', details.url, details, result);
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/114
|
// https://github.com/gorhill/uBlock/issues/114
|
||||||
if ( isFrame && details.frameId > 0 ) {
|
frameId = details.frameId;
|
||||||
pageStore.setFrame(details.frameId, requestURL);
|
if ( frameId > 0 ) {
|
||||||
|
if ( isFrame ) {
|
||||||
|
pageStore.setFrame(frameId, requestURL);
|
||||||
|
} else if ( pageStore.getFrame(frameId) === null ) {
|
||||||
|
pageStore.setFrame(frameId, requestURL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=387198
|
// https://code.google.com/p/chromium/issues/detail?id=387198
|
||||||
|
Loading…
Reference in New Issue
Block a user