mirror of https://github.com/gorhill/uBlock.git
this fixes #193
This commit is contained in:
parent
20f5794b37
commit
e0284b8908
|
@ -403,6 +403,10 @@
|
|||
"message":"No non-blocked requests logged for this page",
|
||||
"description":"English: No non-blocked requests logged for this page"
|
||||
},
|
||||
"logAll":{
|
||||
"message":"All",
|
||||
"description":"Appears in the logger's tab selector"
|
||||
},
|
||||
"logBehindTheScene":{
|
||||
"message":"Behind the scene",
|
||||
"description":"Pretty name for behind-the-scene network requests"
|
||||
|
|
|
@ -7,7 +7,6 @@ body {
|
|||
margin: 0;
|
||||
overflow-x: hidden;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
#toolbar {
|
||||
|
@ -16,7 +15,7 @@ body {
|
|||
box-sizing: border-box;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0 1em;
|
||||
padding: 0.5em 1em;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
@ -28,7 +27,7 @@ body {
|
|||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
font-size: 150%;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
@ -39,6 +38,19 @@ body {
|
|||
#toolbar .button:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
#toolbar > div {
|
||||
white-space: nowrap;
|
||||
}
|
||||
#toolbar > div:first-of-type {
|
||||
font-size: 120%;
|
||||
}
|
||||
#toolbar > div > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
#pageSelector {
|
||||
width: 28em;
|
||||
padding: 0.2em 0;
|
||||
}
|
||||
body #compactViewToggler.button:before {
|
||||
content: '\f102';
|
||||
}
|
||||
|
@ -55,14 +67,13 @@ body.f #filterButton {
|
|||
background-color: #fee;
|
||||
}
|
||||
#maxEntries {
|
||||
margin-left: 3em;
|
||||
margin: 0 2em;
|
||||
}
|
||||
input:focus {
|
||||
background-color: #ffe;
|
||||
}
|
||||
#content {
|
||||
font: 13px sans-serif;
|
||||
margin-top: 3.5em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,15 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// Adjust top padding of content table, to match that of toolbar height.
|
||||
|
||||
document.getElementById('content').style.setProperty(
|
||||
'margin-top',
|
||||
document.getElementById('toolbar').offsetHeight + 'px'
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var messager = vAPI.messaging.channel('logger-ui.js');
|
||||
var tbody = document.querySelector('#content tbody');
|
||||
var trJunkyard = [];
|
||||
|
@ -40,6 +49,8 @@ var maxEntries = 5000;
|
|||
var noTabId = '';
|
||||
var allTabIds = {};
|
||||
|
||||
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
||||
|
||||
var prettyRequestTypes = {
|
||||
'main_frame': 'doc',
|
||||
'stylesheet': 'css',
|
||||
|
@ -61,6 +72,18 @@ var dateOptions = {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var classNameFromTabId = function(tabId) {
|
||||
if ( tabId === noTabId ) {
|
||||
return 'tab_bts';
|
||||
}
|
||||
if ( tabId !== '' ) {
|
||||
return 'tab_' + tabId;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Emphasize hostname in URL, as this is what matters in uMatrix's rules.
|
||||
|
||||
var nodeFromURL = function(url, filter) {
|
||||
|
@ -165,6 +188,14 @@ var createRow = function(layout) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var createHiddenTextNode = function(text) {
|
||||
var node = hiddenTemplate.cloneNode(true);
|
||||
node.textContent = text;
|
||||
return node;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var createGap = function(tabId, url) {
|
||||
var tr = createRow('1');
|
||||
tr.classList.add('tab');
|
||||
|
@ -246,11 +277,9 @@ var renderLogEntry = function(entry) {
|
|||
tr.cells[0].title = time.toLocaleDateString('fullwide', dateOptions);
|
||||
|
||||
if ( entry.tab ) {
|
||||
tr.classList.add('tab');
|
||||
tr.classList.add('tab', classNameFromTabId(entry.tab));
|
||||
if ( entry.tab === noTabId ) {
|
||||
tr.classList.add('tab_bts');
|
||||
} else if ( entry.tab !== '' ) {
|
||||
tr.classList.add('tab_' + entry.tab);
|
||||
tr.cells[1].appendChild(createHiddenTextNode('bts'));
|
||||
}
|
||||
}
|
||||
if ( entry.cat !== '' ) {
|
||||
|
@ -316,6 +345,78 @@ var renderLogEntries = function(response) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var synchronizeTabIds = function(newTabIds) {
|
||||
var oldTabIds = allTabIds;
|
||||
|
||||
// Neuter rows for which a tab does not exist anymore
|
||||
// TODO: sort to avoid using indexOf
|
||||
|
||||
var autoDeleteVoidRows = !!vAPI.localStorage.getItem('loggerAutoDeleteVoidRows');
|
||||
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);
|
||||
if ( autoDeleteVoidRows ) {
|
||||
toJunkyard(trs);
|
||||
} else {
|
||||
trs.removeClass('canMtx');
|
||||
rowVoided = true;
|
||||
}
|
||||
// Remove popup if it is currently bound to a removed tab.
|
||||
if ( tabId === popupManager.tabId ) {
|
||||
popupManager.toggleOff();
|
||||
}
|
||||
}
|
||||
|
||||
var select = document.getElementById('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++ ) {
|
||||
tabId = tabIds[i];
|
||||
if ( tabId === noTabId ) {
|
||||
continue;
|
||||
}
|
||||
option = select.options[j];
|
||||
j += 1;
|
||||
if ( !option ) {
|
||||
option = document.createElement('option');
|
||||
select.appendChild(option);
|
||||
}
|
||||
option.textContent = newTabIds[tabId];
|
||||
option.value = classNameFromTabId(tabId);
|
||||
if ( option.value === selectValue ) {
|
||||
option.setAttribute('selected', '');
|
||||
} else {
|
||||
option.removeAttribute('selected');
|
||||
}
|
||||
}
|
||||
while ( j < select.options.length ) {
|
||||
select.removeChild(select.options[j]);
|
||||
}
|
||||
if ( select.value !== selectValue ) {
|
||||
select.selectedIndex = 0;
|
||||
select.value = '';
|
||||
select.options[0].setAttribute('selected', '');
|
||||
pageSelectorChanged();
|
||||
}
|
||||
|
||||
allTabIds = newTabIds;
|
||||
|
||||
return rowVoided;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var truncateLog = function(size) {
|
||||
if ( size === 0 ) {
|
||||
size = 5000;
|
||||
|
@ -343,28 +444,7 @@ var onLogBufferRead = function(response) {
|
|||
|
||||
// Neuter rows for which a tab does not exist anymore
|
||||
// TODO: sort to avoid using indexOf
|
||||
var autoDeleteVoidRows = vAPI.localStorage.getItem('loggerAutoDeleteVoidRows');
|
||||
var rowVoided = false, trs;
|
||||
for ( var tabId in allTabIds ) {
|
||||
if ( allTabIds.hasOwnProperty(tabId) === false ) {
|
||||
continue;
|
||||
}
|
||||
if ( response.tabIds.hasOwnProperty(tabId) ) {
|
||||
continue;
|
||||
}
|
||||
trs = uDom('.tab_' + tabId);
|
||||
if ( autoDeleteVoidRows ) {
|
||||
toJunkyard(trs);
|
||||
} else {
|
||||
trs.removeClass('canMtx');
|
||||
rowVoided = true;
|
||||
}
|
||||
if ( tabId === popupManager.tabId ) {
|
||||
popupManager.toggleOff();
|
||||
}
|
||||
}
|
||||
allTabIds = response.tabIds;
|
||||
|
||||
var rowVoided = synchronizeTabIds(response.tabIds);
|
||||
renderLogEntries(response);
|
||||
|
||||
if ( rowVoided ) {
|
||||
|
@ -395,6 +475,41 @@ var readLogBuffer = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var pageSelectorChanged = function() {
|
||||
var style = document.getElementById('tabFilterer');
|
||||
var tabClass = document.getElementById('pageSelector').value;
|
||||
var sheet = style.sheet;
|
||||
while ( sheet.cssRules.length !== 0 ) {
|
||||
sheet.deleteRule(0);
|
||||
}
|
||||
if ( tabClass !== '' ) {
|
||||
sheet.insertRule(
|
||||
'#content table tr:not(.' + tabClass + ') { display: none; }',
|
||||
0
|
||||
);
|
||||
}
|
||||
uDom('#refresh').toggleClass(
|
||||
'disabled',
|
||||
tabClass === '' || tabClass === 'tab_bts'
|
||||
);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var reloadTab = function() {
|
||||
var tabClass = document.getElementById('pageSelector').value;
|
||||
var matches = tabClass.match(/^tab_(.+)$/);
|
||||
if ( matches === null ) {
|
||||
return;
|
||||
}
|
||||
if ( matches[1] === 'bts' ) {
|
||||
return;
|
||||
}
|
||||
messager.send({ what: 'reloadTab', tabId: matches[1] });
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMaxEntriesChanged = function() {
|
||||
var raw = uDom(this).val();
|
||||
try {
|
||||
|
@ -649,7 +764,7 @@ var popupManager = (function() {
|
|||
popupObserver = new MutationObserver(resizePopup);
|
||||
container.appendChild(popup);
|
||||
|
||||
style = document.querySelector('#content > style');
|
||||
style = document.getElementById('popupFilterer');
|
||||
style.textContent = styleTemplate.replace('{{tabId}}', localTabId);
|
||||
|
||||
document.body.classList.add('popupOn');
|
||||
|
@ -701,6 +816,8 @@ var popupManager = (function() {
|
|||
uDom.onLoad(function() {
|
||||
readLogBuffer();
|
||||
|
||||
uDom('#pageSelector').on('change', pageSelectorChanged);
|
||||
uDom('#refresh').on('click', reloadTab);
|
||||
uDom('#compactViewToggler').on('click', toggleCompactView);
|
||||
uDom('#clean').on('click', cleanBuffer);
|
||||
uDom('#clear').on('click', clearBuffer);
|
||||
|
|
|
@ -1193,11 +1193,17 @@ var onMessage = function(request, sender, callback) {
|
|||
|
||||
switch ( request.what ) {
|
||||
case 'readAll':
|
||||
var tabIds = {};
|
||||
var tabIds = {}, pageStore;
|
||||
var loggerURL = vAPI.getURL('logger-ui.html');
|
||||
for ( var tabId in µb.pageStores ) {
|
||||
if ( µb.pageStores.hasOwnProperty(tabId) ) {
|
||||
tabIds[tabId] = true;
|
||||
pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) {
|
||||
continue;
|
||||
}
|
||||
if ( pageStore.rawURL.lastIndexOf(loggerURL, 0) === 0 ) {
|
||||
continue;
|
||||
}
|
||||
tabIds[tabId] = pageStore.title;
|
||||
}
|
||||
response = {
|
||||
colorBlind: µb.userSettings.colorBlindFriendly,
|
||||
|
|
|
@ -295,6 +295,8 @@ PageStore.prototype.init = function(tabId) {
|
|||
var tabContext = µb.tabContextManager.lookup(tabId);
|
||||
this.tabId = tabId;
|
||||
this.tabHostname = tabContext.rootHostname;
|
||||
this.title = tabContext.rawURL;
|
||||
this.rawURL = tabContext.rawURL;
|
||||
this.hostnameToCountMap = {};
|
||||
this.contentLastModified = 0;
|
||||
this.frames = {};
|
||||
|
@ -334,6 +336,7 @@ PageStore.prototype.reuse = function(context) {
|
|||
if ( context === 'tabUpdated' ) {
|
||||
// As part of https://github.com/chrisaljoudi/uBlock/issues/405
|
||||
// URL changed, force a re-evaluation of filtering switch
|
||||
this.rawURL = tabContext.rawURL;
|
||||
this.netFilteringReadTime = 0;
|
||||
return this;
|
||||
}
|
||||
|
@ -354,6 +357,9 @@ PageStore.prototype.dispose = function() {
|
|||
// need to release the memory taken by these, which can amount to
|
||||
// sizeable enough chunks (especially requests, through the request URL
|
||||
// used as a key).
|
||||
this.tabHostname = '';
|
||||
this.title = '';
|
||||
this.rawURL = '';
|
||||
this.hostnameToCountMap = null;
|
||||
this.disposeFrameStores();
|
||||
this.netFilteringCache = this.netFilteringCache.dispose();
|
||||
|
|
|
@ -510,9 +510,7 @@ vAPI.tabs.registerListeners();
|
|||
// Create an entry for the tab if it doesn't exist.
|
||||
|
||||
µb.bindTabToPageStats = function(tabId, context) {
|
||||
if ( vAPI.isBehindTheSceneTabId(tabId) === false ) {
|
||||
this.updateBadgeAsync(tabId);
|
||||
}
|
||||
this.updateBadgeAsync(tabId);
|
||||
|
||||
// Do not create a page store for URLs which are of no interests
|
||||
if ( µb.tabContextManager.exists(tabId) === false ) {
|
||||
|
@ -540,6 +538,8 @@ vAPI.tabs.registerListeners();
|
|||
return pageStore;
|
||||
}
|
||||
|
||||
this.updateTitle(tabId);
|
||||
|
||||
// Rebind according to context. We rebind even if the URL did not change,
|
||||
// as maybe the tab was force-reloaded, in which case the page stats must
|
||||
// be all reset.
|
||||
|
@ -570,8 +570,65 @@ vAPI.tabs.registerListeners();
|
|||
// 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');
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µb.updateTitle = (function() {
|
||||
var tabIdToTimer = Object.create(null);
|
||||
var tabIdToTryCount = Object.create(null);
|
||||
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] = setTimeout(updateTitle.bind(µb, tabId), delay);
|
||||
return true;
|
||||
};
|
||||
|
||||
var onTabReady = function(tabId, tab) {
|
||||
if ( !tab ) {
|
||||
return tryNoMore(tabId);
|
||||
}
|
||||
var pageStore = this.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) {
|
||||
return tryNoMore(tabId);
|
||||
}
|
||||
if ( !tab.title && tryAgain(tabId) ) {
|
||||
return;
|
||||
}
|
||||
tryNoMore(tabId);
|
||||
pageStore.title = tab.title || tab.url || '';
|
||||
};
|
||||
|
||||
var updateTitle = function(tabId) {
|
||||
delete tabIdToTimer[tabId];
|
||||
vAPI.tabs.get(tabId, onTabReady.bind(this, tabId));
|
||||
};
|
||||
|
||||
return function(tabId) {
|
||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
||||
return;
|
||||
}
|
||||
if ( tabIdToTimer[tabId] ) {
|
||||
clearTimeout(tabIdToTimer[tabId]);
|
||||
}
|
||||
tabIdToTimer[tabId] = setTimeout(updateTitle.bind(this, tabId), delay);
|
||||
tabIdToTryCount[tabId] = 5;
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Stale page store entries janitor
|
||||
|
@ -612,7 +669,6 @@ var pageStoreJanitor = function() {
|
|||
|
||||
setTimeout(pageStoreJanitor, pageStoreJanitorPeriod);
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
|
|
@ -9,15 +9,25 @@
|
|||
<body class="compactView f">
|
||||
|
||||
<div id="toolbar">
|
||||
<span id="compactViewToggler" class="button fa"></span>
|
||||
<span id="clean" class="button fa disabled"></span>
|
||||
<span id="clear" class="button fa disabled"></span>
|
||||
<span id="filterButton" class="button fa"></span><input id="filterInput" type="text" placeholder="logFilterPrompt">
|
||||
<input id="maxEntries" type="text" size="5" title="logMaxEntriesTip">
|
||||
<div>
|
||||
<select id="pageSelector">
|
||||
<option value="" data-i18n="logAll">
|
||||
<option value="tab_bts" data-i18n="logBehindTheScene">
|
||||
</select>
|
||||
<span id="refresh" class="button disabled fa"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span id="compactViewToggler" class="button fa"></span>
|
||||
<span id="clean" class="button fa disabled"></span>
|
||||
<span id="clear" class="button fa disabled"></span>
|
||||
<span id="filterButton" class="button fa"></span><input id="filterInput" type="text" placeholder="logFilterPrompt">
|
||||
<input id="maxEntries" type="text" size="5" title="logMaxEntriesTip">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<style></style>
|
||||
<style id="tabFilterer"></style>
|
||||
<style id="popupFilterer"></style>
|
||||
<table>
|
||||
<colgroup><col><col><col><col><col></colgroup>
|
||||
<tbody></tbody>
|
||||
|
@ -30,6 +40,7 @@
|
|||
|
||||
<div style="display: none;">
|
||||
<div id="renderedURLTemplate"><span><span></span><b></b><span></span></span></div>
|
||||
<div id="hiddenTemplate"><span style="display:none;"></span></div>
|
||||
</div>
|
||||
|
||||
<script src="js/vapi-common.js"></script>
|
||||
|
|
Loading…
Reference in New Issue