Files
Config/BraveSoftware/Brave-Browser/Default/Extensions/cimiefiiaegbelhefglklhhakcgmhkai/2.1_0/action_popup.js

288 lines
9.9 KiB
JavaScript

/*
Copyright (C) 2019 Kai Uwe Broulik <kde@privat.broulik.de>
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 <http://www.gnu.org/licenses/>.
*/
class TabUtils {
// Gets the currently viewed tab
static getCurrentTab() {
return new Promise((resolve, reject) => {
chrome.tabs.query({
active: true,
currentWindow: true
}, (tabs) => {
const error = chrome.runtime.lastError;
if (error) {
return reject(error.message);
}
const tab = tabs[0];
if (!tab) {
return reject("NO_TAB");
}
resolve(tab);
});
});
}
// Gets the URLs of the currently viewed tab including all of its iframes
static getCurrentTabFramesUrls() {
return new Promise((resolve, reject) => {
TabUtils.getCurrentTab().then((tab) => {
chrome.scripting.executeScript({
target: {
tabId: tab.id,
allFrames: true
},
func: () => {
return window.location.href;
}
}, (result) => {
const error = chrome.runtime.lastError;
if (error) {
return reject(error.message);
}
const urls = result.map(result => result.result);
resolve(urls);
});
});
});
}
};
class MPrisBlocker {
getAllowed() {
return new Promise((resolve, reject) => {
Promise.all([
SettingsUtils.get(),
TabUtils.getCurrentTabFramesUrls()
]).then((result) => {
const settings = result[0];
const currentUrls = result[1];
const mprisSettings = settings.mpris;
if (!mprisSettings.enabled) {
return reject("MPRIS_DISABLED");
}
if (!currentUrls) { // can this happen?
return reject("NO_URLS");
}
const origins = currentUrls.map((url) => {
try {
return new URL(url).origin;
} catch (e) {
console.warn("Invalid url", url);
return "";
}
}).filter((origin) => {
// for URLs like about:blank origin is "null" (as string!).
return !!origin && origin !== "null";
});
if (origins.length === 0) {
return reject("NO_ORIGINS");
}
const uniqueOrigins = [...new Set(origins)];
const websiteSettings = mprisSettings.websiteSettings || {};
let response = {
origins: {},
mprisSettings
};
for (const origin of uniqueOrigins) {
let allowed = true;
if (typeof MPRIS_WEBSITE_SETTINGS[origin] === "boolean") {
allowed = MPRIS_WEBSITE_SETTINGS[origin];
}
if (typeof websiteSettings[origin] === "boolean") {
allowed = websiteSettings[origin];
}
response.origins[origin] = allowed;
}
resolve(response);
}, reject);
});
}
setAllowed(origin, allowed) {
return SettingsUtils.get().then((settings) => {
const mprisSettings = settings.mpris;
if (!mprisSettings.enabled) {
return reject("MPRIS_DISABLED");
}
let websiteSettings = mprisSettings.websiteSettings || {};
let implicitAllowed = true;
if (typeof MPRIS_WEBSITE_SETTINGS[origin] === "boolean") {
implicitAllowed = MPRIS_WEBSITE_SETTINGS[origin];
}
if (allowed !== implicitAllowed) {
websiteSettings[origin] = allowed;
} else {
delete websiteSettings[origin];
}
mprisSettings.websiteSettings = websiteSettings;
return SettingsUtils.set({
mpris: mprisSettings
});
});
}
};
document.addEventListener("DOMContentLoaded", () => {
sendMessage("browserAction", "getStatus").then((status) => {
switch (status.portStatus) {
case "UNSUPPORTED_OS":
document.getElementById("unsupported_os_error").classList.remove("hidden");
break;
case "STARTUP_FAILED": {
document.getElementById("startup_error").classList.remove("hidden");
const errorText = status.portLastErrorMessage;
// Don't show generic error on startup failure. There's already an explanation.
if (errorText && errorText !== "UNKNOWN") {
const errorTextItem = document.getElementById("startup_error_text");
errorTextItem.innerText = errorText;
errorTextItem.classList.remove("hidden");
}
break;
}
default: {
document.getElementById("main").classList.remove("hidden");
let errorText = status.portLastErrorMessage;
if (errorText === "UNKNOWN") {
errorText = chrome.i18n.getMessage("general_error_unknown");
}
if (errorText) {
document.getElementById("runtime_error_text").innerText = errorText;
document.getElementById("runtime_error").classList.remove("hidden");
// There's some content, hide dummy placeholder
document.getElementById("dummy-main").classList.add("hidden");
}
break;
}
}
// HACK so the extension can tell we closed, see "browserAction" "ready" callback in extension.js
chrome.runtime.onConnect.addListener((port) => {
if (port.name !== "browserActionPort") {
return;
}
// do we need to do something with the port here?
});
sendMessage("browserAction", "ready");
});
// MPris blocker checkboxes
const blocker = new MPrisBlocker();
blocker.getAllowed().then((result) => {
const origins = result.origins;
if (Object.entries(origins).length === 0) { // "isEmpty"
return;
}
// To keep media controls setting from always showing up, only show them, if:
// - There is actually a player anywhere on this tab
// or, since when mpris is disabled, there are never any players
// - when media controls are disabled for any origin on this tab
new Promise((resolve, reject) => {
for (let origin in origins) {
if (origins[origin] === false) {
return resolve("HAS_BLOCKED");
}
}
TabUtils.getCurrentTab().then((tab) => {
return sendMessage("mpris", "hasTabPlayer", {
tabId: tab.id
});
}).then((playerIds) => {
if (playerIds.length > 0) {
return resolve("HAS_PLAYER");
}
reject("NO_PLAYER_NO_BLOCKED");
});
}).then(() => {
// There's some content, hide dummy placeholder
document.getElementById("dummy-main").classList.add("hidden");
let blacklistInfoElement = document.querySelector(".mpris-blacklist-info");
blacklistInfoElement.classList.remove("hidden");
let originsListElement = blacklistInfoElement.querySelector("ul.mpris-blacklist-origins");
for (const origin in origins) {
const originAllowed = origins[origin];
let blockListElement = document.createElement("li");
let labelElement = document.createElement("label");
labelElement.innerText = origin;
let checkboxElement = document.createElement("input");
checkboxElement.type = "checkbox";
checkboxElement.checked = (originAllowed === true);
checkboxElement.addEventListener("click", (e) => {
// Let us handle (un)checking the checkbox when setAllowed succeeds
e.preventDefault();
const allowed = checkboxElement.checked;
blocker.setAllowed(origin, allowed).then(() => {
checkboxElement.checked = allowed;
}, (err) => {
console.warn("Failed to change media controls settings:", err);
});
});
labelElement.insertBefore(checkboxElement, labelElement.firstChild);
blockListElement.appendChild(labelElement);
originsListElement.appendChild(blockListElement);
}
}, (err) => {
console.log("Not showing media controls settings because", err);
});
}, (err) => {
console.warn("Failed to check for whether media controls are blocked", err);
});
});