204 lines
5.8 KiB
TypeScript
Raw Normal View History

2021-11-04 21:01:33 +08:00
import {Msg, Page, PluginEvent} from "@/core/types";
2021-04-26 22:27:47 +08:00
2021-11-14 18:05:55 +08:00
// @ts-ignore
import * as UA from "universal-analytics"
import {v4} from "uuid"
// 统计服务
const userID = localStorage.getItem("userID") || v4()
UA("UA-134924925-3", userID);
2021-11-04 21:01:33 +08:00
console.log("on background")
2021-04-26 22:27:47 +08:00
2021-11-04 21:01:33 +08:00
class PortMan {
content: chrome.runtime.Port | null = null;
devtools: chrome.runtime.Port | null = null;
public id: number | null = null;// tab.id作为唯一标识
public title: string = "";
public url: string = "";
private mgr: PortManagement | null = null;
constructor(mgr: PortManagement, {id, url, title}: any) {
this.mgr = mgr;
this.id = id;
this.url = url;
this.title = title;
}
private onPortConnect(port: chrome.runtime.Port, onMsg: Function, onDisconnect: Function) {
2021-11-13 11:51:48 +08:00
console.log(`%c[Connect] ${port.name}`, "color:green");
2021-11-04 21:01:33 +08:00
port.onMessage.addListener((data: any, sender: any) => {
2021-11-13 11:51:48 +08:00
console.log(`%c[Connect-Message] ${sender.name}\n${JSON.stringify(data)}`, "color:blue;")
2021-11-04 21:01:33 +08:00
// 如果多个页面都监听 onMessage 事件,对于某一次事件只有第一次调用 sendResponse() 能成功发出回应,所有其他回应将被忽略。
// sender.postMessage(data);
onMsg && onMsg(data);
});
port.onDisconnect.addListener((port: chrome.runtime.Port) => {
console.log(`%c[Connect-Dis] ${port.name}`, "color:red");
onDisconnect && onDisconnect()
});
}
dealConnect(port: chrome.runtime.Port) {
switch (port.name) {
case Page.Content: {
this.content = port;
this.onPortConnect(port,
(data: PluginEvent) => {
if (data.target === Page.Devtools) {
this.sendDevtoolMsg(data);
}
},
() => {
this.content = null;
this.checkValid();
})
break;
}
case Page.Devtools: {
this.devtools = port;
this.onPortConnect(port,
(data: PluginEvent) => {
// 从devtools过来的消息统一派发到Content中
if (PluginEvent.check(data, Page.Devtools, Page.Background)) {
PluginEvent.reset(data, Page.Background, Page.Content);
this.content?.postMessage(data)
}
},
() => {
this.devtools = null;
this.checkValid();
})
break
}
2021-04-26 22:27:47 +08:00
}
}
2021-11-04 21:01:33 +08:00
checkValid() {
if (!this.devtools && !this.content) {
this.mgr?.remove(this);
}
}
sendContentMsg(data: PluginEvent) {
this.content?.postMessage(data);
}
sendDevtoolMsg(data: PluginEvent) {
this.devtools?.postMessage(data)
}
2021-04-26 22:27:47 +08:00
}
2019-03-18 12:05:07 +08:00
2021-11-04 21:01:33 +08:00
class PortManagement {
port: Array<PortMan> = [];
constructor() {
this.initConnect();
chrome.runtime.onMessage.addListener((request: PluginEvent, sender: any, sendResponse: any) => {
const tabID = sender.tab.id;
const portMan: PortMan | undefined = this.find(tabID);
if (portMan) {
if (PluginEvent.check(request, Page.Content, Page.Background)) {
// 监听来自content.js发来的事件将消息转发到devtools
PluginEvent.reset(request, Page.Background, Page.Devtools)
console.log(`%c[Message]url:${sender.url}]\n${JSON.stringify(request)}`, "color:green")
portMan.sendDevtoolMsg(request);
}
}
})
chrome.tabs.onActivated.addListener(({tabId, windowId}) => {
})
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
// 页面发生刷新,通知重新生成数据
if (changeInfo.status === "complete") {
const {id} = tab;
// -1为自己
if (id && id > -1) {
let portMan = this.find(id);
if (portMan) {
2021-11-13 12:10:46 +08:00
let data = new PluginEvent(Page.Background, Page.Content, Msg.Support);
portMan.sendContentMsg(data);
2021-11-04 21:01:33 +08:00
}
}
}
})
}
initConnect() {
chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => {
if (port.name === Page.Devtools) {
// devtool链接过来没有port.sender.tab
chrome.tabs.getSelected((tab: chrome.tabs.Tab) => {
this._onConnect(tab, port)
})
} else {
const tab: chrome.tabs.Tab | undefined = port.sender?.tab;
if (tab) {
this._onConnect(tab, port)
}
}
})
}
2019-03-15 10:08:39 +08:00
2021-11-04 21:01:33 +08:00
private _onConnect(tab: chrome.tabs.Tab, port: chrome.runtime.Port) {
const {id, title, url} = tab;
if (id !== undefined && id > -1) {
let portMan: PortMan | undefined = this.find(id)
if (!portMan) {
portMan = new PortMan(this, {id, title, url});
this.port.push(portMan);
}
portMan.dealConnect(port);
2021-04-05 18:38:44 +08:00
}
}
2021-11-04 21:01:33 +08:00
find(id: number): PortMan | undefined {
return this.port.find(el => el.id === id)
}
remove(item: PortMan) {
let index = this.port.findIndex(el => el === item)
if (index > -1) {
this.port.splice(index, 1)
2021-05-08 22:05:59 +08:00
}
2019-03-18 18:03:07 +08:00
}
2021-11-04 21:01:33 +08:00
}
(window as any).backgroundInstance = new PortManagement();
2019-03-17 21:44:47 +08:00
function createPluginMenus() {
2021-04-05 18:38:44 +08:00
const menus = [];
2019-03-17 21:44:47 +08:00
let parent = chrome.contextMenus.create({id: "parent", title: "CC-Inspector"});
chrome.contextMenus.create({
id: "test",
title: "测试右键菜单",
parentId: parent,
// 上下文环境,可选:["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"]默认page
2021-04-02 22:34:09 +08:00
contexts: ["page"],
2019-03-17 21:44:47 +08:00
});
chrome.contextMenus.create({
id: "notify",
parentId: parent,
title: "通知"
})
chrome.contextMenus.onClicked.addListener(function (info, tab) {
if (info.menuItemId === "test") {
2021-04-02 22:34:09 +08:00
alert("您点击了右键菜单!");
2019-03-17 21:44:47 +08:00
} else if (info.menuItemId === "notify") {
2021-04-02 22:34:09 +08:00
chrome.notifications.create("null", {
2019-03-17 21:44:47 +08:00
type: "basic",
2021-04-03 16:47:16 +08:00
iconUrl: "icons/48.png",
2019-03-17 21:44:47 +08:00
title: "通知",
message: "测试通知",
})
}
})
}
chrome.contextMenus.removeAll(function () {
createPluginMenus();
});