mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-03 02:44:57 +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,
|
"manifest_version": 2,
|
||||||
"name": "µMatrix",
|
"name": "uMatrix",
|
||||||
"short_name": "µMatrix",
|
"short_name": "uMatrix",
|
||||||
"version": "0.8.1.4",
|
"version": "0.8.1.4",
|
||||||
"description": "__MSG_extShortDesc__",
|
"description": "__MSG_extShortDesc__",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
"default_icon": {
|
"default_icon": {
|
||||||
"19": "img/browsericons/icon19-19.png"
|
"19": "img/browsericons/icon19-19.png"
|
||||||
},
|
},
|
||||||
"default_title": "µMatrix",
|
"default_title": "uMatrix",
|
||||||
"default_popup": "popup.html"
|
"default_popup": "popup.html"
|
||||||
},
|
},
|
||||||
"author": "Raymond Hill",
|
"author": "Raymond Hill",
|
||||||
|
|
|
@ -299,6 +299,10 @@
|
||||||
"message": "Opacity",
|
"message": "Opacity",
|
||||||
"description": "English: Opacity"
|
"description": "English: Opacity"
|
||||||
},
|
},
|
||||||
|
"settingsCollapseBlocked" : {
|
||||||
|
"message": "Collapse placeholder of blocked elements",
|
||||||
|
"description": "English: Collapse placeholder of blocked elements"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
"privacyPageTitle" : {
|
"privacyPageTitle" : {
|
||||||
|
|
|
@ -462,22 +462,22 @@ body.powerOff .matrix .g4Meta.g4Collapsed ~ .matRow.ro {
|
||||||
/* Cell coloring for color blind-friendly (hopefully) */
|
/* Cell coloring for color blind-friendly (hopefully) */
|
||||||
body.colorblind .t81 {
|
body.colorblind .t81 {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #000;
|
background-color: rgb(0, 19, 110);
|
||||||
}
|
}
|
||||||
body.colorblind .t82 {
|
body.colorblind .t82 {
|
||||||
border-color: #aaa;
|
border-color: rgb(255, 194, 57);
|
||||||
color: black;
|
color: black;
|
||||||
background-color: #fff;
|
background-color: rgb(255, 194, 57);
|
||||||
}
|
}
|
||||||
body.colorblind .t1 {
|
body.colorblind .t1 {
|
||||||
border-color: #333;
|
border-color: rgba(0, 19, 110, 0.3);
|
||||||
color: white;
|
color: black;
|
||||||
background-color: #666;
|
background-color: rgba(0, 19, 110, 0.2);
|
||||||
}
|
}
|
||||||
body.colorblind .t2 {
|
body.colorblind .t2 {
|
||||||
border-color: #aaa;
|
border-color: rgba(255, 194, 57, 0.3);
|
||||||
color: black;
|
color: black;
|
||||||
background-color: #ccc;
|
background-color: rgba(255, 194, 57, 0.2);
|
||||||
}
|
}
|
||||||
body.colorblind .matCell.p81 {
|
body.colorblind .matCell.p81 {
|
||||||
background-image: url('../img/permanent-black-small-cb.png');
|
background-image: url('../img/permanent-black-small-cb.png');
|
||||||
|
@ -533,18 +533,15 @@ body.powerOff #whitelist, body.powerOff #blacklist {
|
||||||
background-color: #080;
|
background-color: #080;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
body.colorblind .rw .matCell.t1 #whitelist:hover {
|
body.colorblind .rw .matCell.t1 #whitelist:hover,
|
||||||
background-color: #fff;
|
body.colorblind .rw .matCell.t2 #whitelist:hover {
|
||||||
|
background-color: rgb(255, 194, 57);
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
.rw .matCell.t2 #whitelist:hover {
|
.rw .matCell.t2 #whitelist:hover {
|
||||||
background-color: #080;
|
background-color: #080;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
body.colorblind .rw .matCell.t2 #whitelist:hover {
|
|
||||||
background-color: #fff;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
.matCell.t81 #whitelist:hover {
|
.matCell.t81 #whitelist:hover {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -555,18 +552,15 @@ body.colorblind .rw .matCell.t2 #whitelist:hover {
|
||||||
background-color: #c00;
|
background-color: #c00;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
body.colorblind .rw .matCell.t1 #blacklist:hover {
|
body.colorblind .rw .matCell.t1 #blacklist:hover,
|
||||||
background-color: #000;
|
body.colorblind .rw .matCell.t2 #blacklist:hover {
|
||||||
|
background-color: rgb(0, 19, 110);
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
.rw .matCell.t2 #blacklist:hover {
|
.rw .matCell.t2 #blacklist:hover {
|
||||||
background-color: #c00;
|
background-color: #c00;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
body.colorblind .rw .matCell.t2 #blacklist:hover {
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
.matCell.t81 #blacklist:hover {
|
.matCell.t81 #blacklist:hover {
|
||||||
background-color: transparent;
|
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,
|
autoUpdate: false,
|
||||||
clearBrowserCache: true,
|
clearBrowserCache: true,
|
||||||
clearBrowserCacheAfter: 60,
|
clearBrowserCacheAfter: 60,
|
||||||
|
collapseBlocked: false,
|
||||||
colorBlindFriendly: false,
|
colorBlindFriendly: false,
|
||||||
deleteCookies: false,
|
deleteCookies: false,
|
||||||
deleteUnusedSessionCookies: false,
|
deleteUnusedSessionCookies: false,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
µMatrix - a Chromium browser extension to black/white list requests.
|
µ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
|
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
|
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');
|
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
|
// Unrendered noscript (because CSP) workaround
|
||||||
// means the code will be flushed from memory once executed.
|
|
||||||
|
// Executed once.
|
||||||
|
|
||||||
(function() {
|
(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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
localMessager.send({
|
||||||
|
what: 'checkScriptBlacklisted',
|
||||||
/*------------[ Unrendered Noscript (because CSP) Workaround ]----------------*/
|
url: window.location.href
|
||||||
|
}, checkScriptBlacklistedHandler);
|
||||||
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) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
(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) {
|
var nodesAddedHandler = function(nodeList, summary) {
|
||||||
|
@ -154,17 +309,17 @@ var nodesAddedHandler = function(nodeList, summary) {
|
||||||
if ( node.nodeType !== 1 ) {
|
if ( node.nodeType !== 1 ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( typeof node.tagName !== 'string' ) {
|
if ( typeof node.localName !== 'string' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( node.tagName.toUpperCase() ) {
|
switch ( node.localName ) {
|
||||||
|
|
||||||
case 'SCRIPT':
|
case 'script':
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/252
|
// https://github.com/gorhill/httpswitchboard/issues/252
|
||||||
// Do not count µMatrix's own script tags, they are not required
|
// Do not count µMatrix's own script tags, they are not required
|
||||||
// to "unbreak" a web page
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
text = node.textContent.trim();
|
text = node.textContent.trim();
|
||||||
|
@ -179,14 +334,14 @@ var nodesAddedHandler = function(nodeList, summary) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'a':
|
||||||
if ( node.href.indexOf('javascript:') === 0 ) {
|
if ( node.href.lastIndexOf('javascript', 0) === 0 ) {
|
||||||
summary.scriptSources['{inline_script}'] = true;
|
summary.scriptSources['{inline_script}'] = true;
|
||||||
summary.mustReport = true;
|
summary.mustReport = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'OBJECT':
|
case 'object':
|
||||||
src = (node.data || '').trim();
|
src = (node.data || '').trim();
|
||||||
if ( src !== '' ) {
|
if ( src !== '' ) {
|
||||||
summary.pluginSources[src] = true;
|
summary.pluginSources[src] = true;
|
||||||
|
@ -194,7 +349,7 @@ var nodesAddedHandler = function(nodeList, summary) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'EMBED':
|
case 'embed':
|
||||||
src = (node.src || '').trim();
|
src = (node.src || '').trim();
|
||||||
if ( src !== '' ) {
|
if ( src !== '' ) {
|
||||||
summary.pluginSources[src] = true;
|
summary.pluginSources[src] = true;
|
||||||
|
@ -221,13 +376,18 @@ var nodeListsAddedHandler = function(nodeLists) {
|
||||||
};
|
};
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
nodesAddedHandler(nodeLists[i], summary);
|
nodesAddedHandler(nodeLists[i], summary);
|
||||||
|
collapser.addBranches(nodeLists[i]);
|
||||||
}
|
}
|
||||||
if ( summary.mustReport ) {
|
if ( summary.mustReport ) {
|
||||||
localMessager.send(summary);
|
localMessager.send(summary);
|
||||||
}
|
}
|
||||||
|
collapser.process();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Executed only once.
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var summary = {
|
var summary = {
|
||||||
|
@ -241,62 +401,88 @@ var nodeListsAddedHandler = function(nodeLists) {
|
||||||
// &
|
// &
|
||||||
// Looks for inline javascript also in at least one a[href] element.
|
// Looks for inline javascript also in at least one a[href] element.
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/131
|
// 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);
|
//console.debug('contentscript-end.js > firstObservationHandler(): found %d script tags in "%s"', Object.keys(summary.scriptSources).length, window.location.href);
|
||||||
|
|
||||||
localMessager.send(summary);
|
localMessager.send(summary);
|
||||||
|
|
||||||
|
collapser.addNodes(document.querySelectorAll('iframe,img'));
|
||||||
|
collapser.process();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Observe changes in the DOM
|
// Observe changes in the DOM
|
||||||
|
|
||||||
// Added node lists will be cumulated here before being processed
|
// Added node lists will be cumulated here before being processed
|
||||||
var addedNodeLists = [];
|
|
||||||
var addedNodeListsTimer = null;
|
|
||||||
|
|
||||||
var treeMutationObservedHandler = function() {
|
(function() {
|
||||||
nodeListsAddedHandler(addedNodeLists);
|
var addedNodeLists = [];
|
||||||
addedNodeListsTimer = null;
|
var addedNodeListsTimer = null;
|
||||||
addedNodeLists = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/205
|
var treeMutationObservedHandler = function() {
|
||||||
// Do not handle added node directly from within mutation observer.
|
nodeListsAddedHandler(addedNodeLists);
|
||||||
var treeMutationObservedHandlerAsync = function(mutations) {
|
addedNodeListsTimer = null;
|
||||||
var iMutation = mutations.length;
|
addedNodeLists = [];
|
||||||
var nodeList;
|
};
|
||||||
while ( iMutation-- ) {
|
|
||||||
nodeList = mutations[iMutation].addedNodes;
|
// https://github.com/gorhill/uBlock/issues/205
|
||||||
if ( nodeList.length !== 0 ) {
|
// Do not handle added node directly from within mutation observer.
|
||||||
addedNodeLists.push(nodeList);
|
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 arbitrarily chose 250 ms for now:
|
// I have to compromise between the overhead of processing too few
|
||||||
// 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
|
||||||
// nodes too often and the delay of many nodes less often. There is nothing
|
// time critical here.
|
||||||
// time critical here.
|
if ( addedNodeListsTimer === null ) {
|
||||||
if ( addedNodeListsTimer === null ) {
|
addedNodeListsTimer = setTimeout(treeMutationObservedHandler, 250);
|
||||||
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
|
// https://github.com/gorhill/httpswitchboard/issues/176
|
||||||
var treeObserver = new MutationObserver(treeMutationObservedHandlerAsync);
|
var treeObserver = new MutationObserver(treeMutationObservedHandlerAsync);
|
||||||
treeObserver.observe(document.body, {
|
treeObserver.observe(document.body, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: 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) {
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
|
@ -453,20 +492,12 @@ var onMessage = function(request, sender, callback) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabId = sender.tab.id;
|
var tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
var response;
|
var response;
|
||||||
|
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
case 'contentScriptHasLocalStorage':
|
|
||||||
response = contentScriptLocalStorageHandler(tabId, request.url);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'contentScriptSummary':
|
|
||||||
contentScriptSummaryHandler(tabId, request);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'checkScriptBlacklisted':
|
case 'checkScriptBlacklisted':
|
||||||
response = {
|
response = {
|
||||||
scriptBlacklisted: µm.mustBlock(
|
scriptBlacklisted: µm.mustBlock(
|
||||||
|
@ -477,12 +508,31 @@ var onMessage = function(request, sender, callback) {
|
||||||
};
|
};
|
||||||
break;
|
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':
|
case 'getUserAgentReplaceStr':
|
||||||
response = µm.tMatrix.evaluateSwitchZ('ua-spoof', request.hostname) ?
|
response = µm.tMatrix.evaluateSwitchZ('ua-spoof', request.hostname) ?
|
||||||
µm.userAgentReplaceStr :
|
µm.userAgentReplaceStr :
|
||||||
undefined;
|
undefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'shutdown?':
|
||||||
|
var tabContext = µm.tabContextManager.lookup(tabId);
|
||||||
|
if ( tabContext !== null ) {
|
||||||
|
response = µm.tMatrix.evaluateSwitchZ('matrix-off', tabContext.rootHostname);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return vAPI.messaging.UNHANDLED;
|
return vAPI.messaging.UNHANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,16 @@ ul > li {
|
||||||
<h2 data-i18n="settingsMatrixConvenienceHeader"></h2>
|
<h2 data-i18n="settingsMatrixConvenienceHeader"></h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<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">
|
<span data-i18n="settingsMatrixAutoReloadPrompt"></span> <select id="smart-auto-reload">
|
||||||
<option value="none" data-i18n="settingsMatrixAutoReloadNone">
|
<option value="none" data-i18n="settingsMatrixAutoReloadNone">
|
||||||
<option value="current" data-i18n="settingsMatrixAutoReloadCurrent">
|
<option value="current" data-i18n="settingsMatrixAutoReloadCurrent">
|
||||||
<option value="all" data-i18n="settingsMatrixAutoReloadAll">
|
<option value="all" data-i18n="settingsMatrixAutoReloadAll">
|
||||||
</select> <button class="whatisthis"></button>
|
</select> <button class="whatisthis"></button>
|
||||||
<div class="whatisthis-expandable para" data-i18n="settingsMatrixAutoReloadInfo"></div>
|
<div class="whatisthis-expandable para" data-i18n="settingsMatrixAutoReloadInfo"></div>
|
||||||
|
-->
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue