uBlock/js/pagestore.js

238 lines
7.5 KiB
JavaScript
Raw Normal View History

2014-06-23 16:42:43 -06:00
/*******************************************************************************
µBlock - a Chromium browser extension to block requests.
Copyright (C) 2014 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/uBlock
*/
/* global µBlock */
2014-06-23 16:42:43 -06:00
/*******************************************************************************
A PageRequestStore object is used to store net requests in two ways:
To record distinct net requests
To create a log of net requests
**/
/******************************************************************************/
/******************************************************************************/
µBlock.PageStore = (function() {
/******************************************************************************/
var µb = µBlock;
var frameStoreJunkyard = [];
2014-06-23 16:42:43 -06:00
var pageStoreJunkyard = [];
/******************************************************************************/
var frameStoreFactory = function(frameURL) {
var entry = frameStoreJunkyard.pop();
if ( entry ) {
return entry.init(frameURL);
}
return new FrameStore(frameURL);
};
var disposeFrameStores = function(map) {
for ( var k in map ) {
if ( map.hasOwnProperty(k) === false ) {
continue;
}
if ( frameStoreJunkyard.length > 50 ) {
break;
}
frameStoreJunkyard.push(map[k].dispose());
}
return {};
};
/******************************************************************************/
var FrameStore = function(frameURL) {
this.init(frameURL);
};
/******************************************************************************/
FrameStore.prototype.init = function(frameURL) {
var µburi = µb.URI;
this.pageHostname = µburi.hostnameFromURI(frameURL);
this.pageDomain = µburi.domainFromHostname(this.pageHostname);
return this;
};
/******************************************************************************/
FrameStore.prototype.dispose = function() {
this.pageHostname = this.pageDomain = '';
return this;
};
/******************************************************************************/
2014-06-23 16:42:43 -06:00
var pageStoreFactory = function(tabId, pageURL) {
var entry = pageStoreJunkyard.pop();
if ( entry ) {
return entry.init(tabId, pageURL);
}
return new PageStore(tabId, pageURL);
};
/******************************************************************************/
var PageStore = function(tabId, pageURL) {
2014-06-23 16:42:43 -06:00
this.init(tabId, pageURL);
};
2014-06-23 16:42:43 -06:00
/******************************************************************************/
PageStore.prototype.init = function(tabId, pageURL) {
this.tabId = tabId;
2014-07-14 09:24:59 -06:00
this.previousPageURL = '';
this.pageURL = pageURL;
this.pageHostname = µb.URI.hostnameFromURI(pageURL);
2014-08-27 00:01:10 -06:00
// https://github.com/gorhill/uBlock/issues/185
// Use hostname if no domain can be extracted
this.pageDomain = µb.URI.domainFromHostname(this.pageHostname) || this.pageHostname;
this.frames = disposeFrameStores(this.frames);
2014-08-02 09:40:27 -06:00
this.netFiltering = true;
this.netFilteringReadTime = 0;
2014-07-14 09:24:59 -06:00
this.perLoadBlockedRequestCount = 0;
this.perLoadAllowedRequestCount = 0;
this.blockedRequests = {};
this.allowedRequests = {};
this.disposeTime = 0;
return this;
};
/******************************************************************************/
PageStore.prototype.reuse = function(pageURL) {
2014-08-02 09:40:27 -06:00
var previousPageURL = this.pageURL;
this.init(this.tabId, pageURL);
this.previousPageURL = previousPageURL;
2014-06-23 16:42:43 -06:00
return this;
};
/******************************************************************************/
PageStore.prototype.dispose = function() {
// 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.pageHostname = '';
this.pageDomain = '';
2014-07-06 17:14:32 -06:00
if ( pageStoreJunkyard.length < 8 ) {
2014-06-23 16:42:43 -06:00
pageStoreJunkyard.push(this);
}
};
/******************************************************************************/
PageStore.prototype.addFrame = function(frameId, frameURL) {
var frameStore = this.frames[frameId];
if ( frameStore === undefined ) {
this.frames[frameId] = frameStore = frameStoreFactory(frameURL);
//console.debug('µBlock> PageStore.addFrame(%d, "%s")', frameId, frameURL);
}
return frameStore;
};
/******************************************************************************/
PageStore.prototype.getFrame = function(frameId) {
return this.frames[frameId];
};
/******************************************************************************/
2014-08-02 09:40:27 -06:00
PageStore.prototype.getNetFilteringSwitch = function() {
if ( this.netFilteringReadTime < µb.netWhitelistModifyTime ) {
this.netFiltering = µb.getNetFilteringSwitch(this.pageURL, this.pageDomain);
this.netFilteringReadTime = Date.now();
}
return this.netFiltering;
};
/******************************************************************************/
2014-07-02 10:02:29 -06:00
PageStore.prototype.recordRequest = function(type, url, reason) {
2014-07-06 17:14:32 -06:00
var blocked = reason !== false && reason.slice(0, 2) !== '@@';
2014-06-23 16:42:43 -06:00
2014-07-06 17:14:32 -06:00
if ( !blocked ) {
2014-06-23 16:42:43 -06:00
this.perLoadAllowedRequestCount++;
µb.localSettings.allowedRequestCount++;
2014-07-06 17:14:32 -06:00
if ( µb.userSettings.logAllowedRequests ) {
this.allowedRequests[url] = type + '\t' + (reason || '');
}
2014-06-27 15:06:42 -06:00
return;
2014-06-23 16:42:43 -06:00
}
2014-06-27 15:06:42 -06:00
2014-07-06 17:14:32 -06:00
µb.updateBadgeAsync(this.tabId);
2014-06-27 15:06:42 -06:00
this.perLoadBlockedRequestCount++;
µb.localSettings.blockedRequestCount++;
// https://github.com/gorhill/uBlock/issues/7
// https://github.com/gorhill/uBlock/issues/12
2014-07-03 06:28:15 -06:00
// No need to record blocked requests which are not image or frame, as
// these are the only ones we try to hide when they are blocked.
if ( µb.userSettings.logBlockedRequests === false ) {
if ( type === 'image' || type === 'sub_frame' ) {
this.blockedRequests[url] = true;
}
return;
}
this.blockedRequests[url] = type + '\t' + reason;
2014-06-23 16:42:43 -06:00
};
/******************************************************************************/
PageStore.prototype.updateBadge = function() {
2014-08-02 09:40:27 -06:00
var netFiltering = this.getNetFilteringSwitch();
var iconPaths = netFiltering ?
2014-09-03 19:18:36 -06:00
{ '19': 'img/browsericons/icon19.png', '38': 'img/browsericons/icon38.png' } :
{ '19': 'img/browsericons/icon19-off.png', '38': 'img/browsericons/icon38-off.png' };
2014-06-23 16:42:43 -06:00
var iconStr = '';
2014-08-02 09:40:27 -06:00
if ( µb.userSettings.showIconBadge && netFiltering && this.perLoadBlockedRequestCount ) {
iconStr = µb.utils.formatCount(this.perLoadBlockedRequestCount);
2014-06-23 16:42:43 -06:00
}
µb.XAL.setIcon(this.tabId, iconPaths, iconStr);
2014-06-23 16:42:43 -06:00
};
// https://www.youtube.com/watch?v=drW8p_dTLD4
2014-06-23 16:42:43 -06:00
/******************************************************************************/
return {
factory: pageStoreFactory
};
})();
/******************************************************************************/