diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index fba1a25..3a745bc 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -176,6 +176,7 @@ vAPI.tabs.registerListeners = function() { var reGoodForWebRequestAPI = /^https?:\/\//; var onCreatedNavigationTarget = function(details) { + details.tabId = details.tabId.toString(); //console.debug('onCreatedNavigationTarget: popup candidate tab id %d = "%s"', details.tabId, details.url); if ( reGoodForWebRequestAPI.test(details.url) === false ) { details.frameId = 0; @@ -190,10 +191,12 @@ vAPI.tabs.registerListeners = function() { return; } //console.debug('onBeforeNavigate: popup candidate tab id %d = "%s"', details.tabId, details.url); + details.tabId = details.tabId.toString(); popupCandidateTest(details); }; var onUpdated = function(tabId, changeInfo, tab) { + tabId = tabId.toString(); if ( changeInfo.url && popupCandidateTest({ tabId: tabId, url: changeInfo.url }) ) { return; } @@ -204,6 +207,7 @@ vAPI.tabs.registerListeners = function() { if ( details.frameId !== 0 ) { return; } + details.tabId = details.tabId.toString(); onNavigationClient(details); //console.debug('onCommitted: popup candidate tab id %d = "%s"', details.tabId, details.url); if ( popupCandidateTest(details) === true ) { @@ -231,9 +235,10 @@ 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 + if ( tab instanceof Object ) { + tab.id = tab.id.toString(); + } callback(tab); }; if ( tabId !== null ) { @@ -246,9 +251,13 @@ vAPI.tabs.get = function(tabId, callback) { var onTabReceived = function(tabs) { // https://code.google.com/p/chromium/issues/detail?id=410868#c8 if ( chrome.runtime.lastError ) { - /* noop */ } - callback(tabs[0]); + var tab = null; + if ( Array.isArray(tabs) && tabs.length !== 0 ) { + tab = tabs[0]; + tab.id = tab.id.toString(); + } + callback(tab); }; chrome.tabs.query({ active: true, currentWindow: true }, onTabReceived); }; @@ -256,7 +265,16 @@ vAPI.tabs.get = function(tabId, callback) { /******************************************************************************/ vAPI.tabs.getAll = function(callback) { - chrome.tabs.query({ url: '' }, callback); + var onTabsReady = function(tabs) { + if ( Array.isArray(tabs) ) { + var i = tabs.length; + while ( i-- ) { + tabs[i].id = tabs[i].id.toString(); + } + } + callback(tabs); + }; + chrome.tabs.query({ url: '' }, onTabsReady); }; /******************************************************************************/ @@ -714,7 +732,6 @@ vAPI.net.registerListeners = function() { // If no transposition possible, transpose to `object` as per // Chromium bug 410382 (see below) if ( pos === -1 ) { - details.type = 'object'; return; } @@ -729,8 +746,6 @@ vAPI.net.registerListeners = function() { details.type = 'image'; return; } - // https://code.google.com/p/chromium/issues/detail?id=410382 - details.type = 'object'; }; // <<<<<<<< // End of: Normalizing request types diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 6a94af9..fd4e72d 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -109,15 +109,23 @@ }, "matrixSwitchNoMixedContent" : { "message": "Strict HTTPS", - "description": "" + "description": "A menu entry in the matrix popup" }, "matrixSwitchUASpoof" : { "message": "User agent spoofing", - "description": "" + "description": "A menu entry in the matrix popup" }, "matrixSwitchReferrerSpoof" : { "message": "Referrer spoofing", - "description": "" + "description": "A menu entry in the matrix popup" + }, + "matrixLoggerMenuEntry" : { + "message": "Request log", + "description": "A menu entry in the matrix popup" + }, + "matrixDashboardMenuEntry" : { + "message": "Dashboard", + "description": "A menu entry in the matrix popup" }, diff --git a/src/background.html b/src/background.html index f873fc8..9722274 100644 --- a/src/background.html +++ b/src/background.html @@ -22,6 +22,7 @@ + @@ -30,6 +31,7 @@ + diff --git a/src/css/popup.css b/src/css/popup.css index 653a45b..a88ce41 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -120,7 +120,7 @@ body[dir="rtl"] #mtxSwitches > li > span:before { display: none; font-size: 110%; padding: 3px 0 0 0; - position: absolute; + position: fixed; white-space: normal; z-index: 50; } @@ -203,9 +203,6 @@ body #buttonRevertAll > span:nth-of-type(4) { bottom: 3px; } -button { - position: relative; - } button > span.badge { padding: 1px 1px; display: inline-block; @@ -302,10 +299,9 @@ body .toolbar button#scopeCell { } body #scopeCell + .dropdown-menu { padding: 6px 1px 3px 1px; - left: 0; - right: 0; text-align: right; - width: 16em; + min-width: 50%; + max-width: 80%; } body.tScopeGlobal #scopeCell { background-color: #000; diff --git a/src/dashboard.html b/src/dashboard.html index e3c3f73..d30823c 100644 --- a/src/dashboard.html +++ b/src/dashboard.html @@ -83,7 +83,6 @@ iframe { - diff --git a/src/js/background.js b/src/js/background.js index 3c00487..d606d3e 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -116,7 +116,6 @@ return { // record what chromium is doing behind the scene behindTheSceneURL: 'http://behind-the-scene/', - behindTheSceneTabId: vAPI.noTabId, behindTheSceneMaxReq: 250, behindTheSceneScope: 'behind-the-scene', diff --git a/src/js/cookies.js b/src/js/cookies.js index f9e3fcf..01097f6 100644 --- a/src/js/cookies.js +++ b/src/js/cookies.js @@ -294,11 +294,12 @@ var chromeCookieRemove = function(url, name) { } var cookieKey = cookieKeyFromCookieURL(details.url, 'session', details.name); if ( removeCookieFromDict(cookieKey) ) { + µm.logger.writeOne('', 'info', 'cookie deleted: ' + cookieKey); µm.cookieRemovedCounter += 1; - return; } cookieKey = cookieKeyFromCookieURL(details.url, 'persistent', details.name); if ( removeCookieFromDict(cookieKey) ) { + µm.logger.writeOne('', 'info', 'cookie deleted: ' + cookieKey); µm.cookieRemovedCounter += 1; } }; diff --git a/src/js/logger.js b/src/js/logger.js index 05c34ef..20e6164 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -31,18 +31,18 @@ /******************************************************************************/ /******************************************************************************/ -var LogEntry = function(tabId, details, result) { - this.init(tabId, details, result); +var LogEntry = function(args) { + this.init(args); }; /******************************************************************************/ -var logEntryFactory = function(tabId, details, result) { +var logEntryFactory = function(args) { var entry = logEntryJunkyard.pop(); if ( entry ) { - return entry.init(tabId, details, result); + return entry.init(args); } - return new LogEntry(tabId, details, result); + return new LogEntry(args); }; var logEntryJunkyard = []; @@ -50,13 +50,14 @@ var logEntryJunkyardMax = 100; /******************************************************************************/ -LogEntry.prototype.init = function(tabId, details, result) { +LogEntry.prototype.init = function(args) { this.tstamp = Date.now(); - this.tabId = tabId; - this.url = details.requestURL; - this.hostname = details.requestHostname; - this.type = details.requestType; - this.result = result; + this.tab = args[0] || ''; + this.cat = args[1] || ''; + this.d0 = args[2]; + this.d1 = args[3]; + this.d2 = args[4]; + this.d3 = args[5]; return this; }; @@ -97,13 +98,13 @@ LogBuffer.prototype.dispose = function() { /******************************************************************************/ -LogBuffer.prototype.writeOne = function(tabId, details, result) { +LogBuffer.prototype.writeOne = function(args) { // Reusing log entry = less memory churning var entry = this.buffer[this.writePtr]; if ( entry instanceof LogEntry === false ) { - this.buffer[this.writePtr] = logEntryFactory(tabId, details, result); + this.buffer[this.writePtr] = logEntryFactory(args); } else { - entry.init(tabId, details, result); + entry.init(args); } this.writePtr += 1; if ( this.writePtr === this.size ) { @@ -156,11 +157,11 @@ var loggerJanitorPeriod = 2 * 60 * 1000; /******************************************************************************/ -var writeOne = function(tabId, details, result) { +var writeOne = function() { if ( logBuffer === null ) { return; } - logBuffer.writeOne(tabId, details, result); + logBuffer.writeOne(arguments); }; /******************************************************************************/ diff --git a/src/js/messaging.js b/src/js/messaging.js index 33d3565..2bc0c83 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -170,7 +170,7 @@ var matrixSnapshot = function(tabId, details) { tabContext.rawURL.lastIndexOf(vAPI.getURL('dashboard.html'), 0) === 0 || tabContext.rawURL === µm.behindTheSceneURL ) { - tabId = µm.behindTheSceneTabId; + tabId = vAPI.noTabId; } var pageStore = µm.pageStoreFromTabId(tabId); @@ -491,7 +491,7 @@ var evaluateURLs = function(tabId, requests) { /******************************************************************************/ var tagNameToRequestTypeMap = { - 'iframe': 'sub_frame', + 'iframe': 'frame', 'img': 'image' }; @@ -816,54 +816,6 @@ var getTabURLs = function() { /******************************************************************************/ -// map(pageURL) => array of request log entries - -var getRequestLog = function(tabId) { - var requestLogs = {}; - var pageStores = µm.pageStores; - var tabIds = tabId ? [tabId] : Object.keys(pageStores); - var pageStore, pageURL, pageRequestLog, logEntries, j, logEntry; - - for ( var i = 0; i < tabIds.length; i++ ) { - pageStore = pageStores[tabIds[i]]; - if ( !pageStore ) { - continue; - } - pageURL = pageStore.pageUrl; - pageRequestLog = []; - logEntries = pageStore.requests.getLoggedRequests(); - j = logEntries.length; - while ( j-- ) { - // rhill 2013-12-04: `logEntry` can be null since a ring buffer is - // now used, and it might not have been filled yet. - if ( logEntry = logEntries[j] ) { - pageRequestLog.push(logEntry); - } - } - requestLogs[pageURL] = pageRequestLog; - } - - return requestLogs; -}; - -/******************************************************************************/ - -var clearRequestLog = function(tabId) { - var pageStores = µm.pageStores; - var tabIds = tabId ? [tabId] : Object.keys(pageStores); - var pageStore; - - for ( var i = 0; i < tabIds.length; i++ ) { - pageStore = pageStores[tabIds[i]]; - if ( !pageStore ) { - continue; - } - pageStore.requests.clearLogBuffer(); - } -}; - -/******************************************************************************/ - var onMessage = function(request, sender, callback) { // Async switch ( request.what ) { @@ -893,14 +845,6 @@ var onMessage = function(request, sender, callback) { }; break; - case 'getRequestLogs': - response = getRequestLog(request.tabId); - break; - - case 'clearRequestLogs': - clearRequestLog(request.tabId); - break; - default: return vAPI.messaging.UNHANDLED; } @@ -1004,6 +948,52 @@ vAPI.messaging.listen('about.js', onMessage); /******************************************************************************/ /******************************************************************************/ +// logger-ui.js + +(function() { + +'use strict'; + +/******************************************************************************/ + +var µm = µMatrix; + +/******************************************************************************/ + +var onMessage = function(request, sender, callback) { + // Async + switch ( request.what ) { + default: + break; + } + + // Sync + var response; + + switch ( request.what ) { + case 'readMany': + response = { + colorBlind: false, + entries: µm.logger.readAll(request.tabId) + }; + break; + + default: + return vAPI.messaging.UNHANDLED; + } + + callback(response); +}; + +vAPI.messaging.listen('logger-ui.js', onMessage); + +/******************************************************************************/ + +})(); + +/******************************************************************************/ +/******************************************************************************/ + })(); /******************************************************************************/ diff --git a/src/js/pagestats.js b/src/js/pagestats.js index 93c9082..47a7c4e 100644 --- a/src/js/pagestats.js +++ b/src/js/pagestats.js @@ -27,7 +27,6 @@ A PageRequestStore object is used to store net requests in two ways: To record distinct net requests -To create a log of net requests **/ @@ -152,37 +151,8 @@ var stringPacker = { /******************************************************************************/ -var LogEntry = function() { - this.url = ''; - this.type = ''; - this.when = 0; - this.block = false; -}; - -var logEntryJunkyard = []; - -LogEntry.prototype.dispose = function() { - this.url = this.type = ''; - // Let's not grab and hold onto too much memory.. - if ( logEntryJunkyard.length < 200 ) { - logEntryJunkyard.push(this); - } -}; - -var logEntryFactory = function() { - var entry = logEntryJunkyard.pop(); - if ( entry ) { - return entry; - } - return new LogEntry(); -}; - -/******************************************************************************/ - var PageRequestStats = function() { this.requests = {}; - this.ringBuffer = null; - this.ringBufferPointer = 0; if ( !µmuri ) { µmuri = µm.URI; } @@ -205,7 +175,6 @@ var pageRequestStoreFactory = function() { } else { pageRequestStore = new PageRequestStats(); } - pageRequestStore.resizeLogBuffer(µm.userSettings.maxLoggedRequests); return pageRequestStore; }; @@ -229,16 +198,6 @@ PageRequestStats.prototype.dispose = function() { stringPacker.forget(reqKey.slice(3)); } this.requests = {}; - var i = this.ringBuffer.length; - var logEntry; - while ( i-- ) { - logEntry = this.ringBuffer[i]; - if ( logEntry ) { - logEntry.dispose(); - } - } - this.ringBuffer = []; - this.ringBufferPointer = 0; if ( pageRequestStoreJunkyard.length < 8 ) { pageRequestStoreJunkyard.push(this); } @@ -313,100 +272,6 @@ PageRequestStats.prototype.createEntryIfNotExists = function(url, type) { /******************************************************************************/ -PageRequestStats.prototype.resizeLogBuffer = function(size) { - if ( !this.ringBuffer ) { - this.ringBuffer = new Array(0); - this.ringBufferPointer = 0; - } - if ( size === this.ringBuffer.length ) { - return; - } - if ( !size ) { - this.ringBuffer = new Array(0); - this.ringBufferPointer = 0; - return; - } - var newBuffer = new Array(size); - var copySize = Math.min(size, this.ringBuffer.length); - var newBufferPointer = (copySize % size) | 0; - var isrc = this.ringBufferPointer; - var ides = newBufferPointer; - while ( copySize-- ) { - isrc--; - if ( isrc < 0 ) { - isrc = this.ringBuffer.length - 1; - } - ides--; - if ( ides < 0 ) { - ides = size - 1; - } - newBuffer[ides] = this.ringBuffer[isrc]; - } - this.ringBuffer = newBuffer; - this.ringBufferPointer = newBufferPointer; -}; - -/******************************************************************************/ - -PageRequestStats.prototype.clearLogBuffer = function() { - var buffer = this.ringBuffer; - if ( buffer === null ) { - return; - } - var logEntry; - var i = buffer.length; - while ( i-- ) { - if ( logEntry = buffer[i] ) { - logEntry.dispose(); - buffer[i] = null; - } - } - this.ringBufferPointer = 0; -}; - -/******************************************************************************/ - -PageRequestStats.prototype.logRequest = function(url, type, block) { - var buffer = this.ringBuffer; - var len = buffer.length; - if ( !len ) { - return; - } - var pointer = this.ringBufferPointer; - if ( !buffer[pointer] ) { - buffer[pointer] = logEntryFactory(); - } - var logEntry = buffer[pointer]; - logEntry.url = url; - logEntry.type = type; - logEntry.when = Date.now(); - logEntry.block = block; - this.ringBufferPointer = ((pointer + 1) % len) | 0; -}; - -/******************************************************************************/ - -PageRequestStats.prototype.getLoggedRequests = function() { - var buffer = this.ringBuffer; - if ( !buffer.length ) { - return []; - } - // [0 - pointer] = most recent - // [pointer - length] = least recent - // thus, ascending order: - // [pointer - length] + [0 - pointer] - var pointer = this.ringBufferPointer; - return buffer.slice(pointer).concat(buffer.slice(0, pointer)).reverse(); -}; - -/******************************************************************************/ - -PageRequestStats.prototype.getLoggedRequestEntry = function(reqURL, reqType) { - return this.requests[makeRequestKey(reqURL, reqType)]; -}; - -/******************************************************************************/ - PageRequestStats.prototype.getRequestKeys = function() { return Object.keys(this.requests); }; @@ -520,7 +385,7 @@ PageStore.prototype.recordRequest = function(type, url, block) { this.perLoadAllowedRequestCount++; } - this.requests.logRequest(url, type, block); + µm.logger.writeOne(this.tabId, 'net', block ? '---' : '', type, url); if ( !this.requests.createEntryIfNotExists(url, type, block) ) { return; diff --git a/src/js/popup.js b/src/js/popup.js index bb1db40..f96745e 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -1031,12 +1031,13 @@ function updateMatrixSwitches() { uDom('body').toggleClass('powerOff', switches['matrix-off']); } -function toggleMatrixSwitch() { - var pos = this.id.indexOf('_'); +function toggleMatrixSwitch(ev) { + var elem = ev.currentTarget; + var pos = elem.id.indexOf('_'); if ( pos === -1 ) { return; } - var switchName = this.id.slice(pos + 1); + var switchName = elem.id.slice(pos + 1); var request = { what: 'toggleMatrixSwitch', switchName: switchName, @@ -1113,8 +1114,8 @@ function buttonReloadHandler() { /******************************************************************************/ -function mouseenterMatrixCellHandler() { - matrixCellHotspots.appendTo(this); +function mouseenterMatrixCellHandler(ev) { + matrixCellHotspots.appendTo(ev.target); } function mouseleaveMatrixCellHandler() { @@ -1123,8 +1124,8 @@ function mouseleaveMatrixCellHandler() { /******************************************************************************/ -function gotoExtensionURL() { - var url = uDom(this).attr('data-extension-url'); +function gotoExtensionURL(ev) { + var url = uDom(ev.currentTarget).attr('data-extension-url'); if ( url ) { messager.send({ what: 'gotoExtensionURL', url: url }); } @@ -1133,8 +1134,16 @@ function gotoExtensionURL() { /******************************************************************************/ -function dropDownMenuShow() { - uDom(this).next('.dropdown-menu').addClass('show'); +function dropDownMenuShow(ev) { + var button = ev.target; + var menu = button.nextElementSibling; + var butnRect = button.getBoundingClientRect(); + var viewRect = document.body.getBoundingClientRect(); + var butnNormalLeft = butnRect.left / (viewRect.width - butnRect.width); + menu.classList.add('show'); + var menuRect = menu.getBoundingClientRect(); + var menuLeft = butnNormalLeft * (viewRect.width - menuRect.width); + menu.style.left = menuLeft.toFixed(0) + 'px'; } function dropDownMenuHide() { diff --git a/src/js/start.js b/src/js/start.js index 611d122..8a8b2d2 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -44,24 +44,6 @@ var µm = µMatrix; /******************************************************************************/ -// Browser data jobs - -var jobCallback = function() { - if ( !µm.userSettings.clearBrowserCache ) { - return; - } - µm.clearBrowserCacheCycle -= 15; - if ( µm.clearBrowserCacheCycle > 0 ) { - return; - } - µm.clearBrowserCacheCycle = µm.userSettings.clearBrowserCacheAfter; - µm.browserCacheClearedCounter++; - vAPI.browserCache.clearByTime(0); - // console.debug('clearBrowserCacheCallback()> vAPI.browserCache.clearByTime() called'); -}; - -/******************************************************************************/ - var defaultLocalUserSettings = { placeholderBackground: [ 'linear-gradient(0deg,', @@ -78,7 +60,7 @@ var defaultLocalUserSettings = { 'rgba(0,0,0,0.05) 75%,', 'rgba(0,0,0,0.02) 75%,', 'rgba(0,0,0,0.02)', - ') center center / 10px 10px repeat scroll' + ') #fff center center / 10px 10px repeat scroll' ].join(''), placeholderBorder: '1px solid rgba(0, 0, 0, 0.05)', placeholderDocument: [ @@ -110,8 +92,6 @@ var onAllDone = function() { µm.assetUpdater.onAssetUpdated.addListener(µm.assetUpdatedHandler.bind(µm)); µm.assets.onAssetCacheRemoved.addListener(µm.assetCacheRemovedHandler.bind(µm)); - µMatrix.asyncJobs.add('clearBrowserCache', null, jobCallback, 15 * 60 * 1000, true); - // Important: remove barrier to remote fetching, this was useful only // for launch time. µm.assets.remoteFetchBarrier -= 1; diff --git a/src/js/storage.js b/src/js/storage.js index c5b11a4..72972e4 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -55,9 +55,6 @@ µm.userSettings = store; - // https://github.com/gorhill/uMatrix/issues/47 - µm.resizeLogBuffers(store.maxLoggedRequests); - // https://github.com/gorhill/httpswitchboard/issues/344 µm.userAgentSpoofer.shuffle(); diff --git a/src/js/tab.js b/src/js/tab.js index 13c631c..7d6e9cd 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -620,17 +620,6 @@ vAPI.tabs.registerListeners(); /******************************************************************************/ -µm.resizeLogBuffers = function(size) { - var pageStores = this.pageStores; - for ( var pageURL in pageStores ) { - if ( pageStores.hasOwnProperty(pageURL) ) { - pageStores[pageURL].requests.resizeLogBuffer(size); - } - } -}; - -/******************************************************************************/ - µm.forceReload = function(tabId) { vAPI.tabs.reload(tabId, { bypassCache: true }); }; diff --git a/src/js/usersettings.js b/src/js/usersettings.js index 2452a22..585a739 100644 --- a/src/js/usersettings.js +++ b/src/js/usersettings.js @@ -38,10 +38,6 @@ // Pre-change switch ( name ) { - case 'maxLoggedRequests': - value = Math.max(Math.min(value, 500), 0); - break; - default: break; } @@ -52,10 +48,6 @@ // Post-change switch ( name ) { - case 'maxLoggedRequests': - this.resizeLogBuffers(value); - break; - // https://github.com/gorhill/httpswitchboard/issues/344 case 'spoofUserAgentWith': this.userAgentSpoofer.shuffle(); diff --git a/src/popup.html b/src/popup.html index ca5520d..6df014c 100644 --- a/src/popup.html +++ b/src/popup.html @@ -20,7 +20,7 @@
-