chrome菜单
Some checks failed
test / Run tests (push) Failing after 3s
build / Build (push) Failing after 5s
Some checks failed
test / Run tests (push) Failing after 3s
build / Build (push) Failing after 5s
This commit is contained in:
@ -86,13 +86,19 @@ export class ExtensionMessageConnect implements MessageConnect {
|
||||
}
|
||||
|
||||
export class ExtensionContentMessageSend extends ExtensionMessageSend {
|
||||
constructor(private tabId: number) {
|
||||
constructor(
|
||||
private tabId: number,
|
||||
private options?: {
|
||||
frameId?: number;
|
||||
documentId?: string;
|
||||
}
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
sendMessage(data: any): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
chrome.tabs.sendMessage(this.tabId, data, (resp) => {
|
||||
chrome.tabs.sendMessage(this.tabId, data, this.options || {}, (resp) => {
|
||||
resolve(resp);
|
||||
});
|
||||
});
|
||||
@ -100,7 +106,7 @@ export class ExtensionContentMessageSend extends ExtensionMessageSend {
|
||||
|
||||
connect(data: any): Promise<MessageConnect> {
|
||||
return new Promise((resolve) => {
|
||||
const con = chrome.tabs.connect(this.tabId);
|
||||
const con = chrome.tabs.connect(this.tabId, this.options);
|
||||
con.postMessage(data);
|
||||
resolve(new ExtensionMessageConnect(con));
|
||||
});
|
||||
|
@ -35,6 +35,7 @@ export type ScriptMenuRegisterCallbackValue = {
|
||||
accessKey: string;
|
||||
tabId: number;
|
||||
frameId: number;
|
||||
documentId: string;
|
||||
};
|
||||
|
||||
export function subscribeScriptMenuRegister(
|
||||
|
@ -112,6 +112,12 @@ export class PopupClient extends Client {
|
||||
}
|
||||
|
||||
menuClick(uuid: string, data: ScriptMenuItem) {
|
||||
return this.do("menuClick", { uuid, id: data.id, tabId: data.tabId, frameId: data.frameId });
|
||||
return this.do("menuClick", {
|
||||
uuid,
|
||||
id: data.id,
|
||||
tabId: data.tabId,
|
||||
frameId: data.frameId,
|
||||
documentId: data.documentId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ export default class GMApi {
|
||||
accessKey: accessKey,
|
||||
tabId: sender.getSender().tab!.id!,
|
||||
frameId: sender.getSender().frameId,
|
||||
documentId: sender.getSender().documentId,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,9 @@ export type ScriptMenuItem = {
|
||||
id: number;
|
||||
name: string;
|
||||
accessKey?: string;
|
||||
tabId: number | "background";
|
||||
frameId: number;
|
||||
tabId: number; //-1表示后台脚本
|
||||
frameId?: number;
|
||||
documentId?: string;
|
||||
};
|
||||
|
||||
export type ScriptMenu = {
|
||||
@ -52,6 +53,54 @@ export class PopupService {
|
||||
private runtime: RuntimeService
|
||||
) {}
|
||||
|
||||
genScriptMenuByTabMap(menu: ScriptMenu[]) {
|
||||
menu.forEach((script) => {
|
||||
// 创建脚本菜单
|
||||
if (script.menus.length) {
|
||||
chrome.contextMenus.create({
|
||||
id: `scriptMenu_` + script.uuid,
|
||||
title: script.name,
|
||||
contexts: ["all"],
|
||||
parentId: "scriptMenu",
|
||||
});
|
||||
script.menus.forEach((menu) => {
|
||||
// 创建菜单
|
||||
console.log("create menu", menu);
|
||||
chrome.contextMenus.create({
|
||||
id: `scriptMenu_menu_${script.uuid}_${menu.id}`,
|
||||
title: menu.name,
|
||||
contexts: ["all"],
|
||||
parentId: `scriptMenu_${script.uuid}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 生成chrome菜单
|
||||
async genScriptMenu(tabId: number) {
|
||||
// 移除之前所有的菜单
|
||||
chrome.contextMenus.removeAll();
|
||||
const [menu, backgroundMenu] = await Promise.all([this.getScriptMenu(tabId), this.getScriptMenu(-1)]);
|
||||
console.log(menu, backgroundMenu, tabId);
|
||||
if (!menu.length && !backgroundMenu.length) {
|
||||
return;
|
||||
}
|
||||
// 创建根菜单
|
||||
chrome.contextMenus.create({
|
||||
id: "scriptMenu",
|
||||
title: "ScriptCat",
|
||||
contexts: ["all"],
|
||||
});
|
||||
if (menu) {
|
||||
this.genScriptMenuByTabMap(menu);
|
||||
}
|
||||
// 后台脚本的菜单
|
||||
if (backgroundMenu) {
|
||||
this.genScriptMenuByTabMap(backgroundMenu);
|
||||
}
|
||||
}
|
||||
|
||||
async registerMenuCommand(message: ScriptMenuRegisterCallbackValue) {
|
||||
// 给脚本添加菜单
|
||||
const data = await this.getScriptMenu(message.tabId);
|
||||
@ -65,6 +114,7 @@ export class PopupService {
|
||||
accessKey: message.accessKey,
|
||||
tabId: message.tabId,
|
||||
frameId: message.frameId,
|
||||
documentId: message.documentId,
|
||||
});
|
||||
} else {
|
||||
menu.name = message.name;
|
||||
@ -72,8 +122,10 @@ export class PopupService {
|
||||
menu.tabId = message.tabId;
|
||||
}
|
||||
}
|
||||
console.log(data);
|
||||
Cache.getInstance().set("tabScript:" + message.tabId, data);
|
||||
console.log("set menu", data);
|
||||
await Cache.getInstance().set("tabScript:" + message.tabId, data);
|
||||
console.log("update menu");
|
||||
this.updateScriptMenu();
|
||||
}
|
||||
|
||||
async unregisterMenuCommand({ id, uuid, tabId }: { id: number; uuid: string; tabId: number }) {
|
||||
@ -83,7 +135,21 @@ export class PopupService {
|
||||
if (script) {
|
||||
script.menus = script.menus.filter((item) => item.id !== id);
|
||||
}
|
||||
Cache.getInstance().set("tabScript:" + tabId, data);
|
||||
await Cache.getInstance().set("tabScript:" + tabId, data);
|
||||
this.updateScriptMenu();
|
||||
}
|
||||
|
||||
updateScriptMenu() {
|
||||
// 获取当前页面并更新菜单
|
||||
chrome.tabs.query({ active: true }, (tabs) => {
|
||||
console.log("query", tabs);
|
||||
if (!tabs.length) {
|
||||
return;
|
||||
}
|
||||
const tab = tabs[0];
|
||||
// 生成菜单
|
||||
tab.id && this.genScriptMenu(tab.id);
|
||||
});
|
||||
}
|
||||
|
||||
scriptToMenu(script: Script): ScriptMenu {
|
||||
@ -225,15 +291,34 @@ export class PopupService {
|
||||
});
|
||||
}
|
||||
|
||||
menuClick({ uuid, id, tabId, frameId }: { uuid: string; id: number; tabId: number; frameId: number }) {
|
||||
menuClick({
|
||||
uuid,
|
||||
id,
|
||||
tabId,
|
||||
frameId,
|
||||
documentId,
|
||||
}: {
|
||||
uuid: string;
|
||||
id: number;
|
||||
tabId: number;
|
||||
frameId: number;
|
||||
documentId: string;
|
||||
}) {
|
||||
// 菜单点击事件
|
||||
console.log("click menu", uuid, id, tabId);
|
||||
this.runtime.sendMessageToTab(tabId, "menuClick", {
|
||||
uuid,
|
||||
id,
|
||||
console.log("click menu", uuid, id, tabId, frameId, documentId);
|
||||
this.runtime.sendMessageToTab(
|
||||
tabId,
|
||||
frameId,
|
||||
});
|
||||
"menuClick",
|
||||
{
|
||||
uuid,
|
||||
id,
|
||||
tabId,
|
||||
},
|
||||
{
|
||||
frameId,
|
||||
documentId: documentId,
|
||||
}
|
||||
);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
@ -250,10 +335,47 @@ export class PopupService {
|
||||
// 清理数据
|
||||
Cache.getInstance().del("tabScript:" + tabId);
|
||||
});
|
||||
// 监听页面切换加载菜单
|
||||
chrome.tabs.onActivated.addListener((activeInfo) => {
|
||||
this.genScriptMenu(activeInfo.tabId);
|
||||
});
|
||||
// 处理chrome菜单点击
|
||||
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
||||
const menuIds = (info.menuItemId as string).split("_");
|
||||
if (menuIds.length === 4) {
|
||||
const [, , uuid, id] = menuIds;
|
||||
// 寻找menu信息
|
||||
const menu = await this.getScriptMenu(tab!.id!);
|
||||
const script = menu.find((item) => item.uuid === uuid);
|
||||
if (script) {
|
||||
const menuItem = script.menus.find((item) => item.id === parseInt(id, 10));
|
||||
if (menuItem) {
|
||||
this.menuClick({
|
||||
uuid: script.uuid,
|
||||
id: menuItem.id,
|
||||
tabId: tab!.id!,
|
||||
frameId: menuItem.frameId || 0,
|
||||
documentId: menuItem.documentId || "",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听运行次数
|
||||
this.mq.subscribe(
|
||||
"pageLoad",
|
||||
async ({ tabId, frameId, scripts }: { tabId: number; frameId: number; scripts: ScriptMatchInfo[] }) => {
|
||||
async ({
|
||||
tabId,
|
||||
frameId,
|
||||
scripts,
|
||||
}: {
|
||||
tabId: number;
|
||||
frameId: number;
|
||||
document: string;
|
||||
scripts: ScriptMatchInfo[];
|
||||
}) => {
|
||||
this.addScriptRunNumber({ tabId, frameId, scripts });
|
||||
// 设置角标和脚本
|
||||
chrome.action.getBadgeText(
|
||||
|
@ -122,12 +122,20 @@ export class RuntimeService {
|
||||
}
|
||||
|
||||
// 给指定tab发送消息
|
||||
sendMessageToTab(tabId: number, action: string, data: any) {
|
||||
sendMessageToTab(
|
||||
tabId: number,
|
||||
action: string,
|
||||
data: any,
|
||||
options?: {
|
||||
documentId?: string;
|
||||
frameId?: number;
|
||||
}
|
||||
) {
|
||||
if (tabId === -1) {
|
||||
// 如果是-1, 代表给offscreen发送消息
|
||||
return sendMessage(this.sender, "offscreen/runtime/" + action, data);
|
||||
}
|
||||
return sendMessage(new ExtensionContentMessageSend(tabId), "content/runtime/" + action, data);
|
||||
return sendMessage(new ExtensionContentMessageSend(tabId, options), "content/runtime/" + action, data);
|
||||
}
|
||||
|
||||
async getPageScriptUuidByUrl(url: string) {
|
||||
|
@ -30,6 +30,7 @@
|
||||
"activeTab",
|
||||
"webRequest",
|
||||
"userScripts",
|
||||
"contextMenus",
|
||||
"declarativeNetRequest"
|
||||
],
|
||||
"host_permissions": [
|
||||
|
Reference in New Issue
Block a user