diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js
index b7f9a2b1c..b32e8af9a 100644
--- a/platform/chromium/vapi-background.js
+++ b/platform/chromium/vapi-background.js
@@ -384,32 +384,33 @@ vAPI.tabs.registerListeners = function() {
/******************************************************************************/
-vAPI.tabs.get = function(tabId, callback) {
- var onTabReady = function(tab) {
- // https://code.google.com/p/chromium/issues/detail?id=410868#c8
- if ( chrome.runtime.lastError ) {
- /* noop */
- }
- // Caller must be prepared to deal with nil tab value
- callback(tab);
- };
+// Caller must be prepared to deal with nil tab argument.
- if ( tabId !== null ) {
- tabId = toChromiumTabId(tabId);
- if ( tabId === 0 ) {
- onTabReady(null);
- } else {
- chrome.tabs.get(tabId, onTabReady);
- }
+// https://code.google.com/p/chromium/issues/detail?id=410868#c8
+
+vAPI.tabs.get = function(tabId, callback) {
+ if ( tabId === null ) {
+ chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
+ if ( chrome.runtime.lastError ) { /* noop */ }
+ var tab = tabs && tabs[0];
+ if ( tab ) {
+ tab.id = tab.id.toString();
+ }
+ callback(tab);
+ });
return;
}
- var onTabReceived = function(tabs) {
- // https://code.google.com/p/chromium/issues/detail?id=410868#c8
- void chrome.runtime.lastError;
- callback(tabs[0]);
- };
- chrome.tabs.query({ active: true, currentWindow: true }, onTabReceived);
+ tabId = toChromiumTabId(tabId);
+ if ( tabId === 0 ) {
+ callback(null);
+ return;
+ }
+
+ chrome.tabs.get(tabId, function(tab) {
+ if ( chrome.runtime.lastError ) { /* noop */ }
+ callback(tab);
+ });
};
/******************************************************************************/
diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json
index 0d0222411..c0716de42 100644
--- a/src/_locales/en/messages.json
+++ b/src/_locales/en/messages.json
@@ -511,6 +511,10 @@
"message":"Behind the scene",
"description":"Pretty name for behind-the-scene network requests"
},
+ "loggerCurrentTab":{
+ "message":"Current tab",
+ "description":"Appears in the logger's tab selector"
+ },
"logFilterPrompt":{
"message":"filter log entries",
"description": "English: filter log entries"
diff --git a/src/css/logger-ui.css b/src/css/logger-ui.css
index f68c05055..5a90028af 100644
--- a/src/css/logger-ui.css
+++ b/src/css/logger-ui.css
@@ -207,6 +207,7 @@ body #netInspector td {
}
#netInspector tr td:nth-of-type(1) {
+ cursor: default;
text-align: right;
white-space: nowrap;
}
diff --git a/src/js/logger-ui-inspector.js b/src/js/logger-ui-inspector.js
index a1471eb3a..2cceec1f3 100644
--- a/src/js/logger-ui-inspector.js
+++ b/src/js/logger-ui-inspector.js
@@ -50,7 +50,6 @@ var inspectedURL = '';
var inspectedHostname = '';
var inspector = uDom.nodeFromId('domInspector');
var domTree = uDom.nodeFromId('domTree');
-var tabSelector = uDom.nodeFromId('pageSelector');
var uidGenerator = 1;
var filterToIdMap = new Map();
@@ -562,7 +561,7 @@ var onMouseOver = (function() {
var currentTabId = function() {
if ( showdomButton.classList.contains('active') === false ) { return ''; }
- var tabId = logger.tabIdFromClassName(tabSelector.value) || '';
+ var tabId = logger.tabIdFromPageSelector();
return tabId !== 'bts' ? tabId : '';
};
@@ -636,7 +635,7 @@ var revert = function() {
var toggleOn = function() {
window.addEventListener('beforeunload', toggleOff);
- tabSelector.addEventListener('change', onTabIdChanged);
+ document.addEventListener('tabIdChanged', onTabIdChanged);
domTree.addEventListener('click', onClicked, true);
domTree.addEventListener('mouseover', onMouseOver, true);
uDom.nodeFromSelector('#domInspector .vCompactToggler').addEventListener('click', toggleVCompactView);
@@ -652,7 +651,7 @@ var toggleOn = function() {
var toggleOff = function() {
shutdownInspector();
window.removeEventListener('beforeunload', toggleOff);
- tabSelector.removeEventListener('change', onTabIdChanged);
+ document.removeEventListener('tabIdChanged', onTabIdChanged);
domTree.removeEventListener('click', onClicked, true);
domTree.removeEventListener('mouseover', onMouseOver, true);
uDom.nodeFromSelector('#domInspector .vCompactToggler').removeEventListener('click', toggleVCompactView);
@@ -680,5 +679,3 @@ showdomButton.addEventListener('click', toggle);
/******************************************************************************/
})();
-
-
diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js
index 7a0a2a2af..b3cad3b51 100644
--- a/src/js/logger-ui.js
+++ b/src/js/logger-ui.js
@@ -29,9 +29,12 @@
/******************************************************************************/
-var logger = self.logger = {};
+var logger = self.logger = {
+ ownerId: Date.now()
+};
+
var messaging = vAPI.messaging;
-var ownerId = Date.now();
+var activeTabId;
/******************************************************************************/
@@ -44,11 +47,16 @@ var removeAllChildren = logger.removeAllChildren = function(node) {
/******************************************************************************/
var tabIdFromClassName = logger.tabIdFromClassName = function(className) {
- var matches = className.match(/(?:^| )tab_([^ ]+)(?: |$)/);
- if ( matches === null ) {
- return '';
- }
- return matches[1];
+ var matches = className.match(/\btab_([^ ]+)\b/);
+ return matches !== null ? matches[1] : '';
+};
+
+var tabIdFromPageSelector = logger.tabIdFromPageSelector = function() {
+ var tabClass = uDom.nodeFromId('pageSelector').value;
+ if ( tabClass === '' ) { return ''; }
+ if ( tabClass === 'tab_bts' ) { return noTabId; }
+ if ( tabClass === 'tab_active' ) { return activeTabId; }
+ return tabClass.slice(4);
};
/******************************************************************************/
@@ -408,15 +416,17 @@ var renderLogEntries = function(response) {
/******************************************************************************/
var synchronizeTabIds = function(newTabIds) {
+ var select = uDom.nodeFromId('pageSelector');
+ var selectValue = select.value;
+
var oldTabIds = allTabIds;
- var autoDeleteVoidRows = !!vAPI.localStorage.getItem('loggerAutoDeleteVoidRows');
+ var autoDeleteVoidRows = selectValue === 'tab_active';
var rowVoided = false;
- var trs;
for ( var tabId in oldTabIds ) {
if ( oldTabIds.hasOwnProperty(tabId) === false ) { continue; }
if ( newTabIds.hasOwnProperty(tabId) ) { continue; }
// Mark or remove voided rows
- trs = uDom('.tab_' + tabId);
+ var trs = uDom('.tab_' + tabId);
if ( autoDeleteVoidRows ) {
toJunkyard(trs);
} else {
@@ -429,13 +439,11 @@ var synchronizeTabIds = function(newTabIds) {
}
}
- var select = uDom.nodeFromId('pageSelector');
- var selectValue = select.value;
var tabIds = Object.keys(newTabIds).sort(function(a, b) {
return newTabIds[a].localeCompare(newTabIds[b]);
});
var option;
- for ( var i = 0, j = 2; i < tabIds.length; i++ ) {
+ for ( var i = 0, j = 3; i < tabIds.length; i++ ) {
tabId = tabIds[i];
if ( tabId === noTabId ) { continue; }
option = select.options[j];
@@ -495,6 +503,11 @@ var onLogBufferRead = function(response) {
// This tells us the behind-the-scene tab id
noTabId = response.noTabId;
+ // Tab id of currently active tab
+ if ( response.activeTabId ) {
+ activeTabId = response.activeTabId;
+ }
+
// This may have changed meanwhile
if ( response.maxEntries !== maxEntries ) {
maxEntries = response.maxEntries;
@@ -537,62 +550,70 @@ var onLogBufferRead = function(response) {
// require a bit more code to ensure no multi time out events.
var readLogBuffer = function() {
- if ( ownerId === undefined ) { return; }
+ if ( logger.ownerId === undefined ) { return; }
vAPI.messaging.send(
'loggerUI',
- { what: 'readAll', ownerId: ownerId },
+ { what: 'readAll', ownerId: logger.ownerId },
onLogBufferRead
);
};
var readLogBufferAsync = function() {
- if ( ownerId === undefined ) { return; }
+ if ( logger.ownerId === undefined ) { return; }
vAPI.setTimeout(readLogBuffer, 1200);
};
/******************************************************************************/
var pageSelectorChanged = function() {
- window.location.replace('#' + uDom.nodeFromId('pageSelector').value);
+ var select = uDom.nodeFromId('pageSelector');
+ window.location.replace('#' + select.value);
pageSelectorFromURLHash();
};
-/******************************************************************************/
-
var pageSelectorFromURLHash = (function() {
- var lastHash = '';
+ var lastTabClass = '';
+ var lastEffectiveTabClass = '';
- return function() {
- var hash = window.location.hash;
- if ( hash === lastHash ) {
- return;
+ var selectRows = function(tabClass) {
+ if ( tabClass === 'tab_active' ) {
+ if ( activeTabId === undefined ) { return; }
+ tabClass = 'tab_' + activeTabId;
}
+ if ( tabClass === lastEffectiveTabClass ) { return; }
+ lastEffectiveTabClass = tabClass;
- var tabClass = hash.slice(1);
- var select = uDom.nodeFromId('pageSelector');
- var option = select.querySelector('option[value="' + tabClass + '"]');
- if ( option === null ) {
- hash = window.location.hash = '';
- tabClass = '';
- option = select.options[0];
- }
-
- lastHash = hash;
-
- select.selectedIndex = option.index;
- select.value = option.value;
+ document.dispatchEvent(new Event('tabIdChanged'));
var style = uDom.nodeFromId('tabFilterer');
var sheet = style.sheet;
while ( sheet.cssRules.length !== 0 ) {
sheet.deleteRule(0);
}
- if ( tabClass !== '' ) {
- sheet.insertRule(
- '#netInspector tr:not(.' + tabClass + ') { display: none; }',
- 0
- );
+ if ( tabClass === '' ) { return; }
+ sheet.insertRule(
+ '#netInspector tr:not(.' + tabClass + '):not(.tab_bts) ' +
+ '{display:none;}'
+ );
+ };
+
+ return function() {
+ var tabClass = window.location.hash.slice(1);
+ selectRows(tabClass);
+ if ( tabClass === lastTabClass ) { return; }
+ lastTabClass = tabClass;
+
+ var select = uDom.nodeFromId('pageSelector');
+ var option = select.querySelector('option[value="' + tabClass + '"]');
+ if ( option === null ) {
+ window.location.hash = '';
+ tabClass = '';
+ option = select.options[0];
}
+
+ select.selectedIndex = option.index;
+ select.value = option.value;
+
uDom('.needtab').toggleClass(
'disabled',
tabClass === '' || tabClass === 'tab_bts'
@@ -603,11 +624,8 @@ var pageSelectorFromURLHash = (function() {
/******************************************************************************/
var reloadTab = function() {
- var tabClass = uDom.nodeFromId('pageSelector').value;
- var tabId = tabIdFromClassName(tabClass);
- if ( tabId === 'bts' || tabId === '' ) {
- return;
- }
+ var tabId = tabIdFromPageSelector();
+ if ( tabId === '' || tabId === noTabId ) { return; }
messaging.send('loggerUI', { what: 'reloadTab', tabId: tabId });
};
@@ -1491,13 +1509,13 @@ var toJunkyard = function(trs) {
/******************************************************************************/
var clearBuffer = function() {
- var tabId = uDom.nodeFromId('pageSelector').value || null;
+ var tabClass = uDom.nodeFromId('pageSelector').value || '';
var tbody = document.querySelector('#netInspector tbody');
var tr = tbody.lastElementChild;
var trPrevious;
while ( tr !== null ) {
trPrevious = tr.previousElementSibling;
- if ( tabId === null || tr.classList.contains(tabId) ) {
+ if ( tabClass === '' || tr.classList.contains(tabClass) ) {
trJunkyard.push(tbody.removeChild(tr));
}
tr = trPrevious;
@@ -1656,19 +1674,19 @@ var popupManager = (function() {
/******************************************************************************/
var grabView = function() {
- if ( ownerId === undefined ) {
- ownerId = Date.now();
+ if ( logger.ownerId === undefined ) {
+ logger.ownerId = Date.now();
}
readLogBufferAsync();
};
var releaseView = function() {
- if ( ownerId === undefined ) { return; }
+ if ( logger.ownerId === undefined ) { return; }
vAPI.messaging.send(
'loggerUI',
- { what: 'releaseView', ownerId: ownerId }
+ { what: 'releaseView', ownerId: logger.ownerId }
);
- ownerId = undefined;
+ logger.ownerId = undefined;
};
window.addEventListener('pagehide', releaseView);
diff --git a/src/js/messaging.js b/src/js/messaging.js
index ced2781e6..73801ffc9 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -1015,6 +1015,31 @@ var µb = µBlock,
/******************************************************************************/
+var getLoggerData = function(ownerId, tab, 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 activeTabId;
+ if ( tabIds.hasOwnProperty(tab.id) ) {
+ activeTabId = tab.id;
+ }
+ callback({
+ colorBlind: µb.userSettings.colorBlindFriendly,
+ entries: µb.logger.readAll(ownerId),
+ maxEntries: µb.userSettings.requestLogMaxEntries,
+ noTabId: vAPI.noTabId,
+ activeTabId: activeTabId,
+ tabIds: tabIds,
+ tabIdsToken: µb.pageStoresToken
+ });
+};
+
+/******************************************************************************/
+
var getURLFilteringData = function(details) {
var colors = {};
var response = {
@@ -1049,6 +1074,19 @@ var getURLFilteringData = function(details) {
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
+ case 'readAll':
+ if (
+ µb.logger.ownerId !== undefined &&
+ µb.logger.ownerId !== request.ownerId
+ ) {
+ callback({ unavailable: true });
+ return;
+ }
+ vAPI.tabs.get(null, function(tab) {
+ getLoggerData(request.ownerId, tab, callback);
+ });
+ return;
+
default:
break;
}
@@ -1057,31 +1095,6 @@ var onMessage = function(request, sender, callback) {
var response;
switch ( request.what ) {
- case 'readAll':
- if (
- µb.logger.ownerId !== undefined &&
- µb.logger.ownerId !== request.ownerId
- ) {
- response = { unavailable: true };
- break;
- }
- 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;
- }
- response = {
- colorBlind: µb.userSettings.colorBlindFriendly,
- entries: µb.logger.readAll(request.ownerId),
- maxEntries: µb.userSettings.requestLogMaxEntries,
- noTabId: vAPI.noTabId,
- tabIds: tabIds,
- tabIdsToken: µb.pageStoresToken
- };
- break;
-
case 'releaseView':
if ( request.ownerId === µb.logger.ownerId ) {
µb.logger.ownerId = undefined;
diff --git a/src/logger-ui.html b/src/logger-ui.html
index 9539f44a9..804a1363f 100644
--- a/src/logger-ui.html
+++ b/src/logger-ui.html
@@ -15,6 +15,7 @@