📝 Added entire config directory for backup purposes
This commit is contained in:
parent
4b38e59bb6
commit
9b946e2d14
11091 changed files with 1440953 additions and 0 deletions
|
|
@ -0,0 +1,423 @@
|
|||
/*
|
||||
* NoScript - a Firefox extension for whitelist driven safe JavaScript execution
|
||||
*
|
||||
* Copyright (C) 2005-2022 Giorgio Maone <https://maone.net>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var sitesUI;
|
||||
var port;
|
||||
addEventListener("unload", e => {
|
||||
if (!UI.initialized) {
|
||||
Messages.send("openStandalonePopup");
|
||||
}
|
||||
});
|
||||
|
||||
(async () => {
|
||||
|
||||
function messageBox(className, message, extraUI = null) {
|
||||
let el = document.getElementById("message");
|
||||
if (className === "hidden" && el._lastMessage !== message) return;
|
||||
el._lastMessage = el.textContent = message;
|
||||
el.className = className;
|
||||
if (extraUI) {
|
||||
el.appendChild(extraUI);
|
||||
if (typeof extraUI.focus === "function") {
|
||||
extraUI.focus();
|
||||
}
|
||||
}
|
||||
el.scrollIntoView();
|
||||
}
|
||||
|
||||
try {
|
||||
let tabId;
|
||||
UI.isBrowserAction = true;
|
||||
let optionsClosed = false;
|
||||
|
||||
let tabFlags = {active: true};
|
||||
if (browser.windows) tabFlags.currentWindow = true; // Desktop browsers only
|
||||
let tab = (await browser.tabs.query(tabFlags))[0] ||
|
||||
// work-around for Firefox "forgetting" tabs on Android
|
||||
(await browser.tabs.query({url: ["*://*/*", "file:///*", "ftp://*/*"]}))[0];
|
||||
|
||||
let pageTab = tab;
|
||||
|
||||
if (!tab || tab.id === -1) {
|
||||
log("No tab found to open the UI for");
|
||||
close();
|
||||
}
|
||||
if (tab.url === document.URL) {
|
||||
UI.isBrowserAction = false;
|
||||
try {
|
||||
tabId = parseInt(document.URL.match(/#.*\btab(\d+)/)[1]);
|
||||
pageTab = await browser.tabs.get(tabId);
|
||||
} catch (e) {
|
||||
close();
|
||||
}
|
||||
addEventListener("blur", close);
|
||||
} else {
|
||||
tabId = tab.id;
|
||||
}
|
||||
|
||||
addEventListener("keydown", e => {
|
||||
if (e.code === "Enter") {
|
||||
let focused = document.activeElement;
|
||||
if (focused.closest(".sites")) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
port = browser.runtime.connect({name: "noscript.popup"});
|
||||
await UI.init(pageTab);
|
||||
|
||||
function pendingReload(b) {
|
||||
try {
|
||||
port.postMessage({tabId, pendingReload: b});
|
||||
} catch (e) {
|
||||
debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (UI.isBrowserAction) {
|
||||
browser.tabs.onActivated.addListener(e => {
|
||||
if (e.tabId !== tabId) close();
|
||||
});
|
||||
}
|
||||
|
||||
await include("/ui/toolbar.js");
|
||||
UI.toolbarInit();
|
||||
{
|
||||
let handlers = {
|
||||
"options": e => {
|
||||
if (UA.mobile) { // Fenix fails on openOptionsPage
|
||||
browser.tabs.create({url: browser.runtime.getManifest().options_ui.page});
|
||||
} else {
|
||||
browser.runtime.openOptionsPage();
|
||||
}
|
||||
close();
|
||||
},
|
||||
"close": close,
|
||||
"reload": reload,
|
||||
"temp-trust-page": e => sitesUI.tempTrustAll(),
|
||||
"revoke-temp": e => {
|
||||
UI.revokeTemp(sitesUI && sitesUI.hasTemp);
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
for (let b of document.querySelectorAll("#top .icon")) {
|
||||
b.tabIndex = 0;
|
||||
if (b.id in handlers) {
|
||||
let h = handlers[b.id];
|
||||
b.onclick = h;
|
||||
}
|
||||
}
|
||||
|
||||
let keyHandlers = {
|
||||
"r": "reload",
|
||||
"o": "options",
|
||||
"p": "temp-trust-page",
|
||||
"f": "revoke-temp",
|
||||
"G": "enforce",
|
||||
"T": "enforce-tab",
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", e => {
|
||||
let buttonId = keyHandlers[e.key];
|
||||
if (buttonId) document.getElementById(buttonId).click();
|
||||
}, true);
|
||||
|
||||
let navigate = e => {
|
||||
let sel = e.code === "ArrowUp" ? ":last-child" : "";
|
||||
document.querySelector(`.sites tr.site${sel} input.preset:checked`).focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.querySelector("#top").addEventListener("keydown", e => {
|
||||
switch(e.code) {
|
||||
case "Space":
|
||||
case "Enter":
|
||||
e.target.click();
|
||||
e.preventDefault();
|
||||
break;
|
||||
case "ArrowDown":
|
||||
case "ArrowUp":
|
||||
navigate(e);
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
case "ArrowRight":
|
||||
{
|
||||
let focused = document.activeElement;
|
||||
let all = [...focused.parentNode.querySelectorAll(".icon")];
|
||||
let index = all.indexOf(focused);
|
||||
if (index === -1) return;
|
||||
index += e.code === "ArrowRight" ? 1 : -1;
|
||||
if (index >= all.length) index = 0;
|
||||
else if (index < 0) index = all.length -1;
|
||||
all[index].focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
let originallyEnforced = UI.policy.enforced;
|
||||
let enforcementWarning = button => {
|
||||
if (button) {
|
||||
let clone = button.cloneNode(true);
|
||||
clone.onclick = button.onclick;
|
||||
button = clone;
|
||||
}
|
||||
messageBox(button ? "warning" : "hidden", _("NotEnforced"), button);
|
||||
};
|
||||
let setupEnforcement = () => {
|
||||
let policy = UI.policy;
|
||||
let pressed = policy.enforced;
|
||||
let button = document.getElementById("enforce");
|
||||
button.setAttribute("aria-pressed", pressed);
|
||||
button.title = _(pressed ? "NoEnforcement" : "Enforce");
|
||||
button.onclick = async () => {
|
||||
this.disabled = true;
|
||||
policy.enforced = !pressed;
|
||||
await UI.updateSettings({policy, reloadAffected: false});
|
||||
if (policy.enforced !== originallyEnforced &&
|
||||
(policy.enforced || UI.local.immediateUnrestrict)) {
|
||||
reload();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
setupEnforcement();
|
||||
pendingReload(true);
|
||||
};
|
||||
button.disabled = false;
|
||||
enforcementWarning(!policy.enforced && button);
|
||||
setupTabEnforcement();
|
||||
};
|
||||
|
||||
let setupTabEnforcement = () => {
|
||||
let pressed = !UI.unrestrictedTab;
|
||||
let button = document.getElementById("enforce-tab");
|
||||
button.setAttribute("aria-pressed", pressed);
|
||||
button.title = _(pressed ? "NoEnforcementForTab" : "EnforceForTab");
|
||||
if (UI.policy.enforced) {
|
||||
button.onclick = async () => {
|
||||
this.disabled = true;
|
||||
await UI.updateSettings({
|
||||
unrestrictedTab: pressed,
|
||||
reloadAffected: false,
|
||||
});
|
||||
UI.unrestrictedTab = pressed;
|
||||
if (!(UI.unrestrictedTab && UI.local.stickyUnrestrictedTab)) {
|
||||
reload();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
setupEnforcement();
|
||||
pendingReload(true);
|
||||
}
|
||||
button.disabled = false;
|
||||
enforcementWarning(UI.unrestrictedTab && button);
|
||||
} else {
|
||||
button.disabled = true;
|
||||
}
|
||||
};
|
||||
|
||||
setupEnforcement();
|
||||
|
||||
|
||||
let mainFrame = UI.seen && UI.seen.find(thing => thing.request.type === "main_frame");
|
||||
debug("Seen: %o", UI.seen);
|
||||
if (!mainFrame) {
|
||||
let isHttp = /^https?:/.test(pageTab.url);
|
||||
try {
|
||||
await browser.tabs.executeScript(tabId, { code: "" });
|
||||
if (isHttp) {
|
||||
document.body.classList.add("disabled");
|
||||
messageBox("warning", _("freshInstallReload"));
|
||||
let buttons = document.querySelector("#buttons");
|
||||
let b = document.createElement("button");
|
||||
b.textContent = _("OK");
|
||||
b.onclick = document.getElementById("reload").onclick = () => {
|
||||
reload();
|
||||
close();
|
||||
}
|
||||
buttons.appendChild(b).focus();
|
||||
b = document.createElement("button");
|
||||
b.textContent = _("Cancel");
|
||||
b.onclick = () => close();
|
||||
buttons.appendChild(b);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
error(e, "Could not run scripts on %s: privileged page?", pageTab.url);
|
||||
}
|
||||
|
||||
await include("/nscl/common/restricted.js");
|
||||
let isRestricted = isRestrictedURL(pageTab.url);
|
||||
if (!isHttp || isRestricted) {
|
||||
messageBox("warning", _("privilegedPage"));
|
||||
let tempTrust = document.getElementById("temp-trust-page");
|
||||
tempTrust.disabled = true;
|
||||
return;
|
||||
}
|
||||
if (!UI.seen) {
|
||||
if (!isHttp) return;
|
||||
let {url} = pageTab;
|
||||
UI.seen = [
|
||||
mainFrame = {
|
||||
request: { url, documentUrl: url, type: "main_frame" }
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
let justDomains = !UI.local.showFullAddresses;
|
||||
|
||||
sitesUI = new UI.Sites(document.getElementById("sites"));
|
||||
|
||||
sitesUI.onChange = (row) => {
|
||||
pendingReload(sitesUI.anyPermissionsChanged());
|
||||
if (optionsClosed) return;
|
||||
browser.tabs.query({
|
||||
url: browser.runtime.getURL(
|
||||
browser.runtime.getManifest().options_ui.page)
|
||||
}).then(tabs => {
|
||||
browser.tabs.remove(tabs.map(t => t.id));
|
||||
});
|
||||
optionsClosed = true;
|
||||
};
|
||||
initSitesUI();
|
||||
UI.onSettings = initSitesUI;
|
||||
|
||||
if (UI.incognito) {
|
||||
UI.wireOption("overrideTorBrowserPolicy", "sync", o => {
|
||||
let {checked} = o;
|
||||
if (UI.forceIncognito !== !checked) {
|
||||
UI.forceIncognito = !checked;
|
||||
sitesUI.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initSitesUI() {
|
||||
pendingReload(false);
|
||||
let {
|
||||
typesMap
|
||||
} = sitesUI;
|
||||
typesMap.clear();
|
||||
let policySites = UI.policy.sites;
|
||||
let domains = new Map();
|
||||
let protocols = new Set();
|
||||
function urlToLabel(url) {
|
||||
let origin = Sites.origin(url);
|
||||
let match = policySites.match(url);
|
||||
if (match) {
|
||||
if (match === url.protocol) {
|
||||
protocols.add(match);
|
||||
} else {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
if (domains.has(origin)) {
|
||||
if (justDomains) return domains.get(origin);
|
||||
} else {
|
||||
let domain = tld.getDomain(url.hostname);
|
||||
if (domain) {
|
||||
domain = url.protocol === "https:" ? Sites.secureDomainKey(domain) : domain;
|
||||
} else {
|
||||
domain = url.protocol;
|
||||
}
|
||||
domains.set(origin, domain);
|
||||
if (justDomains) return domain;
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
let seen = UI.seen;
|
||||
let parsedSeen = seen.map(thing => Object.assign({
|
||||
type: thing.policyType
|
||||
}, Sites.parse(thing.request.url)))
|
||||
.filter(parsed => parsed.url && (
|
||||
parsed.url.origin !== "null" || parsed.url.protocol === "file:"));
|
||||
|
||||
let sitesSet = new Set(
|
||||
parsedSeen.map(parsed => parsed.label = urlToLabel(parsed.url))
|
||||
);
|
||||
if (!justDomains) {
|
||||
for (let domain of domains.values()) sitesSet.add(domain);
|
||||
}
|
||||
for (let protocol of protocols) sitesSet.add(protocol);
|
||||
let sites = [...sitesSet];
|
||||
for (let parsed of parsedSeen) {
|
||||
sites.filter(s => parsed.label === s || domains.get(Sites.origin(parsed.url)) === s).forEach(m => {
|
||||
let siteTypes = typesMap.get(m);
|
||||
if (!siteTypes) typesMap.set(m, siteTypes = new Set());
|
||||
siteTypes.add(parsed.type);
|
||||
});
|
||||
}
|
||||
|
||||
sitesUI.mainUrl = new URL(mainFrame.request.url)
|
||||
sitesUI.mainSite = urlToLabel(sitesUI.mainUrl);
|
||||
sitesUI.mainDomain = tld.getDomain(sitesUI.mainUrl.hostname);
|
||||
|
||||
sitesUI.render(sites);
|
||||
sitesUI.focus();
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
if (sitesUI) sitesUI.clear();
|
||||
browser.tabs.reload(tabId);
|
||||
pendingReload(false);
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (UI.isBrowserAction) {
|
||||
window.close();
|
||||
} else {
|
||||
browser.tabs.remove(tab.id);
|
||||
}
|
||||
}
|
||||
|
||||
let {
|
||||
onCompleted
|
||||
} = browser.webNavigation;
|
||||
|
||||
let loadSnapshot = sitesUI.snapshot;
|
||||
let onCompletedListener = navigated => {
|
||||
if (navigated.tabId === tabId) {
|
||||
setTimeout(() => UI.pullSettings(), 500);
|
||||
}
|
||||
};
|
||||
onCompleted.addListener(onCompletedListener, {
|
||||
url: [{
|
||||
hostContains: sitesUI.mainDomain
|
||||
}]
|
||||
});
|
||||
addEventListener("blur", e => {
|
||||
onCompleted.removeListener(onCompletedListener);
|
||||
port.disconnect(); // otherwise Vivaldi keeps it after closing
|
||||
});
|
||||
} catch (e) {
|
||||
error(e, "Can't open popup");
|
||||
close();
|
||||
}
|
||||
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue