Bladeren bron

add options editor

see:
 - https://github.com/gildas-lormeau/SingleFile/discussions/1665
 - https://github.com/gildas-lormeau/SingleFile/issues/1439
Gildas 11 maanden geleden
bovenliggende
commit
a370201f33

+ 19 - 3
_locales/az/messages.json

@@ -292,7 +292,7 @@
 		"description": "Options page label: 'password'"
 	},
 	"optionCreateRootDirectory": {
-		"message":  "kök qovluğu yarat",
+		"message": "kök qovluğu yarat",
 		"description": "Options page label: 'create a root directory'"
 	},
 	"optionPreventAppendedData": {
@@ -900,7 +900,7 @@
 		"description": "Title of the button 'Enable/disable read-only' in the editor"
 	},
 	"editorFormatPage": {
-		"message":  "Səhifəni daha yaxşı oxunacaq şəkildə formatlayın",
+		"message": "Səhifəni daha yaxşı oxunacaq şəkildə formatlayın",
 		"description": "Title of the button 'Format the page for better readability' in the editor"
 	},
 	"editorCutInnerPage": {
@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "URL sahə adı",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Redaktor seçimləri",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Yaddaşa qeyd edin",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Konfiqurasiya yaddaşa qeyd edildi",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Yanlış JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
-}
+}

+ 16 - 0
_locales/de/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "Feldname der URL",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Optionen-Editor",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Speichern",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Konfiguration gespeichert",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Ungültiges JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/en/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "archive URL field name",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Options editor",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Save",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuration saved",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Invalid JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/es/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "archive URL field name",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Editor de opciones",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Guardar",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuración guardada",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "JSON no válido",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/fr/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "Nom du champ de l'URL de l'archive",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Éditeur d'options",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Sauvegarder",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuration sauvegardée",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "JSON invalide",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/it/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "nome del campo URL archivio",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Editor opzioni",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Salva",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configurazione salvata",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "JSON non valido",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/ja/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "アーカイブURLフィールド名",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "オプションエディタ",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "保存",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "設定が保存されました",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "無効な JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/nl_NL/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "veldnaam voor archief-URL",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Opties editor",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Opslaan",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuratie opgeslagen",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Ongeldige JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/pl/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "nazwa pola adresu URL archiwum",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Options editor",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Save",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuration saved",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Invalid JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/pt_PT/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "nome do campo URL do arquivo",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Editor de opções",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Guardar",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuração guardada",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "JSON inválido",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/pt_br/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "nome do campo URL do arquivo",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Editor de opções",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Salvar",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuração salva",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "JSON inválido",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 17 - 1
_locales/ru/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "имя поля URL архива",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Options editor",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Save",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Configuration saved",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Invalid JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
-}
+}

+ 16 - 0
_locales/tr/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "arşiv URL alan adı",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Seçenekler düzenleyici",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Kaydet",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Yapılandırma kaydedildi",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Geçersiz JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/uk/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "назва поля URL-адреси",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "Редактор параметрів",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "Зберегти",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "Конфігурація збережена",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "Недійсний JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/zh_CN/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "网址字段名称",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "选项标题:'选项编辑器'",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "保存",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "配置已保存",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "无效的 JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 16 - 0
_locales/zh_TW/messages.json

@@ -1030,5 +1030,21 @@
 	"optionRestFormApiUrlFieldName": {
 		"message": "網址字段名稱",
 		"description": "Options page label: 'archive URL field name'"
+	},
+	"optionsEditorTitle": {
+		"message": "選項編輯器",
+		"description": "Options title: 'Options editor'"
+	},
+	"optionsEditorSaveButton": {
+		"message": "保存",
+		"description": "Options editor button: 'Save'"
+	},
+	"optionsEditorConfigSaved": {
+		"message": "配置已保存",
+		"description": "Options editor message: 'Configuration saved'"
+	},
+	"optionsEditorInvalidJSON": {
+		"message": "無效的 JSON",
+		"description": "Options editor error message: 'Invalid JSON'"
 	}
 }

+ 14 - 0
src/core/bg/config.js

@@ -351,6 +351,20 @@ function testRegExpRule(rule) {
 }
 
 async function onMessage(message) {
+	if (message.method.endsWith(".get")) {
+		return await getConfig();
+	}
+	if (message.method.endsWith(".set")) {
+		const { config } = message;
+		const profiles = config.profiles;
+		const rules = config.rules;
+		const maxParallelWorkers = config.maxParallelWorkers;
+		const processInForeground = config.processInForeground;
+		const profileKeyNames = await getProfileKeyNames();
+		await configStorage.remove([...profileKeyNames, "rules", "maxParallelWorkers", "processInForeground"]);
+		await configStorage.set({ rules, maxParallelWorkers, processInForeground });
+		Object.keys(profiles).forEach(profileName => setProfile(profileName, profiles[profileName]));
+	}
 	if (message.method.endsWith(".deleteRules")) {
 		await deleteRules(message.profileName);
 	}

+ 67 - 0
src/ui/bg/ui-options-editor.js

@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2020 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   The code in this file is free software: you can redistribute it and/or 
+ *   modify it under the terms of the GNU Affero General Public License 
+ *   (GNU AGPL) as published by the Free Software Foundation, either version 3
+ *   of the License, or (at your option) any later version.
+ * 
+ *   The code in this file 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 Affero 
+ *   General Public License for more details.
+ *
+ *   As additional permission under GNU AGPL version 3 section 7, you may 
+ *   distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU 
+ *   AGPL normally required by section 4, provided you include this license 
+ *   notice and a URL through which recipients can access the Corresponding 
+ *   Source.
+ */
+
+/* global browser, window, document, localStorage, FileReader, location, fetch, TextDecoder, DOMParser, HTMLElement, MouseEvent */
+
+const titleLabel = document.getElementById("titleLabel");
+
+const optionsInput = document.getElementById("optionsInput");
+const saveButton = document.getElementById("saveButton");
+
+titleLabel.textContent = browser.i18n.getMessage("optionsEditorTitle");
+saveButton.textContent = browser.i18n.getMessage("optionsEditorSaveButton");
+const invalidJSONMessage = browser.i18n.getMessage("optionsEditorInvalidJSON");
+const configSavedMessage = browser.i18n.getMessage("optionsEditorConfigSaved");
+
+init();
+saveButton.addEventListener("click", async () => {
+    let config;
+    try {
+        config = JSON.parse(optionsInput.value);
+    } catch (error) {
+        alert(invalidJSONMessage);
+    }
+    if (config) {
+        await browser.runtime.sendMessage({ method: "config.set", config });
+        await refreshExternalComponents(config);
+        alert(configSavedMessage);
+    }
+    saveButton.blur();
+});
+
+async function init() {
+    const config = await browser.runtime.sendMessage({ method: "config.get" });
+    optionsInput.value = JSON.stringify(config, null, 4);
+}
+
+async function refreshExternalComponents(config) {
+    try {
+        await browser.runtime.sendMessage({ method: "ui.refreshMenu" });
+        for (const profileName of Object.keys(config.profiles)) {
+            await browser.runtime.sendMessage({ method: "options.refresh", profileName });
+            await browser.runtime.sendMessage({ method: "options.refreshPanel", profileName });
+        }
+    } catch (error) {
+        // ignored
+    }
+}

+ 48 - 0
src/ui/pages/options-editor.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class="maximized">
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+	<title>SingleFile options editor</title>
+	<link rel="stylesheet" href="options.css">
+	<style>
+		.option {
+			padding: 6px;
+		}
+
+		textarea {
+			width: 100%;
+			height: 80vh;
+		}
+
+		.option.bottom {
+			justify-content: end;
+		}
+	</style>
+	<meta name="viewport" content="width=device-width,initial-scale=1">
+	<meta name="color-scheme" content="light dark">
+	<link rel="icon" href="/src/ui/resources/icon_128.png">
+</head>
+
+<body>
+	<main>
+		<h3>
+			<span class="options-title">
+				<span id="titleLabel"></span>
+			</span>
+		</h3>
+		<div class="option">
+			<textarea id="optionsInput">
+			</textarea>
+		</div>
+		<div class="option bottom">
+			<div class="buttons">
+				<button id="saveButton"></button>
+			</div>
+		</div>
+	</main>
+	<script src="/lib/chrome-browser-polyfill.js"></script>
+	<script type="module" src="../bg/ui-options-editor.js"></script>
+</body>
+
+</html>

+ 2 - 0
src/ui/pages/options.html

@@ -18,6 +18,8 @@
 				<span id="titleLabel"></span>
 				<a href="options.html#" target="_blank" class="new-window-link"><img
 						src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg=="></a>
+				<a href="options-editor.html" target="_blank" class="new-window-link"><img
+						src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAABg2lDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpSIVQYuoOGSoTnbRIo61CkWoEGqFVh1MLv2CJg1Jiouj4Fpw8GOx6uDirKuDqyAIfoC4C06KLlLi/5pCixgPjvvx7t7j7h0g1MtMs7pigKbbZioRFzPZVTHwCgEDGMIIojKzjDlJSsJzfN3Dx9e7CM/yPvfn6FNzFgN8InGMGaZNvEE8s2kbnPeJQ6woq8TnxJMmXZD4keuKy2+cC00WeGbITKfmiUPEYqGDlQ5mRVMjjhKHVU2nfCHjssp5i7NWrrLWPfkLgzl9ZZnrNMeQwCKWIEGEgipKKMNGhFadFAsp2o97+EebfolcCrlKYORYQAUa5KYf/A9+d2vlp6fcpGAc6H5xnI9xILALNGqO833sOI0TwP8MXOltf6UOzH6SXmtr4SOgfxu4uG5ryh5wuQMMPxmyKTclP00hnwfez+ibssDgLdC75vbW2sfpA5CmrpI3wMEhMFGg7HWPd/d09vbvmVZ/P8lTcsmmxgruAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6QISFiAoxdV/BAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAkSURBVBjTY2AgEjBC6f9EqqPcROJNwmci6aaQ6mtGqpmIYhIA3lQFBjN3Og8AAAAASUVORK5CYII="></a>
 			</span>
 			<span class="profiles">
 				<select id="profileNamesInput"></select>