mirror of
https://github.com/tidys/cc-inspector-chrome
synced 2025-04-20 08:58:41 +00:00
222 lines
6.7 KiB
TypeScript
222 lines
6.7 KiB
TypeScript
import {Msg, Page, PluginEvent} from "@/core/types";
|
||
|
||
// @ts-ignore
|
||
import * as UA from "universal-analytics"
|
||
import {v4} from "uuid"
|
||
import {devtools_page} from "./manifest.json"
|
||
|
||
// 统计服务
|
||
const userID = localStorage.getItem("userID") || v4()
|
||
UA("UA-134924925-3", userID);
|
||
|
||
console.log("on background")
|
||
|
||
class PortMan {
|
||
public currentUseContentFrameID = 0;
|
||
public content: Array<chrome.runtime.Port> = []; // 因为iframe的原因,可能对应多个,主iframe的id===0
|
||
public 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) {
|
||
console.log(`%c[Connect] ${port.name}`, "color:green");
|
||
port.onMessage.addListener((data: any, sender: any) => {
|
||
console.log(`%c[Connect-Message] ${sender.name}\n${JSON.stringify(data)}`, "color:blue;")
|
||
// 如果多个页面都监听 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(port)
|
||
});
|
||
}
|
||
|
||
getCurrentUseContent(): chrome.runtime.Port | null {
|
||
return this.content.find(el => el.sender?.frameId !== undefined && el.sender.frameId === this.currentUseContentFrameID) || null;
|
||
}
|
||
|
||
dealConnect(port: chrome.runtime.Port) {
|
||
switch (port.name) {
|
||
case Page.Content: {
|
||
this.content.push(port);
|
||
this.onPortConnect(port,
|
||
(data: PluginEvent) => {
|
||
if (data.target === Page.Devtools) {
|
||
this.sendDevtoolMsg(data);
|
||
}
|
||
},
|
||
(disPort: chrome.runtime.Port) => {
|
||
const index = this.content.findIndex(el =>
|
||
disPort.sender?.frameId !== undefined
|
||
&& el.sender?.frameId !== undefined
|
||
&& el.sender?.frameId === disPort.sender?.frameId
|
||
);
|
||
this.content.splice(index, 1);
|
||
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.getCurrentUseContent()?.postMessage(data)
|
||
}
|
||
},
|
||
() => {
|
||
this.devtools = null;
|
||
this.checkValid();
|
||
})
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
checkValid() {
|
||
if (!this.devtools && !this.content.length) {
|
||
this.mgr?.remove(this);
|
||
}
|
||
}
|
||
|
||
sendContentMsg(data: PluginEvent) {
|
||
this.getCurrentUseContent()?.postMessage(data);
|
||
}
|
||
|
||
sendDevtoolMsg(data: PluginEvent) {
|
||
this.devtools?.postMessage(data)
|
||
}
|
||
}
|
||
|
||
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) {
|
||
let data = new PluginEvent(Page.Background, Page.Content, Msg.Support);
|
||
portMan.sendContentMsg(data);
|
||
}
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
isDevtools(port: chrome.runtime.Port) {
|
||
const devtoolsUrl = `chrome-extension://${port.sender?.id}/${devtools_page}`
|
||
if (port.sender?.url === devtoolsUrl) {
|
||
|
||
}
|
||
}
|
||
|
||
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)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
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)
|
||
}
|
||
}
|
||
}
|
||
|
||
(window as any).backgroundInstance = new PortManagement();
|
||
|
||
function createPluginMenus() {
|
||
const menus = [];
|
||
|
||
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
|
||
contexts: ["page"],
|
||
});
|
||
chrome.contextMenus.create({
|
||
id: "notify",
|
||
parentId: parent,
|
||
title: "通知"
|
||
})
|
||
|
||
chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
||
if (info.menuItemId === "test") {
|
||
alert("您点击了右键菜单!");
|
||
} else if (info.menuItemId === "notify") {
|
||
chrome.notifications.create("null", {
|
||
type: "basic",
|
||
iconUrl: "icons/48.png",
|
||
title: "通知",
|
||
message: "测试通知",
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
chrome.contextMenus.removeAll(function () {
|
||
createPluginMenus();
|
||
});
|
||
|