Files
browserpass-extension/src/options/interface.js

244 lines
6.1 KiB
JavaScript

module.exports = Interface;
var m = require("mithril");
/**
* Options main interface
*
* @since 3.0.0
*
* @param object settings Settings object
* @param function saveSettings Function to save settings
* @return void
*/
function Interface(settings, saveSettings) {
// public methods
this.attach = attach;
this.view = view;
// fields
this.settings = settings;
this.saveSettings = saveSettings;
this.saveEnabled = false;
// 'default' store must not be displayed or later attempted to be saved
delete this.settings.stores.default;
}
/**
* Attach the interface on the given element
*
* @since 3.0.0
*
* @param DOMElement element Target element
* @return void
*/
function attach(element) {
m.mount(element, this);
}
/**
* Generates vnodes for render
*
* @since 3.0.0
*
* @param function ctl Controller
* @param object params Runtime params
* @return []Vnode
*/
function view(ctl, params) {
var nodes = [];
nodes.push(m("h3", "Basic settings"));
nodes.push(createCheckbox.call(this, "autoSubmit", "Automatically submit forms after filling"));
nodes.push(createInput.call(this, "username", "Default username", "john.smith"));
nodes.push(createInput.call(this, "gpgPath", "Custom gpg binary", "/path/to/gpg"));
nodes.push(m("h3", "Custom store locations"));
nodes.push(
m("div", { class: "notice" }, "(this overrides default store and $PASSWORD_STORE_DIR)")
);
for (var storeId in this.settings.stores) {
nodes.push(createCustomStore.call(this, storeId));
}
nodes.push(
m(
"a.add-store",
{
onclick: () => {
addEmptyStore(this.settings.stores);
this.saveEnabled = true;
}
},
"Add store"
)
);
if (typeof this.error !== "undefined") {
nodes.push(m("div.error", this.error.message));
}
if (this.settings.hasOwnProperty("hostError")) {
let hostError = this.settings.hostError;
nodes.push(m("div.error", hostError.params.message));
}
nodes.push(
m(
"button.save",
{
disabled: !this.saveEnabled,
onclick: async () => {
try {
this.settings = await this.saveSettings(this.settings);
this.error = undefined;
} catch (e) {
this.error = e;
}
this.saveEnabled = false;
m.redraw();
}
},
"Save"
)
);
return nodes;
}
/**
* Generates vnode for a input setting
*
* @since 3.0.0
*
* @param string key Settings key
* @param string title Settings title
* @param string placeholder Settings placeholder
* @return Vnode
*/
function createInput(key, title, placeholder) {
return m("div.option", { class: key }, [
m("label", [
title,
m("input[type=text]", {
value: this.settings[key],
placeholder: placeholder,
onchange: e => {
this.settings[key] = e.target.value;
this.saveEnabled = true;
}
})
])
]);
}
/**
* Generates vnode for a checkbox setting
*
* @since 3.0.0
*
* @param string key Settings key
* @param string title Label for the checkbox
* @return Vnode
*/
function createCheckbox(key, title) {
return m("div.option", { class: key }, [
m("label", [
m("input[type=checkbox]", {
title: title,
checked: this.settings[key],
onchange: e => {
this.settings[key] = e.target.checked;
this.saveEnabled = true;
}
}),
title
])
]);
}
/**
* Generates vnode for a custom store configuration
*
* @since 3.0.0
*
* @param string storeId Store ID
* @return Vnode
*/
function createCustomStore(storeId) {
let store = this.settings.stores[storeId];
return m("div.option.custom-store", { class: "store-" + store.name }, [
m("input[type=text].name", {
title: "The name for this password store",
value: store.name,
placeholder: "name",
onchange: e => {
store.name = e.target.value;
this.saveEnabled = true;
}
}),
m("input[type=text].path", {
title: "The full path to this password store",
value: store.path,
placeholder: "/path/to/store",
onchange: e => {
store.path = e.target.value;
this.saveEnabled = true;
}
}),
m("input[type=text].bgColor", {
title: "Badge background color",
value: store.bgColor,
placeholder: "#626262",
onchange: e => {
store.bgColor = e.target.value;
this.saveEnabled = true;
}
}),
m("input[type=text].color", {
title: "Badge text color",
value: store.color,
placeholder: "#c4c4c4",
onchange: e => {
store.color = e.target.value;
this.saveEnabled = true;
}
}),
m(
"a.remove",
{
title: "Remove this password store",
onclick: () => {
delete this.settings.stores[storeId];
this.saveEnabled = true;
}
},
"[X]"
)
]);
}
/**
* Generates new store ID
*
* @since 3.0.0
*
* @return string new store ID
*/
function newId() {
return Math.random()
.toString(36)
.substr(2, 9);
}
/**
* Generates a new empty store
*
* @since 3.0.0
*
* @param []object stores List of stores to add a new store to
* @return void
*/
function addEmptyStore(stores) {
let store = { id: newId(), name: "", path: "" };
stores[store.id] = store;
}