Incorporate new xiMatrix features.
このコミットが含まれているのは:
コミット
8cc7ad512a
|
@ -8,7 +8,7 @@ Built atop the excellent project [xiMatrix](https://github.com/xi/xiMatrix) by T
|
||||||
|
|
||||||
## Why use xiMatrix as a basis instead of uMatrix?
|
## Why use xiMatrix as a basis instead of uMatrix?
|
||||||
|
|
||||||
xiMatrix is simpler with a smaller codebase and is therefore more suitable to hack upon. It is already built in the spririt of 'do one thing and do it well' and implements some of the features I would have liked to see added to uMatrix. uMatrix covers things which may be considered outside the scope of a web request firewall such as spoofing values and managing local storage.
|
xiMatrix is simpler with a smaller codebase and is therefore more suitable to hack upon. It is already built in the spirit of 'do one thing and do it well' and implements some of the features I would have liked to see added to uMatrix. uMatrix covers things which may be considered outside the scope of a web request firewall such as spoofing values and managing local storage.
|
||||||
|
|
||||||
## Why not just contribute to xi's xiMatrix?
|
## Why not just contribute to xi's xiMatrix?
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ He has clearly stated in his project that it is a personal tool and will not lik
|
||||||
|
|
||||||
## TO DO
|
## TO DO
|
||||||
|
|
||||||
- Add column for blocking cookies. Cookie blocking is not as simple as other requests, as it necessitates accepting site cookies (but *not returning* them) when they are blocked.
|
|
||||||
- Display enumerated requests blocked in icon.
|
- Display enumerated requests blocked in icon.
|
||||||
- Placeholder element for blocked images/video.
|
- Placeholder element for blocked images/video.
|
||||||
- Update in-place while keeping paraMatrix popup open.
|
- Update in-place while keeping paraMatrix popup open.
|
||||||
|
|
バイナリ
screenshot.png
バイナリ
screenshot.png
バイナリファイルは表示されません。
変更前 幅: | 高さ: | サイズ: 44 KiB 変更後 幅: | 高さ: | サイズ: 61 KiB |
44
src/bg.js
44
src/bg.js
|
@ -148,6 +148,11 @@ browser.runtime.onMessage.addListener((msg, sender) => {
|
||||||
}
|
}
|
||||||
return savedRules;
|
return savedRules;
|
||||||
}));
|
}));
|
||||||
|
} else if (msg.type === 'reset') {
|
||||||
|
return storageChange('rules', rules => {
|
||||||
|
delete rules[msg.data];
|
||||||
|
return rules;
|
||||||
|
});
|
||||||
} else if (msg.type === 'securitypolicyviolation') {
|
} else if (msg.type === 'securitypolicyviolation') {
|
||||||
return pushRequest(sender.tab.id, 'inline', msg.data);
|
return pushRequest(sender.tab.id, 'inline', msg.data);
|
||||||
} else if (msg.type === 'toggleRecording') {
|
} else if (msg.type === 'toggleRecording') {
|
||||||
|
@ -162,12 +167,8 @@ browser.webNavigation.onBeforeNavigate.addListener(details => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
browser.webRequest.onBeforeRequest.addListener(details => {
|
browser.webRequest.onBeforeSendHeaders.addListener(details => {
|
||||||
if (details.type === 'main_frame') {
|
var context = getHostname(details.documentUrl || details.url);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = getHostname(details.documentUrl);
|
|
||||||
if (details.frameAncestors.length) {
|
if (details.frameAncestors.length) {
|
||||||
var last = details.frameAncestors.length - 1;
|
var last = details.frameAncestors.length - 1;
|
||||||
context = getHostname(details.frameAncestors[last].url);
|
context = getHostname(details.frameAncestors[last].url);
|
||||||
|
@ -175,11 +176,21 @@ browser.webRequest.onBeforeRequest.addListener(details => {
|
||||||
var hostname = getHostname(details.url);
|
var hostname = getHostname(details.url);
|
||||||
var type = shared.TYPE_MAP[details.type] || 'other';
|
var type = shared.TYPE_MAP[details.type] || 'other';
|
||||||
|
|
||||||
|
let isCookie = h => h.name.toLowerCase() === 'cookie';
|
||||||
|
var cookiePromise = Promise.resolve();
|
||||||
|
if (details.requestHeaders.some(isCookie)) {
|
||||||
|
cookiePromise = pushRequest(details.tabId, hostname, 'cookie');
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
pushRequest(details.tabId, hostname, type),
|
pushRequest(details.tabId, hostname, type),
|
||||||
|
cookiePromise,
|
||||||
getRules(context),
|
getRules(context),
|
||||||
]).then(([_, rules]) => {
|
]).then(([_, _2, rules]) => {
|
||||||
if (!shared.shouldAllow(rules, context, hostname, type)) {
|
if (
|
||||||
|
details.type !== 'main_frame'
|
||||||
|
&& !shared.shouldAllow(rules, context, hostname, type)
|
||||||
|
) {
|
||||||
if (details.type === 'sub_frame') {
|
if (details.type === 'sub_frame') {
|
||||||
// this can in turn be blocked by a local CSP
|
// this can in turn be blocked by a local CSP
|
||||||
return {redirectUrl: 'data:,' + encodeURIComponent(details.url)};
|
return {redirectUrl: 'data:,' + encodeURIComponent(details.url)};
|
||||||
|
@ -187,10 +198,17 @@ browser.webRequest.onBeforeRequest.addListener(details => {
|
||||||
return {cancel: true};
|
return {cancel: true};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}, {urls: ['<all_urls>']}, ['blocking']);
|
|
||||||
|
|
||||||
browser.webRequest.onHeadersReceived.addListener(function(details) {
|
if (shared.shouldAllow(rules, context, hostname, 'cookie')) {
|
||||||
|
return {requestHeaders: details.requestHeaders};
|
||||||
|
} else {
|
||||||
|
var filtered = details.requestHeaders.filter(h => !isCookie(h));
|
||||||
|
return {requestHeaders: filtered};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {urls: ['<all_urls>']}, ['blocking', 'requestHeaders']);
|
||||||
|
|
||||||
|
browser.webRequest.onHeadersReceived.addListener(details => {
|
||||||
var context = getHostname(details.url);
|
var context = getHostname(details.url);
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
getRules(context),
|
getRules(context),
|
||||||
|
@ -215,9 +233,7 @@ browser.webRequest.onHeadersReceived.addListener(function(details) {
|
||||||
csp('script', "script-src 'self' *");
|
csp('script', "script-src 'self' *");
|
||||||
csp('media', "img-src 'self' *");
|
csp('media', "img-src 'self' *");
|
||||||
|
|
||||||
return {
|
return {responseHeaders: details.responseHeaders};
|
||||||
responseHeaders: details.responseHeaders,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}, {
|
}, {
|
||||||
urls: ['<all_urls>'],
|
urls: ['<all_urls>'],
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
table {
|
table {
|
||||||
background: var(--orange-light);
|
background: var(--orange-light);
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
margin-bottom: 0.2em;
|
margin-block-end: 0.2em;
|
||||||
}
|
}
|
||||||
th, td {
|
th, td {
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid #1f2042;
|
border: 1px solid #1f2042;
|
||||||
min-width: 3.4em;
|
min-inline-size: 3.4em;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="popup.css">
|
<link rel="stylesheet" href="popup.css">
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
recording
|
recording
|
||||||
</label>
|
</label>
|
||||||
<button type="button" name="commit" disabled>Commit</button>
|
<button type="button" name="commit" disabled>Commit</button>
|
||||||
|
<button type="button" name="reset" disabled>Reset</button>
|
||||||
<button type="button" name="reload" disabled>Reload page</button>
|
<button type="button" name="reload" disabled>Reload page</button>
|
||||||
<button type="button" name="settings">Edit rules</button>
|
<button type="button" name="settings">Edit rules</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
11
src/popup.js
11
src/popup.js
|
@ -7,6 +7,7 @@ var rules;
|
||||||
var table = document.querySelector('table');
|
var table = document.querySelector('table');
|
||||||
var recording = document.querySelector('[name="recording"]')
|
var recording = document.querySelector('[name="recording"]')
|
||||||
var commitButton = document.querySelector('[name="commit"]');
|
var commitButton = document.querySelector('[name="commit"]');
|
||||||
|
var resetButton = document.querySelector('[name="reset"]');
|
||||||
var reloadButton = document.querySelector('[name="reload"]');
|
var reloadButton = document.querySelector('[name="reload"]');
|
||||||
|
|
||||||
var sendMessage = function(type, data) {
|
var sendMessage = function(type, data) {
|
||||||
|
@ -84,6 +85,7 @@ var createCheckbox = function(hostname, type) {
|
||||||
}).then(newRules => {
|
}).then(newRules => {
|
||||||
rules = newRules;
|
rules = newRules;
|
||||||
commitButton.disabled = !rules.dirty;
|
commitButton.disabled = !rules.dirty;
|
||||||
|
resetButton.disabled = !rules.dirty;
|
||||||
reloadButton.disabled = !rules.dirty;
|
reloadButton.disabled = !rules.dirty;
|
||||||
updateInherit(type);
|
updateInherit(type);
|
||||||
});
|
});
|
||||||
|
@ -134,12 +136,13 @@ var createRow = function(hostname) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadContext = function() {
|
var loadContext = function() {
|
||||||
sendMessage('get').then(data => {
|
return sendMessage('get').then(data => {
|
||||||
context = data.context;
|
context = data.context;
|
||||||
requests = data.requests;
|
requests = data.requests;
|
||||||
rules = data.rules;
|
rules = data.rules;
|
||||||
recording.checked = data.recording;
|
recording.checked = data.recording;
|
||||||
commitButton.disabled = !rules.dirty;
|
commitButton.disabled = !rules.dirty;
|
||||||
|
resetButton.disabled = !rules.dirty;
|
||||||
|
|
||||||
table.innerHTML = '';
|
table.innerHTML = '';
|
||||||
table.append(createHeader());
|
table.append(createHeader());
|
||||||
|
@ -175,5 +178,11 @@ reloadButton.addEventListener('click', event => {
|
||||||
commitButton.addEventListener('click', event => {
|
commitButton.addEventListener('click', event => {
|
||||||
sendMessage('commit', context).then(() => {
|
sendMessage('commit', context).then(() => {
|
||||||
commitButton.disabled = true;
|
commitButton.disabled = true;
|
||||||
|
resetButton.disabled = true;
|
||||||
|
reloadButton.disabled= true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
resetButton.addEventListener('click', event => {
|
||||||
|
sendMessage('reset', context).then(loadContext);
|
||||||
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
height: 100vh;
|
block-size: 100vb;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 1fr min-content;
|
grid-template-rows: 1fr min-content;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
|
@ -17,13 +17,19 @@ form {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
block-size: 100%;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
padding: 0.5em 2em;
|
padding-block: 0.5em;
|
||||||
|
padding-inline: 2em;
|
||||||
justify-self: end;
|
justify-self: end;
|
||||||
grid-column: 1 / 3;
|
grid-column: 1 / 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="settings.css">
|
<link rel="stylesheet" href="settings.css">
|
||||||
|
@ -7,8 +7,14 @@
|
||||||
</head>
|
</head>
|
||||||
<body text="#d9d9d9" bgcolor="#1f2042">
|
<body text="#d9d9d9" bgcolor="#1f2042">
|
||||||
<form>
|
<form>
|
||||||
<textarea style="background-color:#868686;" class="rules"></textarea>
|
<label>
|
||||||
<textarea style="background-color:#868686;" class="savedRules"></textarea>
|
Temporary rules
|
||||||
|
<textarea class="rules" style="background-color:#868686"></textarea>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Commited rules
|
||||||
|
<textarea class="savedRules" style="background-color:#868686"></textarea>
|
||||||
|
</label>
|
||||||
<button>Save</button>
|
<button>Save</button>
|
||||||
</form>
|
</form>
|
||||||
<script src="shared.js"></script>
|
<script src="shared.js"></script>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var shared = {};
|
var shared = {};
|
||||||
|
|
||||||
shared.TYPES = ['font', 'css', 'image', 'media', 'script', 'xhr', 'frame', 'other'];
|
shared.TYPES = ['cookie', 'font', 'css', 'image', 'media', 'script', 'xhr', 'frame', 'other'];
|
||||||
shared.TYPE_MAP = {
|
shared.TYPE_MAP = {
|
||||||
'stylesheet': 'css',
|
'stylesheet': 'css',
|
||||||
'font': 'font',
|
'font': 'font',
|
||||||
|
|
読み込み中…
新しいイシューから参照