mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-05-19 19:53:19 +12:00
this fixes #45 + revised color-blind mode + support shutdown of content script
This commit is contained in:
parent
1583a3edc6
commit
0e77cbd15d
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "µMatrix",
|
||||
"short_name": "µMatrix",
|
||||
"name": "uMatrix",
|
||||
"short_name": "uMatrix",
|
||||
"version": "0.8.1.4",
|
||||
"description": "__MSG_extShortDesc__",
|
||||
"icons": {
|
||||
|
@ -12,7 +12,7 @@
|
|||
"default_icon": {
|
||||
"19": "img/browsericons/icon19-19.png"
|
||||
},
|
||||
"default_title": "µMatrix",
|
||||
"default_title": "uMatrix",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"author": "Raymond Hill",
|
||||
|
|
|
@ -299,6 +299,10 @@
|
|||
"message": "Opacity",
|
||||
"description": "English: Opacity"
|
||||
},
|
||||
"settingsCollapseBlocked" : {
|
||||
"message": "Collapse placeholder of blocked elements",
|
||||
"description": "English: Collapse placeholder of blocked elements"
|
||||
},
|
||||
|
||||
|
||||
"privacyPageTitle" : {
|
||||
|
|
|
@ -462,22 +462,22 @@ body.powerOff .matrix .g4Meta.g4Collapsed ~ .matRow.ro {
|
|||
/* Cell coloring for color blind-friendly (hopefully) */
|
||||
body.colorblind .t81 {
|
||||
color: white;
|
||||
background-color: #000;
|
||||
background-color: rgb(0, 19, 110);
|
||||
}
|
||||
body.colorblind .t82 {
|
||||
border-color: #aaa;
|
||||
border-color: rgb(255, 194, 57);
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
background-color: rgb(255, 194, 57);
|
||||
}
|
||||
body.colorblind .t1 {
|
||||
border-color: #333;
|
||||
color: white;
|
||||
background-color: #666;
|
||||
border-color: rgba(0, 19, 110, 0.3);
|
||||
color: black;
|
||||
background-color: rgba(0, 19, 110, 0.2);
|
||||
}
|
||||
body.colorblind .t2 {
|
||||
border-color: #aaa;
|
||||
border-color: rgba(255, 194, 57, 0.3);
|
||||
color: black;
|
||||
background-color: #ccc;
|
||||
background-color: rgba(255, 194, 57, 0.2);
|
||||
}
|
||||
body.colorblind .matCell.p81 {
|
||||
background-image: url('../img/permanent-black-small-cb.png');
|
||||
|
@ -533,18 +533,15 @@ body.powerOff #whitelist, body.powerOff #blacklist {
|
|||
background-color: #080;
|
||||
opacity: 0.25;
|
||||
}
|
||||
body.colorblind .rw .matCell.t1 #whitelist:hover {
|
||||
background-color: #fff;
|
||||
body.colorblind .rw .matCell.t1 #whitelist:hover,
|
||||
body.colorblind .rw .matCell.t2 #whitelist:hover {
|
||||
background-color: rgb(255, 194, 57);
|
||||
opacity: 0.6;
|
||||
}
|
||||
.rw .matCell.t2 #whitelist:hover {
|
||||
background-color: #080;
|
||||
opacity: 0.25;
|
||||
}
|
||||
body.colorblind .rw .matCell.t2 #whitelist:hover {
|
||||
background-color: #fff;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.matCell.t81 #whitelist:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -555,18 +552,15 @@ body.colorblind .rw .matCell.t2 #whitelist:hover {
|
|||
background-color: #c00;
|
||||
opacity: 0.25;
|
||||
}
|
||||
body.colorblind .rw .matCell.t1 #blacklist:hover {
|
||||
background-color: #000;
|
||||
body.colorblind .rw .matCell.t1 #blacklist:hover,
|
||||
body.colorblind .rw .matCell.t2 #blacklist:hover {
|
||||
background-color: rgb(0, 19, 110);
|
||||
opacity: 0.4;
|
||||
}
|
||||
.rw .matCell.t2 #blacklist:hover {
|
||||
background-color: #c00;
|
||||
opacity: 0.25;
|
||||
}
|
||||
body.colorblind .rw .matCell.t2 #blacklist:hover {
|
||||
background-color: #000;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.matCell.t81 #blacklist:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 159 B |
Binary file not shown.
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 151 B |
|
@ -53,6 +53,7 @@ return {
|
|||
autoUpdate: false,
|
||||
clearBrowserCache: true,
|
||||
clearBrowserCacheAfter: 60,
|
||||
collapseBlocked: false,
|
||||
colorBlindFriendly: false,
|
||||
deleteCookies: false,
|
||||
deleteUnusedSessionCookies: false,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
µMatrix - a Chromium browser extension to black/white list requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
Copyright (C) 2014-2105 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
|
||||
|
@ -63,88 +63,243 @@ vAPI.contentscriptEndInjected = true;
|
|||
|
||||
var localMessager = vAPI.messaging.channel('contentscript-end.js');
|
||||
|
||||
vAPI.shutdown.add(function() {
|
||||
localMessager.close();
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// This is to be executed only once: putting this code in its own closure
|
||||
// means the code will be flushed from memory once executed.
|
||||
// Unrendered noscript (because CSP) workaround
|
||||
|
||||
// Executed once.
|
||||
|
||||
(function() {
|
||||
var checkScriptBlacklistedHandler = function(response) {
|
||||
if ( !response.scriptBlacklisted ) {
|
||||
return;
|
||||
}
|
||||
var scripts = document.querySelectorAll('noscript');
|
||||
var i = scripts.length;
|
||||
var realNoscript, fakeNoscript;
|
||||
while ( i-- ) {
|
||||
realNoscript = scripts[i];
|
||||
fakeNoscript = document.createElement('div');
|
||||
fakeNoscript.innerHTML = '<!-- uMatrix NOSCRIPT tag replacement: see <https://github.com/gorhill/httpswitchboard/issues/177> -->\n' + realNoscript.textContent;
|
||||
realNoscript.parentNode.replaceChild(fakeNoscript, realNoscript);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/*------------[ Unrendered Noscript (because CSP) Workaround ]----------------*/
|
||||
|
||||
var checkScriptBlacklistedHandler = function(response) {
|
||||
if ( !response.scriptBlacklisted ) {
|
||||
return;
|
||||
}
|
||||
var scripts = document.querySelectorAll('noscript');
|
||||
var i = scripts.length;
|
||||
var realNoscript, fakeNoscript;
|
||||
while ( i-- ) {
|
||||
realNoscript = scripts[i];
|
||||
fakeNoscript = document.createElement('div');
|
||||
fakeNoscript.innerHTML = '<!-- uMatrix NOSCRIPT tag replacement: see <https://github.com/gorhill/httpswitchboard/issues/177> -->\n' + realNoscript.textContent;
|
||||
realNoscript.parentNode.replaceChild(fakeNoscript, realNoscript);
|
||||
}
|
||||
};
|
||||
|
||||
localMessager.send({
|
||||
what: 'checkScriptBlacklisted',
|
||||
url: window.location.href
|
||||
}, checkScriptBlacklistedHandler);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var localStorageHandler = function(mustRemove) {
|
||||
if ( mustRemove ) {
|
||||
window.localStorage.clear();
|
||||
window.sessionStorage.clear();
|
||||
// console.debug('HTTP Switchboard > found and removed non-empty localStorage');
|
||||
}
|
||||
};
|
||||
|
||||
// Check with extension whether local storage must be emptied
|
||||
// rhill 2014-03-28: we need an exception handler in case 3rd-party access
|
||||
// to site data is disabled.
|
||||
// https://github.com/gorhill/httpswitchboard/issues/215
|
||||
try {
|
||||
var hasLocalStorage = window.localStorage && window.localStorage.length;
|
||||
var hasSessionStorage = window.sessionStorage && window.sessionStorage.length;
|
||||
if ( hasLocalStorage || hasSessionStorage ) {
|
||||
localMessager.send({
|
||||
what: 'contentScriptHasLocalStorage',
|
||||
url: window.location.href
|
||||
}, localStorageHandler);
|
||||
}
|
||||
|
||||
// TODO: indexedDB
|
||||
if ( window.indexedDB && !!window.indexedDB.webkitGetDatabaseNames ) {
|
||||
// var db = window.indexedDB.webkitGetDatabaseNames().onsuccess = function(sender) {
|
||||
// console.debug('webkitGetDatabaseNames(): result=%o', sender.target.result);
|
||||
// };
|
||||
}
|
||||
|
||||
// TODO: Web SQL
|
||||
if ( window.openDatabase ) {
|
||||
// Sad:
|
||||
// "There is no way to enumerate or delete the databases available for an origin from this API."
|
||||
// Ref.: http://www.w3.org/TR/webdatabase/#databases
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
localMessager.send({
|
||||
what: 'checkScriptBlacklisted',
|
||||
url: window.location.href
|
||||
}, checkScriptBlacklistedHandler);
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
// Executed only once.
|
||||
|
||||
(function() {
|
||||
var localStorageHandler = function(mustRemove) {
|
||||
if ( mustRemove ) {
|
||||
window.localStorage.clear();
|
||||
window.sessionStorage.clear();
|
||||
// console.debug('HTTP Switchboard > found and removed non-empty localStorage');
|
||||
}
|
||||
};
|
||||
|
||||
// Check with extension whether local storage must be emptied
|
||||
// rhill 2014-03-28: we need an exception handler in case 3rd-party access
|
||||
// to site data is disabled.
|
||||
// https://github.com/gorhill/httpswitchboard/issues/215
|
||||
try {
|
||||
var hasLocalStorage = window.localStorage && window.localStorage.length;
|
||||
var hasSessionStorage = window.sessionStorage && window.sessionStorage.length;
|
||||
if ( hasLocalStorage || hasSessionStorage ) {
|
||||
localMessager.send({
|
||||
what: 'contentScriptHasLocalStorage',
|
||||
url: window.location.href
|
||||
}, localStorageHandler);
|
||||
}
|
||||
|
||||
// TODO: indexedDB
|
||||
if ( window.indexedDB && !!window.indexedDB.webkitGetDatabaseNames ) {
|
||||
// var db = window.indexedDB.webkitGetDatabaseNames().onsuccess = function(sender) {
|
||||
// console.debug('webkitGetDatabaseNames(): result=%o', sender.target.result);
|
||||
// };
|
||||
}
|
||||
|
||||
// TODO: Web SQL
|
||||
if ( window.openDatabase ) {
|
||||
// Sad:
|
||||
// "There is no way to enumerate or delete the databases available for an origin from this API."
|
||||
// Ref.: http://www.w3.org/TR/webdatabase/#databases
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uMatrix/issues/45
|
||||
|
||||
var collapser = (function() {
|
||||
var timer = null;
|
||||
var requestId = 1;
|
||||
var newRequests = [];
|
||||
var pendingRequests = {};
|
||||
var pendingRequestCount = 0;
|
||||
var srcProps = {
|
||||
'iframe': 'src',
|
||||
'img': 'src'
|
||||
};
|
||||
|
||||
var PendingRequest = function(target, tagName, attr) {
|
||||
this.id = requestId++;
|
||||
this.target = target;
|
||||
pendingRequests[this.id] = this;
|
||||
pendingRequestCount += 1;
|
||||
};
|
||||
|
||||
// Because a while ago I have observed constructors are faster than
|
||||
// literal object instanciations.
|
||||
var BouncingRequest = function(id, tagName, url) {
|
||||
this.id = id;
|
||||
this.tagName = tagName;
|
||||
this.url = url;
|
||||
this.collapse = false;
|
||||
};
|
||||
|
||||
var onProcessed = function(requests) {
|
||||
if ( requests === null || Array.isArray(requests) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var i = requests.length;
|
||||
var request, entry;
|
||||
while ( i-- ) {
|
||||
request = requests[i];
|
||||
if ( pendingRequests.hasOwnProperty(request.id) === false ) {
|
||||
continue;
|
||||
}
|
||||
entry = pendingRequests[request.id];
|
||||
delete pendingRequests[request.id];
|
||||
pendingRequestCount -= 1;
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/869
|
||||
if ( !request.collapse ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/399
|
||||
// Never remove elements from the DOM, just hide them
|
||||
entry.target.style.setProperty('display', 'none', 'important');
|
||||
}
|
||||
// Renew map: I believe that even if all properties are deleted, an
|
||||
// object will still use more memory than a brand new one.
|
||||
if ( pendingRequestCount === 0 ) {
|
||||
pendingRequests = {};
|
||||
}
|
||||
};
|
||||
|
||||
var send = function() {
|
||||
timer = null;
|
||||
localMessager.send({
|
||||
what: 'evaluateURLs',
|
||||
requests: newRequests
|
||||
}, onProcessed);
|
||||
newRequests = [];
|
||||
};
|
||||
|
||||
var process = function(delay) {
|
||||
if ( newRequests.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
if ( delay === 0 ) {
|
||||
clearTimeout(timer);
|
||||
send();
|
||||
} else if ( timer === null ) {
|
||||
timer = setTimeout(send, delay || 50);
|
||||
}
|
||||
};
|
||||
|
||||
var addNode = function(target) {
|
||||
var tagName = target.localName;
|
||||
var prop = srcProps[tagName];
|
||||
if ( prop === undefined ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/174
|
||||
// Do not remove fragment from src URL
|
||||
var src = target[prop];
|
||||
if ( typeof src !== 'string' || src === '' ) {
|
||||
return;
|
||||
}
|
||||
if ( src.lastIndexOf('http', 0) !== 0 ) {
|
||||
return;
|
||||
}
|
||||
var req = new PendingRequest(target, tagName, prop);
|
||||
newRequests.push(new BouncingRequest(req.id, tagName, src));
|
||||
};
|
||||
|
||||
var addNodes = function(nodes) {
|
||||
var node;
|
||||
var i = nodes.length;
|
||||
while ( i-- ) {
|
||||
node = nodes[i];
|
||||
if ( node.nodeType === 1 ) {
|
||||
addNode(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var addBranches = function(branches) {
|
||||
var root;
|
||||
var i = branches.length;
|
||||
while ( i-- ) {
|
||||
root = branches[i];
|
||||
if ( root.nodeType === 1 ) {
|
||||
addNode(root);
|
||||
// blocked images will be reported by onResourceFailed
|
||||
addNodes(root.querySelectorAll('iframe'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Listener to collapse blocked resources.
|
||||
// - Future requests not blocked yet
|
||||
// - Elements dynamically added to the page
|
||||
// - Elements which resource URL changes
|
||||
var onResourceFailed = function(ev) {
|
||||
addNode(ev.target);
|
||||
process();
|
||||
};
|
||||
document.addEventListener('error', onResourceFailed, true);
|
||||
|
||||
vAPI.shutdown.add(function() {
|
||||
if ( timer !== null ) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
document.removeEventListener('error', onResourceFailed, true);
|
||||
newRequests = [];
|
||||
pendingRequests = {};
|
||||
pendingRequestCount = 0;
|
||||
});
|
||||
|
||||
return {
|
||||
addNodes: addNodes,
|
||||
addBranches: addBranches,
|
||||
process: process
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var nodesAddedHandler = function(nodeList, summary) {
|
||||
|
@ -154,17 +309,17 @@ var nodesAddedHandler = function(nodeList, summary) {
|
|||
if ( node.nodeType !== 1 ) {
|
||||
continue;
|
||||
}
|
||||
if ( typeof node.tagName !== 'string' ) {
|
||||
if ( typeof node.localName !== 'string' ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( node.tagName.toUpperCase() ) {
|
||||
switch ( node.localName ) {
|
||||
|
||||
case 'SCRIPT':
|
||||
case 'script':
|
||||
// https://github.com/gorhill/httpswitchboard/issues/252
|
||||
// Do not count µMatrix's own script tags, they are not required
|
||||
// to "unbreak" a web page
|
||||
if ( node.id && node.id.indexOf('uMatrix-') === 0 ) {
|
||||
if ( typeof node.id === 'string' && node.id.lastIndexOf('uMatrix-', 0) === 0 ) {
|
||||
break;
|
||||
}
|
||||
text = node.textContent.trim();
|
||||
|
@ -179,14 +334,14 @@ var nodesAddedHandler = function(nodeList, summary) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
if ( node.href.indexOf('javascript:') === 0 ) {
|
||||
case 'a':
|
||||
if ( node.href.lastIndexOf('javascript', 0) === 0 ) {
|
||||
summary.scriptSources['{inline_script}'] = true;
|
||||
summary.mustReport = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'OBJECT':
|
||||
case 'object':
|
||||
src = (node.data || '').trim();
|
||||
if ( src !== '' ) {
|
||||
summary.pluginSources[src] = true;
|
||||
|
@ -194,7 +349,7 @@ var nodesAddedHandler = function(nodeList, summary) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'EMBED':
|
||||
case 'embed':
|
||||
src = (node.src || '').trim();
|
||||
if ( src !== '' ) {
|
||||
summary.pluginSources[src] = true;
|
||||
|
@ -221,13 +376,18 @@ var nodeListsAddedHandler = function(nodeLists) {
|
|||
};
|
||||
while ( i-- ) {
|
||||
nodesAddedHandler(nodeLists[i], summary);
|
||||
collapser.addBranches(nodeLists[i]);
|
||||
}
|
||||
if ( summary.mustReport ) {
|
||||
localMessager.send(summary);
|
||||
}
|
||||
collapser.process();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// Executed only once.
|
||||
|
||||
(function() {
|
||||
var summary = {
|
||||
|
@ -241,62 +401,88 @@ var nodeListsAddedHandler = function(nodeLists) {
|
|||
// &
|
||||
// Looks for inline javascript also in at least one a[href] element.
|
||||
// https://github.com/gorhill/httpswitchboard/issues/131
|
||||
nodesAddedHandler(document.querySelectorAll('script, a[href^="javascript:"], object, embed'), summary);
|
||||
nodesAddedHandler(document.querySelectorAll('a[href^="javascript:"],embed,object,script'), summary);
|
||||
|
||||
//console.debug('contentscript-end.js > firstObservationHandler(): found %d script tags in "%s"', Object.keys(summary.scriptSources).length, window.location.href);
|
||||
|
||||
localMessager.send(summary);
|
||||
|
||||
collapser.addNodes(document.querySelectorAll('iframe,img'));
|
||||
collapser.process();
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// Observe changes in the DOM
|
||||
|
||||
// Added node lists will be cumulated here before being processed
|
||||
var addedNodeLists = [];
|
||||
var addedNodeListsTimer = null;
|
||||
|
||||
var treeMutationObservedHandler = function() {
|
||||
nodeListsAddedHandler(addedNodeLists);
|
||||
addedNodeListsTimer = null;
|
||||
addedNodeLists = [];
|
||||
};
|
||||
(function() {
|
||||
var addedNodeLists = [];
|
||||
var addedNodeListsTimer = null;
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/205
|
||||
// Do not handle added node directly from within mutation observer.
|
||||
var treeMutationObservedHandlerAsync = function(mutations) {
|
||||
var iMutation = mutations.length;
|
||||
var nodeList;
|
||||
while ( iMutation-- ) {
|
||||
nodeList = mutations[iMutation].addedNodes;
|
||||
if ( nodeList.length !== 0 ) {
|
||||
addedNodeLists.push(nodeList);
|
||||
var treeMutationObservedHandler = function() {
|
||||
nodeListsAddedHandler(addedNodeLists);
|
||||
addedNodeListsTimer = null;
|
||||
addedNodeLists = [];
|
||||
};
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/205
|
||||
// Do not handle added node directly from within mutation observer.
|
||||
var treeMutationObservedHandlerAsync = function(mutations) {
|
||||
var iMutation = mutations.length;
|
||||
var nodeList;
|
||||
while ( iMutation-- ) {
|
||||
nodeList = mutations[iMutation].addedNodes;
|
||||
if ( nodeList.length !== 0 ) {
|
||||
addedNodeLists.push(nodeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
// I arbitrarily chose 250 ms for now:
|
||||
// I have to compromise between the overhead of processing too few
|
||||
// nodes too often and the delay of many nodes less often. There is nothing
|
||||
// time critical here.
|
||||
if ( addedNodeListsTimer === null ) {
|
||||
addedNodeListsTimer = setTimeout(treeMutationObservedHandler, 250);
|
||||
}
|
||||
};
|
||||
// I arbitrarily chose 250 ms for now:
|
||||
// I have to compromise between the overhead of processing too few
|
||||
// nodes too often and the delay of many nodes less often. There is nothing
|
||||
// time critical here.
|
||||
if ( addedNodeListsTimer === null ) {
|
||||
addedNodeListsTimer = setTimeout(treeMutationObservedHandler, 250);
|
||||
}
|
||||
};
|
||||
|
||||
// This fixes http://acid3.acidtests.org/
|
||||
if ( document.body ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This fixes http://acid3.acidtests.org/
|
||||
if ( document.body ) {
|
||||
// https://github.com/gorhill/httpswitchboard/issues/176
|
||||
var treeObserver = new MutationObserver(treeMutationObservedHandlerAsync);
|
||||
treeObserver.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.shutdown.add(function() {
|
||||
if ( addedNodeListsTimer !== null ) {
|
||||
clearTimeout(addedNodeListsTimer);
|
||||
addedNodeListsTimer = null;
|
||||
}
|
||||
if ( treeObserver !== null ) {
|
||||
treeObserver.disconnect();
|
||||
treeObserver = null;
|
||||
}
|
||||
addedNodeLists = [];
|
||||
});
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
localMessager.send({ what: 'shutdown?' }, function(response) {
|
||||
if ( response === true ) {
|
||||
vAPI.shutdown.exec();
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
|
|
@ -446,6 +446,45 @@ var contentScriptLocalStorageHandler = function(tabId, pageURL) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// Evaluate many URLs against the matrix.
|
||||
|
||||
var evaluateURLs = function(tabId, requests) {
|
||||
if ( µm.userSettings.collapseBlocked === false ) {
|
||||
return requests;
|
||||
}
|
||||
|
||||
// Create evaluation context
|
||||
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||
if ( tabContext === null ) {
|
||||
return requests;
|
||||
}
|
||||
var rootHostname = tabContext.rootHostname;
|
||||
|
||||
//console.debug('messaging.js/contentscript-end.js: processing %d requests', requests.length);
|
||||
|
||||
var µmuri = µm.URI;
|
||||
var typeMap = tagNameToRequestTypeMap;
|
||||
var request;
|
||||
var i = requests.length;
|
||||
while ( i-- ) {
|
||||
request = requests[i];
|
||||
request.collapse = µm.mustBlock(
|
||||
rootHostname,
|
||||
µmuri.hostnameFromURI(request.url),
|
||||
typeMap[request.tagName]
|
||||
);
|
||||
}
|
||||
|
||||
return requests;
|
||||
};
|
||||
|
||||
var tagNameToRequestTypeMap = {
|
||||
'iframe': 'sub_frame',
|
||||
'img': 'image'
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMessage = function(request, sender, callback) {
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
|
@ -453,20 +492,12 @@ var onMessage = function(request, sender, callback) {
|
|||
break;
|
||||
}
|
||||
|
||||
var tabId = sender.tab.id;
|
||||
var tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
|
||||
|
||||
// Sync
|
||||
var response;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'contentScriptHasLocalStorage':
|
||||
response = contentScriptLocalStorageHandler(tabId, request.url);
|
||||
break;
|
||||
|
||||
case 'contentScriptSummary':
|
||||
contentScriptSummaryHandler(tabId, request);
|
||||
break;
|
||||
|
||||
case 'checkScriptBlacklisted':
|
||||
response = {
|
||||
scriptBlacklisted: µm.mustBlock(
|
||||
|
@ -477,12 +508,31 @@ var onMessage = function(request, sender, callback) {
|
|||
};
|
||||
break;
|
||||
|
||||
case 'contentScriptHasLocalStorage':
|
||||
response = contentScriptLocalStorageHandler(tabId, request.url);
|
||||
break;
|
||||
|
||||
case 'contentScriptSummary':
|
||||
contentScriptSummaryHandler(tabId, request);
|
||||
break;
|
||||
|
||||
case 'evaluateURLs':
|
||||
response = evaluateURLs(tabId, request.requests);
|
||||
break;
|
||||
|
||||
case 'getUserAgentReplaceStr':
|
||||
response = µm.tMatrix.evaluateSwitchZ('ua-spoof', request.hostname) ?
|
||||
µm.userAgentReplaceStr :
|
||||
undefined;
|
||||
break;
|
||||
|
||||
case 'shutdown?':
|
||||
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||
if ( tabContext !== null ) {
|
||||
response = µm.tMatrix.evaluateSwitchZ('matrix-off', tabContext.rootHostname);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return vAPI.messaging.UNHANDLED;
|
||||
}
|
||||
|
|
|
@ -57,12 +57,16 @@ ul > li {
|
|||
<h2 data-i18n="settingsMatrixConvenienceHeader"></h2>
|
||||
<ul>
|
||||
<li>
|
||||
<input id="collapseBlocked" type="checkbox" data-range="bool">
|
||||
<label data-i18n="settingsCollapseBlocked" for="collapseBlocked"></label>
|
||||
<!-- <li>
|
||||
<span data-i18n="settingsMatrixAutoReloadPrompt"></span> <select id="smart-auto-reload">
|
||||
<option value="none" data-i18n="settingsMatrixAutoReloadNone">
|
||||
<option value="current" data-i18n="settingsMatrixAutoReloadCurrent">
|
||||
<option value="all" data-i18n="settingsMatrixAutoReloadAll">
|
||||
</select> <button class="whatisthis"></button>
|
||||
<div class="whatisthis-expandable para" data-i18n="settingsMatrixAutoReloadInfo"></div>
|
||||
-->
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue