diff --git a/background.js b/background.js index 52eac77..56aef91 100644 --- a/background.js +++ b/background.js @@ -1,6 +1,7 @@ /* global browser */ // cookieStoreIds of all managed containers +let mode = null; let historyPermissionEnabled = false; let intId = null; let historyCleanUpQueue = []; @@ -8,6 +9,8 @@ let containerCleanupTimer = null; let opennewtab = false; let deldelay = 30000; // delay until Tmp Containers and History Entries are removed let multiopen = 3; +let regexList = null; + // array of all allowed container colors const allcolors = [ "blue", @@ -24,6 +27,48 @@ const historyPermission = { permissions: ["history"], }; +function isOnRegexList(url) { + for (let i = 0; i < regexList.length; i++) { + if (regexList[i].test(url)) { + return true; + } + } + return false; +} + +async function buildRegExList() { + let selectors = await getFromStorage("object", "selectors", []); + + const out = []; + + selectors.forEach((e) => { + // check activ + if (typeof e.activ !== "boolean") { + return; + } + if (e.activ !== true) { + return; + } + + // check url regex + if (typeof e.url_regex !== "string") { + return; + } + e.url_regex = e.url_regex.trim(); + if (e.url_regex === "") { + return; + } + + try { + out.push(new RegExp(e.url_regex)); + } catch (e) { + return; + } + }); + + return out; +} + async function getFromStorage(type, id, fallback) { let tmp = await browser.storage.local.get(id); return typeof tmp[id] === type ? tmp[id] : fallback; @@ -169,9 +214,12 @@ async function onStorageChange() { if (usecolors.length < 1) { usecolors = allcolors; } - //deldelay = await getFromStorage("number", "deldelay", 30000); multiopen = await getFromStorage("number", "multiopen", 3); + mode = !(await getFromStorage("boolean", "mode", false)); + + regexList = await buildRegExList(); + historyCleanUpQueue = await getFromStorage( "object", "historyCleanUpQueue", @@ -213,12 +261,6 @@ async function onCommand(command) { } async function onBeforeNavigate(details) { - if (!historyPermissionEnabled) { - return; - } - if (historyCleanUpQueue.includes(details.url)) { - return; - } if (typeof details.url !== "string") { return; } @@ -232,16 +274,26 @@ async function onBeforeNavigate(details) { ); // in a container if (container.name.startsWith("Temp")) { + if (!historyPermissionEnabled) { + return; + } + if (historyCleanUpQueue.includes(details.url)) { + return; + } historyCleanUpQueue.push(details.url); setToStorage("historyCleanUpQueue", historyCleanUpQueue); } } catch (e) { // not in a container + const _isOnList = isOnRegexList(details.url); + if ((!mode && !_isOnList) || (mode && _isOnList)) { + await createTempContainerTab(details.url, true); + browser.tabs.remove(details.tabId); + } } } function cleanupHistory() { - console.debug(historyCleanUpQueue); const len = historyCleanUpQueue.length; const its = len > 1 ? len / 2 : 1; diff --git a/manifest.json b/manifest.json index 018a08b..9934c7f 100644 --- a/manifest.json +++ b/manifest.json @@ -35,5 +35,5 @@ "tabs" ], "optional_permissions": ["bookmarks", "history"], - "version": "1.1.22" + "version": "1.1.23" } diff --git a/options.html b/options.html index a733ce9..756b2b2 100644 --- a/options.html +++ b/options.html @@ -6,14 +6,16 @@
+ + diff --git a/options.js b/options.js index e4b9f1b..6408d9f 100644 --- a/options.js +++ b/options.js @@ -30,7 +30,7 @@ function onChange(evt) { browser.storage.local.set(obj).catch(console.error); } -["multiopen", "opennewtab"].map((id) => { +["mode", "multiopen", "opennewtab"].map((id) => { browser.storage.local .get(id) .then((obj) => { @@ -77,3 +77,151 @@ function onChange(evt) { browser.storage.local.set(obj).catch(console.error); }); }); + +function deleteRow(rowTr) { + mainTableBody.removeChild(rowTr); +} + +function createTableRow(feed) { + var tr = mainTableBody.insertRow(); + var input; + + Object.keys(feed) + .sort() + .forEach((key) => { + if (key === "activ") { + input = document.createElement("input"); + input.className = key; + input.placeholder = key; + input.style.width = "100%"; + input.type = "checkbox"; + input.checked = typeof feed[key] === "boolean" ? feed[key] : true; + tr.insertCell().appendChild(input); + } else if (key !== "action") { + input = document.createElement("input"); + input.className = key; + input.placeholder = key; + input.style.width = "100%"; + input.value = feed[key]; + tr.insertCell().appendChild(input); + } + }); + + var button; + if (feed.action === "save") { + button = createButton("ADD", "saveButton", function () {}, true); + } else { + button = createButton( + "DELETE", + "deleteButton", + function () { + deleteRow(tr); + }, + false + ); + } + tr.insertCell().appendChild(button); +} + +function collectConfig() { + var feeds = []; + for (var row = 0; row < mainTableBody.rows.length; row++) { + try { + var url_regex = mainTableBody.rows[row] + .querySelector(".url_regex") + .value.trim(); + var check = mainTableBody.rows[row].querySelector(".activ").checked; + if (url_regex !== "") { + feeds.push({ + activ: check, + url_regex: url_regex, + }); + } + } catch (e) { + console.error(e); + } + } + return feeds; +} + +function createButton(text, id, callback, submit) { + var span = document.createElement("span"); + var button = document.createElement("button"); + button.id = id; + button.textContent = text; + button.className = "browser-style"; + if (submit) { + button.type = "submit"; + } else { + button.type = "button"; + } + button.name = id; + button.value = id; + button.addEventListener("click", callback); + span.appendChild(button); + return span; +} + +async function saveOptions(/*e*/) { + var config = collectConfig(); + await browser.storage.local.set({ selectors: config }); +} + +async function restoreOptions() { + createTableRow({ + activ: 1, + url_regex: "", + action: "save", + }); + var res = await browser.storage.local.get("selectors"); + if (!Array.isArray(res.selectors)) { + return; + } + res.selectors.forEach((selector) => { + selector.action = "delete"; + createTableRow(selector); + }); +} + +document.addEventListener("DOMContentLoaded", restoreOptions); +document.querySelector("form").addEventListener("submit", saveOptions); + +const impbtnWrp = document.getElementById("impbtn_wrapper"); +const impbtn = document.getElementById("impbtn"); +const expbtn = document.getElementById("expbtn"); + +expbtn.addEventListener("click", async function () { + var dl = document.createElement("a"); + var res = await browser.storage.local.get("selectors"); + var content = JSON.stringify(res.selectors); + dl.setAttribute( + "href", + "data:application/json;charset=utf-8," + encodeURIComponent(content) + ); + dl.setAttribute("download", "data.json"); + dl.setAttribute("visibility", "hidden"); + dl.setAttribute("display", "none"); + document.body.appendChild(dl); + dl.click(); + document.body.removeChild(dl); +}); + +// delegate to real Import Button which is a file selector +impbtnWrp.addEventListener("click", function () { + impbtn.click(); +}); + +impbtn.addEventListener("input", function () { + var file = this.files[0]; + var reader = new FileReader(); + reader.onload = async function () { + try { + var config = JSON.parse(reader.result); + await browser.storage.local.set({ selectors: config }); + document.querySelector("form").submit(); + } catch (e) { + console.error("error loading file: " + e); + } + }; + reader.readAsText(file); +});