1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-07-08 12:57:57 +02:00
This commit is contained in:
Raymond Hill 2018-02-26 13:59:16 -05:00
parent 64682ab8a1
commit 2c901588c7
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
12 changed files with 191 additions and 188 deletions

View File

@ -265,18 +265,29 @@ vAPI.tabs = {};
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/3546
// Added a new flavor of behind-the-scene tab id: vAPI.anyTabId.
// vAPI.anyTabId will be used for network requests which can be filtered,
// because they comes with enough contextual information. It's just not
// possible to pinpoint exactly from which tab it comes from. For example,
// with Firefox/webext, the `documentUrl` property is available for every
// network requests.
vAPI.isBehindTheSceneTabId = function(tabId) {
return tabId.toString() === '-1';
if ( typeof tabId === 'string' ) { debugger; }
return tabId < 0;
};
vAPI.noTabId = '-1';
vAPI.unsetTabId = 0;
vAPI.noTabId = -1; // definitely not any existing tab
vAPI.anyTabId = -2; // one of the existing tab
/******************************************************************************/
// To remove when tabId-as-integer has been tested enough.
var toChromiumTabId = function(tabId) {
if ( typeof tabId === 'string' ) {
tabId = parseInt(tabId, 10);
}
if ( typeof tabId === 'string' ) { debugger; }
if ( typeof tabId !== 'number' || isNaN(tabId) || tabId === -1 ) {
return 0;
}
@ -329,8 +340,8 @@ vAPI.tabs.registerListeners = function() {
}
if ( typeof vAPI.tabs.onPopupCreated === 'function' ) {
vAPI.tabs.onPopupCreated(
details.tabId.toString(),
details.sourceTabId.toString()
details.tabId,
details.sourceTabId
);
}
};
@ -364,7 +375,7 @@ vAPI.tabs.registerListeners = function() {
if ( changeInfo.url ) {
changeInfo.url = sanitizeURL(changeInfo.url);
}
onUpdatedClient(tabId.toString(), changeInfo, tab);
onUpdatedClient(tabId, changeInfo, tab);
};
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate);
@ -542,9 +553,7 @@ vAPI.tabs.open = function(details) {
vAPI.tabs.replace = function(tabId, url) {
tabId = toChromiumTabId(tabId);
if ( tabId === 0 ) {
return;
}
if ( tabId === 0 ) { return; }
var targetURL = url;
@ -565,9 +574,7 @@ vAPI.tabs.replace = function(tabId, url) {
vAPI.tabs.remove = function(tabId) {
tabId = toChromiumTabId(tabId);
if ( tabId === 0 ) {
return;
}
if ( tabId === 0 ) { return; }
var onTabRemoved = function() {
// https://code.google.com/p/chromium/issues/detail?id=410868#c8
@ -605,9 +612,7 @@ vAPI.tabs.reload = function(tabId, bypassCache) {
vAPI.tabs.select = function(tabId) {
tabId = toChromiumTabId(tabId);
if ( tabId === 0 ) {
return;
}
if ( tabId === 0 ) { return; }
chrome.tabs.update(tabId, { active: true }, function(tab) {
if ( chrome.runtime.lastError ) {
@ -789,7 +794,7 @@ vAPI.messaging.onPortMessage = (function() {
case 'connectionRefused':
toPort = messaging.ports.get(msg.fromToken);
if ( toPort !== undefined ) {
msg.tabId = tabId && tabId.toString();
msg.tabId = tabId;
toPort.postMessage(request);
} else {
msg.what = 'connectionBroken';
@ -797,7 +802,7 @@ vAPI.messaging.onPortMessage = (function() {
}
break;
case 'connectionRequested':
msg.tabId = tabId && tabId.toString();
msg.tabId = tabId;
for ( toPort of messaging.ports.values() ) {
toPort.postMessage(request);
}
@ -809,7 +814,7 @@ vAPI.messaging.onPortMessage = (function() {
port.name === msg.fromToken ? msg.toToken : msg.fromToken
);
if ( toPort !== undefined ) {
msg.tabId = tabId && tabId.toString();
msg.tabId = tabId;
toPort.postMessage(request);
} else {
msg.what = 'connectionBroken';

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2017 Raymond Hill
Copyright (C) 2017-2018 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
@ -105,8 +105,6 @@ vAPI.net.registerListeners = function() {
};
var normalizeRequestDetails = function(details) {
details.tabId = details.tabId.toString();
var type = details.type;
// https://github.com/gorhill/uBlock/issues/1493

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2107 The uBlock Origin authors
Copyright (C) 2014-2018 The uBlock Origin authors
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
@ -833,10 +833,11 @@ var getOwnerWindow = function(target) {
/******************************************************************************/
vAPI.isBehindTheSceneTabId = function(tabId) {
return tabId.toString() === '-1';
return tabId < 0;
};
vAPI.noTabId = '-1';
vAPI.noTabId = -1;
vAPI.anyTabId = -2;
/******************************************************************************/
@ -1283,7 +1284,7 @@ var tabWatcher = (function() {
}
var tabId = browserToTabIdMap.get(browser);
if ( tabId === undefined ) {
tabId = '' + tabIdGenerator++;
tabId = tabIdGenerator++;
browserToTabIdMap.set(browser, tabId);
tabIdToBrowserMap.set(tabId, Cu.getWeakReference(browser));
}
@ -1316,7 +1317,7 @@ var tabWatcher = (function() {
var removeBrowserEntry = function(tabId, browser) {
if ( tabId && tabId !== vAPI.noTabId ) {
vAPI.tabs.onClosed(tabId);
delete vAPI.toolbarButton.tabs[tabId];
vAPI.toolbarButton.tabs.delete(tabId);
tabIdToBrowserMap.delete(tabId);
}
if ( browser ) {
@ -1539,7 +1540,7 @@ vAPI.setIcon = function(tabId, iconStatus, badge) {
if ( tabId === undefined ) {
tabId = curTabId;
} else if ( badge !== undefined ) {
tb.tabs[tabId] = { badge: badge, img: iconStatus === 'on' };
tb.tabs.set(tabId, { badge: badge, img: iconStatus === 'on' });
}
if ( curTabId && tabId === curTabId ) {
@ -2028,7 +2029,7 @@ var httpObserver = {
},
// https://github.com/gorhill/uBlock/issues/959
syntheticPendingRequest: { frameId: 0, parentFrameId: -1, tabId: '', rawtype: 1 },
syntheticPendingRequest: { frameId: 0, parentFrameId: -1, tabId: 0, rawtype: 1 },
handleRequest: function(channel, URI, details) {
var type = this.typeMap[details.rawtype] || 'other';
@ -2437,7 +2438,7 @@ vAPI.toolbarButton = {
viewId: location.host + '-panel',
label: vAPI.app.name,
tooltiptext: vAPI.app.name,
tabs: {/*tabId: {badge: 0, img: boolean}*/},
tabs: new Map(/* tabId: { badge: 0, img: boolean } */),
init: null,
codePath: ''
};
@ -2473,8 +2474,8 @@ vAPI.toolbarButton = {
if ( tabId === undefined ) {
return label;
}
var tabDetails = this.tabs[tabId];
if ( !tabDetails ) {
var tabDetails = this.tabs.get(tabId);
if ( tabDetails === undefined ) {
return label;
}
if ( !tabDetails.img ) {
@ -2563,7 +2564,7 @@ vAPI.toolbarButton = {
return;
}
var icon = this.tabs[tabId];
var icon = this.tabs.get(tabId);
button.setAttribute('badge', icon && icon.badge || '');
button.classList.toggle('off', !icon || !icon.img);
@ -3502,9 +3503,8 @@ vAPI.onLoadAllCompleted = function() {
// TODO: vAPI shouldn't know about uBlock. Just like in uMatrix, uBlock
// should collect on its side all the opened tabs whenever it is ready.
var µb = µBlock;
var tabId;
for ( var browser of tabWatcher.browsers() ) {
tabId = tabWatcher.tabIdFromTarget(browser);
var tabId = tabWatcher.tabIdFromTarget(browser);
µb.tabContextManager.commit(tabId, browser.currentURI.asciiSpec);
µb.bindTabToPageStats(tabId);
}

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2017 Raymond Hill
Copyright (C) 2017-2018 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
@ -100,10 +100,16 @@ vAPI.net.registerListeners = function() {
var punycode = self.punycode;
var reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/;
var reNetworkURI = /^(?:ftps?|https?|wss?)/;
var parsedURL = new URL('about:blank');
var normalizeRequestDetails = function(details) {
details.tabId = details.tabId.toString();
if (
details.tabId === vAPI.noTabId &&
reNetworkURI.test(details.documentUrl)
) {
details.tabId = vAPI.anyTabId;
}
if ( mustPunycode && !reAsciiHostname.test(details.url) ) {
parsedURL.href = details.url;

View File

@ -148,7 +148,7 @@ var µBlock = (function() { // jshint ignore:line
selfieAfter: 17 * oneMinute,
pageStores: {},
pageStores: new Map(),
pageStoresToken: 0,
storageQuota: vAPI.storage.QUOTA_BYTES,

View File

@ -45,7 +45,7 @@ if (
var logger = self.logger;
var inspectorConnectionId;
var inspectedTabId = '';
var inspectedTabId = 0;
var inspectedURL = '';
var inspectedHostname = '';
var inspector = uDom.nodeFromId('domInspector');
@ -468,7 +468,7 @@ var startDialog = (function() {
var onClicked = function(ev) {
ev.stopPropagation();
if ( inspectedTabId === '' ) { return; }
if ( inspectedTabId === 0 ) { return; }
var target = ev.target;
var parent = target.parentElement;
@ -540,7 +540,7 @@ var onMouseOver = (function() {
};
return function(ev) {
if ( inspectedTabId === '' ) { return; }
if ( inspectedTabId === 0 ) { return; }
// Convenience: skip real-time highlighting if shift key is pressed.
if ( ev.shiftKey ) { return; }
// Find closest `li`
@ -560,7 +560,7 @@ var onMouseOver = (function() {
/******************************************************************************/
var currentTabId = function() {
if ( showdomButton.classList.contains('active') === false ) { return ''; }
if ( showdomButton.classList.contains('active') === false ) { return 0; }
return logger.tabIdFromPageSelector();
};
@ -568,7 +568,7 @@ var currentTabId = function() {
var injectInspector = function() {
var tabId = currentTabId();
if ( tabId === '' ) { return; }
if ( tabId === 0 ) { return; }
inspectedTabId = tabId;
messaging.send('loggerUI', {
what: 'scriptlet',
@ -586,7 +586,7 @@ var shutdownInspector = function() {
}
logger.removeAllChildren(domTree);
inspector.classList.add('vCompact');
inspectedTabId = '';
inspectedTabId = 0;
};
/******************************************************************************/
@ -658,7 +658,7 @@ var toggleOff = function() {
uDom.nodeFromSelector('#domInspector .permatoolbar .highlightMode').removeEventListener('click', toggleHighlightMode);
uDom.nodeFromSelector('#domInspector .permatoolbar .revert').removeEventListener('click', revert);
uDom.nodeFromSelector('#domInspector .permatoolbar .commit').removeEventListener('click', startDialog);
inspectedTabId = '';
inspectedTabId = 0;
};
/******************************************************************************/

View File

@ -56,7 +56,7 @@ var tabIdFromPageSelector = logger.tabIdFromPageSelector = function() {
if ( tabClass === 'tab_active' && activeTabId !== undefined ) {
return activeTabId;
}
return /^tab_\d+$/.test(tabClass) ? tabClass.slice(4) : '';
return /^tab_\d+$/.test(tabClass) ? parseInt(tabClass.slice(4), 10) : 0;
};
/******************************************************************************/
@ -79,8 +79,7 @@ var tdJunkyard = [];
var firstVarDataCol = 2; // currently, column 2 (0-based index)
var lastVarDataIndex = 4; // currently, d0-d3
var maxEntries = 5000;
var noTabId = '';
var allTabIds = {};
var allTabIds = new Map();
var allTabIdsToken;
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
@ -113,7 +112,7 @@ var staticFilterTypes = {
/******************************************************************************/
var classNameFromTabId = function(tabId) {
if ( tabId === noTabId ) {
if ( tabId < 0 ) {
return 'tab_bts';
}
if ( tabId !== '' ) {
@ -353,7 +352,7 @@ var renderLogEntry = function(entry) {
if ( entry.tab ) {
tr.classList.add('tab');
tr.classList.add(classNameFromTabId(entry.tab));
if ( entry.tab === noTabId ) {
if ( entry.tab < 0 ) {
tr.cells[1].appendChild(createHiddenTextNode('bts'));
}
}
@ -392,7 +391,7 @@ var renderLogEntries = function(response) {
// https://github.com/gorhill/uBlock/issues/1613#issuecomment-217637122
// Unlikely, but it may happen: mark as void if associated tab no
// longer exist.
if ( entry.tab && tabIds.hasOwnProperty(entry.tab) === false ) {
if ( entry.tab && tabIds.has(entry.tab) === false ) {
tr.classList.remove('canMtx');
}
}
@ -422,9 +421,8 @@ var synchronizeTabIds = function(newTabIds) {
var oldTabIds = allTabIds;
var autoDeleteVoidRows = selectValue === 'tab_active';
var rowVoided = false;
for ( var tabId in oldTabIds ) {
if ( oldTabIds.hasOwnProperty(tabId) === false ) { continue; }
if ( newTabIds.hasOwnProperty(tabId) ) { continue; }
for ( var tabId of oldTabIds.keys() ) {
if ( newTabIds.has(tabId) ) { continue; }
// Mark or remove voided rows
var trs = uDom('.tab_' + tabId);
if ( autoDeleteVoidRows ) {
@ -439,20 +437,20 @@ var synchronizeTabIds = function(newTabIds) {
}
}
var tabIds = Object.keys(newTabIds).sort(function(a, b) {
return newTabIds[a].localeCompare(newTabIds[b]);
var tabIds = Array.from(newTabIds.keys()).sort(function(a, b) {
return newTabIds.get(a).localeCompare(newTabIds.get(b));
});
var option;
for ( var i = 0, j = 3; i < tabIds.length; i++ ) {
tabId = tabIds[i];
if ( tabId === noTabId ) { continue; }
if ( tabId < 0 ) { continue; }
option = select.options[j];
if ( !option ) {
option = document.createElement('option');
select.appendChild(option);
}
// Truncate too long labels.
option.textContent = newTabIds[tabId].slice(0, 80);
option.textContent = newTabIds.get(tabId).slice(0, 80);
option.value = classNameFromTabId(tabId);
if ( option.value === selectValue ) {
select.selectedIndex = j;
@ -500,14 +498,15 @@ var onLogBufferRead = function(response) {
return;
}
// This tells us the behind-the-scene tab id
noTabId = response.noTabId;
// Tab id of currently active tab
if ( response.activeTabId ) {
activeTabId = response.activeTabId;
}
if ( Array.isArray(response.tabIds) ) {
response.tabIds = new Map(response.tabIds);
}
// This may have changed meanwhile
if ( response.maxEntries !== maxEntries ) {
maxEntries = response.maxEntries;
@ -625,7 +624,7 @@ var pageSelectorFromURLHash = (function() {
var reloadTab = function(ev) {
var tabId = tabIdFromPageSelector();
if ( tabId === '' ) { return; }
if ( tabId === 0 ) { return; }
messaging.send('loggerUI', {
what: 'reloadTab',
tabId: tabId,
@ -965,7 +964,7 @@ var netFilteringManager = (function() {
// First, whether picker can be used
dialog.querySelector('.picker').classList.toggle(
'hide',
targetTabId === noTabId ||
targetTabId < 0 ||
targetType !== 'image' ||
/(?:^| )[dlsu]b(?: |$)/.test(targetRow.className)
);
@ -1614,7 +1613,7 @@ var popupManager = (function() {
return;
}
if ( localTabId === 'bts' ) {
realTabId = noTabId;
realTabId = -1;
}
container = uDom.nodeFromId('popupContainer');

View File

@ -1022,28 +1022,26 @@ vAPI.messaging.listen('dashboard', onMessage);
/******************************************************************************/
var µb = µBlock,
extensionPageURL = vAPI.getURL('');
extensionOriginURL = vAPI.getURL('');
/******************************************************************************/
var getLoggerData = function(ownerId, activeTabId, callback) {
var tabIds = {};
for ( var tabId in µb.pageStores ) {
var pageStore = µb.pageStoreFromTabId(tabId);
if ( pageStore === null ) { continue; }
if ( pageStore.rawURL.startsWith(extensionPageURL) ) { continue; }
tabIds[tabId] = pageStore.title;
var tabIds = new Map();
for ( var entry of µb.pageStores ) {
var pageStore = entry[1];
if ( pageStore.rawURL.startsWith(extensionOriginURL) ) { continue; }
tabIds.set(entry[0], pageStore.title);
}
if ( activeTabId && tabIds.hasOwnProperty(activeTabId) === false ) {
if ( activeTabId && tabIds.has(activeTabId) === false ) {
activeTabId = undefined;
}
callback({
colorBlind: µb.userSettings.colorBlindFriendly,
entries: µb.logger.readAll(ownerId),
maxEntries: µb.userSettings.requestLogMaxEntries,
noTabId: vAPI.noTabId,
activeTabId: activeTabId,
tabIds: tabIds,
tabIds: Array.from(tabIds),
tabIdsToken: µb.pageStoresToken
});
};
@ -1093,11 +1091,7 @@ var onMessage = function(request, sender, callback) {
return;
}
vAPI.tabs.get(null, function(tab) {
getLoggerData(
request.ownerId,
tab && tab.id.toString(),
callback
);
getLoggerData(request.ownerId, tab && tab.id, callback);
});
return;

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill
Copyright (C) 2014-2018 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
@ -284,7 +284,7 @@ PageStore.prototype.init = function(tabId, context) {
this.rawURL = tabContext.rawURL;
this.hostnameToCountMap = new Map();
this.contentLastModified = 0;
this.frames = Object.create(null);
this.frames = new Map();
this.logData = undefined;
this.perLoadBlockedRequestCount = 0;
this.perLoadAllowedRequestCount = 0;
@ -410,27 +410,26 @@ PageStore.prototype.dispose = function() {
/******************************************************************************/
PageStore.prototype.disposeFrameStores = function() {
var frames = this.frames;
for ( var k in frames ) {
frames[k].dispose();
for ( var frameStore of this.frames.values() ) {
frameStore.dispose();
}
this.frames = Object.create(null);
this.frames.clear();
};
/******************************************************************************/
PageStore.prototype.getFrame = function(frameId) {
return this.frames[frameId] || null;
return this.frames.get(frameId) || null;
};
/******************************************************************************/
PageStore.prototype.setFrame = function(frameId, frameURL) {
var frameStore = this.frames[frameId];
if ( frameStore ) {
var frameStore = this.frames.get(frameId);
if ( frameStore !== undefined ) {
frameStore.init(frameURL);
} else {
this.frames[frameId] = FrameStore.factory(frameURL);
this.frames.set(frameId, FrameStore.factory(frameURL));
}
};
@ -445,8 +444,8 @@ PageStore.prototype.createContextFromPage = function() {
PageStore.prototype.createContextFromFrameId = function(frameId) {
var context = µb.tabContextManager.createContext(this.tabId);
var frameStore = this.frames[frameId];
if ( frameStore ) {
var frameStore = this.frames.get(frameId);
if ( frameStore !== undefined ) {
context.pageHostname = frameStore.pageHostname;
context.pageDomain = frameStore.pageDomain;
} else {

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill
Copyright (C) 2014-2018 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
@ -128,7 +128,7 @@ housekeep itself.
*/
µb.tabContextManager = (function() {
var tabContexts = Object.create(null);
var tabContexts = new Map();
// https://github.com/chrisaljoudi/uBlock/issues/1001
// This is to be used as last-resort fallback in case a tab is found to not
@ -206,7 +206,7 @@ housekeep itself.
};
var TabContext = function(tabId) {
this.tabId = tabId.toString();
this.tabId = tabId;
this.stack = [];
this.rawURL =
this.normalURL =
@ -218,18 +218,16 @@ housekeep itself.
this.netFiltering = true;
this.netFilteringReadTime = 0;
tabContexts[tabId] = this;
tabContexts.set(tabId, this);
};
TabContext.prototype.destroy = function() {
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) {
return;
}
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
if ( this.gcTimer !== null ) {
clearTimeout(this.gcTimer);
this.gcTimer = null;
}
delete tabContexts[this.tabId];
tabContexts.delete(this.tabId);
};
TabContext.prototype.onTab = function(tab) {
@ -363,7 +361,7 @@ housekeep itself.
// These are to be used for the API of the tab context manager.
var push = function(tabId, url) {
var entry = tabContexts[tabId];
var entry = tabContexts.get(tabId);
if ( entry === undefined ) {
entry = new TabContext(tabId);
entry.autodestroy();
@ -376,13 +374,13 @@ housekeep itself.
// Find a tab context for a specific tab.
var lookup = function(tabId) {
return tabContexts[tabId] || null;
return tabContexts.get(tabId) || null;
};
// Find a tab context for a specific tab. If none is found, attempt to
// fix this. When all fail, the behind-the-scene context is returned.
var mustLookup = function(tabId) {
var entry = tabContexts[tabId];
var entry = tabContexts.get(tabId);
if ( entry !== undefined ) {
return entry;
}
@ -407,13 +405,13 @@ housekeep itself.
// about to fall through the cracks.
// Example: Chromium + case #12 at
// http://raymondhill.net/ublock/popup.html
return tabContexts[vAPI.noTabId];
return tabContexts.get(vAPI.noTabId);
};
// https://github.com/gorhill/uBlock/issues/1735
// Filter for popups if actually committing.
var commit = function(tabId, url) {
var entry = tabContexts[tabId];
var entry = tabContexts.get(tabId);
if ( entry === undefined ) {
entry = push(tabId, url);
} else if ( entry.commit(url) ) {
@ -423,7 +421,7 @@ housekeep itself.
};
var exists = function(tabId) {
return tabContexts[tabId] !== undefined;
return tabContexts.get(tabId) !== undefined;
};
// Behind-the-scene tab context
@ -434,6 +432,9 @@ housekeep itself.
entry.normalURL = µb.normalizePageURL(entry.tabId);
entry.rootHostname = µb.URI.hostnameFromURI(entry.normalURL);
entry.rootDomain = µb.URI.domainFromHostname(entry.rootHostname);
entry = new TabContext(vAPI.anyTabId);
entry.stack.push(new StackEntry('', true));
})();
// Context object, typically to be used to feed filtering engines.
@ -445,7 +446,7 @@ housekeep itself.
var tabContext = lookup(tabId);
this.rootHostname = tabContext.rootHostname;
this.rootDomain = tabContext.rootDomain;
this.pageHostname =
this.pageHostname =
this.pageDomain =
this.requestURL =
this.requestHostname =
@ -842,13 +843,15 @@ vAPI.tabs.registerListeners();
}
// 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.get(tabId);
// Tab is not bound
if ( !pageStore ) {
if ( pageStore === undefined ) {
this.updateTitle(tabId);
this.pageStoresToken = Date.now();
return (this.pageStores[tabId] = this.PageStore.factory(tabId, context));
pageStore = this.PageStore.factory(tabId, context);
this.pageStores.set(tabId, pageStore);
return pageStore;
}
// https://github.com/chrisaljoudi/uBlock/issues/516
@ -878,10 +881,10 @@ vAPI.tabs.registerListeners();
µb.unbindTabFromPageStats = function(tabId) {
//console.debug('µBlock> unbindTabFromPageStats(%d)', tabId);
var pageStore = this.pageStores[tabId];
var pageStore = this.pageStores.get(tabId);
if ( pageStore !== undefined ) {
pageStore.dispose();
delete this.pageStores[tabId];
this.pageStores.delete(tabId);
this.pageStoresToken = Date.now();
}
};
@ -889,29 +892,36 @@ vAPI.tabs.registerListeners();
/******************************************************************************/
µb.pageStoreFromTabId = function(tabId) {
return this.pageStores[tabId] || null;
return this.pageStores.get(tabId) || null;
};
µb.mustPageStoreFromTabId = function(tabId) {
return this.pageStores[tabId] || this.pageStores[vAPI.noTabId];
return this.pageStores.get(tabId) || this.pageStores.get(vAPI.noTabId);
};
/******************************************************************************/
// Permanent page store for behind-the-scene requests. Must never be removed.
µb.pageStores[vAPI.noTabId] = µb.PageStore.factory(vAPI.noTabId);
µb.pageStores[vAPI.noTabId].title = vAPI.i18n('logBehindTheScene');
(function() {
var pageStore = µb.PageStore.factory(vAPI.noTabId);
µb.pageStores.set(pageStore.tabId, pageStore);
pageStore.title = vAPI.i18n('logBehindTheScene');
pageStore = µb.PageStore.factory(vAPI.anyTabId);
µb.pageStores.set(pageStore.tabId, pageStore);
pageStore.title = '[Any one of the known tabs]';
})();
/******************************************************************************/
// Update visual of extension icon.
µb.updateBadgeAsync = (function() {
var tabIdToTimer = Object.create(null);
var tabIdToTimer = new Map();
var updateBadge = function(tabId) {
delete tabIdToTimer[tabId];
tabIdToTimer.delete(tabId);
var state = false;
var badge = '';
@ -928,82 +938,70 @@ vAPI.tabs.registerListeners();
};
return function(tabId) {
if ( tabIdToTimer[tabId] ) {
return;
}
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
return;
}
tabIdToTimer[tabId] = vAPI.setTimeout(updateBadge.bind(this, tabId), 701);
if ( tabIdToTimer.has(tabId) ) { return; }
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
tabIdToTimer.set(
tabId,
vAPI.setTimeout(updateBadge.bind(this, tabId), 701)
);
};
})();
/******************************************************************************/
µb.updateTitle = (function() {
var tabIdToTimer = Object.create(null);
var tabIdToTryCount = Object.create(null);
var tabIdToTimer = new Map();
var delay = 499;
var tryNoMore = function(tabId) {
delete tabIdToTryCount[tabId];
};
var tryAgain = function(tabId) {
var count = tabIdToTryCount[tabId];
if ( count === undefined ) {
return false;
}
if ( count === 1 ) {
delete tabIdToTryCount[tabId];
return false;
}
tabIdToTryCount[tabId] = count - 1;
tabIdToTimer[tabId] = vAPI.setTimeout(updateTitle.bind(µb, tabId), delay);
var tryAgain = function(entry) {
if ( entry.count === 1 ) { return false; }
entry.count -= 1;
tabIdToTimer.set(
entry.tabId,
vAPI.setTimeout(updateTitle.bind(null, entry), delay)
);
return true;
};
var onTabReady = function(tabId, tab) {
if ( !tab ) {
return tryNoMore(tabId);
}
var pageStore = this.pageStoreFromTabId(tabId);
if ( pageStore === null ) {
return tryNoMore(tabId);
}
var onTabReady = function(entry, tab) {
if ( !tab ) { return; }
var µb = µBlock;
var pageStore = µb.pageStoreFromTabId(entry.tabId);
if ( pageStore === null ) { return; }
// Firefox needs this: if you detach a tab, the new tab won't have
// its rawURL set. Concretely, this causes the logger to report an
// entry to itself in the logger's tab selector.
// TODO: Investigate for a fix vAPI-side.
pageStore.rawURL = tab.url;
this.pageStoresToken = Date.now();
if ( !tab.title && tryAgain(tabId) ) {
return;
}
µb.pageStoresToken = Date.now();
if ( !tab.title && tryAgain(entry) ) { return; }
// https://github.com/gorhill/uMatrix/issues/225
// Sometimes title changes while page is loading.
var settled = tab.title && tab.title === pageStore.title;
pageStore.title = tab.title || tab.url || '';
this.pageStoresToken = Date.now();
if ( settled || !tryAgain(tabId) ) {
tryNoMore(tabId);
if ( !settled ) {
tryAgain(entry);
}
};
var updateTitle = function(tabId) {
delete tabIdToTimer[tabId];
vAPI.tabs.get(tabId, onTabReady.bind(this, tabId));
var updateTitle = function(entry) {
tabIdToTimer.delete(entry.tabId);
vAPI.tabs.get(entry.tabId, onTabReady.bind(null, entry));
};
return function(tabId) {
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
return;
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
var timer = tabIdToTimer.get(tabId);
if ( timer !== undefined ) {
clearTimeout(timer);
}
if ( tabIdToTimer[tabId] ) {
clearTimeout(tabIdToTimer[tabId]);
}
tabIdToTimer[tabId] = vAPI.setTimeout(updateTitle.bind(this, tabId), delay);
tabIdToTryCount[tabId] = 5;
tabIdToTimer.set(
tabId,
vAPI.setTimeout(
updateTitle.bind(null, { tabId: tabId, count: 5 }),
delay
)
);
};
})();
@ -1018,11 +1016,10 @@ var pageStoreJanitorSampleSize = 10;
var pageStoreJanitor = function() {
var vapiTabs = vAPI.tabs;
var tabIds = Object.keys(µb.pageStores).sort();
var tabIds = Array.from(µb.pageStores.keys()).sort();
var checkTab = function(tabId) {
vapiTabs.get(tabId, function(tab) {
if ( !tab ) {
//console.error('tab.js> pageStoreJanitor(): stale page store found:', µtabId);
µb.unbindTabFromPageStats(tabId);
}
});
@ -1030,14 +1027,10 @@ var pageStoreJanitor = function() {
if ( pageStoreJanitorSampleAt >= tabIds.length ) {
pageStoreJanitorSampleAt = 0;
}
var tabId;
var n = Math.min(pageStoreJanitorSampleAt + pageStoreJanitorSampleSize, tabIds.length);
for ( var i = pageStoreJanitorSampleAt; i < n; i++ ) {
tabId = tabIds[i];
// Do not remove behind-the-scene page store
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
continue;
}
var tabId = tabIds[i];
if ( vAPI.isBehindTheSceneTabId(tabId) ) { continue; }
checkTab(tabId);
}
pageStoreJanitorSampleAt = n;

View File

@ -336,8 +336,8 @@ var toBlockDocResult = function(url, hostname, logData) {
var onBeforeBehindTheSceneRequest = function(details) {
var µb = µBlock,
pageStore = µb.pageStoreFromTabId(vAPI.noTabId);
if ( !pageStore ) { return; }
pageStore = µb.pageStoreFromTabId(details.tabId);
if ( pageStore === null ) { return; }
var result = 0,
context = pageStore.createContextFromPage(),
@ -348,6 +348,13 @@ var onBeforeBehindTheSceneRequest = function(details) {
context.requestHostname = µb.URI.hostnameFromURI(requestURL);
context.requestType = requestType;
if ( details.tabId === vAPI.anyTabId && context.pageHostname === '' ) {
context.pageHostname = µb.URI.hostnameFromURI(details.documentUrl);
context.pageDomain = µb.URI.domainFromHostname(context.pageHostname);
context.rootHostname = context.pageHostname;
context.rootDomain = context.pageDomain;
}
// https://bugs.chromium.org/p/chromium/issues/detail?id=637577#c15
// Do not filter behind-the-scene network request of type `beacon`: there
// is no point. In any case, this will become a non-issue once
@ -361,7 +368,11 @@ var onBeforeBehindTheSceneRequest = function(details) {
// https://github.com/gorhill/uBlock/issues/3150
// Ability to globally block CSP reports MUST also apply to
// behind-the-scene network requests.
if ( µb.userSettings.advancedUserEnabled || requestType === 'csp_report' ) {
if (
details.tabId !== vAPI.noTabId ||
µb.userSettings.advancedUserEnabled ||
requestType === 'csp_report'
) {
result = pageStore.filterRequest(context);
}
@ -369,7 +380,7 @@ var onBeforeBehindTheSceneRequest = function(details) {
if ( µb.logger.isEnabled() ) {
µb.logger.writeOne(
vAPI.noTabId,
details.tabId,
'net',
pageStore.logData,
requestType,

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill
Copyright (C) 2014-2018 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
@ -510,20 +510,18 @@ var reInvalidHostname = /[^a-z0-9.\-\[\]:]/,
/******************************************************************************/
µBlock.logCosmeticFilters = (function() {
var tabIdToTimerMap = {};
var tabIdToTimerMap = new Map();
var injectNow = function(tabId) {
delete tabIdToTimerMap[tabId];
tabIdToTimerMap.delete(tabId);
µBlock.scriptlets.injectDeep(tabId, 'cosmetic-logger');
};
var injectAsync = function(tabId) {
if ( tabIdToTimerMap.hasOwnProperty(tabId) ) {
return;
}
tabIdToTimerMap[tabId] = vAPI.setTimeout(
injectNow.bind(null, tabId),
100
if ( tabIdToTimerMap.has(tabId) ) { return; }
tabIdToTimerMap.set(
tabId,
vAPI.setTimeout(injectNow.bind(null, tabId), 100)
);
};