mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-02 02:14:52 +12:00
this fixes #489
This commit is contained in:
parent
4f63e079bc
commit
e9e1f7e631
|
@ -13,7 +13,6 @@
|
|||
<script src="js/background.js"></script>
|
||||
<script src="js/xal.js"></script>
|
||||
<script src="js/usersettings.js"></script>
|
||||
<script src="js/async.js"></script>
|
||||
<script src="js/liquid-dict.js"></script>
|
||||
<script src="js/matrix.js"></script>
|
||||
<script src="js/utils.js"></script>
|
||||
|
|
174
src/js/async.js
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);
|
||||
};
|
||||
})();
|
|
@ -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);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue