Browse Source

a bit of refacotring work

pull/2/head
gorhill 10 years ago
parent
commit
257844c233
  1. 2
      src/js/background.js
  2. 21
      src/js/pagestats.js
  3. 10
      src/js/start.js
  4. 129
      src/js/tab.js
  5. 2
      src/js/uritools.js

2
src/js/background.js

@ -101,7 +101,7 @@ return {
// urls stats are kept on the back burner while waiting to be reactivated // urls stats are kept on the back burner while waiting to be reactivated
// in a tab or another. // in a tab or another.
pageStats: {},
pageStats: {}, // TODO: rename
// A map of redirects, to allow reverse lookup of redirects from landing // A map of redirects, to allow reverse lookup of redirects from landing
// page, so that redirection can be reported to the user. // page, so that redirection can be reported to the user.

21
src/js/pagestats.js

@ -269,18 +269,18 @@ var makeRequestKey = function(uri, reqType) {
} }
var key = typeToCode[reqType] || 'z'; var key = typeToCode[reqType] || 'z';
return key + return key +
String.fromCharCode(hint >>> 16, hint & 0xFFFF) +
String.fromCharCode(hint >>> 22, hint >>> 12 & 0x3FF, hint & 0xFFF) +
stringPacker.pack(µmuri.hostnameFromURI(uri)); stringPacker.pack(µmuri.hostnameFromURI(uri));
}; };
/******************************************************************************/ /******************************************************************************/
var rememberRequestKey = function(reqKey) { var rememberRequestKey = function(reqKey) {
stringPacker.remember(reqKey.slice(3));
stringPacker.remember(reqKey.slice(4));
}; };
var forgetRequestKey = function(reqKey) { var forgetRequestKey = function(reqKey) {
stringPacker.forget(reqKey.slice(3));
stringPacker.forget(reqKey.slice(4));
}; };
/******************************************************************************/ /******************************************************************************/
@ -288,7 +288,7 @@ var forgetRequestKey = function(reqKey) {
// Exported // Exported
var hostnameFromRequestKey = function(reqKey) { var hostnameFromRequestKey = function(reqKey) {
return stringPacker.unpack(reqKey.slice(3));
return stringPacker.unpack(reqKey.slice(4));
}; };
PageRequestStats.prototype.hostnameFromRequestKey = hostnameFromRequestKey; PageRequestStats.prototype.hostnameFromRequestKey = hostnameFromRequestKey;
@ -436,7 +436,6 @@ var pageStoreFactory = function(pageUrl) {
/******************************************************************************/ /******************************************************************************/
function PageStore(pageUrl) { function PageStore(pageUrl) {
this.visible = false;
this.requestStats = new WebRequestStats(); this.requestStats = new WebRequestStats();
this.off = false; this.off = false;
this.init(pageUrl); this.init(pageUrl);
@ -458,6 +457,8 @@ PageStore.prototype.init = function(pageUrl) {
this.distinctRequestCount = 0; this.distinctRequestCount = 0;
this.perLoadAllowedRequestCount = 0; this.perLoadAllowedRequestCount = 0;
this.perLoadBlockedRequestCount = 0; this.perLoadBlockedRequestCount = 0;
this.boundCount = 0;
this.obsoleteAfter = 0;
return this; return this;
}; };
@ -465,18 +466,12 @@ PageStore.prototype.init = function(pageUrl) {
PageStore.prototype.dispose = function() { PageStore.prototype.dispose = function() {
this.requests.dispose(); this.requests.dispose();
// rhill 2013-11-07: Even though at init time these are reset, I still
// 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.pageUrl = ''; this.pageUrl = '';
this.pageHostname = ''; this.pageHostname = '';
this.pageDomain = ''; this.pageDomain = '';
this.domains = {}; this.domains = {};
this.allHostnamesString = ' '; this.allHostnamesString = ' ';
this.state = {}; this.state = {};
if ( pageStoreJunkyard.length < 8 ) { if ( pageStoreJunkyard.length < 8 ) {
pageStoreJunkyard.push(this); pageStoreJunkyard.push(this);
} }
@ -487,7 +482,7 @@ PageStore.prototype.dispose = function() {
PageStore.prototype.recordRequest = function(type, url, block) { PageStore.prototype.recordRequest = function(type, url, block) {
// TODO: this makes no sense, I forgot why I put this here. // TODO: this makes no sense, I forgot why I put this here.
if ( !this ) { if ( !this ) {
// console.error('HTTP Switchboard> PageStore.recordRequest(): no pageStats');
// console.error('pagestats.js > PageStore.recordRequest(): no pageStats');
return; return;
} }
@ -541,7 +536,7 @@ PageStore.prototype.recordRequest = function(type, url, block) {
} }
µm.urlStatsChanged(this.pageUrl); µm.urlStatsChanged(this.pageUrl);
// console.debug("HTTP Switchboard> PageStore.recordRequest(): %o: %s @ %s", this, type, url);
// console.debug("pagestats.js > PageStore.recordRequest(): %o: %s @ %s", this, type, url);
}; };
/******************************************************************************/ /******************************************************************************/

10
src/js/start.js

@ -29,9 +29,13 @@
// normal way forbid binding behind the scene tab. // normal way forbid binding behind the scene tab.
// https://github.com/gorhill/httpswitchboard/issues/67 // https://github.com/gorhill/httpswitchboard/issues/67
µMatrix.createPageStats(µMatrix.behindTheSceneURL);
µMatrix.pageUrlToTabId[µMatrix.behindTheSceneURL] = µMatrix.behindTheSceneTabId;
µMatrix.tabIdToPageUrl[µMatrix.behindTheSceneTabId] = µMatrix.behindTheSceneURL;
(function() {
var µm = µMatrix;
var pageStore = µm.createPageStore(µm.behindTheSceneURL);
µm.pageUrlToTabId[µm.behindTheSceneURL] = µm.behindTheSceneTabId;
µm.tabIdToPageUrl[µm.behindTheSceneTabId] = µm.behindTheSceneURL;
pageStore.boundCount += 1;
})();
/******************************************************************************/ /******************************************************************************/

129
src/js/tab.js

@ -25,27 +25,34 @@
// Create a new page url stats store (if not already present) // Create a new page url stats store (if not already present)
µMatrix.createPageStats = function(pageUrl) {
µMatrix.createPageStore = function(pageURL) {
// https://github.com/gorhill/httpswitchboard/issues/303 // https://github.com/gorhill/httpswitchboard/issues/303
// At this point, the URL has been page-URL-normalized // At this point, the URL has been page-URL-normalized
// do not create stats store for urls which are of no interest // do not create stats store for urls which are of no interest
if ( pageUrl.search(/^https?:\/\//) !== 0 ) {
return undefined;
if ( pageURL.search(/^https?/) !== 0 ) {
return;
} }
var pageStats = this.pageStats[pageUrl];
if ( !pageStats ) {
pageStats = this.PageStore.factory(pageUrl);
var pageStore = null;
if ( this.pageStats.hasOwnProperty(pageURL) ) {
pageStore = this.pageStats[pageURL];
}
if ( pageStore === null ) {
pageStore = this.PageStore.factory(pageURL);
// These counters are used so that icon presents an overview of how // These counters are used so that icon presents an overview of how
// much allowed/blocked. // much allowed/blocked.
pageStats.perLoadAllowedRequestCount =
pageStats.perLoadBlockedRequestCount = 0;
this.pageStats[pageUrl] = pageStats;
} else if ( pageStats.pageUrl !== pageUrl ) {
pageStats.init(pageUrl);
pageStore.perLoadAllowedRequestCount =
pageStore.perLoadBlockedRequestCount = 0;
this.pageStats[pageURL] = pageStore;
} }
return pageStats;
// TODO: revisit code, need to account for those web pages for which the
// URL changes with the content only updated
if ( pageStore.pageUrl !== pageURL ) {
pageStore.init(pageURL);
}
return pageStore;
}; };
/******************************************************************************/ /******************************************************************************/
@ -54,7 +61,7 @@
// Some kind of trick going on here: // Some kind of trick going on here:
// Any scheme other than 'http' and 'https' is remapped into a fake // Any scheme other than 'http' and 'https' is remapped into a fake
// URL which trick the rest of µMatrix into being able to process an // URL which trick the rest of µMatrix into being able to process an
// otherwise unmanageable scheme. µMatrix needs web page to have a proper
// otherwise unmanageable scheme. µMatrix needs web pages to have a proper
// hostname to work properly, so just like the 'chromium-behind-the-scene' // hostname to work properly, so just like the 'chromium-behind-the-scene'
// fake domain name, we map unknown schemes into a fake '{scheme}-scheme' // fake domain name, we map unknown schemes into a fake '{scheme}-scheme'
// hostname. This way, for a specific scheme you can create scope with // hostname. This way, for a specific scheme you can create scope with
@ -89,15 +96,19 @@
// Normalize to a page-URL. // Normalize to a page-URL.
pageURL = this.normalizePageURL(pageURL); pageURL = this.normalizePageURL(pageURL);
var pageStats = this.createPageStats(pageURL);
if ( this.tabIdToPageUrl[tabId] === pageURL ) {
return this.pageStats[pageURL];
}
var pageStore = this.createPageStore(pageURL);
// console.debug('tab.js > µMatrix.bindTabToPageStats(): dispatching traffic in tab id %d to url stats store "%s"', tabId, pageUrl);
// console.debug('tab.js > bindTabToPageStats(): dispatching traffic in tab id %d to page store "%s"', tabId, pageUrl);
// rhill 2013-11-24: Never ever rebind chromium-behind-the-scene // rhill 2013-11-24: Never ever rebind chromium-behind-the-scene
// virtual tab. // virtual tab.
// https://github.com/gorhill/httpswitchboard/issues/67 // https://github.com/gorhill/httpswitchboard/issues/67
if ( tabId === this.behindTheSceneTabId ) { if ( tabId === this.behindTheSceneTabId ) {
return pageStats;
return pageStore;
} }
this.unbindTabFromPageStats(tabId); this.unbindTabFromPageStats(tabId);
@ -105,23 +116,33 @@
// rhill 2014-02-08: Do not create an entry if no page store // rhill 2014-02-08: Do not create an entry if no page store
// exists (like when visiting about:blank) // exists (like when visiting about:blank)
// https://github.com/gorhill/httpswitchboard/issues/186 // https://github.com/gorhill/httpswitchboard/issues/186
if ( !pageStats ) {
if ( !pageStore ) {
return null; return null;
} }
pageStats.visible = true;
this.pageUrlToTabId[pageURL] = tabId; this.pageUrlToTabId[pageURL] = tabId;
this.tabIdToPageUrl[tabId] = pageURL; this.tabIdToPageUrl[tabId] = pageURL;
pageStore.boundCount += 1;
return pageStats;
return pageStore;
}; };
/******************************************************************************/
µMatrix.unbindTabFromPageStats = function(tabId) { µMatrix.unbindTabFromPageStats = function(tabId) {
var pageUrl = this.tabIdToPageUrl[tabId];
if ( pageUrl ) {
delete this.pageUrlToTabId[pageUrl];
if ( this.tabIdToPageUrl.hasOwnProperty(tabId) === false ) {
return;
}
var pageURL = this.tabIdToPageUrl[tabId];
if ( this.pageStats.hasOwnProperty(pageURL) ) {
var pageStore = this.pageStats[pageURL];
pageStore.boundCount -= 1;
if ( pageStore.boundCount === 0 ) {
pageStore.obsoleteAfter = Date.now() + (5 * 60 * 60 * 1000);
}
} }
delete this.tabIdToPageUrl[tabId]; delete this.tabIdToPageUrl[tabId];
delete this.pageUrlToTabId[pageURL];
}; };
/******************************************************************************/ /******************************************************************************/
@ -355,59 +376,43 @@
// Garbage collect stale url stats entries // Garbage collect stale url stats entries
(function() { (function() {
var gcOrphanPageStats = function(tabs) {
var µm = µMatrix; var µm = µMatrix;
var visibleTabs = {};
tabs.map(function(tab) {
visibleTabs[tab.id] = true;
});
var pageUrls = Object.keys(µm.pageStats);
var i = pageUrls.length;
var pageUrl, tabId, pageStats;
while ( i-- ) {
pageUrl = pageUrls[i];
// Do not dispose of chromium-behind-the-scene virtual tab,
// GC is done differently on this one (i.e. just pruning).
if ( pageUrl === µm.behindTheSceneURL ) {
var gcPageStats = function() {
var pageStore;
var now = Date.now();
for ( var pageURL in µm.pageStats ) {
if ( µm.pageStats.hasOwnProperty(pageURL) === false ) {
continue; continue;
} }
tabId = µm.tabIdFromPageUrl(pageUrl);
pageStats = µm.pageStats[pageUrl];
if ( !visibleTabs[tabId] && !pageStats.visible ) {
// console.debug('HTTP Switchboard> tab.js: page stats garbage collector letting go of "%s"', pageUrl);
µm.cookieHunter.removePageCookies(pageStats);
µm.pageStats[pageUrl].dispose();
delete µm.pageStats[pageUrl];
pageStore = µm.pageStats[pageURL];
if ( pageStore.boundCount !== 0 ) {
continue;
} }
pageStats.visible = !!visibleTabs[tabId];
if ( !pageStats.visible ) {
µm.unbindTabFromPageStats(tabId);
if ( pageStore.obsoleteAfter > now ) {
continue;
} }
µm.cookieHunter.removePageCookies(pageStore);
µm.pageStats[pageURL].dispose();
delete µm.pageStats[pageURL];
} }
};
var gcPageStats = function() {
var µm = µMatrix;
// Get rid of stale pageStats, those not bound to a tab for more than
// {duration placeholder}.
chrome.tabs.query({ 'url': '<all_urls>' }, gcOrphanPageStats);
// Prune content of chromium-behind-the-scene virtual tab // Prune content of chromium-behind-the-scene virtual tab
// When `suggest-as-you-type` is on in Chromium, this can lead to a // When `suggest-as-you-type` is on in Chromium, this can lead to a
// LOT of uninteresting behind the scene requests. // LOT of uninteresting behind the scene requests.
var pageStats = µm.pageStats[µm.behindTheSceneURL];
if ( pageStats ) {
var reqKeys = pageStats.requests.getRequestKeys();
if ( reqKeys.length > µm.behindTheSceneMaxReq ) {
pageStore = µm.pageStats[µm.behindTheSceneURL];
if ( !pageStore ) {
return;
}
var reqKeys = pageStore.requests.getRequestKeys();
if ( reqKeys.length <= µm.behindTheSceneMaxReq ) {
return;
}
reqKeys = reqKeys.sort(function(a,b){ reqKeys = reqKeys.sort(function(a,b){
return pageStats.requests[b] - pageStats.requests[a];
return pageStore.requests[b] - pageStore.requests[a];
}).slice(µm.behindTheSceneMaxReq); }).slice(µm.behindTheSceneMaxReq);
var iReqKey = reqKeys.length; var iReqKey = reqKeys.length;
while ( iReqKey-- ) { while ( iReqKey-- ) {
pageStats.requests.disposeOne(reqKeys[iReqKey]);
}
}
pageStore.requests.disposeOne(reqKeys[iReqKey]);
} }
}; };
@ -417,7 +422,7 @@
'gcPageStats', 'gcPageStats',
null, null,
gcPageStats, gcPageStats,
8 * 60 * 1000,
5 * 60 * 1000,
true true
); );
})(); })();

2
src/js/uritools.js

@ -227,7 +227,7 @@ URI.assemble = function(bits) {
URI.schemeFromURI = function(uri) { URI.schemeFromURI = function(uri) {
var matches = reSchemeFromURI.exec(uri); var matches = reSchemeFromURI.exec(uri);
if ( !matches ) {
if ( matches === null ) {
return ''; return '';
} }
return matches[0].slice(0, -1).toLowerCase(); return matches[0].slice(0, -1).toLowerCase();

Loading…
Cancel
Save