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);