Skip to content

Commit

Permalink
implement import/export controls
Browse files Browse the repository at this point in the history
  • Loading branch information
claustromaniac committed Apr 27, 2019
1 parent 0462c52 commit b3c55c9
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"applications": {
"gecko": {
"id": "httpz@cm.org",
"strict_min_version": "57.0"
"strict_min_version": "60.0"
}
},
"background": {
Expand All @@ -19,6 +19,7 @@
"icons": {"64": "assets/httpz.svg"},
"manifest_version": 2,
"name": "HTTPZ",
"optional_permissions": ["downloads"],
"options_ui": {
"browser_style": true,
"page": "pages/options.htm"
Expand Down
16 changes: 12 additions & 4 deletions src/pages/options.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ body { display: table; }
code, fieldset, textarea { border-radius: 0.3em; }
fieldset { width: 95vw; }
button, input, textarea, p { margin-left: 0.25em; }
button {
margin-right: 0.5em;
margin-top: 1em;
padding: 0 0.75em;
}
textarea {
font-family: "Consolas";
font-weight: 100;
Expand All @@ -20,10 +25,6 @@ textarea {
flex-flow: row wrap;
}
.fb * { margin: auto inherit; }
.hidden {
opacity: 0;
transition: opacity 500ms;
}
button[status-neutral]::after {
content: attr(status-neutral);
}
Expand All @@ -37,3 +38,10 @@ button[status-failure]::after {
color: #300;
text-shadow: 0 0 0.2em #F00;
}
input[type="file"] {display: none;}
button label {margin: 0;}
#fakeFileInput {padding: 0;}
#save {
float: right;
font-weight: 700;
}
12 changes: 9 additions & 3 deletions src/pages/options.htm
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</div>
<div class="browser-style fb">
<input id="permanent" name="period" type="radio"><label for="permanent">never</label>
</div><br>
</div>
<button class="browser-style" id="clearIgnored">Forget ignored sites</button>
</fieldset><br>
<fieldset>
Expand All @@ -25,14 +25,20 @@
<input id="rememberSecureSites" type="checkbox"><label for="rememberSecureSites">
Remember secure sites
</label>
</div><br>
</div>
<button class="browser-style" id="clearSecure">Forget secure sites</button>
</fieldset><br>
<fieldset>
<p>Whitelisted hostnames (will always be ignored by HTTPZ)</p>
<textarea autocomplete="off" class="browser-style" id="whitelist" rows="10" spellcheck="false"></textarea><br>
<textarea autocomplete="off" class="browser-style" id="whitelist" rows="10" spellcheck="false"></textarea>
<button class="browser-style" id="clearWhitelist">Clear whitelist</button>
</fieldset><br>
<button class="browser-style" id="export">Export</button>
<button class="browser-style" id="fakeFileInput">
<label>&nbsp;Import&nbsp;
<input type="file" accept=".json" id="import"></input>
</label>
</button>
<button class="browser-style" id="save">Save</button>
<script src="options.js"></script>
</body>
Expand Down
58 changes: 51 additions & 7 deletions src/pages/options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

const ui = document.getElementsByTagName('*');
const dlpermission = { permissions : ['downloads'] };
let reader;

function setStatus(button, msg, type) {
button.setAttribute(type, ` ${msg}`);
Expand Down Expand Up @@ -32,20 +34,33 @@ function parseWhitelist(str) {
return result;
}

browser.runtime.sendMessage('options').then(msg => {
ui.session.checked = !msg.ignorePeriod;
ui.xdays.checked = msg.ignorePeriod > 0;
function refreshUI(data) {
ui.session.checked = !data.ignorePeriod;
ui.xdays.checked = data.ignorePeriod > 0;
ui.days.disabled = !ui.xdays.checked;
ui.permanent.checked = msg.ignorePeriod === -1;
if (ui.xdays.checked) ui.days.value = msg.ignorePeriod;
ui.permanent.checked = data.ignorePeriod === -1;
if (ui.xdays.checked) ui.days.value = data.ignorePeriod;
ui.rememberSecureSites.checked = data.rememberSecureSites;
ui.whitelist.value = populateWhitelist(data.whitelist);
}

function exportSettings() {
browser.storage.local.get().then(r => {
browser.downloads.download({
saveAs : true,
url : URL.createObjectURL(new Blob([JSON.stringify(r, null, '\t')])),
filename : `HTTPZ_backup-${new Date().toISOString().replace(/.*?(\d.*\d).*/, '$1').replace(/\D/g, '.')}.json`
});
});
}

browser.runtime.sendMessage('options').then(msg => {
const changePeriod = e => {
ui.days.disabled = !ui.xdays.checked;
if (ui.xdays.checked) {
ui.days.value = msg.ignorePeriod > 0 ? msg.ignorePeriod : 1;
}
};
ui.rememberSecureSites.checked = msg.rememberSecureSites;
ui.whitelist.value = populateWhitelist(msg.whitelist);
ui.session.onchange = changePeriod;
ui.xdays.onchange = changePeriod;
ui.permanent.onchange = changePeriod;
Expand All @@ -65,6 +80,25 @@ browser.runtime.sendMessage('options').then(msg => {
setStatus(ui.clearWhitelist, '✔', 'status-success');
});
};
ui.import.onchange = e => {
if (!reader) reader = new FileReader();
reader.onloadend = () => {
try {
const data = JSON.parse(reader.result);
if (data.ignorePeriod) {
browser.storage.local.set(data);
refreshUI(data);
} else throw 'SyntaxError';
} catch {alert('Error. Invalid file (?)')};
};
reader.readAsText(ui.import.files[0]);
};
ui.clearWhitelist.onclick = e => {
browser.storage.local.set({whitelist: {}, incognitoWhitelist: {}}).then(() => {
ui.whitelist.value = '';
setStatus(ui.clearWhitelist, '✔', 'status-success');
});
};
ui.save.onclick = e => {
const changes = Object.assign({}, msg);
if (ui.xdays.checked) {
Expand All @@ -84,4 +118,14 @@ browser.runtime.sendMessage('options').then(msg => {
setStatus(ui.save, '✔', 'status-success');
});
};
browser.permissions.contains(dlpermission).then(r => {
if (r) ui.export.onclick = e => {exportSettings()};
else ui.export.onclick = async e => {
if (await browser.permissions.request(dlpermission)) {
exportSettings();
ui.export.onclick = e => {exportSettings()};
}
};
});
refreshUI(msg);
});

0 comments on commit b3c55c9

Please sign in to comment.