aboutsummaryrefslogtreecommitdiffstats
path: root/js/pagestats.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/pagestats.js')
-rw-r--r--js/pagestats.js440
1 files changed, 220 insertions, 220 deletions
diff --git a/js/pagestats.js b/js/pagestats.js
index 646bf01..276f099 100644
--- a/js/pagestats.js
+++ b/js/pagestats.js
@@ -27,248 +27,248 @@
ηMatrix.pageStoreFactory = (function() {
-/******************************************************************************/
+ /******************************************************************************/
-var ηm = ηMatrix;
+ var ηm = ηMatrix;
-/******************************************************************************/
+ /******************************************************************************/
-var BlockedCollapsibles = function() {
- this.boundPruneAsyncCallback = this.pruneAsyncCallback.bind(this);
- this.blocked = new Map();
- this.hash = 0;
- this.timer = null;
-};
-
-BlockedCollapsibles.prototype = {
-
- shelfLife: 10 * 1000,
-
- add: function(type, url, isSpecific) {
- if ( this.blocked.size === 0 ) { this.pruneAsync(); }
- var now = Date.now() / 1000 | 0;
- // The following "trick" is to encode the specifity into the lsb of the
- // time stamp so as to avoid to have to allocate a memory structure to
- // store both time stamp and specificity.
- if ( isSpecific ) {
- now |= 0x00000001;
- } else {
- now &= 0xFFFFFFFE;
- }
- this.blocked.set(type + ' ' + url, now);
- this.hash = now;
- },
-
- reset: function() {
- this.blocked.clear();
+ var BlockedCollapsibles = function() {
+ this.boundPruneAsyncCallback = this.pruneAsyncCallback.bind(this);
+ this.blocked = new Map();
this.hash = 0;
- if ( this.timer !== null ) {
- clearTimeout(this.timer);
- this.timer = null;
- }
- },
-
- pruneAsync: function() {
- if ( this.timer === null ) {
- this.timer = vAPI.setTimeout(
- this.boundPruneAsyncCallback,
- this.shelfLife * 2
- );
- }
- },
-
- pruneAsyncCallback: function() {
this.timer = null;
- var obsolete = Date.now() - this.shelfLife;
- for ( var entry of this.blocked ) {
- if ( entry[1] <= obsolete ) {
- this.blocked.delete(entry[0]);
+ };
+
+ BlockedCollapsibles.prototype = {
+
+ shelfLife: 10 * 1000,
+
+ add: function(type, url, isSpecific) {
+ if ( this.blocked.size === 0 ) { this.pruneAsync(); }
+ var now = Date.now() / 1000 | 0;
+ // The following "trick" is to encode the specifity into the lsb of the
+ // time stamp so as to avoid to have to allocate a memory structure to
+ // store both time stamp and specificity.
+ if ( isSpecific ) {
+ now |= 0x00000001;
+ } else {
+ now &= 0xFFFFFFFE;
}
- }
- if ( this.blocked.size !== 0 ) { this.pruneAsync(); }
- }
-};
-
-/******************************************************************************/
+ this.blocked.set(type + ' ' + url, now);
+ this.hash = now;
+ },
+
+ reset: function() {
+ this.blocked.clear();
+ this.hash = 0;
+ if ( this.timer !== null ) {
+ clearTimeout(this.timer);
+ this.timer = null;
+ }
+ },
+
+ pruneAsync: function() {
+ if ( this.timer === null ) {
+ this.timer = vAPI.setTimeout(
+ this.boundPruneAsyncCallback,
+ this.shelfLife * 2
+ );
+ }
+ },
-// 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 uMatrix.
-
-var PageStore = function(tabContext) {
- this.hostnameTypeCells = new Map();
- this.domains = new Set();
- this.blockedCollapsibles = new BlockedCollapsibles();
- this.requestStats = ηm.requestStatsFactory();
- this.off = false;
- this.init(tabContext);
-};
-
-PageStore.prototype = {
-
- collapsibleTypes: new Set([ 'image' ]),
- pageStoreJunkyard: [],
-
- 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.hostnameTypeCells.clear();
- this.domains.clear();
- this.allHostnamesString = ' ';
- this.blockedCollapsibles.reset();
- this.requestStats.reset();
- this.distinctRequestCount = 0;
- this.perLoadAllowedRequestCount = 0;
- this.perLoadBlockedRequestCount = 0;
- this.has3pReferrer = false;
- this.hasMixedContent = false;
- this.hasNoscriptTags = false;
- this.hasWebWorkers = false;
- this.incinerationTimer = null;
- this.mtxContentModifiedTime = 0;
- this.mtxCountModifiedTime = 0;
- return this;
- },
-
- dispose: function() {
- this.rawUrl = '';
- this.pageUrl = '';
- this.pageHostname = '';
- this.pageDomain = '';
- this.title = '';
- this.hostnameTypeCells.clear();
- this.domains.clear();
- this.allHostnamesString = ' ';
- this.blockedCollapsibles.reset();
- if ( this.incinerationTimer !== null ) {
- clearTimeout(this.incinerationTimer);
- this.incinerationTimer = null;
- }
- if ( this.pageStoreJunkyard.length < 8 ) {
- this.pageStoreJunkyard.push(this);
- }
- },
-
- cacheBlockedCollapsible: function(type, url, specificity) {
- if ( this.collapsibleTypes.has(type) ) {
- this.blockedCollapsibles.add(
- type,
- url,
- specificity !== 0 && specificity < 5
- );
+ pruneAsyncCallback: function() {
+ this.timer = null;
+ var obsolete = Date.now() - this.shelfLife;
+ for ( var entry of this.blocked ) {
+ if ( entry[1] <= obsolete ) {
+ this.blocked.delete(entry[0]);
+ }
+ }
+ if ( this.blocked.size !== 0 ) { this.pruneAsync(); }
}
- },
-
- lookupBlockedCollapsibles: function(request, response) {
- var tabContext = ηm.tabContextManager.lookup(this.tabId);
- if ( tabContext === null ) { return; }
-
- var collapseBlacklisted = ηm.userSettings.collapseBlacklisted,
- collapseBlocked = ηm.userSettings.collapseBlocked,
- entry;
-
- var blockedResources = response.blockedResources;
-
- if (
- Array.isArray(request.toFilter) &&
- request.toFilter.length !== 0
- ) {
- var roothn = tabContext.rootHostname,
- hnFromURI = ηm.URI.hostnameFromURI,
- tMatrix = ηm.tMatrix;
- for ( entry of request.toFilter ) {
- if ( tMatrix.mustBlock(roothn, hnFromURI(entry.url), entry.type) === false ) {
- continue;
+ };
+
+ /******************************************************************************/
+
+ // 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 uMatrix.
+
+ var PageStore = function(tabContext) {
+ this.hostnameTypeCells = new Map();
+ this.domains = new Set();
+ this.blockedCollapsibles = new BlockedCollapsibles();
+ this.requestStats = ηm.requestStatsFactory();
+ this.off = false;
+ this.init(tabContext);
+ };
+
+ PageStore.prototype = {
+
+ collapsibleTypes: new Set([ 'image' ]),
+ pageStoreJunkyard: [],
+
+ 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.hostnameTypeCells.clear();
+ this.domains.clear();
+ this.allHostnamesString = ' ';
+ this.blockedCollapsibles.reset();
+ this.requestStats.reset();
+ this.distinctRequestCount = 0;
+ this.perLoadAllowedRequestCount = 0;
+ this.perLoadBlockedRequestCount = 0;
+ this.has3pReferrer = false;
+ this.hasMixedContent = false;
+ this.hasNoscriptTags = false;
+ this.hasWebWorkers = false;
+ this.incinerationTimer = null;
+ this.mtxContentModifiedTime = 0;
+ this.mtxCountModifiedTime = 0;
+ return this;
+ },
+
+ dispose: function() {
+ this.rawUrl = '';
+ this.pageUrl = '';
+ this.pageHostname = '';
+ this.pageDomain = '';
+ this.title = '';
+ this.hostnameTypeCells.clear();
+ this.domains.clear();
+ this.allHostnamesString = ' ';
+ this.blockedCollapsibles.reset();
+ if ( this.incinerationTimer !== null ) {
+ clearTimeout(this.incinerationTimer);
+ this.incinerationTimer = null;
+ }
+ if ( this.pageStoreJunkyard.length < 8 ) {
+ this.pageStoreJunkyard.push(this);
+ }
+ },
+
+ cacheBlockedCollapsible: function(type, url, specificity) {
+ if ( this.collapsibleTypes.has(type) ) {
+ this.blockedCollapsibles.add(
+ type,
+ url,
+ specificity !== 0 && specificity < 5
+ );
+ }
+ },
+
+ lookupBlockedCollapsibles: function(request, response) {
+ var tabContext = ηm.tabContextManager.lookup(this.tabId);
+ if ( tabContext === null ) { return; }
+
+ var collapseBlacklisted = ηm.userSettings.collapseBlacklisted,
+ collapseBlocked = ηm.userSettings.collapseBlocked,
+ entry;
+
+ var blockedResources = response.blockedResources;
+
+ if (
+ Array.isArray(request.toFilter) &&
+ request.toFilter.length !== 0
+ ) {
+ var roothn = tabContext.rootHostname,
+ hnFromURI = ηm.URI.hostnameFromURI,
+ tMatrix = ηm.tMatrix;
+ for ( entry of request.toFilter ) {
+ if ( tMatrix.mustBlock(roothn, hnFromURI(entry.url), entry.type) === false ) {
+ continue;
+ }
+ blockedResources.push([
+ entry.type + ' ' + entry.url,
+ collapseBlocked ||
+ collapseBlacklisted && tMatrix.specificityRegister !== 0 &&
+ tMatrix.specificityRegister < 5
+ ]);
}
+ }
+
+ if ( this.blockedCollapsibles.hash === response.hash ) { return; }
+ response.hash = this.blockedCollapsibles.hash;
+
+ for ( entry of this.blockedCollapsibles.blocked ) {
blockedResources.push([
- entry.type + ' ' + entry.url,
- collapseBlocked ||
- collapseBlacklisted && tMatrix.specificityRegister !== 0 &&
- tMatrix.specificityRegister < 5
+ entry[0],
+ collapseBlocked || collapseBlacklisted && (entry[1] & 1) !== 0
]);
}
- }
-
- if ( this.blockedCollapsibles.hash === response.hash ) { return; }
- response.hash = this.blockedCollapsibles.hash;
+ },
- for ( entry of this.blockedCollapsibles.blocked ) {
- blockedResources.push([
- entry[0],
- collapseBlocked || collapseBlacklisted && (entry[1] & 1) !== 0
- ]);
- }
- },
+ recordRequest: function(type, url, block) {
+ if ( block !== false ) {
+ this.perLoadBlockedRequestCount++;
+ } else {
+ this.perLoadAllowedRequestCount++;
+ }
- recordRequest: function(type, url, block) {
- if ( block !== false ) {
- this.perLoadBlockedRequestCount++;
- } else {
- this.perLoadAllowedRequestCount++;
- }
-
- // 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
- var hostname = ηm.URI.hostnameFromURI(url),
- key = hostname + ' ' + type,
- uids = this.hostnameTypeCells.get(key);
- if ( uids === undefined ) {
- this.hostnameTypeCells.set(key, (uids = new Set()));
- } else if ( uids.size > 99 ) {
- return;
- }
- var uid = this.uidFromURL(url);
- if ( uids.has(uid) ) { return; }
- uids.add(uid);
+ // 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
+ var hostname = ηm.URI.hostnameFromURI(url),
+ key = hostname + ' ' + type,
+ uids = this.hostnameTypeCells.get(key);
+ if ( uids === undefined ) {
+ this.hostnameTypeCells.set(key, (uids = new Set()));
+ } else if ( uids.size > 99 ) {
+ return;
+ }
+ var uid = this.uidFromURL(url);
+ if ( uids.has(uid) ) { return; }
+ uids.add(uid);
- // Count blocked/allowed requests
- this.requestStats.record(type, block);
+ // 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);
+ // https://github.com/gorhill/httpswitchboard/issues/306
+ // If it is recorded locally, record globally
+ ηm.requestStats.record(type, block);
+ ηm.updateBadgeAsync(this.tabId);
- // this.distinctRequestCount++;
- this.mtxCountModifiedTime = Date.now();
+ // this.distinctRequestCount++;
+ this.mtxCountModifiedTime = Date.now();
- if ( this.domains.has(hostname) === false ) {
- this.domains.add(hostname);
- this.allHostnamesString += hostname + ' ';
- this.mtxContentModifiedTime = Date.now();
- }
- },
-
- uidFromURL: function(uri) {
- var hint = 0x811c9dc5,
- i = uri.length;
- while ( i-- ) {
- hint ^= uri.charCodeAt(i) | 0;
- hint += (hint<<1) + (hint<<4) + (hint<<7) + (hint<<8) + (hint<<24) | 0;
- hint >>>= 0;
+ if ( this.domains.has(hostname) === false ) {
+ this.domains.add(hostname);
+ this.allHostnamesString += hostname + ' ';
+ this.mtxContentModifiedTime = Date.now();
+ }
+ },
+
+ uidFromURL: function(uri) {
+ var hint = 0x811c9dc5,
+ 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;
}
- return hint;
- }
-};
+ };
-/******************************************************************************/
+ /******************************************************************************/
-return function pageStoreFactory(tabContext) {
- var entry = PageStore.prototype.pageStoreJunkyard.pop();
- if ( entry ) {
- return entry.init(tabContext);
- }
- return new PageStore(tabContext);
-};
+ return function pageStoreFactory(tabContext) {
+ var entry = PageStore.prototype.pageStoreJunkyard.pop();
+ if ( entry ) {
+ return entry.init(tabContext);
+ }
+ return new PageStore(tabContext);
+ };
-/******************************************************************************/
+ /******************************************************************************/
})();