diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index 2c569f32d..b7f9a2b1c 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -779,8 +779,7 @@ vAPI.messaging.onPortMessage = (function() { var toFramework = function(request, port, callback) { var sender = port && port.sender; if ( !sender ) { return; } - var tabId = sender.tab && sender.tab.id; - if ( !tabId ) { return; } + var tabId = sender.tab && sender.tab.id || undefined; var msg = request.msg, toPort; switch ( msg.what ) { @@ -788,7 +787,7 @@ vAPI.messaging.onPortMessage = (function() { case 'connectionRefused': toPort = messaging.ports.get(msg.fromToken); if ( toPort !== undefined ) { - msg.tabId = tabId.toString(); + msg.tabId = tabId && tabId.toString(); toPort.postMessage(request); } else { msg.what = 'connectionBroken'; @@ -796,7 +795,7 @@ vAPI.messaging.onPortMessage = (function() { } break; case 'connectionRequested': - msg.tabId = '' + tabId.toString(); + msg.tabId = tabId && tabId.toString(); for ( toPort of messaging.ports.values() ) { toPort.postMessage(request); } @@ -808,7 +807,7 @@ vAPI.messaging.onPortMessage = (function() { port.name === msg.fromToken ? msg.toToken : msg.fromToken ); if ( toPort !== undefined ) { - msg.tabId = tabId.toString(); + msg.tabId = tabId && tabId.toString(); toPort.postMessage(request); } else { msg.what = 'connectionBroken'; @@ -816,6 +815,7 @@ vAPI.messaging.onPortMessage = (function() { } break; case 'userCSS': + if ( tabId === undefined ) { break; } var details = { code: undefined, frameId: sender.frameId, diff --git a/platform/webext/manifest.json b/platform/webext/manifest.json index 70e97de5f..679ddbb1e 100644 --- a/platform/webext/manifest.json +++ b/platform/webext/manifest.json @@ -80,5 +80,13 @@ "" ], "short_name":"uBlock₀", + "sidebar_action":{ + "default_title":"__MSG_statsPageName__", + "default_panel":"logger-ui.html", + "default_icon":{ + "16":"img/ublock.svg", + "48":"img/ublock.svg" + } + }, "version":"1.9.15.101" } diff --git a/src/css/logger-ui.css b/src/css/logger-ui.css index a7c525258..f68c05055 100644 --- a/src/css/logger-ui.css +++ b/src/css/logger-ui.css @@ -128,19 +128,19 @@ textarea { width: 4.6em; } #netInspector table > colgroup > col:nth-of-type(2) { - width: 2.2em; + width: 2.1em; } #netInspector table > colgroup > col:nth-of-type(3) { width: 20%; } #netInspector table > colgroup > col:nth-of-type(4) { - width: 2.2em; + width: 2.1em; } #netInspector table > colgroup > col:nth-of-type(5) { - width: 6em; + width: 5.8em; } #netInspector table > colgroup > col:nth-of-type(6) { - width: calc(100% - 15em - 20%); + width: calc(100% - 14.6em - 20%); } #netInspector.f table tr.f { display: none; @@ -200,7 +200,7 @@ body #netInspector td { #netInspector tr td:last-of-type { border-right: none; } -#netInspector.vCompact td { +#netInspector.vCompact tr:not(.vExpanded) td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; diff --git a/src/js/logger-ui-inspector.js b/src/js/logger-ui-inspector.js index f598ec2db..a1471eb3a 100644 --- a/src/js/logger-ui-inspector.js +++ b/src/js/logger-ui-inspector.js @@ -79,7 +79,12 @@ messaging.addChannelListener('loggerUI', function(msg) { break; case 'connectionRequested': if ( msg.from !== 'domInspector' ) { return false; } - if ( msg.tabId !== inspectedTabId ) { return false; } + if ( + msg.tabId === undefined || + msg.tabId !== inspectedTabId + ) { + return false; + } filterToIdMap.clear(); logger.removeAllChildren(domTree); inspectorConnectionId = msg.id; diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js index 218f44fb3..7a0a2a2af 100644 --- a/src/js/logger-ui.js +++ b/src/js/logger-ui.js @@ -31,6 +31,7 @@ var logger = self.logger = {}; var messaging = vAPI.messaging; +var ownerId = Date.now(); /******************************************************************************/ @@ -486,6 +487,11 @@ var truncateLog = function(size) { /******************************************************************************/ var onLogBufferRead = function(response) { + if ( !response || response.unavailable ) { + readLogBufferAsync(); + return; + } + // This tells us the behind-the-scene tab id noTabId = response.noTabId; @@ -521,7 +527,7 @@ var onLogBufferRead = function(response) { tbody.querySelector('tr') === null ); - vAPI.setTimeout(readLogBuffer, 1200); + readLogBufferAsync(); }; /******************************************************************************/ @@ -531,9 +537,19 @@ var onLogBufferRead = function(response) { // require a bit more code to ensure no multi time out events. var readLogBuffer = function() { - messaging.send('loggerUI', { what: 'readAll' }, onLogBufferRead); + if ( ownerId === undefined ) { return; } + vAPI.messaging.send( + 'loggerUI', + { what: 'readAll', ownerId: ownerId }, + onLogBufferRead + ); }; +var readLogBufferAsync = function() { + if ( ownerId === undefined ) { return; } + vAPI.setTimeout(readLogBuffer, 1200); +}; + /******************************************************************************/ var pageSelectorChanged = function() { @@ -1511,6 +1527,11 @@ var cleanBuffer = function() { var toggleVCompactView = function() { uDom.nodeFromId('netInspector').classList.toggle('vCompact'); + uDom('#netInspector .vExpanded').toggleClass('vExpanded'); +}; + +var toggleVCompactRow = function(ev) { + ev.target.parentElement.classList.toggle('vExpanded'); }; /******************************************************************************/ @@ -1634,6 +1655,29 @@ var popupManager = (function() { /******************************************************************************/ +var grabView = function() { + if ( ownerId === undefined ) { + ownerId = Date.now(); + } + readLogBufferAsync(); +}; + +var releaseView = function() { + if ( ownerId === undefined ) { return; } + vAPI.messaging.send( + 'loggerUI', + { what: 'releaseView', ownerId: ownerId } + ); + ownerId = undefined; +}; + +window.addEventListener('pagehide', releaseView); +window.addEventListener('pageshow', grabView); +// https://bugzilla.mozilla.org/show_bug.cgi?id=1398625 +window.addEventListener('beforeunload', releaseView); + +/******************************************************************************/ + readLogBuffer(); uDom('#pageSelector').on('change', pageSelectorChanged); @@ -1644,6 +1688,7 @@ uDom('#netInspector .vCompactToggler').on('click', toggleVCompactView); uDom('#clean').on('click', cleanBuffer); uDom('#clear').on('click', clearBuffer); uDom('#maxEntries').on('change', onMaxEntriesChanged); +uDom('#netInspector table').on('click', 'tr > td:nth-of-type(1)', toggleVCompactRow); uDom('#netInspector table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn); uDom('#netInspector').on('click', 'tr.canLookup > td:nth-of-type(3)', reverseLookupManager.toggleOn); uDom('#netInspector').on('click', 'tr.cat_net > td:nth-of-type(4)', netFilteringManager.toggleOn); diff --git a/src/js/logger.js b/src/js/logger.js index 37da162a7..f4e33f5c8 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -47,7 +47,7 @@ // After 60 seconds without being read, a buffer will be considered // unused, and thus removed from memory. - var logBufferObsoleteAfter = 60 * 1000; + var logBufferObsoleteAfter = 30 * 1000; var janitor = function() { if ( @@ -56,6 +56,7 @@ ) { buffer = null; writePtr = 0; + api.ownerId = undefined; vAPI.messaging.broadcast({ what: 'loggerDisabled' }); } if ( buffer !== null ) { @@ -63,7 +64,8 @@ } }; - return { + var api = { + ownerId: undefined, writeOne: function() { if ( buffer === null ) { return; } if ( writePtr === buffer.length ) { @@ -73,7 +75,8 @@ } writePtr += 1; }, - readAll: function() { + readAll: function(ownerId) { + this.ownerId = ownerId; if ( buffer === null ) { buffer = []; vAPI.setTimeout(janitor, logBufferObsoleteAfter); @@ -88,6 +91,8 @@ } }; + return api; + })(); /******************************************************************************/ diff --git a/src/js/messaging.js b/src/js/messaging.js index 34980672e..ced2781e6 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -1010,7 +1010,8 @@ vAPI.messaging.listen('dashboard', onMessage); /******************************************************************************/ -var µb = µBlock; +var µb = µBlock, + extensionPageURL = vAPI.getURL(''); /******************************************************************************/ @@ -1057,21 +1058,23 @@ var onMessage = function(request, sender, callback) { switch ( request.what ) { case 'readAll': - var tabIds = {}, pageStore; - var loggerURL = vAPI.getURL('logger-ui.html'); + if ( + µb.logger.ownerId !== undefined && + µb.logger.ownerId !== request.ownerId + ) { + response = { unavailable: true }; + break; + } + var tabIds = {}; for ( var tabId in µb.pageStores ) { - pageStore = µb.pageStoreFromTabId(tabId); - if ( pageStore === null ) { - continue; - } - if ( pageStore.rawURL.startsWith(loggerURL) ) { - continue; - } + 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(), + entries: µb.logger.readAll(request.ownerId), maxEntries: µb.userSettings.requestLogMaxEntries, noTabId: vAPI.noTabId, tabIds: tabIds, @@ -1079,6 +1082,12 @@ var onMessage = function(request, sender, callback) { }; break; + case 'releaseView': + if ( request.ownerId === µb.logger.ownerId ) { + µb.logger.ownerId = undefined; + } + break; + case 'saveURLFilteringRules': response = µb.permanentURLFiltering.copyRules( µb.sessionURLFiltering, @@ -1112,8 +1121,6 @@ vAPI.messaging.listen('loggerUI', onMessage); })(); -// https://www.youtube.com/watch?v=3_WcygKJP1k - /******************************************************************************/ /******************************************************************************/