notes/.config/chromium/Default/Extensions/doojmbjmlfjjnbmnoijecmcbfeoakpjm/11.4.6_0/ui/popup.js

423 lines
12 KiB
JavaScript

/*
* 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();
}
})();