diff --git a/src/background.html b/src/background.html
index 9770a60..06b789b 100644
--- a/src/background.html
+++ b/src/background.html
@@ -13,7 +13,6 @@
-
diff --git a/src/js/async.js b/src/js/async.js
deleted file mode 100644
index c6b89bc..0000000
--- a/src/js/async.js
+++ /dev/null
@@ -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);
- };
-})();
diff --git a/src/js/cookies.js b/src/js/cookies.js
index 98166a3..95fb2c3 100644
--- a/src/js/cookies.js
+++ b/src/js/cookies.js
@@ -1,7 +1,7 @@
/*******************************************************************************
µ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
it under the terms of the GNU General Public License as published by
@@ -35,6 +35,8 @@
µMatrix.cookieHunter = (function() {
+"use strict";
+
/******************************************************************************/
var µm = µMatrix;
@@ -44,6 +46,10 @@ var removePageCookiesQueue = {};
var removeCookieQueue = {};
var cookieDict = {};
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;
}
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;
}
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
var removeCookieAsync = function(cookieKey) {
- // console.log('cookies.js/removeCookieAsync()> cookie key = "%s"', cookieKey);
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 persistCookieKey = cookieKeyFromCookieURL(url, 'persistent', name);
var callback = function(details) {
@@ -316,6 +317,8 @@ var i18nCookieDeleteFailure = vAPI.i18n('loggerEntryDeleteCookieError');
/******************************************************************************/
var processPageRecordQueue = function() {
+ processPageRecordQueueTimer = null;
+
for ( var pageURL in recordPageCookiesQueue ) {
if ( !recordPageCookiesQueue.hasOwnProperty(pageURL) ) {
continue;
@@ -328,6 +331,8 @@ var processPageRecordQueue = function() {
/******************************************************************************/
var processPageRemoveQueue = function() {
+ processPageRemoveQueueTimer = null;
+
for ( var pageURL in removePageCookiesQueue ) {
if ( !removePageCookiesQueue.hasOwnProperty(pageURL) ) {
continue;
@@ -361,18 +366,24 @@ var processRemoveQueue = function() {
}
delete removeCookieQueue[cookieKey];
- cookieEntry = cookieDict[cookieKey];
-
// rhill 2014-05-12: Apparently this can happen. I have to
// investigate how (A session cookie has same name as a
// persistent cookie?)
+ cookieEntry = cookieDict[cookieKey];
if ( !cookieEntry ) {
- // console.error('cookies.js > processRemoveQueue(): no cookieEntry for "%s"', cookieKey);
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;
}
@@ -384,22 +395,12 @@ var processRemoveQueue = function() {
// Ensure cookie is not allowed on ALL current web pages: It can
// happen that a cookie is blacklisted on one web page while
// 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 ) {
removeCookieAsync(cookieKeys.pop());
}
+
+ vAPI.setTimeout(processClean, processCleanPeriod);
};
/******************************************************************************/
@@ -530,8 +533,8 @@ vAPI.cookies.onChanged = function(cookie) {
vAPI.cookies.getAll(addCookiesToDict);
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);
/******************************************************************************/
diff --git a/src/js/tab.js b/src/js/tab.js
index 5b4a410..7622920 100644
--- a/src/js/tab.js
+++ b/src/js/tab.js
@@ -1,7 +1,7 @@
/*******************************************************************************
µ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
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() {
var tabIdToTimer = Object.create(null);
var tabIdToTryCount = Object.create(null);
diff --git a/src/js/useragent.js b/src/js/useragent.js
index cd788d2..c28d323 100644
--- a/src/js/useragent.js
+++ b/src/js/useragent.js
@@ -1,7 +1,7 @@
/*******************************************************************************
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
it under the terms of the GNU General Public License as published by
@@ -23,6 +23,8 @@
µMatrix.userAgentSpoofer = (function() {
+"use strict";
+
/******************************************************************************/
var userAgentRandomPicker = function() {
@@ -61,17 +63,14 @@ var userAgentSpoofer = function(force) {
µm.userAgentReplaceStr = userAgentRandomPicker();
µm.userAgentReplaceStrBirth = Date.now();
}
+
+ vAPI.setTimeout(userAgentSpoofer, 120 * 1000);
};
-// Prime spoofer
userAgentSpoofer();
/******************************************************************************/
-µMatrix.asyncJobs.add('userAgentSwitcher', null, userAgentSpoofer, 120 * 1000, true);
-
-/******************************************************************************/
-
return {
shuffle: function() {
userAgentSpoofer(true);