first pass
parent
a5d051de3f
commit
ed67045360
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,141 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
µMatrix - a Chromium browser extension to black/white list 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/uMatrix
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This is the reference client-side implementation of µBlock's messaging
|
|
||||||
// infrastructure. The "server"-side implementation is in messaging.js.
|
|
||||||
|
|
||||||
// The client-side implementation creates a port in order to connect to
|
|
||||||
// µBlock's background page. With this port we can "ask", "tell" or "announce":
|
|
||||||
//
|
|
||||||
// "ask": send a request and expect an answer using a callback.
|
|
||||||
// "tell": send a request with no expectation of an answer.
|
|
||||||
// "announce": send a request to be relayed to all connections -- no answer
|
|
||||||
// expected.
|
|
||||||
//
|
|
||||||
// The tricky part in this implementation is to ensure all the requests are
|
|
||||||
// uniquely identified, so that the background-page can keep track of these
|
|
||||||
// until it is ready to send back an answer, which will be tagged with the
|
|
||||||
// same id. The uniqueness must be true for all ports which connect to the
|
|
||||||
// background page at any given time.
|
|
||||||
//
|
|
||||||
// Currently using Math.random() to generate this id... I don't know about the
|
|
||||||
// implementation of Math.random(), but as long as I have a good expectation
|
|
||||||
// of uniqueness, it's ok, we are not dealing with critical stuff here.
|
|
||||||
|
|
||||||
/* global chrome */
|
|
||||||
|
|
||||||
var messaging = (function(name){
|
|
||||||
var port = null;
|
|
||||||
var requestId = 1;
|
|
||||||
var requestIdToCallbackMap = {};
|
|
||||||
var listenCallback = null;
|
|
||||||
|
|
||||||
var onPortMessage = function(details) {
|
|
||||||
if ( typeof details.id !== 'number' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Announcement?
|
|
||||||
if ( details.id < 0 ) {
|
|
||||||
if ( listenCallback ) {
|
|
||||||
listenCallback(details.msg);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var callback = requestIdToCallbackMap[details.id];
|
|
||||||
if ( !callback ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Must be removed before calling client to be sure to not execute
|
|
||||||
// callback again if the client stops the messaging service.
|
|
||||||
delete requestIdToCallbackMap[details.id];
|
|
||||||
callback(details.msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
var start = function(name) {
|
|
||||||
port = chrome.runtime.connect({ name: name });
|
|
||||||
port.onMessage.addListener(onPortMessage);
|
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/193
|
|
||||||
port.onDisconnect.addListener(stop);
|
|
||||||
};
|
|
||||||
|
|
||||||
var stop = function() {
|
|
||||||
listenCallback = null;
|
|
||||||
port.disconnect();
|
|
||||||
port = null;
|
|
||||||
flushCallbacks();
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( typeof name === 'string' && name !== '' ) {
|
|
||||||
start(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ask = function(msg, callback) {
|
|
||||||
if ( port === null ) {
|
|
||||||
if ( typeof callback === 'function' ) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( callback === undefined ) {
|
|
||||||
tell(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var id = requestId++;
|
|
||||||
port.postMessage({ id: id, msg: msg });
|
|
||||||
requestIdToCallbackMap[id] = callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
var tell = function(msg) {
|
|
||||||
if ( port !== null ) {
|
|
||||||
port.postMessage({ id: 0, msg: msg });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var listen = function(callback) {
|
|
||||||
listenCallback = callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
var flushCallbacks = function() {
|
|
||||||
var callback;
|
|
||||||
for ( var id in requestIdToCallbackMap ) {
|
|
||||||
if ( requestIdToCallbackMap.hasOwnProperty(id) === false ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
callback = requestIdToCallbackMap[id];
|
|
||||||
if ( !callback ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Must be removed before calling client to be sure to not execute
|
|
||||||
// callback again if the client stops the messaging service.
|
|
||||||
delete requestIdToCallbackMap[id];
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
start: start,
|
|
||||||
stop: stop,
|
|
||||||
ask: ask,
|
|
||||||
tell: tell,
|
|
||||||
listen: listen
|
|
||||||
};
|
|
||||||
})();
|
|
@ -1,816 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
µMatrix - a Chromium browser extension to black/white list 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/uMatrix
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* global chrome, µMatrix */
|
|
||||||
/* jshint boss: true */
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
// popup.js
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var smartReload = function(tabs) {
|
|
||||||
var i = tabs.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
µm.smartReloadTabs(µm.userSettings.smartAutoReload, tabs[i].id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Constructor is faster than object literal
|
|
||||||
|
|
||||||
var RowSnapshot = function(srcHostname, desHostname, desDomain) {
|
|
||||||
this.domain = desDomain;
|
|
||||||
this.temporary = µm.tMatrix.evaluateRowZXY(srcHostname, desHostname);
|
|
||||||
this.permanent = µm.pMatrix.evaluateRowZXY(srcHostname, desHostname);
|
|
||||||
this.counts = RowSnapshot.counts.slice();
|
|
||||||
this.totals = RowSnapshot.counts.slice();
|
|
||||||
};
|
|
||||||
|
|
||||||
RowSnapshot.counts = (function() {
|
|
||||||
var i = Object.keys(µm.Matrix.getColumnHeaders()).length;
|
|
||||||
var aa = new Array(i);
|
|
||||||
while ( i-- ) {
|
|
||||||
aa[i] = 0;
|
|
||||||
}
|
|
||||||
return aa;
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var matrixSnapshot = function(details) {
|
|
||||||
var µmuser = µm.userSettings;
|
|
||||||
var r = {
|
|
||||||
tabId: details.tabId,
|
|
||||||
url: '',
|
|
||||||
hostname: '',
|
|
||||||
domain: '',
|
|
||||||
blockedCount: 0,
|
|
||||||
scope: '*',
|
|
||||||
headers: µm.Matrix.getColumnHeaders(),
|
|
||||||
tSwitches: {},
|
|
||||||
pSwitches: {},
|
|
||||||
rows: {},
|
|
||||||
rowCount: 0,
|
|
||||||
diff: [],
|
|
||||||
userSettings: {
|
|
||||||
colorBlindFriendly: µmuser.colorBlindFriendly,
|
|
||||||
displayTextSize: µmuser.displayTextSize,
|
|
||||||
popupCollapseDomains: µmuser.popupCollapseDomains,
|
|
||||||
popupCollapseSpecificDomains: µmuser.popupCollapseSpecificDomains,
|
|
||||||
popupHideBlacklisted: µmuser.popupHideBlacklisted,
|
|
||||||
popupScopeLevel: µmuser.popupScopeLevel
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow examination of behind-the-scene requests
|
|
||||||
// TODO: Not portable
|
|
||||||
if ( details.tabURL ) {
|
|
||||||
if ( details.tabURL.indexOf('chrome-extension://' + chrome.runtime.id + '/') === 0 ) {
|
|
||||||
details.tabId = µm.behindTheSceneTabId;
|
|
||||||
} else if ( details.tabURL === µm.behindTheSceneURL ) {
|
|
||||||
details.tabId = µm.behindTheSceneTabId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageStore = µm.pageStatsFromTabId(details.tabId);
|
|
||||||
if ( !pageStore ) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
var headers = r.headers;
|
|
||||||
|
|
||||||
r.url = pageStore.pageUrl;
|
|
||||||
r.hostname = pageStore.pageHostname;
|
|
||||||
r.domain = pageStore.pageDomain;
|
|
||||||
r.blockedCount = pageStore.requestStats.blocked.all;
|
|
||||||
|
|
||||||
if ( µmuser.popupScopeLevel === 'site' ) {
|
|
||||||
r.scope = r.hostname;
|
|
||||||
} else if ( µmuser.popupScopeLevel === 'domain' ) {
|
|
||||||
r.scope = r.domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
var switchNames = µm.Matrix.getSwitchNames();
|
|
||||||
for ( var switchName in switchNames ) {
|
|
||||||
if ( switchNames.hasOwnProperty(switchName) === false ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
r.tSwitches[switchName] = µm.tMatrix.evaluateSwitchZ(switchName, r.scope);
|
|
||||||
r.pSwitches[switchName] = µm.pMatrix.evaluateSwitchZ(switchName, r.scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
// These rows always exist
|
|
||||||
r.rows['*'] = new RowSnapshot(r.scope, '*', '*');
|
|
||||||
r.rows['1st-party'] = new RowSnapshot(r.scope, '1st-party', '1st-party');
|
|
||||||
r.rowCount += 1;
|
|
||||||
|
|
||||||
var µmuri = µm.URI;
|
|
||||||
var reqKey, reqType, reqHostname, reqDomain;
|
|
||||||
var desHostname;
|
|
||||||
var row, typeIndex;
|
|
||||||
var anyIndex = headers['*'];
|
|
||||||
|
|
||||||
var pageRequests = pageStore.requests;
|
|
||||||
var reqKeys = pageRequests.getRequestKeys();
|
|
||||||
var iReqKey = reqKeys.length;
|
|
||||||
var pos;
|
|
||||||
|
|
||||||
while ( iReqKey-- ) {
|
|
||||||
reqKey = reqKeys[iReqKey];
|
|
||||||
reqType = pageRequests.typeFromRequestKey(reqKey);
|
|
||||||
reqHostname = pageRequests.hostnameFromRequestKey(reqKey);
|
|
||||||
// rhill 2013-10-23: hostname can be empty if the request is a data url
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/26
|
|
||||||
if ( reqHostname === '' ) {
|
|
||||||
reqHostname = pageStore.pageHostname;
|
|
||||||
}
|
|
||||||
reqDomain = µmuri.domainFromHostname(reqHostname) || reqHostname;
|
|
||||||
|
|
||||||
// We want rows of self and ancestors
|
|
||||||
desHostname = reqHostname;
|
|
||||||
for ( ;; ) {
|
|
||||||
// If row exists, ancestors exist
|
|
||||||
if ( r.rows.hasOwnProperty(desHostname) !== false ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
r.rows[desHostname] = new RowSnapshot(r.scope, desHostname, reqDomain);
|
|
||||||
r.rowCount += 1;
|
|
||||||
if ( desHostname === reqDomain ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = desHostname.indexOf('.');
|
|
||||||
if ( pos === -1 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
desHostname = desHostname.slice(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
typeIndex = headers[reqType];
|
|
||||||
|
|
||||||
row = r.rows[reqHostname];
|
|
||||||
row.counts[typeIndex] += 1;
|
|
||||||
row.counts[anyIndex] += 1;
|
|
||||||
|
|
||||||
row = r.rows[reqDomain];
|
|
||||||
row.totals[typeIndex] += 1;
|
|
||||||
row.totals[anyIndex] += 1;
|
|
||||||
|
|
||||||
row = r.rows['*'];
|
|
||||||
row.totals[typeIndex] += 1;
|
|
||||||
row.totals[anyIndex] += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.diff = µm.tMatrix.diff(µm.pMatrix, r.hostname, Object.keys(r.rows));
|
|
||||||
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'disconnected':
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/94
|
|
||||||
if ( µm.userSettings.smartAutoReload ) {
|
|
||||||
chrome.tabs.query({ active: true }, smartReload);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'matrixSnapshot':
|
|
||||||
response = matrixSnapshot(request);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'toggleMatrixSwitch':
|
|
||||||
µm.tMatrix.setSwitchZ(
|
|
||||||
request.switchName,
|
|
||||||
request.srcHostname,
|
|
||||||
µm.tMatrix.evaluateSwitchZ(request.switchName, request.srcHostname) === false
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'blacklistMatrixCell':
|
|
||||||
µm.tMatrix.blacklistCell(
|
|
||||||
request.srcHostname,
|
|
||||||
request.desHostname,
|
|
||||||
request.type
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'whitelistMatrixCell':
|
|
||||||
µm.tMatrix.whitelistCell(
|
|
||||||
request.srcHostname,
|
|
||||||
request.desHostname,
|
|
||||||
request.type
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'graylistMatrixCell':
|
|
||||||
µm.tMatrix.graylistCell(
|
|
||||||
request.srcHostname,
|
|
||||||
request.desHostname,
|
|
||||||
request.type
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'applyDiffToPermanentMatrix': // aka "persist"
|
|
||||||
if ( µm.pMatrix.applyDiff(request.diff, µm.tMatrix) ) {
|
|
||||||
µm.saveMatrix();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'applyDiffToTemporaryMatrix': // aka "revert"
|
|
||||||
µm.tMatrix.applyDiff(request.diff, µm.pMatrix);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'revertTemporaryMatrix':
|
|
||||||
µm.tMatrix.assign(µm.pMatrix);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µm.messaging.listen('popup.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// content scripts
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var contentScriptSummaryHandler = function(tabId, details) {
|
|
||||||
// TODO: Investigate "Error in response to tabs.executeScript: TypeError:
|
|
||||||
// Cannot read property 'locationURL' of null" (2013-11-12). When can this
|
|
||||||
// happens?
|
|
||||||
if ( !details || !details.locationURL ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var pageURL = µm.pageUrlFromTabId(tabId);
|
|
||||||
var pageStats = µm.pageStatsFromPageUrl(pageURL);
|
|
||||||
var µmuri = µm.URI.set(details.locationURL);
|
|
||||||
var frameURL = µmuri.normalizedURI();
|
|
||||||
var frameHostname = µmuri.hostname;
|
|
||||||
var urls, url, r;
|
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/333
|
|
||||||
// Look-up here whether inline scripting is blocked for the frame.
|
|
||||||
var inlineScriptBlocked = µm.mustBlock(µm.scopeFromURL(pageURL), frameHostname, 'script');
|
|
||||||
|
|
||||||
// scripts
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/25
|
|
||||||
if ( pageStats && inlineScriptBlocked ) {
|
|
||||||
urls = details.scriptSources;
|
|
||||||
for ( url in urls ) {
|
|
||||||
if ( !urls.hasOwnProperty(url) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( url === '{inline_script}' ) {
|
|
||||||
url = frameURL + '{inline_script}';
|
|
||||||
}
|
|
||||||
r = µm.filterRequest(pageURL, 'script', url);
|
|
||||||
pageStats.recordRequest('script', url, r !== false, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: as of 2014-05-26, not sure this is needed anymore, since µMatrix
|
|
||||||
// no longer uses chrome.contentSettings API (I think that was the reason
|
|
||||||
// this code was put in).
|
|
||||||
// plugins
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/25
|
|
||||||
if ( pageStats ) {
|
|
||||||
urls = details.pluginSources;
|
|
||||||
for ( url in urls ) {
|
|
||||||
if ( !urls.hasOwnProperty(url) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
r = µm.filterRequest(pageURL, 'plugin', url);
|
|
||||||
pageStats.recordRequest('plugin', url, r !== false, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/181
|
|
||||||
µm.onPageLoadCompleted(pageURL);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var contentScriptLocalStorageHandler = function(pageURL) {
|
|
||||||
var µmuri = µm.URI.set(pageURL);
|
|
||||||
var response = µm.mustBlock(µm.scopeFromURL(pageURL), µmuri.hostname, 'cookie');
|
|
||||||
µm.recordFromPageUrl(
|
|
||||||
pageURL,
|
|
||||||
'cookie',
|
|
||||||
µmuri.rootURL() + '/{localStorage}',
|
|
||||||
response
|
|
||||||
);
|
|
||||||
response = response && µm.userSettings.deleteLocalStorage;
|
|
||||||
if ( response ) {
|
|
||||||
µm.localStorageRemovedCounter++;
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tabId = sender.tab.id;
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'contentScriptHasLocalStorage':
|
|
||||||
response = contentScriptLocalStorageHandler(request.url);
|
|
||||||
µm.updateBadgeAsync(tabId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'contentScriptSummary':
|
|
||||||
contentScriptSummaryHandler(tabId, request);
|
|
||||||
µm.updateBadgeAsync(tabId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'checkScriptBlacklisted':
|
|
||||||
response = {
|
|
||||||
scriptBlacklisted: µm.mustBlock(
|
|
||||||
µm.scopeFromURL(request.url),
|
|
||||||
µm.hostnameFromURL(request.url),
|
|
||||||
'script'
|
|
||||||
)
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'getUserAgentReplaceStr':
|
|
||||||
response = µm.tMatrix.evaluateSwitchZ('ua-spoof', request.hostname) ?
|
|
||||||
µm.userAgentReplaceStr :
|
|
||||||
undefined;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('contentscript-start.js', onMessage);
|
|
||||||
µMatrix.messaging.listen('contentscript-end.js', onMessage);
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// settings.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('settings.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// privacy.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'getPrivacySettings':
|
|
||||||
response = {
|
|
||||||
userSettings: µm.userSettings,
|
|
||||||
matrixSwitches: {
|
|
||||||
'https-strict': µm.pMatrix.evaluateSwitch('https-strict', '*') === 1,
|
|
||||||
'ua-spoof': µm.pMatrix.evaluateSwitch('ua-spoof', '*') === 1,
|
|
||||||
'referrer-spoof': µm.pMatrix.evaluateSwitch('referrer-spoof', '*') === 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'setMatrixSwitch':
|
|
||||||
µm.tMatrix.setSwitch(request.switchName, '*', request.state);
|
|
||||||
if ( µm.pMatrix.setSwitch(request.switchName, '*', request.state) ) {
|
|
||||||
µm.saveMatrix();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('privacy.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// user-rules.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'getUserRules':
|
|
||||||
response = {
|
|
||||||
temporaryRules: µm.tMatrix.toString(),
|
|
||||||
permanentRules: µm.pMatrix.toString()
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'setUserRules':
|
|
||||||
if ( typeof request.temporaryRules === 'string' ) {
|
|
||||||
µm.tMatrix.fromString(request.temporaryRules);
|
|
||||||
}
|
|
||||||
if ( typeof request.permanentRules === 'string' ) {
|
|
||||||
µm.pMatrix.fromString(request.permanentRules);
|
|
||||||
µm.saveMatrix();
|
|
||||||
}
|
|
||||||
response = {
|
|
||||||
temporaryRules: µm.tMatrix.toString(),
|
|
||||||
permanentRules: µm.pMatrix.toString()
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('user-rules.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// hosts-files.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var getLists = function(callback) {
|
|
||||||
var r = {
|
|
||||||
available: null,
|
|
||||||
cache: null,
|
|
||||||
current: µm.liveHostsFiles,
|
|
||||||
blockedHostnameCount: µm.ubiquitousBlacklist.count,
|
|
||||||
autoUpdate: µm.userSettings.autoUpdate
|
|
||||||
};
|
|
||||||
var onMetadataReady = function(entries) {
|
|
||||||
r.cache = entries;
|
|
||||||
callback(r);
|
|
||||||
};
|
|
||||||
var onAvailableHostsFilesReady = function(lists) {
|
|
||||||
r.available = lists;
|
|
||||||
µm.assets.metadata(onMetadataReady);
|
|
||||||
};
|
|
||||||
µm.getAvailableHostsFiles(onAvailableHostsFilesReady);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'getLists':
|
|
||||||
return getLists(callback);
|
|
||||||
|
|
||||||
case 'purgeAllCaches':
|
|
||||||
return µm.assets.purgeAll(callback);
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'purgeCache':
|
|
||||||
µm.assets.purge(request.path);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('hosts-files.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// info.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// map(pageURL) => array of request log entries
|
|
||||||
|
|
||||||
var getRequestLog = function(pageURL) {
|
|
||||||
var requestLogs = {};
|
|
||||||
var pageStores = µMatrix.pageStats;
|
|
||||||
var pageURLs = pageURL ? [pageURL] : Object.keys(pageStores);
|
|
||||||
var pageStore, pageRequestLog, logEntries, j, logEntry;
|
|
||||||
|
|
||||||
for ( var i = 0; i < pageURLs.length; i++ ) {
|
|
||||||
pageURL = pageURLs[i];
|
|
||||||
pageStore = pageStores[pageURL];
|
|
||||||
if ( !pageStore ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pageRequestLog = [];
|
|
||||||
logEntries = pageStore.requests.getLoggedRequests();
|
|
||||||
j = logEntries.length;
|
|
||||||
while ( j-- ) {
|
|
||||||
// rhill 2013-12-04: `logEntry` can be null since a ring buffer is
|
|
||||||
// now used, and it might not have been filled yet.
|
|
||||||
if ( logEntry = logEntries[j] ) {
|
|
||||||
pageRequestLog.push(logEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestLogs[pageURL] = pageRequestLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestLogs;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var clearRequestLog = function(pageURL) {
|
|
||||||
var pageStores = µMatrix.pageStats;
|
|
||||||
var pageURLs = pageURL ? [pageURL] : Object.keys(pageStores);
|
|
||||||
var pageStore;
|
|
||||||
|
|
||||||
for ( var i = 0; i < pageURLs.length; i++ ) {
|
|
||||||
if ( pageStore = pageStores[pageURLs[i]] ) {
|
|
||||||
pageStore.requests.clearLogBuffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'getPageURLs':
|
|
||||||
response = {
|
|
||||||
pageURLs: Object.keys(µm.pageUrlToTabId),
|
|
||||||
behindTheSceneURL: µm.behindTheSceneURL
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'getStats':
|
|
||||||
var pageStore = µm.pageStats[request.pageURL];
|
|
||||||
response = {
|
|
||||||
globalNetStats: µm.requestStats,
|
|
||||||
pageNetStats: pageStore ? pageStore.requestStats : null,
|
|
||||||
cookieHeaderFoiledCounter: µm.cookieHeaderFoiledCounter,
|
|
||||||
refererHeaderFoiledCounter: µm.refererHeaderFoiledCounter,
|
|
||||||
hyperlinkAuditingFoiledCounter: µm.hyperlinkAuditingFoiledCounter,
|
|
||||||
cookieRemovedCounter: µm.cookieRemovedCounter,
|
|
||||||
localStorageRemovedCounter: µm.localStorageRemovedCounter,
|
|
||||||
browserCacheClearedCounter: µm.browserCacheClearedCounter
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'getRequestLogs':
|
|
||||||
response = getRequestLog(request.pageURL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'clearRequestLogs':
|
|
||||||
clearRequestLog(request.pageURL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('info.js', onMessage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// about.js
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var µm = µMatrix;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var restoreUserData = function(userData) {
|
|
||||||
var countdown = 3;
|
|
||||||
var onCountdown = function() {
|
|
||||||
countdown -= 1;
|
|
||||||
if ( countdown === 0 ) {
|
|
||||||
µm.XAL.restart();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var onAllRemoved = function() {
|
|
||||||
// Be sure to adjust `countdown` if adding/removing anything below
|
|
||||||
µm.XAL.keyvalSetMany(userData.settings, onCountdown);
|
|
||||||
µm.XAL.keyvalSetOne('userMatrix', userData.rules, onCountdown);
|
|
||||||
µm.XAL.keyvalSetOne('liveHostsFiles', userData.hostsFiles, onCountdown);
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we are going to restore all, might as well wipe out clean local
|
|
||||||
// storage
|
|
||||||
µm.XAL.keyvalRemoveAll(onAllRemoved);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var resetUserData = function() {
|
|
||||||
var onAllRemoved = function() {
|
|
||||||
µm.XAL.restart();
|
|
||||||
};
|
|
||||||
µm.XAL.keyvalRemoveAll(onAllRemoved);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
|
||||||
// Async
|
|
||||||
switch ( request.what ) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
var response;
|
|
||||||
|
|
||||||
switch ( request.what ) {
|
|
||||||
case 'getAllUserData':
|
|
||||||
response = {
|
|
||||||
app: 'µMatrix',
|
|
||||||
version: µm.manifest.version,
|
|
||||||
when: Date.now(),
|
|
||||||
settings: µm.userSettings,
|
|
||||||
rules: µm.pMatrix.toString(),
|
|
||||||
hostsFiles: µm.liveHostsFiles
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'getSomeStats':
|
|
||||||
response = {
|
|
||||||
version: µm.manifest.version,
|
|
||||||
storageQuota: µm.storageQuota,
|
|
||||||
storageUsed: µm.storageUsed
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'restoreAllUserData':
|
|
||||||
restoreUserData(request.userData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'resetAllUserData':
|
|
||||||
resetUserData();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return µm.messaging.defaultHandler(request, sender, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
µMatrix.messaging.listen('about.js', onMessage);
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
Loading…
Reference in New Issue