summaryrefslogtreecommitdiff
path: root/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel')
-rw-r--r--data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/pref.js315
-rw-r--r--data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/preferences_panel.html81
-rw-r--r--data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/prefs.css87
3 files changed, 0 insertions, 483 deletions
diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/pref.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/pref.js
deleted file mode 100644
index d90e72e..0000000
--- a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/pref.js
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
-* GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
-*
-* Copyright (C) 2017 Nathan Nichols
-* Copyright (C) 2018 Giorgio maone
-* Copyright (C) 2022 Yuchen Pei
-*
-* This file is part of GNU LibreJS.
-*
-* GNU LibreJS is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* GNU LibreJS is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with GNU LibreJS. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-(() => {
- "use strict";
-
- const LIST_NAMES = ["white", "black"];
-
- const Model = {
- lists: {},
- prefs: null,
-
- malformedUrl(url) {
- try {
- const objUrl = new URL(url);
- const newUrl = objUrl.href;
- if (!objUrl.protocol.startsWith("http")) {
- return "Please enter http:// or https:// URLs only";
- } else if (!/^[^*]+\*?$/.test(newUrl)) {
- return "Only one single trailing path wildcard (/*) allowed";
- }
- } catch (e) {
- if (/^https?:\/\/\*\./.test(url)) {
- return this.malformedUrl(url.replace("*.", ""));
- }
- const prefix = "Invalid URL";
- if (url && !url.includes("://"))
- return prefix + ": missing protocol, either http:// or https://";
- else if (url.endsWith("://"))
- return prefix + ": missing domain name";
- else
- return prefix;
- }
- return null;
- },
-
- async save(prefs = this.prefs) {
- if (prefs !== this.prefs) {
- this.prefs = Object.assign(this.prefs, prefs);
- }
- this.saving = true;
- try {
- return await browser.storage.local.set(prefs);
- } finally {
- this.saving = false;
- }
- },
-
- async addToList(list, ...items) {
- const other = list === Model.lists.black ? Model.lists.white : Model.lists.black;
- this.saving = true;
- try {
- await Promise.all([
- other.remove(...items),
- list.store(...items)
- ]);
- } finally {
- this.saving = false;
- }
- }
- };
-
- Model.loading = (async () => {
- const prefsNames = [
- "whitelist",
- "blacklist",
- "subject",
- "body"
- ];
- Model.prefs = await browser.storage.local.get(prefsNames.map(name => `pref_${name}`));
-
- for (const listName of LIST_NAMES) {
- const prefName = `pref_${listName}list`;
- await (Model.lists[listName] = new ListStore(prefName, Storage.CSV))
- .load(Model.prefs[prefName]);
- }
- })();
-
- const Controller = {
- init() {
- const widgetsRoot = this.root = document.getElementById("widgets");
- for (const widget of widgetsRoot.querySelectorAll('[id^="pref_"]')) {
- if (widget.id in Model.lists) {
- populateListUI(widget);
- } else if (widget.id in Model.prefs) {
- widget.value = Model.prefs[widget.id];
- }
- }
-
- this.populateListUI();
- this.syncAll();
-
- for (const ev in Listeners) {
- widgetsRoot.addEventListener(ev, Listeners[ev]);
- }
- document.getElementById("site").onfocus = e => {
- if (!e.target.value.trim()) {
- e.target.value = "https://";
- }
- };
-
- browser.storage.onChanged.addListener(changes => {
- if (!Model.saving &&
- ("pref_whitelist" in changes || "pref_blacklist" in changes)) {
- setTimeout(() => {
- this.populateListUI();
- this.syncAll();
- }, 10);
- }
- });
- },
-
- async addSite(list) {
- const url = document.getElementById("site").value.trim();
-
- if (url && !Model.malformedUrl(url)) {
- await this.addToList(list, url);
- }
- },
- async addToList(list, ...items) {
- await Model.addToList(list, ...items);
- this.populateListUI();
- this.syncAll();
- },
- async swapSelection(list) {
- const origin = list === Model.lists.black ? "white" : "black";
- await this.addToList(list, ...Array.prototype.map.call(
- document.querySelectorAll(`select#${origin} option:checked`),
- option => option.value)
- );
- },
-
- syncAll() {
- this.syncListsUI();
- this.syncSiteUI();
- },
-
- syncSiteUI() {
- const widget = document.getElementById("site");
- const list2button = listName => document.getElementById(`cmd-${listName}list-site`);
-
- for (const bi of LIST_NAMES.map(list2button)) {
- bi.disabled = true;
- }
-
- const url = widget.value.trim();
- const malformedUrl = url && Model.malformedUrl(url);
- widget.classList.toggle("error", !!malformedUrl);
- document.getElementById("site-error").textContent = malformedUrl || "";
- if (!url) return;
- if (url !== widget.value) {
- widget.value = url;
- }
-
- for (const listName of LIST_NAMES) {
- const list = Model.lists[listName];
- if (!list.contains(url)) {
- list2button(listName).disabled = false;
- }
- }
- },
-
- syncListsUI() {
- const total = ["black", "white"].reduce((cum, id) => {
- const selected = document.querySelectorAll(`select#${id} option:checked`).length;
- const other = id === "black" ? "white" : "black";
- document.getElementById(`cmd-${other}list`).disabled = selected === 0;
- return cum + selected;
- }, 0);
- document.getElementById("cmd-delete").disabled = total === 0;
- },
-
- async deleteSelection() {
- for (const id of ["black", "white"]) {
- const selection = document.querySelectorAll(`select#${id} option:checked`);
- await Model.lists[id].remove(...Array.prototype.map.call(selection, option => option.value));
- }
- this.populateListUI();
- this.syncAll();
- },
-
- populateListUI(widget) {
- if (!widget) {
- for (const id of ["white", "black"]) {
- this.populateListUI(document.getElementById(id));
- }
- return;
- }
- widget.innerHTML = "";
- const items = [...Model.lists[widget.id].items].sort();
- const options = new DocumentFragment();
- for (const item of items) {
- const option = document.createElement("option");
- option.value = option.textContent = option.title = item;
- options.appendChild(option);
- }
- widget.appendChild(options);
- }
- };
-
- const KeyEvents = {
- Delete(e) {
- if (e.target.matches("#lists select")) {
- Controller.deleteSelection();
- }
- },
- Enter(e) {
- if (e.target.id === "site") {
- e.target.parentElement.querySelector("button[default]").click();
- }
- },
- KeyA(e) {
- if (e.target.matches("select") && e.ctrlKey) {
- for (const o of e.target.options) {
- o.selected = true;
- }
- Controller.syncListsUI();
- }
- }
- }
-
- const Listeners = {
- async change(e) {
- const { target } = e;
- const { id } = target;
-
- if (id in Model.lists) {
- Controller.syncListsUI();
- const selection = target.querySelectorAll("option:checked");
- if (selection.length === 1) {
- document.getElementById("site").value = selection[0].value;
- }
- return;
- }
- },
-
- click(e) {
- const { target } = e;
-
- const match = /^cmd-(white|black|delete)(list-site)?/.exec(target.id);
- if (!match) return;
- e.preventDefault();
- const cmd = match[1];
- if (cmd === "delete") {
- Controller.deleteSelection();
- return;
- }
- const list = Model.lists[cmd];
- if (list) {
- Controller[match[2] ? "addSite" : "swapSelection"](list);
- return;
- }
- },
-
- keypress(e) {
- const { code } = e;
- if (code && typeof KeyEvents[code] === "function") {
- if (KeyEvents[code](e) === false) {
- e.preventDefault();
- }
- return;
- }
- },
-
- async input(e) {
- const { target } = e;
- const { id } = target;
- if (!id) return;
-
- if (id === "site") {
- Controller.syncSiteUI();
- const url = target.value;
- if (url) {
- const o = document.querySelector(`#lists select option[value="${url}"]`);
- if (o) {
- o.scrollIntoView();
- o.selected = true;
- }
- }
- return;
- }
-
- if (id.startsWith("pref_")) {
- await Model.save({ [id]: target.value });
- return;
- }
- }
- };
-
- window.addEventListener("DOMContentLoaded", async _ => {
- await Model.loading;
- Controller.init();
- });
-
-})();
diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/preferences_panel.html b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/preferences_panel.html
deleted file mode 100644
index 081ae07..0000000
--- a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/preferences_panel.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<meta charset="utf-8"/>
-<!-- /**
- * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
- * *
- * Copyright (C) 2011, 2012, 2014 Loic J. Duros
- * Copyright (C) 2014, 2015 Nik Nyby
- * Copyright (C) 2018 Giorgio Maone
- *
- * This file is part of GNU LibreJS.
- *
- * GNU LibreJS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GNU LibreJS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU LibreJS. If not, see <http://www.gnu.org/licenses/>.
- */
--->
- <title>
- LibreJS preferences
- </title>
- <link rel="stylesheet" type="text/css" href="./prefs.css"/>
- <script src="/html/mobile.js"></script>
- <script type="text/javascript" src="/common/Storage.js"></script>
- <script type="text/javascript" src="pref.js"></script>
- </head>
-
- <body>
- <div class="libre">
- <a class="libre"
- id="ljs-settings"
- href="https://www.gnu.org/software/librejs/"
- title="LibreJS Settings">
- <h1 class="libre">LibreJS</h1>
- </a>
- <h3>Settings</h3>
- </div>
- <div id="widgets">
- <fieldset id="section-lists"><legend>Allow or block scripts matching the following URLs ("*."" matches any subdomain, "/*" matches any path)</legend>
- <label>Type a new whitelist / blacklist entry:</label>
- <div id="new-site">
- <input type="text" id="site" value="" placeholder="https://*.gnu.org/*">
- <button id="cmd-whitelist-site" class="white" title="Whitelist this site" default>Whitelist</button>
- <button id="cmd-blacklist-site" class="red" title="Blacklist this site">Blacklist</button>
- </div>
- <div id="site-error" class="error-msg"></div>
- <div id="lists">
- <div class="white list-container">
- <label>Whitelist (always allow)</label>
- <select id="white" multiple size="10"></select>
- </div>
- <div id="commands">
- <button id="cmd-delete" title="Delete">x</button>
- <button id="cmd-blacklist" title="Move to blacklist">&raquo;</button>
- <button id="cmd-whitelist" title="Move to whitelist">&laquo;</button>
- </div>
- <div class="black list-container">
- <label>Blacklist (always block)</label>
- <select id="black" multiple size="10"></select>
- </div>
- </div>
- </fieldset>
-
- <fieldset id="section-complaint"><legend>Complaint email defaults</legend>
- <label for="pref_subject">Subject</label>
- <input id="pref_subject" type="text"/>
- <label for="pref_body">Body</label>
- <textarea id="pref_body" rows="5"></textarea>
- </fieldset>
- </div>
- </body>
-</html>
diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/prefs.css b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/prefs.css
deleted file mode 100644
index 6e2d206..0000000
--- a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/html/preferences_panel/prefs.css
+++ /dev/null
@@ -1,87 +0,0 @@
-@import url("chrome://browser/content/extension.css");
-@import url("/html/common.css");
-h3 {
- position: absolute;
- bottom: 0px;
- left: 240px;
- font-size: 18px;
-}
-textarea {
- width: 100%;
-}
-fieldset {
- border: none;
- padding: 0;
- margin-top: 1em;
- border-top: 1px solid #ccc;
-}
-legend {
- font-weight: bold;
- margin: 0;
- padding: 0;
-}
-label, legend {
- display: block;
- font-size: 1.2em;
-}
-
-#lists {
- display: flex;
- flex-direction: row;
-}
-.list-container {
- flex: 3;
- flex-direction: row;
-}
-.list-container select {
-width: 100%
-}
-
-.black {
- color: #600;
-}
-.white {
- color: #060;
-}
-
-#commands {
- display: flex;
- justify-content: center;
- flex: none;
- flex-flow: column nowrap;
-}
-
-#commands button {
- font-weight: bold;
-}
-input[type="text"] {
- width: 100%;
-}
-
-#lists label {
- font-weight: bold;
-}
-#lists select {
- color: black;
-}
-#black {
- background-color: #fcc;
-}
-#white {
- background-color: #cfc;
-}
-
-#new-site {
- display: flex;
- flex: 2;
-}
-.error-msg {
- color: red;
-}
-.error-msg::after {
- content: "\00A0";
-}
-.error {
- background: #ffe;
- color: #800;
-}