1
0
Fork 0
mirror of https://github.com/gorhill/uMatrix.git synced 2024-06-02 02:14:52 +12:00
uMatrix/src/js/pagestats.js

187 lines
6.2 KiB
JavaScript

/*******************************************************************************
uMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2013-2017 Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
/* jshint bitwise: false, boss: true */
'use strict';
/*******************************************************************************
A PageRequestStats object is used to store distinct network requests.
This is used to:
- remember which hostname/type were seen
- count the number of distinct URLs for any given hostname-type pair
**/
µMatrix.pageRequestStatsFactory = (function() {
var µm = µMatrix;
var µmuri;
var pageRequestStoreJunkyard = [];
// Ref: Given a URL, returns a (somewhat) unique 32-bit value
// Based on: FNV32a
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-reference-source
// The rest is custom, suited for µMatrix.
var uidFromURL = function(uri) {
var hint = 0x811c9dc5;
var i = uri.length;
while ( i-- ) {
hint ^= uri.charCodeAt(i) | 0;
hint += (hint<<1) + (hint<<4) + (hint<<7) + (hint<<8) + (hint<<24) | 0;
hint >>>= 0;
}
return hint;
};
var PageRequestStats = function() {
this.hostnameTypeCells = new Map();
};
PageRequestStats.prototype = {
dispose: function() {
this.hostnameTypeCells.clear();
if ( pageRequestStoreJunkyard.length < 8 ) {
pageRequestStoreJunkyard.push(this);
}
},
createEntryIfNotExists: function(url, type) {
var hn = µmuri.hostnameFromURI(url),
key = hn + ' ' + type,
uids = this.hostnameTypeCells.get(key);
if ( uids === undefined ) {
this.hostnameTypeCells.set(key, (uids = new Set()));
} else {
if ( uids.size > 99 ) { return false; }
}
var uid = uidFromURL(url);
if ( uids.has(uid) ) { return false; }
uids.add(uid);
return true;
}
};
return function pageRequestStatsFactory() {
if ( pageRequestStoreJunkyard.length !== 0 ) {
return pageRequestStoreJunkyard.pop();
}
if ( µmuri === undefined ) { µmuri = µm.URI; }
return new PageRequestStats();
};
})();
/******************************************************************************/
/******************************************************************************/
µMatrix.pageStoreFactory = (function() {
var µm = µMatrix;
var pageStoreJunkyard = [];
function PageStore(tabContext) {
this.requestStats = µm.requestStatsFactory();
this.off = false;
this.init(tabContext);
}
PageStore.prototype = {
init: function(tabContext) {
this.tabId = tabContext.tabId;
this.rawUrl = tabContext.rawURL;
this.pageUrl = tabContext.normalURL;
this.pageHostname = tabContext.rootHostname;
this.pageDomain = tabContext.rootDomain;
this.title = '';
this.requests = µm.pageRequestStatsFactory();
this.domains = {};
this.allHostnamesString = ' ';
this.requestStats.reset();
this.distinctRequestCount = 0;
this.perLoadAllowedRequestCount = 0;
this.perLoadBlockedRequestCount = 0;
this.incinerationTimer = null;
this.mtxContentModifiedTime = 0;
this.mtxCountModifiedTime = 0;
return this;
},
dispose: function() {
this.requests.dispose();
this.rawUrl = '';
this.pageUrl = '';
this.pageHostname = '';
this.pageDomain = '';
this.title = '';
this.domains = {};
this.allHostnamesString = ' ';
if ( this.incinerationTimer !== null ) {
clearTimeout(this.incinerationTimer);
this.incinerationTimer = null;
}
if ( pageStoreJunkyard.length < 8 ) {
pageStoreJunkyard.push(this);
}
},
recordRequest: function(type, url, block) {
if ( this.requests.createEntryIfNotExists(url, type) === false ) {
return;
}
// Count blocked/allowed requests
this.requestStats.record(type, block);
// https://github.com/gorhill/httpswitchboard/issues/306
// If it is recorded locally, record globally
µm.requestStats.record(type, block);
µm.updateBadgeAsync(this.tabId);
if ( block !== false ) {
this.perLoadBlockedRequestCount++;
} else {
this.perLoadAllowedRequestCount++;
}
var hostname = µm.URI.hostnameFromURI(url);
this.distinctRequestCount++;
this.mtxCountModifiedTime = Date.now();
if ( this.domains.hasOwnProperty(hostname) === false ) {
this.domains[hostname] = true;
this.allHostnamesString += hostname + ' ';
this.mtxContentModifiedTime = Date.now();
}
}
};
return function pageStoreFactory(tabContext) {
var entry = pageStoreJunkyard.pop();
if ( entry ) {
return entry.init(tabContext);
}
return new PageStore(tabContext);
};
})();
/******************************************************************************/