mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2024-11-10 07:08:52 +01:00
d100932236
Fixes #600
460 lines
14 KiB
JavaScript
460 lines
14 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
(function(){
|
|
"use strict";
|
|
|
|
let scope;
|
|
if ((typeof exports) !== "undefined"){
|
|
scope = exports;
|
|
}
|
|
else {
|
|
scope = require.register("./optionsGui", {});
|
|
}
|
|
|
|
const extension = require("../lib/extension");
|
|
const logging = require("../lib/logging");
|
|
|
|
function createDescription(setting){
|
|
const c = document.createElement("div");
|
|
c.className = "content";
|
|
|
|
const title = document.createElement("span");
|
|
title.className = "title";
|
|
title.textContent = extension.getTranslation(setting.name + "_title");
|
|
c.appendChild(title);
|
|
|
|
let descriptionText = extension.getTranslation(setting.name + "_description");
|
|
if (setting.urlSpecific){
|
|
const urlSpecificDescription = extension.getTranslation(setting.name + "_urlSpecific");
|
|
if (urlSpecificDescription){
|
|
descriptionText += (descriptionText? "\n\n": "") + urlSpecificDescription;
|
|
}
|
|
}
|
|
if (descriptionText){
|
|
const info = document.createElement("div");
|
|
info.className = "info";
|
|
c.appendChild(info);
|
|
|
|
const description = document.createElement("div");
|
|
description.className = "description";
|
|
description.textContent = descriptionText;
|
|
info.appendChild(description);
|
|
}
|
|
return c;
|
|
}
|
|
|
|
function createSelect(setting){
|
|
const select = document.createElement("select");
|
|
select.dataset.type = typeof setting.defaultValue;
|
|
setting.options.forEach(function(value){
|
|
const option = document.createElement("option");
|
|
if (typeof value === typeof setting.defaultValue){
|
|
option.value = value;
|
|
if (setting.defaultValue === value){
|
|
option.selected = true;
|
|
}
|
|
option.text = extension.getTranslation(setting.name + "_options." + value) || value;
|
|
}
|
|
else {
|
|
option.disabled = true;
|
|
option.text = "\u2500".repeat(20);
|
|
}
|
|
select.appendChild(option);
|
|
});
|
|
return select;
|
|
}
|
|
|
|
const inputTypes = {
|
|
number: {
|
|
input: function(value){
|
|
const input = document.createElement("input");
|
|
input.type = "number";
|
|
input.value = value;
|
|
return input;
|
|
},
|
|
updateCallback: function(input, value){
|
|
input.value = value;
|
|
return input.value;
|
|
},
|
|
getValue: function(input){
|
|
return parseFloat(input.value);
|
|
}
|
|
},
|
|
string: {
|
|
input: function(value, setting){
|
|
let input;
|
|
if (setting && setting.display && setting.display.multiline){
|
|
input = document.createElement("textarea");
|
|
input.rows = 1;
|
|
}
|
|
else {
|
|
input = document.createElement("input");
|
|
input.type = "text";
|
|
}
|
|
input.value = value;
|
|
return input;
|
|
},
|
|
updateCallback: function(input, value){
|
|
input.value = value;
|
|
return input.value;
|
|
},
|
|
getValue: function(input){
|
|
return input.value;
|
|
}
|
|
},
|
|
boolean: {
|
|
input: function(value){
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.checked = value;
|
|
input.style.display = "inline-block";
|
|
return input;
|
|
},
|
|
updateCallback: function(input, value){
|
|
input.checked = value;
|
|
return input.checked;
|
|
},
|
|
getValue: function(input){
|
|
return input.checked;
|
|
}
|
|
},
|
|
object: false
|
|
};
|
|
|
|
function createKeyInput(setting, url){
|
|
const input = document.createElement("table");
|
|
let inSection = false;
|
|
setting.keys.forEach(function(key){
|
|
if (setting.display.displayedSection){
|
|
if (typeof key === "object"){
|
|
if (key.level === 1){
|
|
inSection = key.name === setting.display.displayedSection;
|
|
return;
|
|
}
|
|
}
|
|
if (!inSection){
|
|
return;
|
|
}
|
|
}
|
|
let row = document.createElement("tr");
|
|
if (typeof key === "object"){
|
|
let cell = document.createElement("td");
|
|
cell.colSpan = 2;
|
|
let h = document.createElement("h" + (2 + (key.level || 1)));
|
|
h.textContent = key.message? extension.getTranslation(key.message): key.name;
|
|
cell.appendChild(h);
|
|
row.appendChild(cell);
|
|
input.appendChild(row);
|
|
return;
|
|
}
|
|
|
|
let nameCell = document.createElement("td");
|
|
nameCell.textContent = setting.display.replaceKeyPattern?
|
|
key.replace(setting.display.replaceKeyPattern, ""):
|
|
key;
|
|
row.appendChild(nameCell);
|
|
|
|
let keyType = inputTypes[typeof setting.defaultKeyValue];
|
|
let keyInput = keyType.input(setting.defaultKeyValue);
|
|
|
|
let inputCell = document.createElement("td");
|
|
inputCell.appendChild(keyInput);
|
|
row.appendChild(inputCell);
|
|
|
|
setting.on(function(){
|
|
const container = setting.get(url);
|
|
keyType.updateCallback(
|
|
keyInput,
|
|
container && container.hasOwnProperty(key)?
|
|
container[key]:
|
|
setting.defaultKeyValue,
|
|
url
|
|
);
|
|
});
|
|
keyInput.addEventListener("change", function(){
|
|
const value = keyType.getValue(keyInput);
|
|
let container = setting.get(url);
|
|
if (!container){
|
|
container = setting.defaultValue;
|
|
}
|
|
container[key] = value;
|
|
if (setting.set(container, url)){
|
|
logging.message("changed setting", setting.name, "(", key, "):", value);
|
|
}
|
|
else {
|
|
container = setting.get(url);
|
|
keyType.updateCallback(
|
|
keyInput,
|
|
container && container.hasOwnProperty(key)?
|
|
container[key]:
|
|
setting.defaultKeyValue,
|
|
url
|
|
);
|
|
logging.message("setting", setting.name, "(", key, ") was not changed");
|
|
}
|
|
});
|
|
input.appendChild(row);
|
|
});
|
|
return input;
|
|
}
|
|
|
|
function getPopulateUrlTable(setting, type, body){
|
|
return function populateUrlTable({newValue}){
|
|
body.innerHTML = "";
|
|
newValue.forEach(function(entry){
|
|
let row = document.createElement("tr");
|
|
let urlCell = document.createElement("td");
|
|
urlCell.classList.add("url");
|
|
urlCell.addEventListener("click", function(){
|
|
const input = document.createElement("input");
|
|
input.classList.add("urlInput");
|
|
input.style.width = urlCell.clientWidth + "px";
|
|
input.style.height = urlCell.clientHeight + "px";
|
|
urlCell.innerHTML = "";
|
|
urlCell.appendChild(input);
|
|
input.title = extension.getTranslation("inputURL");
|
|
input.value = entry.url;
|
|
input.focus();
|
|
input.addEventListener("blur", function(){
|
|
const url = input.value.trim();
|
|
if (url){
|
|
entry.url = url;
|
|
setting.urlContainer.refresh();
|
|
}
|
|
urlCell.removeChild(input);
|
|
urlCell.textContent = entry.url;
|
|
});
|
|
input.addEventListener("click", function(event){
|
|
event.stopPropagation();
|
|
});
|
|
});
|
|
urlCell.textContent = entry.url;
|
|
row.appendChild(urlCell);
|
|
let input = createInput(setting, entry.url);
|
|
type.updateCallback(input, setting.get(entry.url));
|
|
if (!entry.hasOwnProperty(setting.name)){
|
|
input.classList.add("notSpecifiedForUrl");
|
|
}
|
|
let inputCell = document.createElement("td");
|
|
inputCell.appendChild(input);
|
|
row.appendChild(inputCell);
|
|
let clearCell = document.createElement("td");
|
|
let clearButton = document.createElement("button");
|
|
clearButton.className = "reset";
|
|
clearButton.textContent = "\xD7";
|
|
clearButton.addEventListener("click", function(){
|
|
setting.reset(entry.url);
|
|
});
|
|
clearCell.appendChild(clearButton);
|
|
row.appendChild(clearCell);
|
|
body.appendChild(row);
|
|
});
|
|
};
|
|
}
|
|
function createUrlSpecificInput(setting, input, type){
|
|
const container = document.createElement("div");
|
|
container.className = "urlValues " + (setting.getExpand()? "expanded": "collapsed");
|
|
container.appendChild(input);
|
|
const collapser = document.createElement("button");
|
|
collapser.classList.add("collapser");
|
|
container.appendChild(collapser);
|
|
collapser.addEventListener("click", function(){
|
|
setting.setExpand(!setting.getExpand());
|
|
});
|
|
setting.onExpandChange(function(value){
|
|
container.classList[value? "remove": "add"]("collapsed");
|
|
container.classList[value? "add": "remove"]("expanded");
|
|
});
|
|
let urlTable = document.createElement("table");
|
|
let caption = document.createElement("caption");
|
|
caption.textContent = extension.getTranslation(setting.urlContainer.name + "_title");
|
|
urlTable.appendChild(caption);
|
|
let body = document.createElement("tbody");
|
|
urlTable.appendChild(body);
|
|
let foot = document.createElement("tfoot");
|
|
let footRow = document.createElement("tr");
|
|
let footCell = document.createElement("td");
|
|
footCell.colSpan = 3;
|
|
let newInput = document.createElement("input");
|
|
newInput.className = "inputURL";
|
|
newInput.title = extension.getTranslation("inputURL");
|
|
const addURLSetting = function(){
|
|
const url = newInput.value.trim();
|
|
if (url){
|
|
setting.set(setting.get(url), url);
|
|
newInput.value = "";
|
|
newInput.focus();
|
|
}
|
|
};
|
|
newInput.addEventListener("keypress", function(event){
|
|
if ([10, 13].indexOf(event.keyCode) !== -1){
|
|
addURLSetting();
|
|
}
|
|
});
|
|
footCell.appendChild(newInput);
|
|
let footPlus = document.createElement("button");
|
|
footPlus.classList.add("add");
|
|
footPlus.textContent = "+";
|
|
footPlus.addEventListener("click", addURLSetting);
|
|
footCell.appendChild(footPlus);
|
|
footRow.appendChild(footCell);
|
|
foot.appendChild(footRow);
|
|
urlTable.appendChild(foot);
|
|
container.appendChild(urlTable);
|
|
|
|
setting.urlContainer.on(getPopulateUrlTable(setting, type, body));
|
|
return container;
|
|
}
|
|
|
|
function createInput(setting, url = ""){
|
|
const type = inputTypes[typeof setting.defaultValue];
|
|
let input;
|
|
if (setting.options){
|
|
input = createSelect(setting);
|
|
}
|
|
else {
|
|
if (type){
|
|
input = type.input(setting.defaultValue, setting);
|
|
}
|
|
}
|
|
if (type){
|
|
setting.on(function(){type.updateCallback(input, setting.get(url));}, url);
|
|
input.addEventListener("change", function(){
|
|
const value = type.getValue(input);
|
|
if (setting.set(value, url)){
|
|
logging.message("changed setting", setting.name, ":", value);
|
|
}
|
|
else {
|
|
type.updateCallback(input, setting.get(url));
|
|
logging.message("setting", setting.name, "was not changed");
|
|
}
|
|
});
|
|
}
|
|
else if (setting.keys){
|
|
input = createKeyInput(setting, url);
|
|
}
|
|
|
|
if (setting.urlSpecific && url === ""){
|
|
return createUrlSpecificInput(setting, input, type);
|
|
}
|
|
return input || document.createElement("span");
|
|
}
|
|
|
|
function createButton(setting){
|
|
const button = document.createElement("button");
|
|
button.textContent = extension.getTranslation(setting.name + "_label");
|
|
button.addEventListener("click", setting.action);
|
|
return button;
|
|
}
|
|
|
|
function createInteraction(setting){
|
|
const c = document.createElement("div");
|
|
c.className = "content";
|
|
|
|
let interaction;
|
|
if (setting.action){
|
|
interaction = createButton(setting);
|
|
}
|
|
else if (setting.actions){
|
|
interaction = document.createElement("span");
|
|
setting.actions.forEach(function(action){
|
|
const button = createButton(action);
|
|
interaction.appendChild(button);
|
|
});
|
|
}
|
|
else if (setting.inputs){
|
|
interaction = document.createElement("span");
|
|
setting.inputs.forEach(function(inputSetting){
|
|
const input = createInput(inputSetting);
|
|
input.classList.add("multiple" + setting.inputs.length);
|
|
interaction.appendChild(input);
|
|
});
|
|
}
|
|
else {
|
|
interaction = createInput(setting);
|
|
}
|
|
|
|
interaction.classList.add("setting");
|
|
interaction.dataset.storageName = setting.name;
|
|
interaction.dataset.storageType = typeof setting.defaultValue;
|
|
|
|
c.appendChild(interaction);
|
|
return c;
|
|
}
|
|
|
|
function createHide(setting){
|
|
const label = document.createElement("label");
|
|
label.className = "content hideContent";
|
|
label.title = extension.getTranslation("hideSetting");
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.className = "hide";
|
|
input.checked = setting.getHide();
|
|
input.addEventListener("change", function(){
|
|
setting.setHide(this.checked);
|
|
});
|
|
setting.onHideChange(function(value){
|
|
input.checked = value;
|
|
});
|
|
|
|
label.appendChild(input);
|
|
const display = document.createElement("span");
|
|
display.className = "display";
|
|
label.appendChild(display);
|
|
return label;
|
|
}
|
|
|
|
function createSettingRow(setting){
|
|
const tr = document.createElement("tr");
|
|
tr.className = "settingRow";
|
|
|
|
const hide = document.createElement("td");
|
|
hide.className = "hideColumn";
|
|
hide.appendChild(createHide(setting));
|
|
tr.appendChild(hide);
|
|
|
|
const left = document.createElement("td");
|
|
left.appendChild(createDescription(setting));
|
|
tr.appendChild(left);
|
|
|
|
const right = document.createElement("td");
|
|
right.appendChild(createInteraction(setting));
|
|
tr.appendChild(right);
|
|
|
|
return tr;
|
|
}
|
|
|
|
scope.createSettingRow = createSettingRow;
|
|
|
|
function createThead(displayHidden, restContent){
|
|
const tHead = document.createElement("thead");
|
|
const searchRow = document.createElement("tr");
|
|
const hideHeadCell = document.createElement("td");
|
|
hideHeadCell.className = "hideColumn";
|
|
searchRow.appendChild(hideHeadCell);
|
|
|
|
const restHeadCell = document.createElement("td");
|
|
restHeadCell.colSpan = 2;
|
|
if (restContent){
|
|
restHeadCell.appendChild(restContent);
|
|
}
|
|
searchRow.appendChild(restHeadCell);
|
|
tHead.appendChild(searchRow);
|
|
|
|
const displayHiddenRow = document.createElement("tr");
|
|
displayHiddenRow.className = "settingRow displayHiddenRow";
|
|
displayHiddenRow.appendChild(hideHeadCell.cloneNode());
|
|
const displayHiddenDescription = document.createElement("td");
|
|
displayHiddenDescription.appendChild(createDescription(displayHidden));
|
|
displayHiddenRow.appendChild(displayHiddenDescription);
|
|
|
|
const displayHiddenInteraction = document.createElement("td");
|
|
displayHiddenInteraction.appendChild(createInteraction(displayHidden));
|
|
displayHiddenRow.appendChild(displayHiddenInteraction);
|
|
tHead.appendChild(displayHiddenRow);
|
|
return tHead;
|
|
}
|
|
|
|
scope.createThead = createThead;
|
|
}()); |