Browse Source

this fixes #489

pull/2/head
gorhill 9 years ago
parent
commit
e9e1f7e631
  1. 1
      src/background.html
  2. 174
      src/js/async.js
  3. 79
      src/js/cookies.js
  4. 47
      src/js/tab.js
  5. 11
      src/js/useragent.js

1
src/background.html

@ -13,7 +13,6 @@
<script src="js/background.js"></script> <script src="js/background.js"></script>
<script src="js/xal.js"></script> <script src="js/xal.js"></script>
<script src="js/usersettings.js"></script> <script src="js/usersettings.js"></script>
<script src="js/async.js"></script>
<script src="js/liquid-dict.js"></script> <script src="js/liquid-dict.js"></script>
<script src="js/matrix.js"></script> <script src="js/matrix.js"></script>
<script src="js/utils.js"></script> <script src="js/utils.js"></script>

174
src/js/async.js

@ -1,174 +0,0 @@
/*******************************************************************************
µMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2013 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
*/
/* global chrome, µMatrix */
/******************************************************************************/
// Async job queue module
µMatrix.asyncJobs = (function() {
var processJobs = function() {
asyncJobManager.process();
};
var AsyncJobEntry = function(name) {
this.name = name;
this.data = null;
this.callback = null;
this.when = 0;
this.period = 0;
};
AsyncJobEntry.prototype.destroy = function() {
this.name = '';
this.data = null;
this.callback = null;
};
var AsyncJobManager = function() {
this.timeResolution = 200;
this.jobs = {};
this.jobCount = 0;
this.jobJunkyard = [];
this.timerId = null;
this.timerWhen = Number.MAX_VALUE;
};
AsyncJobManager.prototype.restartTimer = function() {
var when = Number.MAX_VALUE;
var jobs = this.jobs, job;
for ( var jobName in jobs ) {
job = jobs[jobName];
if ( job instanceof AsyncJobEntry ) {
if ( job.when < when ) {
when = job.when;
}
}
}
// Quantize time value
when = Math.floor((when + this.timeResolution - 1) / this.timeResolution) * this.timeResolution;
if ( when < this.timerWhen ) {
clearTimeout(this.timerId);
this.timerWhen = when;
this.timerId = vAPI.setTimeout(processJobs, Math.max(when - Date.now(), 10));
}
};
AsyncJobManager.prototype.add = function(name, data, callback, delay, recurrent) {
var job = this.jobs[name];
if ( !job ) {
job = this.jobJunkyard.pop();
if ( !job ) {
job = new AsyncJobEntry(name);
} else {
job.name = name;
}
this.jobs[name] = job;
this.jobCount++;
}
job.data = data;
job.callback = callback;
job.when = Date.now() + delay;
job.period = recurrent ? delay : 0;
this.restartTimer();
};
AsyncJobManager.prototype.process = function() {
this.timerId = null;
this.timerWhen = Number.MAX_VALUE;
var now = Date.now();
var job;
for ( var jobName in this.jobs ) {
if ( this.jobs.hasOwnProperty(jobName) === false ) {
continue;
}
job = this.jobs[jobName];
if ( job.when > now ) {
continue;
}
job.callback(job.data);
if ( job.period ) {
job.when = now + job.period;
} else {
delete this.jobs[jobName];
job.destroy();
this.jobCount--;
this.jobJunkyard.push(job);
}
}
this.restartTimer();
};
// Only one instance
var asyncJobManager = new AsyncJobManager();
// Publish
return asyncJobManager;
})();
/******************************************************************************/
// Update badge
// rhill 2013-11-09: well this sucks, I can't update icon/badge
// incrementally, as chromium overwrite the icon at some point without
// notifying me, and this causes internal cached state to be out of sync.
µMatrix.updateBadgeAsync = (function() {
var tabIdToTimer = Object.create(null);
var updateBadge = function(tabId) {
delete tabIdToTimer[tabId];
var iconId = null;
var badgeStr = '';
var pageStore = this.pageStoreFromTabId(tabId);
if ( pageStore !== null ) {
var total = pageStore.perLoadAllowedRequestCount +
pageStore.perLoadBlockedRequestCount;
if ( total ) {
var squareSize = 19;
var greenSize = squareSize * Math.sqrt(pageStore.perLoadAllowedRequestCount / total);
iconId = greenSize < squareSize/2 ? Math.ceil(greenSize) : Math.floor(greenSize);
}
if ( this.userSettings.iconBadgeEnabled && pageStore.distinctRequestCount !== 0) {
badgeStr = this.formatCount(pageStore.distinctRequestCount);
}
}
vAPI.setIcon(tabId, iconId, badgeStr);
};
return function(tabId) {
if ( tabIdToTimer[tabId] ) {
return;
}
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
return;
}
tabIdToTimer[tabId] = vAPI.setTimeout(updateBadge.bind(this, tabId), 500);
};
})();

79
src/js/cookies.js

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µMatrix - a Chromium browser extension to black/white list requests. µMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2013 Raymond Hill
Copyright (C) 2013-2106 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -35,6 +35,8 @@
µMatrix.cookieHunter = (function() { µMatrix.cookieHunter = (function() {
"use strict";
/******************************************************************************/ /******************************************************************************/
var µm = µMatrix; var µm = µMatrix;
@ -44,6 +46,10 @@ var removePageCookiesQueue = {};
var removeCookieQueue = {}; var removeCookieQueue = {};
var cookieDict = {}; var cookieDict = {};
var cookieEntryJunkyard = []; var cookieEntryJunkyard = [];
var processRemoveQueuePeriod = 2 * 60 * 1000;
var processCleanPeriod = 10 * 60 * 1000;
var processPageRecordQueueTimer = null;
var processPageRemoveQueueTimer = null;
/******************************************************************************/ /******************************************************************************/
@ -198,13 +204,9 @@ var recordPageCookiesAsync = function(pageStats) {
return; return;
} }
recordPageCookiesQueue[pageStats.pageUrl] = pageStats; recordPageCookiesQueue[pageStats.pageUrl] = pageStats;
µm.asyncJobs.add(
'cookieHunterPageRecord',
null,
processPageRecordQueue,
1000,
false
);
if ( processPageRecordQueueTimer === null ) {
processPageRecordQueueTimer = vAPI.setTimeout(processPageRecordQueue, 1000);
}
}; };
/******************************************************************************/ /******************************************************************************/
@ -267,13 +269,9 @@ var removePageCookiesAsync = function(pageStats) {
return; return;
} }
removePageCookiesQueue[pageStats.pageUrl] = pageStats; removePageCookiesQueue[pageStats.pageUrl] = pageStats;
µm.asyncJobs.add(
'cookieHunterPageRemove',
null,
processPageRemoveQueue,
15 * 1000,
false
);
if ( processPageRemoveQueueTimer === null ) {
processPageRemoveQueueTimer = vAPI.setTimeout(processPageRemoveQueue, 15 * 1000);
}
}; };
/******************************************************************************/ /******************************************************************************/
@ -281,13 +279,16 @@ var removePageCookiesAsync = function(pageStats) {
// Candidate for removal // Candidate for removal
var removeCookieAsync = function(cookieKey) { var removeCookieAsync = function(cookieKey) {
// console.log('cookies.js/removeCookieAsync()> cookie key = "%s"', cookieKey);
removeCookieQueue[cookieKey] = true; removeCookieQueue[cookieKey] = true;
}; };
/******************************************************************************/ /******************************************************************************/
var chromeCookieRemove = function(url, name) {
var chromeCookieRemove = function(cookieEntry, name) {
var url = cookieURLFromCookieEntry(cookieEntry);
if ( url === '' ) {
return;
}
var sessionCookieKey = cookieKeyFromCookieURL(url, 'session', name); var sessionCookieKey = cookieKeyFromCookieURL(url, 'session', name);
var persistCookieKey = cookieKeyFromCookieURL(url, 'persistent', name); var persistCookieKey = cookieKeyFromCookieURL(url, 'persistent', name);
var callback = function(details) { var callback = function(details) {
@ -316,6 +317,8 @@ var i18nCookieDeleteFailure = vAPI.i18n('loggerEntryDeleteCookieError');
/******************************************************************************/ /******************************************************************************/
var processPageRecordQueue = function() { var processPageRecordQueue = function() {
processPageRecordQueueTimer = null;
for ( var pageURL in recordPageCookiesQueue ) { for ( var pageURL in recordPageCookiesQueue ) {
if ( !recordPageCookiesQueue.hasOwnProperty(pageURL) ) { if ( !recordPageCookiesQueue.hasOwnProperty(pageURL) ) {
continue; continue;
@ -328,6 +331,8 @@ var processPageRecordQueue = function() {
/******************************************************************************/ /******************************************************************************/
var processPageRemoveQueue = function() { var processPageRemoveQueue = function() {
processPageRemoveQueueTimer = null;
for ( var pageURL in removePageCookiesQueue ) { for ( var pageURL in removePageCookiesQueue ) {
if ( !removePageCookiesQueue.hasOwnProperty(pageURL) ) { if ( !removePageCookiesQueue.hasOwnProperty(pageURL) ) {
continue; continue;
@ -361,18 +366,24 @@ var processRemoveQueue = function() {
} }
delete removeCookieQueue[cookieKey]; delete removeCookieQueue[cookieKey];
cookieEntry = cookieDict[cookieKey];
// rhill 2014-05-12: Apparently this can happen. I have to // rhill 2014-05-12: Apparently this can happen. I have to
// investigate how (A session cookie has same name as a // investigate how (A session cookie has same name as a
// persistent cookie?) // persistent cookie?)
cookieEntry = cookieDict[cookieKey];
if ( !cookieEntry ) { if ( !cookieEntry ) {
// console.error('cookies.js > processRemoveQueue(): no cookieEntry for "%s"', cookieKey);
continue; continue;
} }
// Just in case setting was changed after cookie was put in queue.
if ( cookieEntry.session === false && deleteCookies === false ) {
// Delete obsolete session cookies: enabled.
if ( tstampObsolete !== 0 && cookieEntry.session ) {
if ( cookieEntry.tstamp < tstampObsolete ) {
chromeCookieRemove(cookieEntry, cookieEntry.name);
continue;
}
}
// Delete all blocked cookies: disabled.
if ( deleteCookies === false ) {
continue; continue;
} }
@ -384,22 +395,12 @@ var processRemoveQueue = function() {
// Ensure cookie is not allowed on ALL current web pages: It can // Ensure cookie is not allowed on ALL current web pages: It can
// happen that a cookie is blacklisted on one web page while // happen that a cookie is blacklisted on one web page while
// being whitelisted on another (because of per-page permissions). // being whitelisted on another (because of per-page permissions).
if ( canRemoveCookie(cookieKey, srcHostnames) === false ) {
// Exception: session cookie may have to be removed even though
// they are seen as being whitelisted.
if ( cookieEntry.session === false || cookieEntry.tstamp > tstampObsolete ) {
continue;
}
if ( canRemoveCookie(cookieKey, srcHostnames) ) {
chromeCookieRemove(cookieEntry, cookieEntry.name);
} }
var url = cookieURLFromCookieEntry(cookieEntry);
if ( !url ) {
continue;
}
// console.debug('cookies.js > processRemoveQueue(): removing "%s" (age=%s min)', cookieKey, ((Date.now() - cookieEntry.tstamp) / 60000).toFixed(1));
chromeCookieRemove(url, cookieEntry.name);
} }
vAPI.setTimeout(processRemoveQueue, processRemoveQueuePeriod);
}; };
/******************************************************************************/ /******************************************************************************/
@ -418,6 +419,8 @@ var processClean = function() {
while ( cookieKeys.length ) { while ( cookieKeys.length ) {
removeCookieAsync(cookieKeys.pop()); removeCookieAsync(cookieKeys.pop());
} }
vAPI.setTimeout(processClean, processCleanPeriod);
}; };
/******************************************************************************/ /******************************************************************************/
@ -530,8 +533,8 @@ vAPI.cookies.onChanged = function(cookie) {
vAPI.cookies.getAll(addCookiesToDict); vAPI.cookies.getAll(addCookiesToDict);
vAPI.cookies.start(); vAPI.cookies.start();
µm.asyncJobs.add('cookieHunterRemove', null, processRemoveQueue, 2 * 60 * 1000, true);
µm.asyncJobs.add('cookieHunterClean', null, processClean, 10 * 60 * 1000, true);
vAPI.setTimeout(processRemoveQueue, processRemoveQueuePeriod);
vAPI.setTimeout(processClean, processCleanPeriod);
/******************************************************************************/ /******************************************************************************/

47
src/js/tab.js

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µMatrix - a Chromium browser extension to black/white list requests. µMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2014 Raymond Hill
Copyright (C) 2014-2016 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -571,6 +571,51 @@ vAPI.tabs.registerListeners();
/******************************************************************************/ /******************************************************************************/
// Update badge
// rhill 2013-11-09: well this sucks, I can't update icon/badge
// incrementally, as chromium overwrite the icon at some point without
// notifying me, and this causes internal cached state to be out of sync.
µm.updateBadgeAsync = (function() {
var tabIdToTimer = Object.create(null);
var updateBadge = function(tabId) {
delete tabIdToTimer[tabId];
var iconId = null;
var badgeStr = '';
var pageStore = this.pageStoreFromTabId(tabId);
if ( pageStore !== null ) {
var total = pageStore.perLoadAllowedRequestCount +
pageStore.perLoadBlockedRequestCount;
if ( total ) {
var squareSize = 19;
var greenSize = squareSize * Math.sqrt(pageStore.perLoadAllowedRequestCount / total);
iconId = greenSize < squareSize/2 ? Math.ceil(greenSize) : Math.floor(greenSize);
}
if ( this.userSettings.iconBadgeEnabled && pageStore.distinctRequestCount !== 0) {
badgeStr = this.formatCount(pageStore.distinctRequestCount);
}
}
vAPI.setIcon(tabId, iconId, badgeStr);
};
return function(tabId) {
if ( tabIdToTimer[tabId] ) {
return;
}
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
return;
}
tabIdToTimer[tabId] = vAPI.setTimeout(updateBadge.bind(this, tabId), 500);
};
})();
/******************************************************************************/
µm.updateTitle = (function() { µm.updateTitle = (function() {
var tabIdToTimer = Object.create(null); var tabIdToTimer = Object.create(null);
var tabIdToTryCount = Object.create(null); var tabIdToTryCount = Object.create(null);

11
src/js/useragent.js

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uMatrix - a Chromium browser extension to black/white list requests. uMatrix - a Chromium browser extension to black/white list requests.
Copyright (C) 2014-2015 Raymond Hill
Copyright (C) 2014-2016 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -23,6 +23,8 @@
µMatrix.userAgentSpoofer = (function() { µMatrix.userAgentSpoofer = (function() {
"use strict";
/******************************************************************************/ /******************************************************************************/
var userAgentRandomPicker = function() { var userAgentRandomPicker = function() {
@ -61,17 +63,14 @@ var userAgentSpoofer = function(force) {
µm.userAgentReplaceStr = userAgentRandomPicker(); µm.userAgentReplaceStr = userAgentRandomPicker();
µm.userAgentReplaceStrBirth = Date.now(); µm.userAgentReplaceStrBirth = Date.now();
} }
vAPI.setTimeout(userAgentSpoofer, 120 * 1000);
}; };
// Prime spoofer
userAgentSpoofer(); userAgentSpoofer();
/******************************************************************************/ /******************************************************************************/
µMatrix.asyncJobs.add('userAgentSwitcher', null, userAgentSpoofer, 120 * 1000, true);
/******************************************************************************/
return { return {
shuffle: function() { shuffle: function() {
userAgentSpoofer(true); userAgentSpoofer(true);

Loading…
Cancel
Save