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?
|
||||
|
||||
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?
|
||||
|
||||
|
@ -34,7 +34,6 @@ He has clearly stated in his project that it is a personal tool and will not lik
|
|||
|
||||
## 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.
|
||||
- Placeholder element for blocked images/video.
|
||||
- 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;
|
||||
}));
|
||||
} else if (msg.type === 'reset') {
|
||||
return storageChange('rules', rules => {
|
||||
delete rules[msg.data];
|
||||
return rules;
|
||||
});
|
||||
} else if (msg.type === 'securitypolicyviolation') {
|
||||
return pushRequest(sender.tab.id, 'inline', msg.data);
|
||||
} else if (msg.type === 'toggleRecording') {
|
||||
|
@ -162,12 +167,8 @@ browser.webNavigation.onBeforeNavigate.addListener(details => {
|
|||
}
|
||||
});
|
||||
|
||||
browser.webRequest.onBeforeRequest.addListener(details => {
|
||||
if (details.type === 'main_frame') {
|
||||
return;
|
||||
}
|
||||
|
||||
var context = getHostname(details.documentUrl);
|
||||
browser.webRequest.onBeforeSendHeaders.addListener(details => {
|
||||
var context = getHostname(details.documentUrl || details.url);
|
||||
if (details.frameAncestors.length) {
|
||||
var last = details.frameAncestors.length - 1;
|
||||
context = getHostname(details.frameAncestors[last].url);
|
||||
|
@ -175,11 +176,21 @@ browser.webRequest.onBeforeRequest.addListener(details => {
|
|||
var hostname = getHostname(details.url);
|
||||
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([
|
||||
pushRequest(details.tabId, hostname, type),
|
||||
cookiePromise,
|
||||
getRules(context),
|
||||
]).then(([_, rules]) => {
|
||||
if (!shared.shouldAllow(rules, context, hostname, type)) {
|
||||
]).then(([_, _2, rules]) => {
|
||||
if (
|
||||
details.type !== 'main_frame'
|
||||
&& !shared.shouldAllow(rules, context, hostname, type)
|
||||
) {
|
||||
if (details.type === 'sub_frame') {
|
||||
// this can in turn be blocked by a local CSP
|
||||
return {redirectUrl: 'data:,' + encodeURIComponent(details.url)};
|
||||
|
@ -187,10 +198,17 @@ browser.webRequest.onBeforeRequest.addListener(details => {
|
|||
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);
|
||||
return Promise.all([
|
||||
getRules(context),
|
||||
|
@ -215,9 +233,7 @@ browser.webRequest.onHeadersReceived.addListener(function(details) {
|
|||
csp('script', "script-src 'self' *");
|
||||
csp('media', "img-src 'self' *");
|
||||
|
||||
return {
|
||||
responseHeaders: details.responseHeaders,
|
||||
};
|
||||
return {responseHeaders: details.responseHeaders};
|
||||
});
|
||||
}, {
|
||||
urls: ['<all_urls>'],
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
table {
|
||||
background: var(--orange-light);
|
||||
border-spacing: 0;
|
||||
margin-bottom: 0.2em;
|
||||
margin-block-end: 0.2em;
|
||||
}
|
||||
th, td {
|
||||
position: relative;
|
||||
border: 1px solid #1f2042;
|
||||
min-width: 3.4em;
|
||||
min-inline-size: 3.4em;
|
||||
line-height: 1.8;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="popup.css">
|
||||
|
@ -12,6 +12,7 @@
|
|||
recording
|
||||
</label>
|
||||
<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="settings">Edit rules</button>
|
||||
</div>
|
||||
|
|
11
src/popup.js
11
src/popup.js
|
@ -7,6 +7,7 @@ var rules;
|
|||
var table = document.querySelector('table');
|
||||
var recording = document.querySelector('[name="recording"]')
|
||||
var commitButton = document.querySelector('[name="commit"]');
|
||||
var resetButton = document.querySelector('[name="reset"]');
|
||||
var reloadButton = document.querySelector('[name="reload"]');
|
||||
|
||||
var sendMessage = function(type, data) {
|
||||
|
@ -84,6 +85,7 @@ var createCheckbox = function(hostname, type) {
|
|||
}).then(newRules => {
|
||||
rules = newRules;
|
||||
commitButton.disabled = !rules.dirty;
|
||||
resetButton.disabled = !rules.dirty;
|
||||
reloadButton.disabled = !rules.dirty;
|
||||
updateInherit(type);
|
||||
});
|
||||
|
@ -134,12 +136,13 @@ var createRow = function(hostname) {
|
|||
};
|
||||
|
||||
var loadContext = function() {
|
||||
sendMessage('get').then(data => {
|
||||
return sendMessage('get').then(data => {
|
||||
context = data.context;
|
||||
requests = data.requests;
|
||||
rules = data.rules;
|
||||
recording.checked = data.recording;
|
||||
commitButton.disabled = !rules.dirty;
|
||||
resetButton.disabled = !rules.dirty;
|
||||
|
||||
table.innerHTML = '';
|
||||
table.append(createHeader());
|
||||
|
@ -175,5 +178,11 @@ reloadButton.addEventListener('click', event => {
|
|||
commitButton.addEventListener('click', event => {
|
||||
sendMessage('commit', context).then(() => {
|
||||
commitButton.disabled = true;
|
||||
resetButton.disabled = true;
|
||||
reloadButton.disabled= true;
|
||||
});
|
||||
});
|
||||
|
||||
resetButton.addEventListener('click', event => {
|
||||
sendMessage('reset', context).then(loadContext);
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ body {
|
|||
}
|
||||
|
||||
form {
|
||||
height: 100vh;
|
||||
block-size: 100vb;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr min-content;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
@ -17,13 +17,19 @@ form {
|
|||
padding: 0.5em;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
block-size: 100%;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5em 2em;
|
||||
padding-block: 0.5em;
|
||||
padding-inline: 2em;
|
||||
justify-self: end;
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="settings.css">
|
||||
|
@ -7,8 +7,14 @@
|
|||
</head>
|
||||
<body text="#d9d9d9" bgcolor="#1f2042">
|
||||
<form>
|
||||
<textarea style="background-color:#868686;" class="rules"></textarea>
|
||||
<textarea style="background-color:#868686;" class="savedRules"></textarea>
|
||||
<label>
|
||||
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>
|
||||
</form>
|
||||
<script src="shared.js"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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 = {
|
||||
'stylesheet': 'css',
|
||||
'font': 'font',
|
||||
|
|
読み込み中…
新しいイシューから参照