chrome-extension-archive/AutoplayStopper/options.js

292 lines
13 KiB
JavaScript
Raw Normal View History

2021-02-10 18:28:04 +00:00
"use strict";
const Options = new function() {
const {i18n, storage, permissions: perms} = chrome.extension.getBackgroundPage().Background;
const permsAutoplayKey = perms.key("autoplay");
const permsAutoplayDefaultKey = perms.defaultKey("autoplay");
const permsFlashKey = perms.key("flash");
const permsFlashDefaultKey = perms.defaultKey("flash");
const data = { flash: { type: "flash", dirty: false}, autoplay: { type: "autoplay", dirty: false}};
const { autoplay, flash } = data;
var tabId = null;
var selected = null;
// chrome.tabs.getCurrent(function(tab) { tabId = tab.id; }); // chrome workaround ...
chrome.tabs.query({ active: true, currentWindow: true}, function(tabs) { tabId = tabs[0].id; });
chrome.tabs.onActivated.addListener(function(info){ if (tabId == info.tabId) postActive(); });
addEventListener("load", init);
addEventListener("hashchange", function() { updateState(location.hash.slice(1)); });
function init()
{
i18n.process(document);
var listener = storage.addChangeListener(function(changes){
if (changes.indexOf(permsAutoplayKey) != -1) {
autoplay.exceptions.init(perms.entries("autoplay"));
autoplay.dirty = false;
updateApply();
}
if(changes.indexOf(permsAutoplayDefaultKey) != -1) {
document.getElementById("autoplay-default").value = perms.default("autoplay");
}
if (changes.indexOf(permsFlashKey) != -1) {
flash.exceptions.init(perms.entries("flash"));
flash.dirty = false;
updateApply();
}
if(changes.indexOf(permsFlashDefaultKey) != -1) {
document.getElementById("flash-default").value = perms.default("flash");
}
});
addEventListener("unload", function(){ storage.removeChangeListener(listener); });
var manifest = chrome.runtime.getManifest();
document.getElementById("extension-version").appendChild(document.createTextNode(manifest.version));
document.getElementById("autoplay-default").value = perms.default("autoplay");
document.getElementById("flash-default").value = perms.default("flash");
document.getElementById("devtools").checked = storage.data.devtools;
autoplay.exceptions = new ExceptionsList(document.getElementById("autoplay-list"));
autoplay.exceptions.init(perms.entries("autoplay"));
document.getElementById("autoplay-default").addEventListener("change", function(e) {
perms.setDefault("autoplay", e.target.value);
storage.commit([permsAutoplayDefaultKey]);
});
flash.exceptions = new ExceptionsList(document.getElementById("flash-list"));
flash.exceptions.init(perms.entries("flash"));
document.getElementById("flash-default").addEventListener("change", function(e) {
perms.setDefault("flash", e.target.value);
storage.commit([permsFlashDefaultKey]);
});
document.querySelectorAll(".exceptions-list-button").forEach(function(button) {
button.onclick = function(e) { location.hash = `${button.getAttribute("contenttype")}`; };
});
autoplay.exceptions.addDirtyListener(function(d) { autoplay.dirty = d; updateApply(); });
flash.exceptions.addDirtyListener(function(d) { flash.dirty = d; updateApply(); });
document.querySelector(".close-button").onclick = function() { location.hash = ""; };
document.getElementById("exceptions-clear").onclick = function() { selected.exceptions.clear(); };
document.getElementById("exceptions-apply").onclick = apply;
document.getElementById("exceptions-confirm").onclick = function() { apply(); location.hash = ""; };
document.getElementById("devtools").onclick = function(e) {
storage.data.devtools = this.checked;
storage.commit(["devtools"]);
};
if (location.hash) updateState(location.hash.slice(1));
postActive();
};
function postActive() { chrome.extension.getBackgroundPage().postMessage("optionsPageActive", "*"); };
function updateApply() { document.getElementById("exceptions-apply").disabled = !selected || !selected.dirty; };
function apply()
{
if (selected.dirty) {
perms.clear(selected.type);
for (var [url, perm] of selected.exceptions.entries()) { perms.set(selected.type, url, perm); };
storage.commit([perms.key(selected.type)], function(err){
if (err) { selected.dirty = true; };
updateApply();
});
selected.dirty = false;
}
};
function updateState(state)
{
// console.log(`updateState(${state})`);
if (state) {
document.querySelector("div[contenttype]:not([hidden])").hidden = true;
document.querySelector("h2[contenttype]:not([hidden])").hidden = true;
document.querySelector(`div[contenttype=${state}]`).hidden = false;
document.querySelector(`h2[contenttype=${state}]`).hidden = false;
var overlay = document.querySelector(".overlay");
overlay.hidden = false;
setTimeout(function() { overlay.classList.remove("transparent"); }, 20);
selected = data[state];
updateApply();
}
else {
var overlay = document.querySelector(".overlay");
overlay.classList.add("transparent");
setTimeout(function() { overlay.hidden = true; }, 500);
}
}
};
const ExceptionsList = function ExceptionsList(list){
var itemid = 0;
var baseitem = list.querySelector("#listitem");
var inputitem = list.querySelector("#inputitem");
var selected = list.querySelector("[selected]");
var listeners = [];
var dirty = false;
baseitem.remove();
list.addEventListener("mousedown", handleMousedown.bind(this));
list.addEventListener("click", handleClick.bind(this));
list.addEventListener("keydown", handleKeyDown.bind(this));
list.addEventListener("change", handleChange.bind(this));
list.addEventListener("focus", function(e) {
if (!e.target.classList.contains("row-delete-button")) {
list.setAttribute("has-element-focus", "hasElementFocus");
handleSelection(e.target.closest("[role=listitem]"));
if (e.target.getAttribute("displaymode") == "static") e.target.nextSibling.focus();
}
}, true);
list.addEventListener("blur", function(e) {
if (!list.contains(e.relatedTarget) && !e.target.classList.contains("row-delete-button")) {
list.removeAttribute("has-element-focus");
handleSelection();
if (!e.relatedTarget) list.parentNode.closest("[tabindex]").focus();
}
}, true);
return {
init: function init(entries) {
this.clear();
entries.sort(function(a, b) { return a[0].localeCompare(b[0]); });
for (var [key, type] of entries) { appendItem(key, type); };
dirty = false;
},
entries: function * entries()
{
for (var node of list.children)
if (node.id.search("listitem") == 0 && node != inputitem)
yield [node.querySelector("#perms-host").textContent, parseInt(node.querySelector("#perms-type-select").value)];
},
clear: function clear()
{
for (var node of [].slice.apply(list.children))
if (node.id.search("listitem") == 0 && node != inputitem) node.remove();
inputitem.querySelector("#perms-host-input").focus();
fireDirty(true);
},
get dirty() { return dirty; },
addDirtyListener: function(listener) { listeners.push(listener); },
removeDirtyListener: function(listener) { var idx = listeners.indexOf(listener); if (idx != -1) listeners.splice(idx); }
};
function appendItem(host, type, scroll)
{
var item = baseitem.cloneNode(true);
item.id = item.id + "-" + (++itemid);
item.querySelector("#perms-host-input").value = item.querySelector("#perms-host").textContent = host;
var select = item.querySelector("#perms-type-select");
select.value = type;
if (type != 0) item.querySelector("#perms-type").textContent = select[select.selectedIndex].text;
list.insertBefore(item, inputitem);
if (scroll) scrollToBottom(inputitem);
};
function scrollToBottom(node)
{
if (node.clientHeight < node.scrollHeight)
return node.scrollTop = node.scrollHeight - node.clientHeight;
if (node.parentNode) scrollToBottom(node.parentNode);
};
function handleMousedown(e)
{
var target = e.target;
var item = target.closest("[role=listitem]");
if (target.classList.contains("row-delete-button")) return;
if (target.id == "perms-host") {
var x = e.clientX, y = e.clientY, offset = document.caretPositionFromPoint ?
document.caretPositionFromPoint(x, y).offset : document.caretRangeFromPoint(x, y).startOffset;
var input = item.querySelector("#perms-host-input");
var inside = x < inputitem.querySelector("#perms-host-input").getBoundingClientRect().right;
input.selectionStart = input.selectionEnd = inside ? 0 : input.value.length;
setTimeout(function() { input.selectionStart = input.selectionEnd = offset; }, 25);
}
if (item && !target.hasAttribute("tabindex") && !item.hasAttribute("editing")) {
item.querySelector("[id^=perms-host]").focus();
e.preventDefault();
};
};
function handleSelection(item)
{
if (selected && item != selected) {
selected.removeAttribute("lead");
selected.removeAttribute("editing");
if (item) selected.removeAttribute("selected");
if (selected == inputitem) handleInput(!item);
selected.querySelectorAll("[id^=perms]").forEach(function(a) { a.tabIndex = item ? -1 : 0; });
}
if (item && !item.hasAttribute("editing")) {
item.setAttribute("selected", "selected");
item.setAttribute("lead", "lead");
item.setAttribute("editing", "");
item.querySelectorAll("[id^=perms]")
.forEach(function(a) { a.tabIndex = a.getAttribute("displaymode") == "static" ? -1 : 0; });
selected = item;
}
};
function handleClick(e)
{
var target = e.target;
if (target.classList.contains("row-delete-button")) {
var item = target.closest("[role=listitem]");
if (item == selected) handleSelection(inputitem);
item.remove();
list.focus({preventScroll: true});
fireDirty(true);
return;
};
};
function handleKeyDown(e)
{
if (selected && selected != inputitem && e.target.id != "perms-host-input" && e.keyCode == 46)
selected.querySelector(".row-delete-button").click();
if (selected && e.key == "Enter") selected == inputitem ? handleInput(true) : list.focus({preventScroll: true});
if (selected && e.key == "ArrowUp" && e.target.id != "perms-type-select" && selected != list.querySelector("[role=listitem]"))
selected.previousSibling.querySelector("[id^=perms-host]").focus();
if (selected && e.key == "ArrowDown" && e.target.id != "perms-type-select" && selected != inputitem)
selected.nextSibling.querySelector("[id^=perms-host]").focus();
};
function handleChange(e)
{
var target = e.target;
var item = target.closest("[role=listitem]");
if (item != inputitem) {
if (target.id == "perms-type-select") {
item.querySelector("#perms-type").textContent =
target.value != 0 ? target[target.selectedIndex].text : "";
fireDirty(true);
}
if (target.id == "perms-host-input"){
try {
var url = new URL(target.value);
target.value = url.origin;
item.querySelector("#perms-host").textContent = target.value;
fireDirty(true);
}
catch (e) { target.value = item.querySelector("#perms-host").textContent; };
}
}
};
function handleInput(scroll)
{
try {
var target = inputitem.querySelector("#perms-host-input")
var url = new URL(target.value);
target.value = url.origin;
appendItem(target.value, inputitem.querySelector("#perms-type-select").value, scroll);
target.value = null;
fireDirty(true);
}
catch (e) {};
};
function fireDirty(d) { dirty = d; for (var listener of listeners) listener(d); };
};
// </>