mirror of
https://github.com/tidys/cc-inspector-chrome
synced 2025-04-15 14:41:05 +00:00
完成节点数据的收集
This commit is contained in:
parent
e0c1f2336c
commit
36a81db153
30
README.md
30
README.md
@ -1,27 +1,7 @@
|
||||
# Vue.js Chrome Extension Template ([wcer](https://github.com/YuraDev/wcer))
|
||||
> Template for quick creation of Chrome extension on Vuejs c hot reloading when developing.
|
||||
#说明
|
||||
|
||||

|
||||
|
||||
## Installation:
|
||||
This boilerplate was built as a template for [vue-cli](https://github.com/vuejs/vue-cli) and includes options to customize your final scaffolded app.
|
||||
``` bash
|
||||
# install vue-cli
|
||||
$ npm install -g vue-cli
|
||||
# create a new project using the template
|
||||
$ vue init YuraDev/vue-chrome-extension-template my-project
|
||||
# install dependencies and go!
|
||||
$ cd my-project
|
||||
$ npm install # or yarn
|
||||
$ npm run dev # or yarn dev
|
||||
inject在development模式下无法正常使用,暂时的解决办法,注释掉`vue-cli-plugin-browser-extension`代码中的
|
||||
```
|
||||
|
||||
## Structure
|
||||
* [backend](https://developer.chrome.com/extensions/background_pages): Background work of your scripts
|
||||
* [content](https://developer.chrome.com/extensions/content_scripts) Run in the context of web pages
|
||||
* [devtools](https://developer.chrome.com/extensions/devtools) - It can add new UI panels and sidebars, interact with the inspected page, get information about network requests, and more.
|
||||
* [options](https://developer.chrome.com/extensions/options) - To allow users to customize the behavior of your extension, you may wish to provide an options page.
|
||||
* popup - The page (window) that will be displayed when the icon is clicked
|
||||
* tab - Your application will work in a separate tab
|
||||
* ext - Shared scripts
|
||||
* [manifest.js](https://developer.chrome.com/extensions/manifest) - Descriptions of the application, its rights and possibilities
|
||||
webpackConfig.plugin('extension-reloader').use(ExtensionReloader, [{ entries, ...extensionReloaderOptions }])
|
||||
```
|
||||
详细原因参考:[issues](https://github.com/adambullmer/vue-cli-plugin-browser-extension/issues/120)
|
||||
|
@ -1,5 +1,8 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
globals: {
|
||||
chrome: true,
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
webextensions: true,
|
||||
@ -37,5 +40,7 @@ module.exports = {
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
}
|
||||
};
|
||||
|
@ -5,36 +5,22 @@ let DevtoolsPanel: chrome.runtime.Port | null = null;
|
||||
let Content: chrome.runtime.Port | null = null;
|
||||
console.log('on background')
|
||||
|
||||
function shortConnectionLink(request: any, sender: any, sendResponse: any) {
|
||||
// console.log(`%c[短连接|id:${sender.id}|url:${sender.url}]\n${JSON.stringify(request)}`, 'background:#aaa;color:#BD4E19')
|
||||
sendResponse && sendResponse(request);
|
||||
if (request.msg === PluginMsg.Msg.Support ||
|
||||
request.msg === PluginMsg.Msg.ListInfo ||
|
||||
request.msg === PluginMsg.Msg.NodeInfo) {
|
||||
// 将消息转发到devtools
|
||||
Devtools && Devtools.postMessage(request);
|
||||
}
|
||||
}
|
||||
|
||||
function longConnectionLink(data: any, sender: any) {
|
||||
console.log(`%c[长连接:${sender.name}]\n${JSON.stringify(data)}`, "background:#aaa;color:#bada55")
|
||||
sender.postMessage(data);
|
||||
if (data.msg === PluginMsg.Msg.UrlChange) {
|
||||
if (sender.name === PluginMsg.Page.DevToolsPanel) {
|
||||
Content && Content.postMessage({msg: PluginMsg.Msg.UrlChange, data: {}})
|
||||
chrome.runtime.onConnect.addListener((port: chrome.runtime.Port) => {
|
||||
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;")
|
||||
sender.postMessage(data);
|
||||
if (data.msg === PluginMsg.Msg.UrlChange) {
|
||||
if (sender.name === PluginMsg.Page.DevToolsPanel) {
|
||||
Content && Content.postMessage({msg: PluginMsg.Msg.UrlChange, data: {}})
|
||||
}
|
||||
}
|
||||
}
|
||||
// chrome.tabs.executeScript(message.tabId, {code: message.content});
|
||||
// port.postMessage(message);
|
||||
}
|
||||
|
||||
// 长连接
|
||||
chrome.runtime.onConnect.addListener((port) => {
|
||||
console.log(`%c[长连接:${port.name}] 建立链接!`, "background:#aaa;color:#ff0000");
|
||||
port.onMessage.addListener(longConnectionLink);
|
||||
port.onDisconnect.addListener(function (port) {
|
||||
console.log(`%c[长连接:${port.name}] 断开链接!`, "background:#aaa;color:#00ff00");
|
||||
port.onMessage.removeListener(longConnectionLink);
|
||||
// chrome.tabs.executeScript(message.tabId, {code: message.content});
|
||||
// port.postMessage(message);
|
||||
});
|
||||
port.onDisconnect.addListener(function (port: chrome.runtime.Port) {
|
||||
console.log(`%c[Connect-Dis] ${port.name}`, "color:red");
|
||||
// port.onMessage.removeListener(longConnectionLink);
|
||||
if (port.name === PluginMsg.Page.Devtools) {
|
||||
Devtools = null;
|
||||
} else if (port.name === PluginMsg.Page.Content) {
|
||||
@ -55,8 +41,18 @@ chrome.runtime.onConnect.addListener((port) => {
|
||||
});
|
||||
|
||||
// background.js 更像是一个主进程,负责整个插件的调度,生命周期和chrome保持一致
|
||||
// [短连接] 监听来自content.js发来的事件
|
||||
chrome.runtime.onMessage.addListener(shortConnectionLink);
|
||||
// 监听来自content.js发来的事件
|
||||
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 (request.msg === PluginMsg.Msg.Support ||
|
||||
request.msg === PluginMsg.Msg.ListInfo ||
|
||||
request.msg === PluginMsg.Msg.NodeInfo) {
|
||||
// 将消息转发到devtools
|
||||
Devtools && Devtools.postMessage(request);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
||||
if (changeInfo.status === "complete") {
|
||||
@ -69,7 +65,8 @@ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
||||
})
|
||||
|
||||
function createPluginMenus() {
|
||||
// 右键菜单
|
||||
const menus = [];
|
||||
|
||||
let parent = chrome.contextMenus.create({id: "parent", title: "CC-Inspector"});
|
||||
chrome.contextMenus.create({
|
||||
id: "test",
|
||||
|
@ -1,37 +1,32 @@
|
||||
console.log('content code')
|
||||
// 具有操作dom的能力
|
||||
// 加载其他脚本
|
||||
// content.js 和原始界面共享DOM,但是不共享js,要想访问页面js,只能通过注入的方式
|
||||
// content.js 和原始界面共享DOM,具有操作dom的能力
|
||||
// 但是不共享js,要想访问页面js,只能通过注入的方式
|
||||
import * as PluginMsg from './core/plugin-msg'
|
||||
|
||||
function injectScriptToPage(url) {
|
||||
function injectScriptToPage(url: string) {
|
||||
let content = chrome.extension.getURL(url)
|
||||
console.log(`[cc-inspector]注入脚本:${content}`);
|
||||
let script = document.createElement('script')
|
||||
script.setAttribute('type', 'text/javascript')
|
||||
script.setAttribute('src', content)
|
||||
script.onload = function () {
|
||||
// 注入脚本执行完后移除掉
|
||||
this.parentNode.removeChild(this);
|
||||
document.body.removeChild(script);
|
||||
}
|
||||
document.body.appendChild(script)
|
||||
}
|
||||
debugger
|
||||
|
||||
injectScriptToPage("js/inject.js");
|
||||
|
||||
// 和background.js保持长连接通讯
|
||||
let conn = chrome.runtime.connect({name: PluginMsg.Page.Content})
|
||||
// conn.postMessage('test');
|
||||
conn.onMessage.addListener(function (data) {
|
||||
// 将background.js的消息返回到injection.js
|
||||
console.log(`%c[Connect-Message] ${JSON.stringify(data)}`, "color:green;")
|
||||
window.postMessage(data, "*");
|
||||
})
|
||||
// 接受来自inject.js的消息数据,然后中转到background.js
|
||||
window.addEventListener('message', function (event) {
|
||||
let data = event.data;
|
||||
if (data.data.log) {
|
||||
}
|
||||
console.log(`%c[content] ${JSON.stringify(data)}`, "color:#BD4E19");
|
||||
console.log(`%c[Window-Message] ${JSON.stringify(data)}`, "color:green;");
|
||||
chrome.runtime.sendMessage(data);
|
||||
}, false);
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
export const Page = {
|
||||
Inject: "inject.js",
|
||||
Devtools: "devtools.js",
|
||||
Inject: "Inject",
|
||||
Devtools: "Devtools",
|
||||
DevToolsPanel: "DevToolsPanel",
|
||||
Content: "content.js",
|
||||
Popup: "popup.js",
|
||||
Options: "options.js",
|
||||
Content: "Content",
|
||||
Popup: "Popup",
|
||||
Options: "Options",
|
||||
}
|
||||
export const Msg = {
|
||||
NodeInfo: "node_info",// 具体的节点信息
|
||||
|
@ -39,9 +39,6 @@ export default class NodeBaseProperty extends Vue {
|
||||
@Prop({default: "label"})
|
||||
private label?: string | undefined
|
||||
|
||||
@Prop()
|
||||
private itemData: any;
|
||||
|
||||
setup() {
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ import {DataType} from '../data'
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
// todo 支持array
|
||||
export default class UiProp extends Vue {
|
||||
@Prop({default: ""})
|
||||
name: string | undefined;
|
||||
|
@ -11,6 +11,7 @@ export enum DataType {
|
||||
|
||||
class Info {
|
||||
public type: DataType = DataType.Number;
|
||||
public data: any;
|
||||
}
|
||||
|
||||
export class TextData extends Info {
|
||||
@ -20,10 +21,19 @@ export class TextData extends Info {
|
||||
}
|
||||
}
|
||||
|
||||
export class ColorData extends Info {
|
||||
constructor(color: string) {
|
||||
super();
|
||||
this.type = DataType.Color;
|
||||
this.data = color;
|
||||
}
|
||||
}
|
||||
|
||||
export class StringData extends Info {
|
||||
constructor() {
|
||||
constructor(data: string) {
|
||||
super();
|
||||
this.type = DataType.String;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,33 +41,44 @@ export class NumberData extends Info {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = DataType.Number;
|
||||
this.data = 1;
|
||||
}
|
||||
}
|
||||
|
||||
export class BoolData extends Info {
|
||||
constructor(bol: boolean) {
|
||||
super();
|
||||
this.type = DataType.Bool;
|
||||
this.data = bol;
|
||||
}
|
||||
}
|
||||
|
||||
export class Vec2Data extends Info {
|
||||
public v1: number = 0;
|
||||
public v2: number = 0;
|
||||
|
||||
constructor(v1: number, v2: number) {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = DataType.Vec2
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
this.data = [];
|
||||
return this;
|
||||
}
|
||||
|
||||
add(info: Property) {
|
||||
this.data.push(info);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class Vec3Data extends Info {
|
||||
public v1: number = 0;
|
||||
public v2: number = 0;
|
||||
public v3: number = 0;
|
||||
|
||||
constructor(v1: number, v2: number, v3: number) {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = DataType.Vec3
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
this.v3 = v3;
|
||||
this.type = DataType.Vec3;
|
||||
this.data = [];
|
||||
return this;
|
||||
}
|
||||
|
||||
add(info: Property) {
|
||||
this.data.push(info);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +90,29 @@ export class EnumData extends Info {
|
||||
|
||||
}
|
||||
|
||||
export class Property {
|
||||
public name: string = 'property';
|
||||
public value: Info = new Info();
|
||||
|
||||
constructor(name: string, info: Info) {
|
||||
this.name = name;
|
||||
this.value = info;
|
||||
}
|
||||
}
|
||||
|
||||
export class Group {
|
||||
public name: string = 'group';
|
||||
public data: Array<Property> = [];
|
||||
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
addProperty(property: Property) {
|
||||
this.data.push(property)
|
||||
}
|
||||
}
|
||||
|
||||
class NodeInfo {
|
||||
public type: string = ''; // 类型
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
<div id="devtools">
|
||||
<div v-show="isShowDebug" class="find">
|
||||
<div v-if="false">
|
||||
<el-button type="success" @click="onBtnClickTest1">Test1</el-button>
|
||||
<el-button type="success" @click="onBtnClickTest2">Test2</el-button>
|
||||
<el-button type="success" @click="onMemoryTest">内存测试</el-button>
|
||||
</div>
|
||||
<div v-if="false">
|
||||
@ -28,7 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<NodeBaseProperty :item-data="treeItemData"></NodeBaseProperty>
|
||||
<NodeBaseProperty :all-group="treeItemData"></NodeBaseProperty>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="!isShowDebug" class="no-find">
|
||||
@ -56,7 +54,7 @@ const PluginMsg = require("../core/plugin-msg");
|
||||
})
|
||||
export default class Index extends Vue {
|
||||
private isShowDebug: boolean = false;
|
||||
treeItemData: Record<string, any> = {};
|
||||
treeItemData: Array<Record<string, any>> = [];
|
||||
treeData: Array<Record<string, any>> = []
|
||||
bgConn: chrome.runtime.Port | null = null// 与background.js的链接
|
||||
|
||||
@ -97,11 +95,17 @@ export default class Index extends Vue {
|
||||
let eventMsg = data.msg;
|
||||
if (eventMsg === PluginMsg.Msg.ListInfo) {
|
||||
this.isShowDebug = true;
|
||||
this._updateTreeView(eventData);
|
||||
if (!Array.isArray(eventData)) {
|
||||
eventData = [eventData]
|
||||
}
|
||||
this.treeData = eventData;
|
||||
} else if (eventMsg === PluginMsg.Msg.Support) {
|
||||
this.isShowDebug = eventData.support;
|
||||
} else if (eventMsg === PluginMsg.Msg.NodeInfo) {
|
||||
this.isShowDebug = true;
|
||||
if (!Array.isArray(eventData)) {
|
||||
eventData = [eventData]
|
||||
}
|
||||
this.treeItemData = eventData;
|
||||
} else if (eventMsg === PluginMsg.Msg.MemoryInfo) {
|
||||
this.memory = eventData;
|
||||
@ -114,27 +118,6 @@ export default class Index extends Vue {
|
||||
for (let i = 0; i < 40; i++) {
|
||||
this.treeData.push({name: `node${i}`, children: [{name: `children11111111111111111111111111111111111111${i}`}]})
|
||||
}
|
||||
|
||||
this.treeItemData = {
|
||||
"uuid": "11",
|
||||
"name": "name",
|
||||
"type": "cc_Node",
|
||||
"height": 1080.986301369863,
|
||||
"color": "#fff85f",
|
||||
"opacity": 255,
|
||||
"components": [
|
||||
{
|
||||
"uuid": "Comp.931",
|
||||
"type": "cc_Canvas",
|
||||
"name": "Canvas<Canvas>"
|
||||
},
|
||||
{
|
||||
"uuid": "Comp.932",
|
||||
"type": "HotUpdateScene",
|
||||
"name": "Canvas<HotUpdateScene>"
|
||||
}],
|
||||
"active": true
|
||||
};
|
||||
}
|
||||
|
||||
handleNodeClick(data: any) {
|
||||
@ -157,191 +140,44 @@ export default class Index extends Vue {
|
||||
|
||||
}
|
||||
|
||||
_updateTreeView(data: any) {
|
||||
this.treeData = [data.scene];
|
||||
return;
|
||||
// 构建树形数据
|
||||
if (this.treeData.length === 0) {// 第一次赋值
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
evalInspectorFunction(func: string, para?: string = '') {
|
||||
if (!func || func.length < 0) {
|
||||
console.log("缺失执行函数名!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let treeData = [];
|
||||
debugger
|
||||
let sceneData = data.scene;
|
||||
if (sceneData) {
|
||||
// scene info
|
||||
let dataRoot = {
|
||||
type: sceneData.type, uuid: sceneData.uuid,
|
||||
label: sceneData.name, children: []
|
||||
};
|
||||
treeData.push(dataRoot);
|
||||
this.handleNodeClick(dataRoot);
|
||||
// scene children info
|
||||
for (let k in sceneData.children) {
|
||||
let itemSceneData = sceneData.children[k];
|
||||
// let sceneItem = {uuid: itemSceneData.uuid, label: itemSceneData.name, children: []};
|
||||
let sceneItem = {};
|
||||
dealChildrenNode(itemSceneData, sceneItem);
|
||||
treeData[0].children.push(sceneItem);
|
||||
}
|
||||
if (!chrome || !chrome.devtools) {
|
||||
console.log("环境异常,无法执行函数");
|
||||
return;
|
||||
}
|
||||
this.treeData = treeData;
|
||||
|
||||
function dealChildrenNode(rootData: any, obj: any) {
|
||||
obj["data"] = rootData;
|
||||
obj["uuid"] = rootData.uuid;
|
||||
obj["label"] = rootData.name;
|
||||
obj["type"] = rootData.type;
|
||||
obj["children"] = [];
|
||||
let rootChildren = rootData.children;
|
||||
for (let k in rootChildren) {
|
||||
let itemData = rootChildren[k];
|
||||
let item = {};
|
||||
dealChildrenNode(itemData, item);
|
||||
obj.children.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getInjectScriptString() {
|
||||
let injectScript = "";
|
||||
let code = injectScript.toString();
|
||||
let array = code.split("\n");
|
||||
array.splice(0, 1);// 删除开头
|
||||
array.splice(-1, 1);// 删除结尾
|
||||
let evalCode = "";
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
evalCode += array[i] + "\n";
|
||||
}
|
||||
// console.log(evalCode);
|
||||
return evalCode;
|
||||
}
|
||||
|
||||
|
||||
evalInspectorFunction(funcString: string, parm?: any) {
|
||||
if (funcString || funcString.length > 0) {
|
||||
let injectCode =
|
||||
`if(window.ccinspector){
|
||||
let func = window.ccinspector.${funcString};
|
||||
let injectCode =
|
||||
`if(window.ccinspector){
|
||||
let func = window.ccinspector.${func};
|
||||
if(func){
|
||||
console.log("执行${funcString}成功");
|
||||
func.apply(window.ccinspector,[${parm}]);
|
||||
console.log("执行${func}成功");
|
||||
func.apply(window.ccinspector,[${para}]);
|
||||
}else{
|
||||
console.log("未发现${funcString}函数");
|
||||
console.log("未发现${func}函数");
|
||||
}
|
||||
}else{
|
||||
console.log("可能脚本没有注入");
|
||||
}`;
|
||||
console.log(injectCode);
|
||||
if (chrome && chrome.devtools) {
|
||||
let ret = chrome.devtools.inspectedWindow.eval(injectCode, function (result, info) {
|
||||
if (info && info.isException) {
|
||||
console.log(info.value);
|
||||
}
|
||||
|
||||
});
|
||||
console.log(`ret:${ret}`);
|
||||
}else{
|
||||
console.log("脚本inject.js未注入");
|
||||
}`;
|
||||
chrome.devtools.inspectedWindow.eval(injectCode, (result, isException) => {
|
||||
if (isException) {
|
||||
console.error(isException);
|
||||
} else {
|
||||
console.log(`执行结果:${result}`)
|
||||
}
|
||||
} else {
|
||||
console.log("执行失败!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onBtnClickUpdateTree() {
|
||||
this.evalInspectorFunction("updateTreeInfo");
|
||||
|
||||
}
|
||||
|
||||
onBtnClickUpdatePage() {
|
||||
this.evalInspectorFunction("checkIsGamePage", "true");
|
||||
// let code = this._getInjectScriptString();
|
||||
// chrome.devtools.inspectedWindow.eval(code, function () {
|
||||
// console.log("刷新成功!");
|
||||
// });
|
||||
}
|
||||
|
||||
onBtnClickTest1() {
|
||||
chrome.devtools.inspectedWindow.eval(`window.ccinspector.testMsg1()`);
|
||||
}
|
||||
|
||||
_getTime() {
|
||||
return new Date().getTime().toString();
|
||||
}
|
||||
|
||||
onBtnClickTest2() {
|
||||
// chrome.devtools.inspectedWindow.eval(`window.ccinspector.testMsg2()`)
|
||||
|
||||
|
||||
let newData = [
|
||||
{
|
||||
name: this._getTime(),
|
||||
children: [
|
||||
{
|
||||
name: this._getTime(),
|
||||
children: [
|
||||
{
|
||||
name: this._getTime(),
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: this._getTime(),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
// this.treeData = newData;
|
||||
this._update37(this.treeData[0], newData[0]);
|
||||
}
|
||||
|
||||
_update37(oldTreeNode: any, newTreeNode: any) {
|
||||
debugger
|
||||
if (!newTreeNode) {
|
||||
return;
|
||||
}
|
||||
if (!oldTreeNode) {
|
||||
oldTreeNode = {name: "", children: []};
|
||||
}
|
||||
if (oldTreeNode.name !== newTreeNode.name) {
|
||||
oldTreeNode.name = newTreeNode.name;
|
||||
}
|
||||
|
||||
let oldChildren = oldTreeNode.children;
|
||||
let newChildren = newTreeNode.children;
|
||||
|
||||
if (oldChildren.length === 0) {
|
||||
oldChildren = newChildren;
|
||||
} else {
|
||||
// 比较2个数据: treeData, newTreeData
|
||||
// 比较该层级的数据
|
||||
for (let i = 0; i < newChildren.length; i++) {
|
||||
let itemNew = newChildren[i];
|
||||
let itemOld = oldChildren[i];
|
||||
if (itemOld === undefined) {
|
||||
// 老节点中没有
|
||||
oldChildren.push(itemNew);
|
||||
} else if (itemNew.name !== itemOld.name) {
|
||||
// 替换
|
||||
oldChildren.splice(i, 1, itemNew);
|
||||
} else {
|
||||
this._update37(itemOld, itemNew);
|
||||
}
|
||||
}
|
||||
// 多余的删除了
|
||||
if (oldChildren.length > newChildren.length) {
|
||||
oldChildren.splice(newChildren.length, oldChildren.length - newChildren.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBtnClickTest3() {
|
||||
// chrome.devtools.inspectedWindow.eval(`window.ccinspector.testMsg3()`)
|
||||
}
|
||||
|
||||
onMemoryTest() {
|
||||
|
@ -11,8 +11,8 @@ if (chrome && chrome.devtools) {
|
||||
chrome.devtools.panels.create("Cocos", "icons/48.png", Manifest.devtools_page, (panel: chrome.devtools.panels.ExtensionPanel) => {
|
||||
console.log("[CC-Inspector] Dev Panel Created!");
|
||||
let conn = chrome.runtime.connect({name: PluginMsg.Page.DevToolsPanel});
|
||||
conn.onMessage.addListener(function (event, sender) {
|
||||
// debugger
|
||||
conn.onMessage.addListener((event, sender) => {
|
||||
console.log(`[Message] ${JSON.stringify(event)}`);
|
||||
});
|
||||
|
||||
panel.onShown.addListener((window) => {
|
||||
@ -27,7 +27,5 @@ if (chrome && chrome.devtools) {
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// eval 注入脚本的代码,变量尽量使用var,后来发现在import之后,let会自动变为var
|
||||
const PluginMsg = require("./core/plugin-msg");
|
||||
import {BoolData, ColorData, Group, NumberData, Property, StringData, Vec2Data, Vec3Data} from "./devtools/data";
|
||||
|
||||
let cc_inspector = {
|
||||
inspectorGameMemoryStorage: {},
|
||||
@ -22,19 +23,18 @@ let cc_inspector = {
|
||||
// }
|
||||
}.bind(this), 1000);
|
||||
// 注册cc_after_render事件
|
||||
window.addEventListener('message', function (event) {
|
||||
window.addEventListener("message", function (event) {
|
||||
if (event.data.msg === PluginMsg.Msg.UrlChange) {
|
||||
this.checkIsGamePage(true);
|
||||
let isCocosGame = this.checkIsGamePage();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
updateTreeInfo() {
|
||||
let isCocosCreatorGame = this.checkIsGamePage(true);
|
||||
let isCocosCreatorGame = this.checkIsGamePage();
|
||||
if (isCocosCreatorGame) {
|
||||
let scene = cc.director.getScene();
|
||||
if (scene) {
|
||||
this.postData.scene = {
|
||||
type: 1,// 标识类型
|
||||
let sendData = {
|
||||
uuid: scene.uuid,
|
||||
name: scene.name,
|
||||
children: [],
|
||||
@ -43,40 +43,25 @@ let cc_inspector = {
|
||||
let sceneChildren = scene.getChildren();
|
||||
for (let i = 0; i < sceneChildren.length; i++) {
|
||||
let node = sceneChildren[i];
|
||||
this.getNodeChildren(node, this.postData.scene.children);
|
||||
this.getNodeChildren(node, sendData.children);
|
||||
}
|
||||
// console.log(postData);
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.ListInfo, this.postData);
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.ListInfo, sendData);
|
||||
} else {
|
||||
this.postData.scene = null;
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.Support, {support: false, msg: "未发现游戏场景,不支持调试游戏!"});
|
||||
}
|
||||
}
|
||||
},
|
||||
checkIsGamePage(isLog) {
|
||||
// 检测是否包含cc变量
|
||||
let isCocosCreatorGame = true;
|
||||
let msg = "支持调试游戏!";
|
||||
try {
|
||||
cc
|
||||
} catch (e) {
|
||||
isCocosCreatorGame = false;
|
||||
msg = "不支持调试游戏!";
|
||||
}
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.Support, {support: isCocosCreatorGame, msg: msg, log: isLog});
|
||||
return isCocosCreatorGame;
|
||||
},
|
||||
testEval() {
|
||||
console.log("hello devtools eval")
|
||||
// 检测是否包含cc变量
|
||||
checkIsGamePage() {
|
||||
let isCocosGame = typeof cc !== "undefined";
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.Support, {support: isCocosGame});
|
||||
return isCocosGame;
|
||||
},
|
||||
|
||||
testMsg2() {
|
||||
debugger
|
||||
chrome.runtime.connect({name: "inject"});
|
||||
},
|
||||
testMsg3() {
|
||||
debugger
|
||||
chrome.runtime.sendMessage("ffff");
|
||||
},
|
||||
// 收集组件信息
|
||||
getNodeComponentsInfo(node) {
|
||||
let ret = [];
|
||||
@ -130,42 +115,118 @@ let cc_inspector = {
|
||||
}
|
||||
}
|
||||
},
|
||||
_getNodeKeys(node) {
|
||||
let keys = [];
|
||||
let excludeProperty = ["children", "quat"];
|
||||
for (let key in node) {
|
||||
if (!key.startsWith("_") &&
|
||||
!excludeProperty.includes(key) &&
|
||||
typeof node[key] !== "function") {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
},
|
||||
_getPairProperty(key) {
|
||||
let pairProperty = {
|
||||
rotation: ["rotationX", "rotationY"],
|
||||
anchor: ["anchorX", "anchorY"],
|
||||
size: ["width", "height"],
|
||||
position: ["x", "y", "z"],
|
||||
scale: ["scaleX", "scaleY", "scaleZ"],
|
||||
|
||||
};
|
||||
for (let value in pairProperty) {
|
||||
let pair = pairProperty[value];
|
||||
if (pair.includes(key)) {
|
||||
return {key: value, values: pair};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
_genInfoData(propertyValue) {
|
||||
let info = null;
|
||||
switch (typeof propertyValue) {
|
||||
case "boolean":
|
||||
info = new BoolData(propertyValue);
|
||||
break;
|
||||
case "number":
|
||||
info = new NumberData(propertyValue);
|
||||
break;
|
||||
case "string":
|
||||
info = new StringData(propertyValue);
|
||||
break;
|
||||
default:
|
||||
if (Array.isArray(propertyValue)) {
|
||||
|
||||
} else if (propertyValue instanceof cc.Color) {
|
||||
let hex = propertyValue.toHEX();
|
||||
info = new ColorData(`#${hex}`);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!info) {
|
||||
console.error(`暂不支持的属性值`, propertyValue);
|
||||
}
|
||||
return info;
|
||||
},
|
||||
// 获取节点信息
|
||||
getNodeInfo(uuid) {
|
||||
debugger
|
||||
let node = this.inspectorGameMemoryStorage[uuid];
|
||||
if (node) {
|
||||
let nodeGroup = new Group("Node");
|
||||
let keys = this._getNodeKeys(node);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i];
|
||||
let propertyValue = node[key];
|
||||
let pair = this._getPairProperty(key);
|
||||
if (pair) {
|
||||
// 把这个成对的属性剔除掉
|
||||
pair.values.forEach(item => {
|
||||
let index = keys.findIndex(el => el === item);
|
||||
if (index !== -1) {
|
||||
keys.splice(index, 1);
|
||||
}
|
||||
});
|
||||
// 序列化成对的属性
|
||||
let info = null;
|
||||
let pairValues = pair.values;
|
||||
if (pairValues.length === 2) {
|
||||
info = new Vec2Data();
|
||||
} else if (pairValues.length === 3) {
|
||||
info = new Vec3Data();
|
||||
}
|
||||
pairValues.forEach(el => {
|
||||
if (el in node) {
|
||||
let vecData = this._genInfoData(node[el]);
|
||||
if (vecData) {
|
||||
info.add(new Property(el, vecData));
|
||||
}
|
||||
} else {
|
||||
console.warn(`属性异常,节点丢失属性: ${el},请检查 pairProperty的设置`);
|
||||
}
|
||||
});
|
||||
if (info) {
|
||||
let property = new Property(pair.key, info);
|
||||
nodeGroup.addProperty(property);
|
||||
}
|
||||
} else {
|
||||
let info = this._genInfoData(propertyValue);
|
||||
if (info) {
|
||||
nodeGroup.addProperty(new Property(key, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let nodeComp = this.getNodeComponentsInfo(node);
|
||||
let nodeData = {
|
||||
type: node.constructor.name,
|
||||
uuid: node.uuid,
|
||||
name: node.name,
|
||||
x: node.x,
|
||||
y: node.y,
|
||||
zIndex: node.zIndex,
|
||||
childrenCount: node.childrenCount,
|
||||
children: [],
|
||||
width: node.width,
|
||||
height: node.height,
|
||||
color: node.color.toCSS(),
|
||||
opacity: node.opacity,
|
||||
rotation: node.rotation,
|
||||
rotationX: node.rotationX,
|
||||
rotationY: node.rotationY,
|
||||
anchorX: node.anchorX,
|
||||
anchorY: node.anchorY,
|
||||
scaleX: node.scaleX,
|
||||
scaleY: node.scaleY,
|
||||
skewX: node.skewX,
|
||||
skewY: node.skewY,
|
||||
components: nodeComp
|
||||
};
|
||||
let nodeType = node.constructor.name;
|
||||
if (nodeType === 'cc_Scene') {
|
||||
|
||||
} else {
|
||||
nodeData.active = node.active;
|
||||
}
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.NodeInfo, nodeData);
|
||||
this.sendMsgToDevTools(PluginMsg.Msg.NodeInfo, nodeGroup);
|
||||
} else {
|
||||
// 未获取到节点数据
|
||||
console.log("未获取到节点数据");
|
||||
@ -190,6 +251,7 @@ let cc_inspector = {
|
||||
data.push(nodeData);
|
||||
},
|
||||
sendMsgToDevTools(msg, data) {
|
||||
// 发送给content.js处理
|
||||
window.postMessage({msg: msg, data: data}, "*");
|
||||
},
|
||||
|
||||
@ -207,7 +269,7 @@ let cc_inspector = {
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
window.ccinspector = window.ccinspector || cc_inspector;
|
||||
window.ccinspector.init && window.ccinspector.init();// 执行初始化函数
|
||||
|
||||
|
@ -28,13 +28,7 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
mode: "development",
|
||||
mode: "development",// production
|
||||
devtool: "#source-map",
|
||||
entry: {
|
||||
inject: Path.join(__dirname, "src/inject.js"),
|
||||
},
|
||||
plugins: [
|
||||
// new Copy([{src: "src/inject.js", dest: "js/inject.js"}]),
|
||||
]
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user