mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-02 02:14:52 +12:00
one pulling if needed is better than always pushing to many + polishing logger
This commit is contained in:
parent
1d8243583c
commit
af57d6d9e7
|
@ -141,9 +141,19 @@ body.compactView #content td {
|
|||
content: '\f070';
|
||||
font: 1em FontAwesome;
|
||||
}
|
||||
body:not(.popupOn) #content table tr.cat_net td:nth-of-type(2) {
|
||||
#content table tr.tab:not(.canMtx) {
|
||||
opacity: 0.2;
|
||||
}
|
||||
#content table tr.tab:not(.canMtx) > td:nth-of-type(2):before {
|
||||
content: '\f00d';
|
||||
font: 1em FontAwesome;
|
||||
}
|
||||
body:not(.popupOn) #content table tr.canMtx td:nth-of-type(2) {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
body:not(.popupOn) #content table tr.canMtx td:nth-of-type(2):hover {
|
||||
background: white;
|
||||
}
|
||||
#content table tr.cat_net td:nth-of-type(3) {
|
||||
font: 12px monospace;
|
||||
text-align: center;
|
||||
|
@ -172,6 +182,8 @@ body.popupOn #popupContainer {
|
|||
}
|
||||
#popupContainer > div {
|
||||
background: #444;
|
||||
border: 0;
|
||||
border-bottom: 1px solid white;
|
||||
cursor: -webkit-grab;
|
||||
cursor: grab;
|
||||
height: 2em;
|
||||
|
|
|
@ -172,22 +172,3 @@ return asyncJobManager;
|
|||
tabIdToTimer[tabId] = setTimeout(updateBadge.bind(this, tabId), 500);
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Notify whoever care that url stats have changed (they need to
|
||||
// rebuild their matrix).
|
||||
|
||||
µMatrix.urlStatsChanged = function(pageUrl) {
|
||||
// rhill 2013-11-17: No point in sending this message if the popup menu
|
||||
// does not exist. I suspect this could be related to
|
||||
// https://github.com/gorhill/httpswitchboard/issues/58
|
||||
var urlStatsChangedCallback = function(pageUrl) {
|
||||
vAPI.messaging.broadcast({
|
||||
what: 'urlStatsChanged',
|
||||
pageURL: pageUrl
|
||||
});
|
||||
};
|
||||
|
||||
this.asyncJobs.add('urlStatsChanged-' + pageUrl, pageUrl, urlStatsChangedCallback, 1000);
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@ var firstVarDataCol = 2; // currently, column 2 (0-based index)
|
|||
var lastVarDataIndex = 3; // currently, d0-d3
|
||||
var maxEntries = 5000;
|
||||
var noTabId = '';
|
||||
var allTabIds = {};
|
||||
|
||||
var prettyRequestTypes = {
|
||||
'main_frame': 'doc',
|
||||
|
@ -167,6 +168,8 @@ var createRow = function(layout) {
|
|||
var createGap = function(tabId, url) {
|
||||
var tr = createRow('1');
|
||||
tr.classList.add('doc');
|
||||
tr.classList.add('tab');
|
||||
tr.classList.add('canMtx');
|
||||
tr.classList.add('tab_' + tabId);
|
||||
tr.cells[firstVarDataCol].textContent = url;
|
||||
tbody.insertBefore(tr, tbody.firstChild);
|
||||
|
@ -187,6 +190,7 @@ var renderLogEntry = function(entry) {
|
|||
|
||||
case 'net':
|
||||
tr = createRow('111');
|
||||
tr.classList.add('canMtx');
|
||||
// If the request is that of a root frame, insert a gap in the table
|
||||
// in order to visually separate entries for different documents.
|
||||
if ( entry.d2 === 'doc' && entry.tab !== noTabId ) {
|
||||
|
@ -213,10 +217,13 @@ var renderLogEntry = function(entry) {
|
|||
tr.cells[0].textContent = time.toLocaleTimeString('fullwide', timeOptions);
|
||||
tr.cells[0].title = time.toLocaleDateString('fullwide', dateOptions);
|
||||
|
||||
if ( entry.tab === noTabId ) {
|
||||
tr.classList.add('tab_bts');
|
||||
} else if ( entry.tab !== '' ) {
|
||||
tr.classList.add('tab_' + entry.tab);
|
||||
if ( entry.tab ) {
|
||||
tr.classList.add('tab');
|
||||
if ( entry.tab === noTabId ) {
|
||||
tr.classList.add('tab_bts');
|
||||
} else if ( entry.tab !== '' ) {
|
||||
tr.classList.add('tab_' + entry.tab);
|
||||
}
|
||||
}
|
||||
if ( entry.cat !== '' ) {
|
||||
tr.classList.add('cat_' + entry.cat);
|
||||
|
@ -233,8 +240,6 @@ var renderLogBuffer = function(response) {
|
|||
return;
|
||||
}
|
||||
|
||||
noTabId = response.noTabId;
|
||||
|
||||
// Preserve scroll position
|
||||
var height = tbody.offsetHeight;
|
||||
|
||||
|
@ -276,7 +281,7 @@ var truncateLog = function(size) {
|
|||
if ( size === 0 ) {
|
||||
size = 5000;
|
||||
}
|
||||
size = Math.min(size, 5000);
|
||||
size = Math.min(size, 10000);
|
||||
var tr;
|
||||
while ( tbody.childElementCount > size ) {
|
||||
tr = tbody.lastElementChild;
|
||||
|
@ -286,13 +291,38 @@ var truncateLog = function(size) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var onBufferRead = function(response) {
|
||||
var onLogBufferRead = function(response) {
|
||||
// This tells us the behind-the-scene tab id
|
||||
noTabId = response.noTabId;
|
||||
|
||||
// This may have changed meanwhile
|
||||
if ( response.maxLoggedRequests !== maxEntries ) {
|
||||
maxEntries = response.maxLoggedRequests;
|
||||
uDom('#maxEntries').val(maxEntries || '');
|
||||
}
|
||||
|
||||
// Neuter rows for which a tab does not exist anymore
|
||||
// TODO: sort to avoid using indexOf
|
||||
var targetTabId;
|
||||
var i = allTabIds.length;
|
||||
while ( i-- ) {
|
||||
targetTabId = allTabIds[i];
|
||||
if ( targetTabId === noTabId ) {
|
||||
continue;
|
||||
}
|
||||
if ( response.allTabIds.indexOf(targetTabId) !== -1 ) {
|
||||
continue;
|
||||
}
|
||||
uDom('.tab_' + targetTabId).removeClass('canMtx');
|
||||
// Close popup if it is currently inspecting this tab
|
||||
if ( targetTabId === popupManager.tabId ) {
|
||||
popupManager.toggleOff();
|
||||
}
|
||||
}
|
||||
allTabIds = response.allTabIds;
|
||||
|
||||
renderLogBuffer(response);
|
||||
setTimeout(readLogBuffer, 1000);
|
||||
setTimeout(readLogBuffer, 1200);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -302,7 +332,7 @@ var onBufferRead = function(response) {
|
|||
// require a bit more code to ensure no multi time out events.
|
||||
|
||||
var readLogBuffer = function() {
|
||||
messager.send({ what: 'readMany' }, onBufferRead);
|
||||
messager.send({ what: 'readMany' }, onLogBufferRead);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -326,7 +356,7 @@ var toggleCompactView = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var togglePopup = (function() {
|
||||
var popupManager = (function() {
|
||||
var realTabId = null;
|
||||
var localTabId = null;
|
||||
var container = null;
|
||||
|
@ -337,7 +367,7 @@ var togglePopup = (function() {
|
|||
var styleTemplate = [
|
||||
'tr:not(.tab_{{tabId}}) {',
|
||||
'cursor: not-allowed;',
|
||||
'opacity: 0.1;',
|
||||
'opacity: 0.2;',
|
||||
'}'
|
||||
].join('\n');
|
||||
|
||||
|
@ -511,11 +541,24 @@ var togglePopup = (function() {
|
|||
realTabId = null;
|
||||
};
|
||||
|
||||
return function(ev) {
|
||||
if ( realTabId === null ) {
|
||||
toggleOn(ev.target);
|
||||
var exports = {
|
||||
toggleOn: function(ev) {
|
||||
if ( realTabId === null ) {
|
||||
toggleOn(ev.target);
|
||||
}
|
||||
},
|
||||
toggleOff: function() {
|
||||
if ( realTabId !== null ) {
|
||||
toggleOff();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(exports, 'tabId', {
|
||||
get: function() { return realTabId || 0; }
|
||||
});
|
||||
|
||||
return exports;
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -548,7 +591,7 @@ uDom.onLoad(function() {
|
|||
uDom('#compactViewToggler').on('click', toggleCompactView);
|
||||
uDom('#clear').on('click', clearBuffer);
|
||||
uDom('#maxEntries').on('change', onMaxEntriesChanged);
|
||||
uDom('#content table').on('click', 'tr.cat_net > td:nth-of-type(2)', togglePopup);
|
||||
uDom('#content table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -178,7 +178,7 @@ var writeOne = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var readAll = function(tabId) {
|
||||
var readAll = function() {
|
||||
if ( logBuffer === null ) {
|
||||
logBuffer = new LogBuffer();
|
||||
setTimeout(janitor, logBufferObsoleteAfter);
|
||||
|
|
|
@ -138,21 +138,23 @@ RowSnapshot.counts = (function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var matrixSnapshot = function(tabId, details) {
|
||||
var matrixSnapshot = function(pageStore, details) {
|
||||
var µmuser = µm.userSettings;
|
||||
var r = {
|
||||
tabId: tabId,
|
||||
url: '',
|
||||
hostname: '',
|
||||
domain: '',
|
||||
blockedCount: 0,
|
||||
scope: '*',
|
||||
blockedCount: pageStore.requestStats.blocked.all,
|
||||
diff: [],
|
||||
domain: pageStore.pageDomain,
|
||||
headers: µm.Matrix.getColumnHeaders(),
|
||||
tSwitches: {},
|
||||
hostname: pageStore.pageHostname,
|
||||
mtxContentModifiedTime: pageStore.mtxContentModifiedTime,
|
||||
mtxCountModifiedTime: pageStore.mtxCountModifiedTime,
|
||||
pSwitches: {},
|
||||
rows: {},
|
||||
rowCount: 0,
|
||||
diff: [],
|
||||
scope: '*',
|
||||
tabId: pageStore.tabId,
|
||||
tSwitches: {},
|
||||
url: pageStore.pageUrl,
|
||||
userSettings: {
|
||||
colorBlindFriendly: µmuser.colorBlindFriendly,
|
||||
displayTextSize: µmuser.displayTextSize,
|
||||
|
@ -163,28 +165,8 @@ var matrixSnapshot = function(tabId, details) {
|
|||
}
|
||||
};
|
||||
|
||||
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||
|
||||
// Allow examination of behind-the-scene requests
|
||||
if (
|
||||
tabContext.rawURL.lastIndexOf(vAPI.getURL('dashboard.html'), 0) === 0 ||
|
||||
tabContext.rawURL === µm.behindTheSceneURL
|
||||
) {
|
||||
tabId = vAPI.noTabId;
|
||||
}
|
||||
|
||||
var pageStore = µm.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) {
|
||||
return r;
|
||||
}
|
||||
|
||||
var headers = r.headers;
|
||||
|
||||
r.url = pageStore.pageUrl;
|
||||
r.hostname = pageStore.pageHostname;
|
||||
r.domain = pageStore.pageDomain;
|
||||
r.blockedCount = pageStore.requestStats.blocked.all;
|
||||
|
||||
if ( µmuser.popupScopeLevel === 'site' ) {
|
||||
r.scope = r.hostname;
|
||||
} else if ( µmuser.popupScopeLevel === 'domain' ) {
|
||||
|
@ -269,16 +251,46 @@ var matrixSnapshot = function(tabId, details) {
|
|||
/******************************************************************************/
|
||||
|
||||
var matrixSnapshotFromTabId = function(details, callback) {
|
||||
var matrixSnapshotIf = function(tabId, details) {
|
||||
var pageStore = µm.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) {
|
||||
callback('ENOTFOUND');
|
||||
return;
|
||||
}
|
||||
|
||||
// First verify whether we must return data or not.
|
||||
if (
|
||||
pageStore.mtxContentModifiedTime === details.mtxContentModifiedTime &&
|
||||
pageStore.mtxCountModifiedTime === details.mtxCountModifiedTime
|
||||
) {
|
||||
callback('ENOCHANGE');
|
||||
return ;
|
||||
}
|
||||
|
||||
callback(matrixSnapshot(pageStore, details));
|
||||
};
|
||||
|
||||
// Specific tab id requested?
|
||||
if ( details.tabId ) {
|
||||
callback(matrixSnapshot(details.tabId, details));
|
||||
matrixSnapshotIf(details.tabId, details);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise use tab id of current tab
|
||||
vAPI.tabs.get(null, function(tab) {
|
||||
callback(matrixSnapshot(tab.id, details));
|
||||
});
|
||||
// Fall back to currently active tab
|
||||
var onTabReady = function(tab) {
|
||||
if ( typeof tab !== 'object' ) {
|
||||
callback('ENOTFOUND');
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow examination of behind-the-scene requests
|
||||
var tabId = tab.url.lastIndexOf(vAPI.getURL('dashboard.html'), 0) !== 0 ?
|
||||
tab.id :
|
||||
vAPI.noTabId;
|
||||
matrixSnapshotIf(tabId, details);
|
||||
};
|
||||
|
||||
vAPI.tabs.get(null, onTabReady);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -962,9 +974,10 @@ var onMessage = function(request, sender, callback) {
|
|||
case 'readMany':
|
||||
response = {
|
||||
colorBlind: false,
|
||||
entries: µm.logger.readAll(request.tabId),
|
||||
entries: µm.logger.readAll(),
|
||||
maxLoggedRequests: µm.userSettings.maxLoggedRequests,
|
||||
noTabId: vAPI.noTabId
|
||||
noTabId: vAPI.noTabId,
|
||||
allTabIds: Object.keys(µm.pageStores)
|
||||
};
|
||||
break;
|
||||
|
||||
|
|
|
@ -344,6 +344,8 @@ PageStore.prototype.init = function(tabContext) {
|
|||
this.perLoadAllowedRequestCount = 0;
|
||||
this.perLoadBlockedRequestCount = 0;
|
||||
this.incinerationTimer = null;
|
||||
this.mtxContentModifiedTime = 0;
|
||||
this.mtxCountModifiedTime = 0;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
@ -397,12 +399,14 @@ PageStore.prototype.recordRequest = function(type, url, block) {
|
|||
}
|
||||
|
||||
this.distinctRequestCount++;
|
||||
this.mtxCountModifiedTime = Date.now();
|
||||
|
||||
if ( this.domains.hasOwnProperty(hostname) === false ) {
|
||||
this.domains[hostname] = true;
|
||||
this.allHostnamesString += hostname + ' ';
|
||||
this.mtxContentModifiedTime = Date.now();
|
||||
}
|
||||
|
||||
µm.urlStatsChanged(this.pageUrl);
|
||||
// console.debug("pagestats.js > PageStore.recordRequest(): %o: %s @ %s", this, type, url);
|
||||
};
|
||||
|
||||
|
|
100
src/js/popup.js
100
src/js/popup.js
|
@ -67,22 +67,7 @@ var matrixHeaderPrettyNames = {
|
|||
var firstPartyLabel = '';
|
||||
var blacklistedHostnamesLabel = '';
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/httpswitchboard/issues/345
|
||||
|
||||
var onMessage = function(msg) {
|
||||
if ( msg.what !== 'urlStatsChanged' ) {
|
||||
return;
|
||||
}
|
||||
if ( matrixSnapshot.url !== msg.pageURL ) {
|
||||
return;
|
||||
}
|
||||
queryMatrixSnapshot(makeMenu);
|
||||
};
|
||||
|
||||
var messager = vAPI.messaging.channel('popup.js', onMessage);
|
||||
var messager = vAPI.messaging.channel('popup.js');
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
@ -108,7 +93,7 @@ function updateMatrixSnapshot() {
|
|||
updateMatrixBehavior();
|
||||
updateMatrixButtons();
|
||||
};
|
||||
queryMatrixSnapshot(snapshotReady);
|
||||
matrixSnapshotPoller.mustFetch(snapshotReady);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -1177,35 +1162,80 @@ var onMatrixSnapshotReady = function(response) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var queryMatrixSnapshot = function(callback) {
|
||||
var tabId = matrixSnapshot.tabId;
|
||||
var matrixSnapshotPoller = (function() {
|
||||
var timer = null;
|
||||
|
||||
// If no tab id yet, see if there is one specified in our URL
|
||||
if ( tabId === undefined ) {
|
||||
var matches = window.location.search.match(/(?:\?|&)tabId=([^&]+)/);
|
||||
if ( matches !== null ) {
|
||||
tabId = matches[1];
|
||||
var snapshotPolled = function(response) {
|
||||
timer = null;
|
||||
if ( typeof response === 'object' ) {
|
||||
matrixSnapshot = response;
|
||||
makeMenu();
|
||||
}
|
||||
}
|
||||
pollSnapshotAsync();
|
||||
};
|
||||
|
||||
var request = {
|
||||
what: 'matrixSnapshot',
|
||||
tabId: tabId,
|
||||
tabURL: matrixSnapshot.url
|
||||
var pollSnapshot = function() {
|
||||
timer = null;
|
||||
messager.send({
|
||||
what: 'matrixSnapshot',
|
||||
tabId: matrixSnapshot.tabId,
|
||||
mtxContentModifiedTime: matrixSnapshot.mtxContentModifiedTime,
|
||||
mtxCountModifiedTime: matrixSnapshot.mtxCountModifiedTime
|
||||
}, snapshotPolled);
|
||||
};
|
||||
var snapshotReceived = function(response) {
|
||||
matrixSnapshot = response;
|
||||
callback();
|
||||
|
||||
var pollSnapshotAsync = function() {
|
||||
if ( timer !== null ) {
|
||||
return;
|
||||
}
|
||||
timer = setTimeout(pollSnapshot, 1414);
|
||||
};
|
||||
messager.send(request, snapshotReceived);
|
||||
};
|
||||
|
||||
var cancelSnapshotAsync = function() {
|
||||
if ( timer !== null ) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
};
|
||||
|
||||
var mustFetch = function(callback) {
|
||||
cancelSnapshotAsync();
|
||||
|
||||
var tabId = matrixSnapshot.tabId;
|
||||
|
||||
// If no tab id yet, see if there is one specified in our URL
|
||||
if ( tabId === undefined ) {
|
||||
var matches = window.location.search.match(/(?:\?|&)tabId=([^&]+)/);
|
||||
if ( matches !== null ) {
|
||||
tabId = matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
var snapshotFetched = function(response) {
|
||||
if ( typeof response === 'object' ) {
|
||||
matrixSnapshot = response;
|
||||
}
|
||||
callback();
|
||||
pollSnapshotAsync();
|
||||
};
|
||||
|
||||
messager.send({
|
||||
what: 'matrixSnapshot',
|
||||
tabId: tabId
|
||||
}, snapshotFetched);
|
||||
};
|
||||
|
||||
return {
|
||||
mustFetch: mustFetch
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Make menu only when popup html is fully loaded
|
||||
|
||||
uDom.onLoad(function() {
|
||||
queryMatrixSnapshot(onMatrixSnapshotReady);
|
||||
matrixSnapshotPoller.mustFetch(onMatrixSnapshotReady);
|
||||
|
||||
// Below is UI stuff which is not key to make the menu, so this can
|
||||
// be done without having to wait for a tab to be bound to the menu.
|
||||
|
|
Loading…
Reference in a new issue