diff --git a/source/src/background.ts b/source/src/background.ts index d801c7c..f95bf78 100644 --- a/source/src/background.ts +++ b/source/src/background.ts @@ -1,6 +1,4 @@ -import * as PluginMsg from "./core/plugin-msg" -import {PluginEvent} from "@/devtools/type"; -import {MsgInclude} from "./core/plugin-msg"; +import {PluginEvent, Page, Msg} from "@/core/types"; let Devtools: chrome.runtime.Port | null = null; let Content: chrome.runtime.Port | null = null; @@ -8,12 +6,13 @@ console.log('on background') chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => { switch (port.name) { - case PluginMsg.Page.Devtools: { + case Page.Devtools: { Devtools = port; onPortConnect(port, (data: PluginEvent) => { // 从devtools过来的消息统一派发到Content中 - if (MsgInclude(data.msg)) { + if (data.target === Page.Background) { + data.target = Page.Content; Content && Content.postMessage(data) } }, @@ -22,7 +21,7 @@ chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => { }) break; } - case PluginMsg.Page.Content: { + case Page.Content: { Content = port; onPortConnect(port, () => { @@ -41,6 +40,7 @@ function onPortConnect(port: chrome.runtime.Port, onMsg: Function, onDisconnect: console.log(`%c[Connect] ${port.name}`, "color:blue;"); port.onMessage.addListener((data: any, sender: any) => { console.log(`%c[Connect-Message] ${sender.name}\n${JSON.stringify(data)}`, "color:green;") + // 如果多个页面都监听 onMessage 事件,对于某一次事件只有第一次调用 sendResponse() 能成功发出回应,所有其他回应将被忽略。 // sender.postMessage(data); onMsg && onMsg(data); }); @@ -53,10 +53,11 @@ function onPortConnect(port: chrome.runtime.Port, onMsg: Function, onDisconnect: // background.js 更像是一个主进程,负责整个插件的调度,生命周期和chrome保持一致 // 监听来自content.js发来的事件,将消息转发到devtools -chrome.runtime.onMessage.addListener((request: any, sender: any, sendResponse: any) => { - console.log(`%c[Message]url:${sender.url}]\n${JSON.stringify(request)}`, 'color:green') - sendResponse && sendResponse(request); - if (MsgInclude(request.msg)) { +chrome.runtime.onMessage.addListener((request: PluginEvent, sender: any, sendResponse: any) => { + if (request.target === Page.Background) { + request.target = Page.Devtools; + console.log(`%c[Message]url:${sender.url}]\n${JSON.stringify(request)}`, 'color:green') + sendResponse && sendResponse(request); Devtools && Devtools.postMessage(request); } } @@ -65,9 +66,9 @@ chrome.runtime.onMessage.addListener((request: any, sender: any, sendResponse: a chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { if (changeInfo.status === "complete") { // 加载新的url - if (Content) { - Content.postMessage(new PluginEvent(PluginMsg.Msg.UrlChange, {url: tab.favIconUrl})); - } + // if (Content) { + // Content.postMessage(new PluginEvent(Msg.UrlChange, {url: tab.favIconUrl})); + // } } }) diff --git a/source/src/content.ts b/source/src/content.ts index e1db734..147c221 100644 --- a/source/src/content.ts +++ b/source/src/content.ts @@ -1,29 +1,35 @@ // content.js 和原始界面共享DOM,具有操作dom的能力 // 但是不共享js,要想访问页面js,只能通过注入的方式 -import * as PluginMsg from './core/plugin-msg' import {injectScript} from "@/core/util"; -import {PluginEvent} from "@/devtools/type"; +import {PluginEvent, Page, Msg} from "@/core/types"; injectScript("js/inject.js"); // 和background.js保持长连接通讯 -let conn = chrome.runtime.connect({name: PluginMsg.Page.Content}) -conn.onMessage.addListener(function (data) { +let conn = chrome.runtime.connect({name: Page.Content}) +conn.onMessage.addListener((data: PluginEvent, sender) => { // 将background.js的消息返回到injection.js console.log(`%c[Connect-Message] ${JSON.stringify(data)}`, "color:green;") - window.postMessage(data, "*"); + if (data.target === Page.Content) { + data.target = Page.Inject; + window.postMessage(data, "*"); + } }) + // 接受来自inject.js的消息数据,然后中转到background.js -// window.addEventListener('message', function (event) { -// let data = event.data; -// console.log(`%c[Window-Message] ${JSON.stringify(data)}`, "color:green;"); -// chrome.runtime.sendMessage(data); -// }, false); +window.addEventListener('message', function (event) { + let data: PluginEvent = event.data; + console.log(`%c[Window-Message] ${JSON.stringify(data)}`, "color:green;"); + if (data.target === Page.Inject) { + data.target = Page.Background; + chrome.runtime.sendMessage(data); + } +}, false); let gameCanvas = document.querySelector("#GameCanvas"); if (!gameCanvas) { - let sendData = new PluginEvent(PluginMsg.Msg.Support, { + let sendData = new PluginEvent(Page.Background, Msg.Support, { support: false, msg: "未发现GameCanvas,不支持调试游戏!" }) diff --git a/source/src/core/plugin-msg.ts b/source/src/core/plugin-msg.ts deleted file mode 100644 index 70a2487..0000000 --- a/source/src/core/plugin-msg.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const Page = { - Inject: "Inject", - Devtools: "Devtools", - Content: "Content", - Popup: "Popup", - Options: "Options", -} -export const Msg = { - NodeInfo: "node-info",// 具体的节点信息 - TreeInfo: "tree-info",// 节点树信息 - Support: "game-support",// 游戏支持信息 - MemoryInfo: "memory-info",// - TabsInfo: "tabs_info", // 当前页面信息 - UrlChange: "url_change", // 网址发生变化 - SetProperty: "set-property", // 设置node属性 -} - -export function MsgInclude(msg: string) { - for (let key in Msg) { - if (Msg.hasOwnProperty(key)) { - //@ts-ignore - let m = Msg[key] as string; - if (m === msg) { - return true - } - } - } - return false; -} diff --git a/source/src/core/types.ts b/source/src/core/types.ts new file mode 100644 index 0000000..c7638e9 --- /dev/null +++ b/source/src/core/types.ts @@ -0,0 +1,56 @@ +export enum Page { + Inject = "Inject", + Devtools = "Devtools", + Background = 'Background', + Content = "Content", + Popup = "Popup", + Options = "Options", +} + +export enum Msg { + NodeInfo = "node-info",// 具体的节点信息 + TreeInfo = "tree-info",// 节点树信息 + Support = "game-support",// 游戏支持信息 + MemoryInfo = "memory-info",// + TabsInfo = "tabs_info", // 当前页面信息 + UrlChange = "url_change", // 网址发生变化 + SetProperty = "set-property", // 设置node属性 +} + +export class PluginEvent { + msg: Msg | null = null; + data: any = null; + target: Page | null = null; // 事件要发送的目标 + + constructor(target: Page, msg: Msg, data?: any) { + if (PageInclude(target)) { + this.target = target; + this.msg = msg; + this.data = data || null; + } else { + console.warn(`无效的target: ${target}`) + } + } +} + +function inEnum(enumValues: any, value: Page | Msg) { + for (let key in enumValues) { + if (enumValues.hasOwnProperty(key)) { + //@ts-ignore + let itemEnum = enumValues[key] as string; + if (itemEnum === value) { + return true + } + } + } + return false; +} + +export function PageInclude(page: Page) { + return inEnum(Page, page); +} + + +export function MsgInclude(msg: Msg) { + return inEnum(Msg, msg) +} diff --git a/source/src/devtools/connectBackground.ts b/source/src/devtools/connectBackground.ts index 62a68e8..f7eb7c1 100644 --- a/source/src/devtools/connectBackground.ts +++ b/source/src/devtools/connectBackground.ts @@ -1,12 +1,11 @@ -import * as PluginMsg from "@/core/plugin-msg"; -import {PluginEvent} from "@/devtools/type"; +import {PluginEvent, Page} from "@/core/types"; class ConnectBackground { connect: chrome.runtime.Port | null = null; constructor() { if (chrome && chrome.runtime) { - this.connect = chrome.runtime.connect({name: PluginMsg.Page.Devtools}); + this.connect = chrome.runtime.connect({name: Page.Devtools}); this.connect.onDisconnect.addListener(() => { console.log(`%c[Connect-Dis]`, 'color:red;') this.connect = null; @@ -23,7 +22,7 @@ class ConnectBackground { } } - postMessage(data: PluginEvent) { + postMessageToBackground(data: PluginEvent) { if (this.connect) { this.connect.postMessage(data) } else { diff --git a/source/src/devtools/index.vue b/source/src/devtools/index.vue index 3180a04..d9ff8c5 100644 --- a/source/src/devtools/index.vue +++ b/source/src/devtools/index.vue @@ -45,10 +45,10 @@ import Vue from "vue"; import {Component} from "vue-property-decorator"; import properties from "./propertys.vue"; -import {DataSupport, PluginEvent, NodeData} from "@/devtools/type"; +import {DataSupport, NodeData} from "@/devtools/type"; +import {PluginEvent, Page, Msg} from '@/core/types' import {connectBackground} from "@/devtools/connectBackground"; -const PluginMsg = require("../core/plugin-msg"); @Component({ components: { properties, @@ -117,7 +117,7 @@ export default class Index extends Vue { if (data.support) { // 如果节点树为空,就刷新一次 if (this.treeData.length === 0) { - this.onBtnClickUpdateTree(); + // this.onBtnClickUpdateTree(); } } else { this._reset(); @@ -131,39 +131,41 @@ export default class Index extends Vue { _initChromeRuntimeConnect() { // 接收来自background.js的消息数据 - connectBackground.onBackgroundMessage((data: any, sender: any) => { + connectBackground.onBackgroundMessage((data: PluginEvent, sender: any) => { if (!data) { return; } - - let eventData: any = data.data; - console.log(data) - switch (data.msg) { - case PluginMsg.Msg.UrlChange: { - break; - } - case PluginMsg.Msg.TreeInfo: { - this._onMsgListInfo(eventData as Array); - break; - } - case PluginMsg.Msg.Support: { - this._onMsgSupport(eventData as DataSupport) - break; - } - case PluginMsg.Msg.NodeInfo: { - this._onMsgNodeInfo(eventData); - break; - } - case PluginMsg.Msg.MemoryInfo: { - this._onMsgMemory(eventData) - break; - } - case PluginMsg.Msg.TabsInfo: { - debugger - break + if (data.target === Page.Background) { + let eventData: any = data.data; + console.log(data) + switch (data.msg) { + case Msg.UrlChange: { + break; + } + case Msg.TreeInfo: { + this._onMsgListInfo(eventData as Array); + break; + } + case Msg.Support: { + this._onMsgSupport(eventData as DataSupport) + break; + } + case Msg.NodeInfo: { + this._onMsgNodeInfo(eventData); + break; + } + case Msg.MemoryInfo: { + this._onMsgMemory(eventData) + break; + } + case Msg.TabsInfo: { + debugger + break + } } } }); + } handleNodeClick(data: NodeData) { @@ -172,8 +174,7 @@ export default class Index extends Vue { // console.log(data); let uuid = data.uuid; if (uuid !== undefined) { - PluginMsg.Msg.TabsInfo; - this.runToContentScript(PluginMsg.Msg.NodeInfo, uuid); + this.runToContentScript(Msg.NodeInfo, uuid); } } @@ -188,14 +189,14 @@ export default class Index extends Vue { } - runToContentScript(msg: string, data?: any) { + runToContentScript(msg: Msg, data?: any) { if (!chrome || !chrome.devtools) { console.log("环境异常,无法执行函数"); return; } debugger - let sendData = new PluginEvent(msg, data) - connectBackground.postMessage(sendData); + let sendData = new PluginEvent(Page.Background, msg, data) + connectBackground.postMessageToBackground(sendData); } // 问题:没有上下文的权限,只能操作DOM @@ -220,15 +221,15 @@ export default class Index extends Vue { } onBtnClickUpdateTree() { - this.runToContentScript(PluginMsg.Msg.TreeInfo); + this.runToContentScript(Msg.TreeInfo); } onBtnClickUpdatePage() { - this.runToContentScript(PluginMsg.Msg.Support); + this.runToContentScript(Msg.Support); } onMemoryTest() { - this.runToContentScript(PluginMsg.Msg.MemoryInfo); + this.runToContentScript(Msg.MemoryInfo); } onNodeExpand(data: NodeData) { diff --git a/source/src/devtools/inject.ts b/source/src/devtools/inject.ts index d175b2c..3073709 100644 --- a/source/src/devtools/inject.ts +++ b/source/src/devtools/inject.ts @@ -1,5 +1,4 @@ // eval 注入脚本的代码,变量尽量使用var,后来发现在import之后,let会自动变为var -import * as PluginMsg from '../core/plugin-msg' import { ArrayData, BoolData, @@ -13,7 +12,7 @@ import { Vec3Data } from "./data"; -import {PluginEvent} from './type' +import {PluginEvent, Page, Msg} from '@/core/types' class CCInspector { inspectorGameMemoryStorage: Record = {} @@ -27,57 +26,64 @@ class CCInspector { // } }, 1000); // 注册cc_after_render事件 - window.addEventListener("message", (event: any) => { - // 接受来自background的事件,有可能也会受到其他插件的 + window.addEventListener("message", (event) => { + // 接受来自content的事件,有可能也会受到其他插件的 if (!event || !event.data) { return } let pluginEvent: PluginEvent = event.data; - switch (pluginEvent.msg) { - case PluginMsg.Msg.UrlChange: - case PluginMsg.Msg.Support: { - let isCocosGame = this._isCocosGame(); - this.sendMsgToContent(PluginMsg.Msg.Support, {support: isCocosGame}); - break; - } - case PluginMsg.Msg.TreeInfo: { + if (pluginEvent.target === Page.Inject) { + switch (pluginEvent.msg) { + case Msg.UrlChange: + case Msg.Support: { + let isCocosGame = this._isCocosGame(); + this.sendMsgToContent(Msg.Support, {support: isCocosGame}); + break; + } + case Msg.TreeInfo: { - debugger - break; - } - case PluginMsg.Msg.NodeInfo: { - debugger - break; - } - case PluginMsg.Msg.SetProperty: { - debugger; - break; + debugger + break; + } + case Msg.NodeInfo: { + debugger + break; + } + case Msg.SetProperty: { + debugger; + break; + } } } }); } + sendMsgToContent(msg: Msg, data: any) { + // 发送给content.js处理,也会导致发送给了自身,死循环 + window.postMessage(new PluginEvent(Page.Inject, msg, data), "*"); + } + devPageCallEntry(str: string) { let para: PluginEvent = JSON.parse(str); debugger if (this._isCocosGame()) { switch (para.msg) { - case PluginMsg.Msg.TreeInfo: + case Msg.TreeInfo: this.updateTreeInfo(); break; - case PluginMsg.Msg.Support: + case Msg.Support: break; - case PluginMsg.Msg.MemoryInfo: + case Msg.MemoryInfo: break; - case PluginMsg.Msg.SetProperty: + case Msg.SetProperty: break; - case PluginMsg.Msg.NodeInfo: + case Msg.NodeInfo: this.getNodeInfo(para.data as string); break; } } else { - this.sendMsgToContent(PluginMsg.Msg.Support, {support: false}); + this.sendMsgToContent(Msg.Support, {support: false}); } } @@ -98,9 +104,9 @@ class CCInspector { let node = sceneChildren[i]; this.getNodeChildren(node, sendData.children); } - this.sendMsgToContent(PluginMsg.Msg.TreeInfo, sendData); + this.sendMsgToContent(Msg.TreeInfo, sendData); } else { - this.sendMsgToContent(PluginMsg.Msg.Support, {support: false, msg: "未发现游戏场景,不支持调试游戏!"}); + this.sendMsgToContent(Msg.Support, {support: false, msg: "未发现游戏场景,不支持调试游戏!"}); } } } @@ -276,7 +282,7 @@ class CCInspector { let compGroup = this._getGroupData(itemComp); groupData.push(compGroup); } - this.sendMsgToContent(PluginMsg.Msg.NodeInfo, groupData); + this.sendMsgToContent(Msg.NodeInfo, groupData); } else { // 未获取到节点数据 console.log("未获取到节点数据"); @@ -297,13 +303,9 @@ class CCInspector { } } - sendMsgToContent(msg: string, data: any) { - // 发送给content.js处理 - window.postMessage(new PluginEvent(msg, data), "*"); - } onMemoryInfo() { - this.sendMsgToContent(PluginMsg.Msg.MemoryInfo, { + this.sendMsgToContent(Msg.MemoryInfo, { performance: { // @ts-ignore jsHeapSizeLimit: window.performance.memory.jsHeapSizeLimit, diff --git a/source/src/devtools/register-panel.ts b/source/src/devtools/register-panel.ts index 933945c..4db0613 100644 --- a/source/src/devtools/register-panel.ts +++ b/source/src/devtools/register-panel.ts @@ -1,6 +1,4 @@ -import * as PluginMsg from '../core/plugin-msg' import Manifest from '../manifest.json' -import {PluginEvent} from "@/devtools/type"; import {connectBackground} from "@/devtools/connectBackground"; export function init() { diff --git a/source/src/devtools/type.ts b/source/src/devtools/type.ts index dbf4379..58368e1 100644 --- a/source/src/devtools/type.ts +++ b/source/src/devtools/type.ts @@ -10,12 +10,4 @@ export class DataSupport { } -export class PluginEvent { - msg: string = ''; - data: any = null; - constructor(msg: string, data?: any) { - this.msg = msg; - this.data = data || null; - } -}