mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-12 18:39:58 +00:00
Add whitelist menu items
This commit is contained in:
@@ -31,6 +31,15 @@
|
|||||||
, "contextCast": {
|
, "contextCast": {
|
||||||
"message": "Cast..."
|
"message": "Cast..."
|
||||||
}
|
}
|
||||||
|
, "contextAddToWhitelist": {
|
||||||
|
"message": "Add to Whitelist"
|
||||||
|
}
|
||||||
|
, "contextAddToWhitelistRecommended": {
|
||||||
|
"message": "Add $1 (Recommended)"
|
||||||
|
}
|
||||||
|
, "contextAddToWhitelistAdvancedAdd": {
|
||||||
|
"message": "Add $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
, "optionsBridgeLoading": {
|
, "optionsBridgeLoading": {
|
||||||
|
|||||||
243
ext/src/main.ts
243
ext/src/main.ts
@@ -65,9 +65,18 @@ browser.runtime.onInstalled.addListener(async details => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
type MenuId = string | number;
|
||||||
|
|
||||||
// Menu IDs
|
// Menu IDs
|
||||||
let mirrorCastMenuId: string | number;
|
let mirrorCastMenuId: MenuId;
|
||||||
let mediaCastMenuId: string | number;
|
let mediaCastMenuId: MenuId;
|
||||||
|
|
||||||
|
|
||||||
|
let whitelistMenuId: MenuId;
|
||||||
|
let whitelistRecommendedMenuId: MenuId;
|
||||||
|
|
||||||
|
const whitelistMenuMap = new Map<MenuId, string>();
|
||||||
|
|
||||||
|
|
||||||
const mediaCastTargetUrlPatterns = new Set([
|
const mediaCastTargetUrlPatterns = new Set([
|
||||||
"http://*/*"
|
"http://*/*"
|
||||||
@@ -102,7 +111,7 @@ async function createMenus () {
|
|||||||
|
|
||||||
// Screen/Tab mirroring "Cast..." context menu item
|
// Screen/Tab mirroring "Cast..." context menu item
|
||||||
mirrorCastMenuId = await browser.menus.create({
|
mirrorCastMenuId = await browser.menus.create({
|
||||||
contexts: [ "browser_action", "page" ]
|
contexts: [ "browser_action", "page", "tools_menu" ]
|
||||||
, id: "contextCast"
|
, id: "contextCast"
|
||||||
, title: _("contextCast")
|
, title: _("contextCast")
|
||||||
, visible: options.mirroringEnabled
|
, visible: options.mirroringEnabled
|
||||||
@@ -113,6 +122,119 @@ async function createMenus () {
|
|||||||
, "https://*/*"
|
, "https://*/*"
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
whitelistMenuId = await browser.menus.create({
|
||||||
|
contexts: [ "browser_action", "tools_menu" ]
|
||||||
|
, title: _("contextAddToWhitelist")
|
||||||
|
, visible: false
|
||||||
|
});
|
||||||
|
|
||||||
|
whitelistRecommendedMenuId = await browser.menus.create({
|
||||||
|
title: _("contextAddToWhitelistRecommended")
|
||||||
|
, parentId: whitelistMenuId
|
||||||
|
});
|
||||||
|
|
||||||
|
await browser.menus.create({
|
||||||
|
type: "separator"
|
||||||
|
, parentId: whitelistMenuId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
browser.webNavigation.onCommitted.addListener(
|
||||||
|
details => {
|
||||||
|
// Only track navigation in top level contexts
|
||||||
|
if (details.frameId === 0) {
|
||||||
|
rebuildWhitelistMenus(details.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, { url: [
|
||||||
|
{ schemes: [ "http", "https" ]}]
|
||||||
|
});
|
||||||
|
|
||||||
|
browser.tabs.onActivated.addListener(async () => {
|
||||||
|
const { url } = (await browser.tabs.query({
|
||||||
|
active: true
|
||||||
|
, currentWindow: true
|
||||||
|
}))[0];
|
||||||
|
|
||||||
|
rebuildWhitelistMenus(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function rebuildWhitelistMenus (urlString: string) {
|
||||||
|
const url = new URL(urlString);
|
||||||
|
|
||||||
|
await browser.menus.update(whitelistMenuId, {
|
||||||
|
visible: url.origin !== "null"
|
||||||
|
})
|
||||||
|
|
||||||
|
function addWhitelistMenuItem (pattern: string) {
|
||||||
|
const menuId = browser.menus.create({
|
||||||
|
title: _("contextAddToWhitelistAdvancedAdd", pattern)
|
||||||
|
, parentId: whitelistMenuId
|
||||||
|
});
|
||||||
|
|
||||||
|
whitelistMenuMap.set(menuId, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [ menuId ] of whitelistMenuMap) {
|
||||||
|
// Remove all temporary menus
|
||||||
|
if (menuId !== whitelistRecommendedMenuId) {
|
||||||
|
browser.menus.remove(menuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear map
|
||||||
|
whitelistMenuMap.delete(menuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const recommendedPattern = `${url.origin}/*`;
|
||||||
|
|
||||||
|
browser.menus.update(whitelistRecommendedMenuId, {
|
||||||
|
title: _("contextAddToWhitelistRecommended", recommendedPattern)
|
||||||
|
});
|
||||||
|
|
||||||
|
whitelistMenuMap.set(whitelistRecommendedMenuId, recommendedPattern);
|
||||||
|
|
||||||
|
|
||||||
|
if (url.search) {
|
||||||
|
addWhitelistMenuItem(`${url.origin}${url.pathname}${url.search}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const pathTrimmed = url.pathname.endsWith("/")
|
||||||
|
? url.pathname.substring(0, url.pathname.length - 1)
|
||||||
|
: url.pathname;
|
||||||
|
|
||||||
|
const pathSegments = pathTrimmed.split("/")
|
||||||
|
.filter(segment => segment)
|
||||||
|
.reverse();
|
||||||
|
|
||||||
|
if (pathSegments.length) {
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
for (const pathSegment of pathSegments) {
|
||||||
|
const partialPath = pathSegments
|
||||||
|
.slice(index)
|
||||||
|
.reverse()
|
||||||
|
.join("/");
|
||||||
|
|
||||||
|
addWhitelistMenuItem(`${url.origin}/${partialPath}/*`);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const baseHost = (url.host.match(/\./g) || []).length > 1
|
||||||
|
? url.host.substring(url.host.indexOf(".") + 1)
|
||||||
|
: url.host;
|
||||||
|
|
||||||
|
// Wildcard protocol
|
||||||
|
addWhitelistMenuItem(`*://${url.host}/*`);
|
||||||
|
// Wildcard subdomain
|
||||||
|
addWhitelistMenuItem(`${url.protocol}//*.${baseHost}/*`);
|
||||||
|
// Wildcard protocol and subdomain
|
||||||
|
addWhitelistMenuItem(`*://*.${baseHost}/*`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -299,63 +421,84 @@ let mirrorCastFrameId: number;
|
|||||||
|
|
||||||
|
|
||||||
browser.menus.onClicked.addListener(async (info, tab) => {
|
browser.menus.onClicked.addListener(async (info, tab) => {
|
||||||
const { frameId } = info;
|
if (info.menuItemId === mirrorCastMenuId
|
||||||
const { options } = await browser.storage.sync.get("options");
|
|| info.menuItemId === mediaCastMenuId) {
|
||||||
|
|
||||||
// Load cast setup script
|
const { frameId } = info;
|
||||||
await browser.tabs.executeScript(tab.id, {
|
const { options } = await browser.storage.sync.get("options");
|
||||||
file: "shim/content.js"
|
|
||||||
, frameId
|
|
||||||
});
|
|
||||||
|
|
||||||
switch (info.menuItemId) {
|
// Load cast setup script
|
||||||
case "contextCast": {
|
await browser.tabs.executeScript(tab.id, {
|
||||||
mirrorCastTabId = tab.id;
|
file: "shim/content.js"
|
||||||
mirrorCastFrameId = frameId;
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
await browser.tabs.executeScript(tab.id, {
|
switch (info.menuItemId) {
|
||||||
code: `
|
case mirrorCastMenuId: {
|
||||||
var selectedMedia = "${info.pageUrl ? "tab" : "screen"}";
|
mirrorCastTabId = tab.id;
|
||||||
var FX_CAST_RECEIVER_APP_ID = "${options.mirroringAppId}";
|
mirrorCastFrameId = frameId;
|
||||||
`
|
|
||||||
, frameId
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load mirroring sender app
|
await browser.tabs.executeScript(tab.id, {
|
||||||
await browser.tabs.executeScript(tab.id, {
|
code: `
|
||||||
file: "mirroringCast.js"
|
var selectedMedia = "${info.pageUrl ? "tab" : "screen"}";
|
||||||
, frameId
|
var FX_CAST_RECEIVER_APP_ID = "${options.mirroringAppId}";
|
||||||
});
|
`
|
||||||
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
break;
|
// Load mirroring sender app
|
||||||
|
await browser.tabs.executeScript(tab.id, {
|
||||||
|
file: "mirroringCast.js"
|
||||||
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case mediaCastMenuId: {
|
||||||
|
mediaCastTabId = tab.id;
|
||||||
|
mediaCastFrameId = frameId;
|
||||||
|
|
||||||
|
// Pass media URL to media sender app
|
||||||
|
await browser.tabs.executeScript(tab.id, {
|
||||||
|
code: `var srcUrl = "${info.srcUrl}";
|
||||||
|
var targetElementId = ${info.targetElementId};`
|
||||||
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load media sender app
|
||||||
|
await browser.tabs.executeScript(tab.id, {
|
||||||
|
file: "mediaCast.js"
|
||||||
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "contextCastMedia": {
|
// Load cast API
|
||||||
mediaCastTabId = tab.id;
|
await browser.tabs.executeScript(tab.id, {
|
||||||
mediaCastFrameId = frameId;
|
file: "shim/bundle.js"
|
||||||
|
, frameId
|
||||||
|
});
|
||||||
|
|
||||||
// Pass media URL to media sender app
|
return;
|
||||||
await browser.tabs.executeScript(tab.id, {
|
|
||||||
code: `var srcUrl = "${info.srcUrl}";
|
|
||||||
var targetElementId = ${info.targetElementId};`
|
|
||||||
, frameId
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load media sender app
|
|
||||||
await browser.tabs.executeScript(tab.id, {
|
|
||||||
file: "mediaCast.js"
|
|
||||||
, frameId
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load cast API
|
|
||||||
await browser.tabs.executeScript(tab.id, {
|
if (info.parentMenuItemId === whitelistMenuId) {
|
||||||
file: "shim/bundle.js"
|
const matchPattern = whitelistMenuMap.get(info.menuItemId);
|
||||||
, frameId
|
const options: Options =
|
||||||
});
|
(await browser.storage.sync.get("options")).options;
|
||||||
|
|
||||||
|
// Add to whitelist
|
||||||
|
options.userAgentWhitelist.push(matchPattern);
|
||||||
|
|
||||||
|
// Update options
|
||||||
|
await browser.storage.sync.set({
|
||||||
|
options: options
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
, "menus"
|
, "menus"
|
||||||
, "nativeMessaging"
|
, "nativeMessaging"
|
||||||
, "storage"
|
, "storage"
|
||||||
|
, "tabs"
|
||||||
, "webNavigation"
|
, "webNavigation"
|
||||||
, "webRequest"
|
, "webRequest"
|
||||||
, "webRequestBlocking"
|
, "webRequestBlocking"
|
||||||
|
|||||||
Reference in New Issue
Block a user