mirror of https://github.com/gorhill/uBlock.git
parent
64682ab8a1
commit
2c901588c7
|
@ -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) {
|
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) {
|
var toChromiumTabId = function(tabId) {
|
||||||
if ( typeof tabId === 'string' ) {
|
if ( typeof tabId === 'string' ) { debugger; }
|
||||||
tabId = parseInt(tabId, 10);
|
|
||||||
}
|
|
||||||
if ( typeof tabId !== 'number' || isNaN(tabId) || tabId === -1 ) {
|
if ( typeof tabId !== 'number' || isNaN(tabId) || tabId === -1 ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -329,8 +340,8 @@ vAPI.tabs.registerListeners = function() {
|
||||||
}
|
}
|
||||||
if ( typeof vAPI.tabs.onPopupCreated === 'function' ) {
|
if ( typeof vAPI.tabs.onPopupCreated === 'function' ) {
|
||||||
vAPI.tabs.onPopupCreated(
|
vAPI.tabs.onPopupCreated(
|
||||||
details.tabId.toString(),
|
details.tabId,
|
||||||
details.sourceTabId.toString()
|
details.sourceTabId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -364,7 +375,7 @@ vAPI.tabs.registerListeners = function() {
|
||||||
if ( changeInfo.url ) {
|
if ( changeInfo.url ) {
|
||||||
changeInfo.url = sanitizeURL(changeInfo.url);
|
changeInfo.url = sanitizeURL(changeInfo.url);
|
||||||
}
|
}
|
||||||
onUpdatedClient(tabId.toString(), changeInfo, tab);
|
onUpdatedClient(tabId, changeInfo, tab);
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate);
|
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate);
|
||||||
|
@ -542,9 +553,7 @@ vAPI.tabs.open = function(details) {
|
||||||
|
|
||||||
vAPI.tabs.replace = function(tabId, url) {
|
vAPI.tabs.replace = function(tabId, url) {
|
||||||
tabId = toChromiumTabId(tabId);
|
tabId = toChromiumTabId(tabId);
|
||||||
if ( tabId === 0 ) {
|
if ( tabId === 0 ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var targetURL = url;
|
var targetURL = url;
|
||||||
|
|
||||||
|
@ -565,9 +574,7 @@ vAPI.tabs.replace = function(tabId, url) {
|
||||||
|
|
||||||
vAPI.tabs.remove = function(tabId) {
|
vAPI.tabs.remove = function(tabId) {
|
||||||
tabId = toChromiumTabId(tabId);
|
tabId = toChromiumTabId(tabId);
|
||||||
if ( tabId === 0 ) {
|
if ( tabId === 0 ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var onTabRemoved = function() {
|
var onTabRemoved = function() {
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=410868#c8
|
// 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) {
|
vAPI.tabs.select = function(tabId) {
|
||||||
tabId = toChromiumTabId(tabId);
|
tabId = toChromiumTabId(tabId);
|
||||||
if ( tabId === 0 ) {
|
if ( tabId === 0 ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.tabs.update(tabId, { active: true }, function(tab) {
|
chrome.tabs.update(tabId, { active: true }, function(tab) {
|
||||||
if ( chrome.runtime.lastError ) {
|
if ( chrome.runtime.lastError ) {
|
||||||
|
@ -789,7 +794,7 @@ vAPI.messaging.onPortMessage = (function() {
|
||||||
case 'connectionRefused':
|
case 'connectionRefused':
|
||||||
toPort = messaging.ports.get(msg.fromToken);
|
toPort = messaging.ports.get(msg.fromToken);
|
||||||
if ( toPort !== undefined ) {
|
if ( toPort !== undefined ) {
|
||||||
msg.tabId = tabId && tabId.toString();
|
msg.tabId = tabId;
|
||||||
toPort.postMessage(request);
|
toPort.postMessage(request);
|
||||||
} else {
|
} else {
|
||||||
msg.what = 'connectionBroken';
|
msg.what = 'connectionBroken';
|
||||||
|
@ -797,7 +802,7 @@ vAPI.messaging.onPortMessage = (function() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'connectionRequested':
|
case 'connectionRequested':
|
||||||
msg.tabId = tabId && tabId.toString();
|
msg.tabId = tabId;
|
||||||
for ( toPort of messaging.ports.values() ) {
|
for ( toPort of messaging.ports.values() ) {
|
||||||
toPort.postMessage(request);
|
toPort.postMessage(request);
|
||||||
}
|
}
|
||||||
|
@ -809,7 +814,7 @@ vAPI.messaging.onPortMessage = (function() {
|
||||||
port.name === msg.fromToken ? msg.toToken : msg.fromToken
|
port.name === msg.fromToken ? msg.toToken : msg.fromToken
|
||||||
);
|
);
|
||||||
if ( toPort !== undefined ) {
|
if ( toPort !== undefined ) {
|
||||||
msg.tabId = tabId && tabId.toString();
|
msg.tabId = tabId;
|
||||||
toPort.postMessage(request);
|
toPort.postMessage(request);
|
||||||
} else {
|
} else {
|
||||||
msg.what = 'connectionBroken';
|
msg.what = 'connectionBroken';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
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) {
|
var normalizeRequestDetails = function(details) {
|
||||||
details.tabId = details.tabId.toString();
|
|
||||||
|
|
||||||
var type = details.type;
|
var type = details.type;
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/1493
|
// https://github.com/gorhill/uBlock/issues/1493
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
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) {
|
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);
|
var tabId = browserToTabIdMap.get(browser);
|
||||||
if ( tabId === undefined ) {
|
if ( tabId === undefined ) {
|
||||||
tabId = '' + tabIdGenerator++;
|
tabId = tabIdGenerator++;
|
||||||
browserToTabIdMap.set(browser, tabId);
|
browserToTabIdMap.set(browser, tabId);
|
||||||
tabIdToBrowserMap.set(tabId, Cu.getWeakReference(browser));
|
tabIdToBrowserMap.set(tabId, Cu.getWeakReference(browser));
|
||||||
}
|
}
|
||||||
|
@ -1316,7 +1317,7 @@ var tabWatcher = (function() {
|
||||||
var removeBrowserEntry = function(tabId, browser) {
|
var removeBrowserEntry = function(tabId, browser) {
|
||||||
if ( tabId && tabId !== vAPI.noTabId ) {
|
if ( tabId && tabId !== vAPI.noTabId ) {
|
||||||
vAPI.tabs.onClosed(tabId);
|
vAPI.tabs.onClosed(tabId);
|
||||||
delete vAPI.toolbarButton.tabs[tabId];
|
vAPI.toolbarButton.tabs.delete(tabId);
|
||||||
tabIdToBrowserMap.delete(tabId);
|
tabIdToBrowserMap.delete(tabId);
|
||||||
}
|
}
|
||||||
if ( browser ) {
|
if ( browser ) {
|
||||||
|
@ -1539,7 +1540,7 @@ vAPI.setIcon = function(tabId, iconStatus, badge) {
|
||||||
if ( tabId === undefined ) {
|
if ( tabId === undefined ) {
|
||||||
tabId = curTabId;
|
tabId = curTabId;
|
||||||
} else if ( badge !== undefined ) {
|
} 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 ) {
|
if ( curTabId && tabId === curTabId ) {
|
||||||
|
@ -2028,7 +2029,7 @@ var httpObserver = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/959
|
// 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) {
|
handleRequest: function(channel, URI, details) {
|
||||||
var type = this.typeMap[details.rawtype] || 'other';
|
var type = this.typeMap[details.rawtype] || 'other';
|
||||||
|
@ -2437,7 +2438,7 @@ vAPI.toolbarButton = {
|
||||||
viewId: location.host + '-panel',
|
viewId: location.host + '-panel',
|
||||||
label: vAPI.app.name,
|
label: vAPI.app.name,
|
||||||
tooltiptext: vAPI.app.name,
|
tooltiptext: vAPI.app.name,
|
||||||
tabs: {/*tabId: {badge: 0, img: boolean}*/},
|
tabs: new Map(/* tabId: { badge: 0, img: boolean } */),
|
||||||
init: null,
|
init: null,
|
||||||
codePath: ''
|
codePath: ''
|
||||||
};
|
};
|
||||||
|
@ -2473,8 +2474,8 @@ vAPI.toolbarButton = {
|
||||||
if ( tabId === undefined ) {
|
if ( tabId === undefined ) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
var tabDetails = this.tabs[tabId];
|
var tabDetails = this.tabs.get(tabId);
|
||||||
if ( !tabDetails ) {
|
if ( tabDetails === undefined ) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
if ( !tabDetails.img ) {
|
if ( !tabDetails.img ) {
|
||||||
|
@ -2563,7 +2564,7 @@ vAPI.toolbarButton = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var icon = this.tabs[tabId];
|
var icon = this.tabs.get(tabId);
|
||||||
|
|
||||||
button.setAttribute('badge', icon && icon.badge || '');
|
button.setAttribute('badge', icon && icon.badge || '');
|
||||||
button.classList.toggle('off', !icon || !icon.img);
|
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
|
// 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.
|
// should collect on its side all the opened tabs whenever it is ready.
|
||||||
var µb = µBlock;
|
var µb = µBlock;
|
||||||
var tabId;
|
|
||||||
for ( var browser of tabWatcher.browsers() ) {
|
for ( var browser of tabWatcher.browsers() ) {
|
||||||
tabId = tabWatcher.tabIdFromTarget(browser);
|
var tabId = tabWatcher.tabIdFromTarget(browser);
|
||||||
µb.tabContextManager.commit(tabId, browser.currentURI.asciiSpec);
|
µb.tabContextManager.commit(tabId, browser.currentURI.asciiSpec);
|
||||||
µb.bindTabToPageStats(tabId);
|
µb.bindTabToPageStats(tabId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
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 punycode = self.punycode;
|
||||||
var reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/;
|
var reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/;
|
||||||
|
var reNetworkURI = /^(?:ftps?|https?|wss?)/;
|
||||||
var parsedURL = new URL('about:blank');
|
var parsedURL = new URL('about:blank');
|
||||||
|
|
||||||
var normalizeRequestDetails = function(details) {
|
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) ) {
|
if ( mustPunycode && !reAsciiHostname.test(details.url) ) {
|
||||||
parsedURL.href = details.url;
|
parsedURL.href = details.url;
|
||||||
|
|
|
@ -148,7 +148,7 @@ var µBlock = (function() { // jshint ignore:line
|
||||||
|
|
||||||
selfieAfter: 17 * oneMinute,
|
selfieAfter: 17 * oneMinute,
|
||||||
|
|
||||||
pageStores: {},
|
pageStores: new Map(),
|
||||||
pageStoresToken: 0,
|
pageStoresToken: 0,
|
||||||
|
|
||||||
storageQuota: vAPI.storage.QUOTA_BYTES,
|
storageQuota: vAPI.storage.QUOTA_BYTES,
|
||||||
|
|
|
@ -45,7 +45,7 @@ if (
|
||||||
|
|
||||||
var logger = self.logger;
|
var logger = self.logger;
|
||||||
var inspectorConnectionId;
|
var inspectorConnectionId;
|
||||||
var inspectedTabId = '';
|
var inspectedTabId = 0;
|
||||||
var inspectedURL = '';
|
var inspectedURL = '';
|
||||||
var inspectedHostname = '';
|
var inspectedHostname = '';
|
||||||
var inspector = uDom.nodeFromId('domInspector');
|
var inspector = uDom.nodeFromId('domInspector');
|
||||||
|
@ -468,7 +468,7 @@ var startDialog = (function() {
|
||||||
var onClicked = function(ev) {
|
var onClicked = function(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
|
||||||
if ( inspectedTabId === '' ) { return; }
|
if ( inspectedTabId === 0 ) { return; }
|
||||||
|
|
||||||
var target = ev.target;
|
var target = ev.target;
|
||||||
var parent = target.parentElement;
|
var parent = target.parentElement;
|
||||||
|
@ -540,7 +540,7 @@ var onMouseOver = (function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(ev) {
|
return function(ev) {
|
||||||
if ( inspectedTabId === '' ) { return; }
|
if ( inspectedTabId === 0 ) { return; }
|
||||||
// Convenience: skip real-time highlighting if shift key is pressed.
|
// Convenience: skip real-time highlighting if shift key is pressed.
|
||||||
if ( ev.shiftKey ) { return; }
|
if ( ev.shiftKey ) { return; }
|
||||||
// Find closest `li`
|
// Find closest `li`
|
||||||
|
@ -560,7 +560,7 @@ var onMouseOver = (function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var currentTabId = function() {
|
var currentTabId = function() {
|
||||||
if ( showdomButton.classList.contains('active') === false ) { return ''; }
|
if ( showdomButton.classList.contains('active') === false ) { return 0; }
|
||||||
return logger.tabIdFromPageSelector();
|
return logger.tabIdFromPageSelector();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ var currentTabId = function() {
|
||||||
|
|
||||||
var injectInspector = function() {
|
var injectInspector = function() {
|
||||||
var tabId = currentTabId();
|
var tabId = currentTabId();
|
||||||
if ( tabId === '' ) { return; }
|
if ( tabId === 0 ) { return; }
|
||||||
inspectedTabId = tabId;
|
inspectedTabId = tabId;
|
||||||
messaging.send('loggerUI', {
|
messaging.send('loggerUI', {
|
||||||
what: 'scriptlet',
|
what: 'scriptlet',
|
||||||
|
@ -586,7 +586,7 @@ var shutdownInspector = function() {
|
||||||
}
|
}
|
||||||
logger.removeAllChildren(domTree);
|
logger.removeAllChildren(domTree);
|
||||||
inspector.classList.add('vCompact');
|
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 .highlightMode').removeEventListener('click', toggleHighlightMode);
|
||||||
uDom.nodeFromSelector('#domInspector .permatoolbar .revert').removeEventListener('click', revert);
|
uDom.nodeFromSelector('#domInspector .permatoolbar .revert').removeEventListener('click', revert);
|
||||||
uDom.nodeFromSelector('#domInspector .permatoolbar .commit').removeEventListener('click', startDialog);
|
uDom.nodeFromSelector('#domInspector .permatoolbar .commit').removeEventListener('click', startDialog);
|
||||||
inspectedTabId = '';
|
inspectedTabId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -56,7 +56,7 @@ var tabIdFromPageSelector = logger.tabIdFromPageSelector = function() {
|
||||||
if ( tabClass === 'tab_active' && activeTabId !== undefined ) {
|
if ( tabClass === 'tab_active' && activeTabId !== undefined ) {
|
||||||
return activeTabId;
|
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 firstVarDataCol = 2; // currently, column 2 (0-based index)
|
||||||
var lastVarDataIndex = 4; // currently, d0-d3
|
var lastVarDataIndex = 4; // currently, d0-d3
|
||||||
var maxEntries = 5000;
|
var maxEntries = 5000;
|
||||||
var noTabId = '';
|
var allTabIds = new Map();
|
||||||
var allTabIds = {};
|
|
||||||
var allTabIdsToken;
|
var allTabIdsToken;
|
||||||
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
||||||
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
||||||
|
@ -113,7 +112,7 @@ var staticFilterTypes = {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var classNameFromTabId = function(tabId) {
|
var classNameFromTabId = function(tabId) {
|
||||||
if ( tabId === noTabId ) {
|
if ( tabId < 0 ) {
|
||||||
return 'tab_bts';
|
return 'tab_bts';
|
||||||
}
|
}
|
||||||
if ( tabId !== '' ) {
|
if ( tabId !== '' ) {
|
||||||
|
@ -353,7 +352,7 @@ var renderLogEntry = function(entry) {
|
||||||
if ( entry.tab ) {
|
if ( entry.tab ) {
|
||||||
tr.classList.add('tab');
|
tr.classList.add('tab');
|
||||||
tr.classList.add(classNameFromTabId(entry.tab));
|
tr.classList.add(classNameFromTabId(entry.tab));
|
||||||
if ( entry.tab === noTabId ) {
|
if ( entry.tab < 0 ) {
|
||||||
tr.cells[1].appendChild(createHiddenTextNode('bts'));
|
tr.cells[1].appendChild(createHiddenTextNode('bts'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +391,7 @@ var renderLogEntries = function(response) {
|
||||||
// https://github.com/gorhill/uBlock/issues/1613#issuecomment-217637122
|
// https://github.com/gorhill/uBlock/issues/1613#issuecomment-217637122
|
||||||
// Unlikely, but it may happen: mark as void if associated tab no
|
// Unlikely, but it may happen: mark as void if associated tab no
|
||||||
// longer exist.
|
// longer exist.
|
||||||
if ( entry.tab && tabIds.hasOwnProperty(entry.tab) === false ) {
|
if ( entry.tab && tabIds.has(entry.tab) === false ) {
|
||||||
tr.classList.remove('canMtx');
|
tr.classList.remove('canMtx');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,9 +421,8 @@ var synchronizeTabIds = function(newTabIds) {
|
||||||
var oldTabIds = allTabIds;
|
var oldTabIds = allTabIds;
|
||||||
var autoDeleteVoidRows = selectValue === 'tab_active';
|
var autoDeleteVoidRows = selectValue === 'tab_active';
|
||||||
var rowVoided = false;
|
var rowVoided = false;
|
||||||
for ( var tabId in oldTabIds ) {
|
for ( var tabId of oldTabIds.keys() ) {
|
||||||
if ( oldTabIds.hasOwnProperty(tabId) === false ) { continue; }
|
if ( newTabIds.has(tabId) ) { continue; }
|
||||||
if ( newTabIds.hasOwnProperty(tabId) ) { continue; }
|
|
||||||
// Mark or remove voided rows
|
// Mark or remove voided rows
|
||||||
var trs = uDom('.tab_' + tabId);
|
var trs = uDom('.tab_' + tabId);
|
||||||
if ( autoDeleteVoidRows ) {
|
if ( autoDeleteVoidRows ) {
|
||||||
|
@ -439,20 +437,20 @@ var synchronizeTabIds = function(newTabIds) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabIds = Object.keys(newTabIds).sort(function(a, b) {
|
var tabIds = Array.from(newTabIds.keys()).sort(function(a, b) {
|
||||||
return newTabIds[a].localeCompare(newTabIds[b]);
|
return newTabIds.get(a).localeCompare(newTabIds.get(b));
|
||||||
});
|
});
|
||||||
var option;
|
var option;
|
||||||
for ( var i = 0, j = 3; i < tabIds.length; i++ ) {
|
for ( var i = 0, j = 3; i < tabIds.length; i++ ) {
|
||||||
tabId = tabIds[i];
|
tabId = tabIds[i];
|
||||||
if ( tabId === noTabId ) { continue; }
|
if ( tabId < 0 ) { continue; }
|
||||||
option = select.options[j];
|
option = select.options[j];
|
||||||
if ( !option ) {
|
if ( !option ) {
|
||||||
option = document.createElement('option');
|
option = document.createElement('option');
|
||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
}
|
}
|
||||||
// Truncate too long labels.
|
// Truncate too long labels.
|
||||||
option.textContent = newTabIds[tabId].slice(0, 80);
|
option.textContent = newTabIds.get(tabId).slice(0, 80);
|
||||||
option.value = classNameFromTabId(tabId);
|
option.value = classNameFromTabId(tabId);
|
||||||
if ( option.value === selectValue ) {
|
if ( option.value === selectValue ) {
|
||||||
select.selectedIndex = j;
|
select.selectedIndex = j;
|
||||||
|
@ -500,14 +498,15 @@ var onLogBufferRead = function(response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tells us the behind-the-scene tab id
|
|
||||||
noTabId = response.noTabId;
|
|
||||||
|
|
||||||
// Tab id of currently active tab
|
// Tab id of currently active tab
|
||||||
if ( response.activeTabId ) {
|
if ( response.activeTabId ) {
|
||||||
activeTabId = response.activeTabId;
|
activeTabId = response.activeTabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Array.isArray(response.tabIds) ) {
|
||||||
|
response.tabIds = new Map(response.tabIds);
|
||||||
|
}
|
||||||
|
|
||||||
// This may have changed meanwhile
|
// This may have changed meanwhile
|
||||||
if ( response.maxEntries !== maxEntries ) {
|
if ( response.maxEntries !== maxEntries ) {
|
||||||
maxEntries = response.maxEntries;
|
maxEntries = response.maxEntries;
|
||||||
|
@ -625,7 +624,7 @@ var pageSelectorFromURLHash = (function() {
|
||||||
|
|
||||||
var reloadTab = function(ev) {
|
var reloadTab = function(ev) {
|
||||||
var tabId = tabIdFromPageSelector();
|
var tabId = tabIdFromPageSelector();
|
||||||
if ( tabId === '' ) { return; }
|
if ( tabId === 0 ) { return; }
|
||||||
messaging.send('loggerUI', {
|
messaging.send('loggerUI', {
|
||||||
what: 'reloadTab',
|
what: 'reloadTab',
|
||||||
tabId: tabId,
|
tabId: tabId,
|
||||||
|
@ -965,7 +964,7 @@ var netFilteringManager = (function() {
|
||||||
// First, whether picker can be used
|
// First, whether picker can be used
|
||||||
dialog.querySelector('.picker').classList.toggle(
|
dialog.querySelector('.picker').classList.toggle(
|
||||||
'hide',
|
'hide',
|
||||||
targetTabId === noTabId ||
|
targetTabId < 0 ||
|
||||||
targetType !== 'image' ||
|
targetType !== 'image' ||
|
||||||
/(?:^| )[dlsu]b(?: |$)/.test(targetRow.className)
|
/(?:^| )[dlsu]b(?: |$)/.test(targetRow.className)
|
||||||
);
|
);
|
||||||
|
@ -1614,7 +1613,7 @@ var popupManager = (function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( localTabId === 'bts' ) {
|
if ( localTabId === 'bts' ) {
|
||||||
realTabId = noTabId;
|
realTabId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
container = uDom.nodeFromId('popupContainer');
|
container = uDom.nodeFromId('popupContainer');
|
||||||
|
|
|
@ -1022,28 +1022,26 @@ vAPI.messaging.listen('dashboard', onMessage);
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var µb = µBlock,
|
var µb = µBlock,
|
||||||
extensionPageURL = vAPI.getURL('');
|
extensionOriginURL = vAPI.getURL('');
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var getLoggerData = function(ownerId, activeTabId, callback) {
|
var getLoggerData = function(ownerId, activeTabId, callback) {
|
||||||
var tabIds = {};
|
var tabIds = new Map();
|
||||||
for ( var tabId in µb.pageStores ) {
|
for ( var entry of µb.pageStores ) {
|
||||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
var pageStore = entry[1];
|
||||||
if ( pageStore === null ) { continue; }
|
if ( pageStore.rawURL.startsWith(extensionOriginURL) ) { continue; }
|
||||||
if ( pageStore.rawURL.startsWith(extensionPageURL) ) { continue; }
|
tabIds.set(entry[0], pageStore.title);
|
||||||
tabIds[tabId] = pageStore.title;
|
|
||||||
}
|
}
|
||||||
if ( activeTabId && tabIds.hasOwnProperty(activeTabId) === false ) {
|
if ( activeTabId && tabIds.has(activeTabId) === false ) {
|
||||||
activeTabId = undefined;
|
activeTabId = undefined;
|
||||||
}
|
}
|
||||||
callback({
|
callback({
|
||||||
colorBlind: µb.userSettings.colorBlindFriendly,
|
colorBlind: µb.userSettings.colorBlindFriendly,
|
||||||
entries: µb.logger.readAll(ownerId),
|
entries: µb.logger.readAll(ownerId),
|
||||||
maxEntries: µb.userSettings.requestLogMaxEntries,
|
maxEntries: µb.userSettings.requestLogMaxEntries,
|
||||||
noTabId: vAPI.noTabId,
|
|
||||||
activeTabId: activeTabId,
|
activeTabId: activeTabId,
|
||||||
tabIds: tabIds,
|
tabIds: Array.from(tabIds),
|
||||||
tabIdsToken: µb.pageStoresToken
|
tabIdsToken: µb.pageStoresToken
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1093,11 +1091,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vAPI.tabs.get(null, function(tab) {
|
vAPI.tabs.get(null, function(tab) {
|
||||||
getLoggerData(
|
getLoggerData(request.ownerId, tab && tab.id, callback);
|
||||||
request.ownerId,
|
|
||||||
tab && tab.id.toString(),
|
|
||||||
callback
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
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.rawURL = tabContext.rawURL;
|
||||||
this.hostnameToCountMap = new Map();
|
this.hostnameToCountMap = new Map();
|
||||||
this.contentLastModified = 0;
|
this.contentLastModified = 0;
|
||||||
this.frames = Object.create(null);
|
this.frames = new Map();
|
||||||
this.logData = undefined;
|
this.logData = undefined;
|
||||||
this.perLoadBlockedRequestCount = 0;
|
this.perLoadBlockedRequestCount = 0;
|
||||||
this.perLoadAllowedRequestCount = 0;
|
this.perLoadAllowedRequestCount = 0;
|
||||||
|
@ -410,27 +410,26 @@ PageStore.prototype.dispose = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PageStore.prototype.disposeFrameStores = function() {
|
PageStore.prototype.disposeFrameStores = function() {
|
||||||
var frames = this.frames;
|
for ( var frameStore of this.frames.values() ) {
|
||||||
for ( var k in frames ) {
|
frameStore.dispose();
|
||||||
frames[k].dispose();
|
|
||||||
}
|
}
|
||||||
this.frames = Object.create(null);
|
this.frames.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PageStore.prototype.getFrame = function(frameId) {
|
PageStore.prototype.getFrame = function(frameId) {
|
||||||
return this.frames[frameId] || null;
|
return this.frames.get(frameId) || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PageStore.prototype.setFrame = function(frameId, frameURL) {
|
PageStore.prototype.setFrame = function(frameId, frameURL) {
|
||||||
var frameStore = this.frames[frameId];
|
var frameStore = this.frames.get(frameId);
|
||||||
if ( frameStore ) {
|
if ( frameStore !== undefined ) {
|
||||||
frameStore.init(frameURL);
|
frameStore.init(frameURL);
|
||||||
} else {
|
} 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) {
|
PageStore.prototype.createContextFromFrameId = function(frameId) {
|
||||||
var context = µb.tabContextManager.createContext(this.tabId);
|
var context = µb.tabContextManager.createContext(this.tabId);
|
||||||
var frameStore = this.frames[frameId];
|
var frameStore = this.frames.get(frameId);
|
||||||
if ( frameStore ) {
|
if ( frameStore !== undefined ) {
|
||||||
context.pageHostname = frameStore.pageHostname;
|
context.pageHostname = frameStore.pageHostname;
|
||||||
context.pageDomain = frameStore.pageDomain;
|
context.pageDomain = frameStore.pageDomain;
|
||||||
} else {
|
} else {
|
||||||
|
|
157
src/js/tab.js
157
src/js/tab.js
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -128,7 +128,7 @@ housekeep itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
µb.tabContextManager = (function() {
|
µb.tabContextManager = (function() {
|
||||||
var tabContexts = Object.create(null);
|
var tabContexts = new Map();
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/1001
|
// https://github.com/chrisaljoudi/uBlock/issues/1001
|
||||||
// This is to be used as last-resort fallback in case a tab is found to not
|
// 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) {
|
var TabContext = function(tabId) {
|
||||||
this.tabId = tabId.toString();
|
this.tabId = tabId;
|
||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.rawURL =
|
this.rawURL =
|
||||||
this.normalURL =
|
this.normalURL =
|
||||||
|
@ -218,18 +218,16 @@ housekeep itself.
|
||||||
this.netFiltering = true;
|
this.netFiltering = true;
|
||||||
this.netFilteringReadTime = 0;
|
this.netFilteringReadTime = 0;
|
||||||
|
|
||||||
tabContexts[tabId] = this;
|
tabContexts.set(tabId, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
TabContext.prototype.destroy = function() {
|
TabContext.prototype.destroy = function() {
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( this.gcTimer !== null ) {
|
if ( this.gcTimer !== null ) {
|
||||||
clearTimeout(this.gcTimer);
|
clearTimeout(this.gcTimer);
|
||||||
this.gcTimer = null;
|
this.gcTimer = null;
|
||||||
}
|
}
|
||||||
delete tabContexts[this.tabId];
|
tabContexts.delete(this.tabId);
|
||||||
};
|
};
|
||||||
|
|
||||||
TabContext.prototype.onTab = function(tab) {
|
TabContext.prototype.onTab = function(tab) {
|
||||||
|
@ -363,7 +361,7 @@ housekeep itself.
|
||||||
// These are to be used for the API of the tab context manager.
|
// These are to be used for the API of the tab context manager.
|
||||||
|
|
||||||
var push = function(tabId, url) {
|
var push = function(tabId, url) {
|
||||||
var entry = tabContexts[tabId];
|
var entry = tabContexts.get(tabId);
|
||||||
if ( entry === undefined ) {
|
if ( entry === undefined ) {
|
||||||
entry = new TabContext(tabId);
|
entry = new TabContext(tabId);
|
||||||
entry.autodestroy();
|
entry.autodestroy();
|
||||||
|
@ -376,13 +374,13 @@ housekeep itself.
|
||||||
|
|
||||||
// Find a tab context for a specific tab.
|
// Find a tab context for a specific tab.
|
||||||
var lookup = function(tabId) {
|
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
|
// 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.
|
// fix this. When all fail, the behind-the-scene context is returned.
|
||||||
var mustLookup = function(tabId) {
|
var mustLookup = function(tabId) {
|
||||||
var entry = tabContexts[tabId];
|
var entry = tabContexts.get(tabId);
|
||||||
if ( entry !== undefined ) {
|
if ( entry !== undefined ) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -407,13 +405,13 @@ housekeep itself.
|
||||||
// about to fall through the cracks.
|
// about to fall through the cracks.
|
||||||
// Example: Chromium + case #12 at
|
// Example: Chromium + case #12 at
|
||||||
// http://raymondhill.net/ublock/popup.html
|
// http://raymondhill.net/ublock/popup.html
|
||||||
return tabContexts[vAPI.noTabId];
|
return tabContexts.get(vAPI.noTabId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/1735
|
// https://github.com/gorhill/uBlock/issues/1735
|
||||||
// Filter for popups if actually committing.
|
// Filter for popups if actually committing.
|
||||||
var commit = function(tabId, url) {
|
var commit = function(tabId, url) {
|
||||||
var entry = tabContexts[tabId];
|
var entry = tabContexts.get(tabId);
|
||||||
if ( entry === undefined ) {
|
if ( entry === undefined ) {
|
||||||
entry = push(tabId, url);
|
entry = push(tabId, url);
|
||||||
} else if ( entry.commit(url) ) {
|
} else if ( entry.commit(url) ) {
|
||||||
|
@ -423,7 +421,7 @@ housekeep itself.
|
||||||
};
|
};
|
||||||
|
|
||||||
var exists = function(tabId) {
|
var exists = function(tabId) {
|
||||||
return tabContexts[tabId] !== undefined;
|
return tabContexts.get(tabId) !== undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Behind-the-scene tab context
|
// Behind-the-scene tab context
|
||||||
|
@ -434,6 +432,9 @@ housekeep itself.
|
||||||
entry.normalURL = µb.normalizePageURL(entry.tabId);
|
entry.normalURL = µb.normalizePageURL(entry.tabId);
|
||||||
entry.rootHostname = µb.URI.hostnameFromURI(entry.normalURL);
|
entry.rootHostname = µb.URI.hostnameFromURI(entry.normalURL);
|
||||||
entry.rootDomain = µb.URI.domainFromHostname(entry.rootHostname);
|
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.
|
// Context object, typically to be used to feed filtering engines.
|
||||||
|
@ -842,13 +843,15 @@ vAPI.tabs.registerListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reuse page store if one exists: this allows to guess if a tab is a popup
|
// 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
|
// Tab is not bound
|
||||||
if ( !pageStore ) {
|
if ( pageStore === undefined ) {
|
||||||
this.updateTitle(tabId);
|
this.updateTitle(tabId);
|
||||||
this.pageStoresToken = Date.now();
|
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
|
// https://github.com/chrisaljoudi/uBlock/issues/516
|
||||||
|
@ -878,10 +881,10 @@ vAPI.tabs.registerListeners();
|
||||||
|
|
||||||
µb.unbindTabFromPageStats = function(tabId) {
|
µb.unbindTabFromPageStats = function(tabId) {
|
||||||
//console.debug('µBlock> unbindTabFromPageStats(%d)', tabId);
|
//console.debug('µBlock> unbindTabFromPageStats(%d)', tabId);
|
||||||
var pageStore = this.pageStores[tabId];
|
var pageStore = this.pageStores.get(tabId);
|
||||||
if ( pageStore !== undefined ) {
|
if ( pageStore !== undefined ) {
|
||||||
pageStore.dispose();
|
pageStore.dispose();
|
||||||
delete this.pageStores[tabId];
|
this.pageStores.delete(tabId);
|
||||||
this.pageStoresToken = Date.now();
|
this.pageStoresToken = Date.now();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -889,29 +892,36 @@ vAPI.tabs.registerListeners();
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µb.pageStoreFromTabId = function(tabId) {
|
µb.pageStoreFromTabId = function(tabId) {
|
||||||
return this.pageStores[tabId] || null;
|
return this.pageStores.get(tabId) || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
µb.mustPageStoreFromTabId = function(tabId) {
|
µ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.
|
// Permanent page store for behind-the-scene requests. Must never be removed.
|
||||||
|
|
||||||
µb.pageStores[vAPI.noTabId] = µb.PageStore.factory(vAPI.noTabId);
|
(function() {
|
||||||
µb.pageStores[vAPI.noTabId].title = vAPI.i18n('logBehindTheScene');
|
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.
|
// Update visual of extension icon.
|
||||||
|
|
||||||
µb.updateBadgeAsync = (function() {
|
µb.updateBadgeAsync = (function() {
|
||||||
var tabIdToTimer = Object.create(null);
|
var tabIdToTimer = new Map();
|
||||||
|
|
||||||
var updateBadge = function(tabId) {
|
var updateBadge = function(tabId) {
|
||||||
delete tabIdToTimer[tabId];
|
tabIdToTimer.delete(tabId);
|
||||||
|
|
||||||
var state = false;
|
var state = false;
|
||||||
var badge = '';
|
var badge = '';
|
||||||
|
@ -928,82 +938,70 @@ vAPI.tabs.registerListeners();
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(tabId) {
|
return function(tabId) {
|
||||||
if ( tabIdToTimer[tabId] ) {
|
if ( tabIdToTimer.has(tabId) ) { return; }
|
||||||
return;
|
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
|
||||||
}
|
tabIdToTimer.set(
|
||||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
tabId,
|
||||||
return;
|
vAPI.setTimeout(updateBadge.bind(this, tabId), 701)
|
||||||
}
|
);
|
||||||
tabIdToTimer[tabId] = vAPI.setTimeout(updateBadge.bind(this, tabId), 701);
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µb.updateTitle = (function() {
|
µb.updateTitle = (function() {
|
||||||
var tabIdToTimer = Object.create(null);
|
var tabIdToTimer = new Map();
|
||||||
var tabIdToTryCount = Object.create(null);
|
|
||||||
var delay = 499;
|
var delay = 499;
|
||||||
|
|
||||||
var tryNoMore = function(tabId) {
|
var tryAgain = function(entry) {
|
||||||
delete tabIdToTryCount[tabId];
|
if ( entry.count === 1 ) { return false; }
|
||||||
};
|
entry.count -= 1;
|
||||||
|
tabIdToTimer.set(
|
||||||
var tryAgain = function(tabId) {
|
entry.tabId,
|
||||||
var count = tabIdToTryCount[tabId];
|
vAPI.setTimeout(updateTitle.bind(null, entry), delay)
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var onTabReady = function(tabId, tab) {
|
var onTabReady = function(entry, tab) {
|
||||||
if ( !tab ) {
|
if ( !tab ) { return; }
|
||||||
return tryNoMore(tabId);
|
var µb = µBlock;
|
||||||
}
|
var pageStore = µb.pageStoreFromTabId(entry.tabId);
|
||||||
var pageStore = this.pageStoreFromTabId(tabId);
|
if ( pageStore === null ) { return; }
|
||||||
if ( pageStore === null ) {
|
|
||||||
return tryNoMore(tabId);
|
|
||||||
}
|
|
||||||
// Firefox needs this: if you detach a tab, the new tab won't have
|
// 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
|
// its rawURL set. Concretely, this causes the logger to report an
|
||||||
// entry to itself in the logger's tab selector.
|
// entry to itself in the logger's tab selector.
|
||||||
// TODO: Investigate for a fix vAPI-side.
|
// TODO: Investigate for a fix vAPI-side.
|
||||||
pageStore.rawURL = tab.url;
|
pageStore.rawURL = tab.url;
|
||||||
this.pageStoresToken = Date.now();
|
µb.pageStoresToken = Date.now();
|
||||||
if ( !tab.title && tryAgain(tabId) ) {
|
if ( !tab.title && tryAgain(entry) ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
// https://github.com/gorhill/uMatrix/issues/225
|
// https://github.com/gorhill/uMatrix/issues/225
|
||||||
// Sometimes title changes while page is loading.
|
// Sometimes title changes while page is loading.
|
||||||
var settled = tab.title && tab.title === pageStore.title;
|
var settled = tab.title && tab.title === pageStore.title;
|
||||||
pageStore.title = tab.title || tab.url || '';
|
pageStore.title = tab.title || tab.url || '';
|
||||||
this.pageStoresToken = Date.now();
|
if ( !settled ) {
|
||||||
if ( settled || !tryAgain(tabId) ) {
|
tryAgain(entry);
|
||||||
tryNoMore(tabId);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateTitle = function(tabId) {
|
var updateTitle = function(entry) {
|
||||||
delete tabIdToTimer[tabId];
|
tabIdToTimer.delete(entry.tabId);
|
||||||
vAPI.tabs.get(tabId, onTabReady.bind(this, tabId));
|
vAPI.tabs.get(entry.tabId, onTabReady.bind(null, entry));
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(tabId) {
|
return function(tabId) {
|
||||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
|
||||||
return;
|
var timer = tabIdToTimer.get(tabId);
|
||||||
|
if ( timer !== undefined ) {
|
||||||
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
if ( tabIdToTimer[tabId] ) {
|
tabIdToTimer.set(
|
||||||
clearTimeout(tabIdToTimer[tabId]);
|
tabId,
|
||||||
}
|
vAPI.setTimeout(
|
||||||
tabIdToTimer[tabId] = vAPI.setTimeout(updateTitle.bind(this, tabId), delay);
|
updateTitle.bind(null, { tabId: tabId, count: 5 }),
|
||||||
tabIdToTryCount[tabId] = 5;
|
delay
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -1018,11 +1016,10 @@ var pageStoreJanitorSampleSize = 10;
|
||||||
|
|
||||||
var pageStoreJanitor = function() {
|
var pageStoreJanitor = function() {
|
||||||
var vapiTabs = vAPI.tabs;
|
var vapiTabs = vAPI.tabs;
|
||||||
var tabIds = Object.keys(µb.pageStores).sort();
|
var tabIds = Array.from(µb.pageStores.keys()).sort();
|
||||||
var checkTab = function(tabId) {
|
var checkTab = function(tabId) {
|
||||||
vapiTabs.get(tabId, function(tab) {
|
vapiTabs.get(tabId, function(tab) {
|
||||||
if ( !tab ) {
|
if ( !tab ) {
|
||||||
//console.error('tab.js> pageStoreJanitor(): stale page store found:', µtabId);
|
|
||||||
µb.unbindTabFromPageStats(tabId);
|
µb.unbindTabFromPageStats(tabId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1030,14 +1027,10 @@ var pageStoreJanitor = function() {
|
||||||
if ( pageStoreJanitorSampleAt >= tabIds.length ) {
|
if ( pageStoreJanitorSampleAt >= tabIds.length ) {
|
||||||
pageStoreJanitorSampleAt = 0;
|
pageStoreJanitorSampleAt = 0;
|
||||||
}
|
}
|
||||||
var tabId;
|
|
||||||
var n = Math.min(pageStoreJanitorSampleAt + pageStoreJanitorSampleSize, tabIds.length);
|
var n = Math.min(pageStoreJanitorSampleAt + pageStoreJanitorSampleSize, tabIds.length);
|
||||||
for ( var i = pageStoreJanitorSampleAt; i < n; i++ ) {
|
for ( var i = pageStoreJanitorSampleAt; i < n; i++ ) {
|
||||||
tabId = tabIds[i];
|
var tabId = tabIds[i];
|
||||||
// Do not remove behind-the-scene page store
|
if ( vAPI.isBehindTheSceneTabId(tabId) ) { continue; }
|
||||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
checkTab(tabId);
|
checkTab(tabId);
|
||||||
}
|
}
|
||||||
pageStoreJanitorSampleAt = n;
|
pageStoreJanitorSampleAt = n;
|
||||||
|
|
|
@ -336,8 +336,8 @@ var toBlockDocResult = function(url, hostname, logData) {
|
||||||
|
|
||||||
var onBeforeBehindTheSceneRequest = function(details) {
|
var onBeforeBehindTheSceneRequest = function(details) {
|
||||||
var µb = µBlock,
|
var µb = µBlock,
|
||||||
pageStore = µb.pageStoreFromTabId(vAPI.noTabId);
|
pageStore = µb.pageStoreFromTabId(details.tabId);
|
||||||
if ( !pageStore ) { return; }
|
if ( pageStore === null ) { return; }
|
||||||
|
|
||||||
var result = 0,
|
var result = 0,
|
||||||
context = pageStore.createContextFromPage(),
|
context = pageStore.createContextFromPage(),
|
||||||
|
@ -348,6 +348,13 @@ var onBeforeBehindTheSceneRequest = function(details) {
|
||||||
context.requestHostname = µb.URI.hostnameFromURI(requestURL);
|
context.requestHostname = µb.URI.hostnameFromURI(requestURL);
|
||||||
context.requestType = requestType;
|
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
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=637577#c15
|
||||||
// Do not filter behind-the-scene network request of type `beacon`: there
|
// 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
|
// 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
|
// https://github.com/gorhill/uBlock/issues/3150
|
||||||
// Ability to globally block CSP reports MUST also apply to
|
// Ability to globally block CSP reports MUST also apply to
|
||||||
// behind-the-scene network requests.
|
// 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);
|
result = pageStore.filterRequest(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +380,7 @@ var onBeforeBehindTheSceneRequest = function(details) {
|
||||||
|
|
||||||
if ( µb.logger.isEnabled() ) {
|
if ( µb.logger.isEnabled() ) {
|
||||||
µb.logger.writeOne(
|
µb.logger.writeOne(
|
||||||
vAPI.noTabId,
|
details.tabId,
|
||||||
'net',
|
'net',
|
||||||
pageStore.logData,
|
pageStore.logData,
|
||||||
requestType,
|
requestType,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
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
|
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
|
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() {
|
µBlock.logCosmeticFilters = (function() {
|
||||||
var tabIdToTimerMap = {};
|
var tabIdToTimerMap = new Map();
|
||||||
|
|
||||||
var injectNow = function(tabId) {
|
var injectNow = function(tabId) {
|
||||||
delete tabIdToTimerMap[tabId];
|
tabIdToTimerMap.delete(tabId);
|
||||||
µBlock.scriptlets.injectDeep(tabId, 'cosmetic-logger');
|
µBlock.scriptlets.injectDeep(tabId, 'cosmetic-logger');
|
||||||
};
|
};
|
||||||
|
|
||||||
var injectAsync = function(tabId) {
|
var injectAsync = function(tabId) {
|
||||||
if ( tabIdToTimerMap.hasOwnProperty(tabId) ) {
|
if ( tabIdToTimerMap.has(tabId) ) { return; }
|
||||||
return;
|
tabIdToTimerMap.set(
|
||||||
}
|
tabId,
|
||||||
tabIdToTimerMap[tabId] = vAPI.setTimeout(
|
vAPI.setTimeout(injectNow.bind(null, tabId), 100)
|
||||||
injectNow.bind(null, tabId),
|
|
||||||
100
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue