diff --git a/source/package.json b/source/package.json index 77d74d1..8590431 100644 --- a/source/package.json +++ b/source/package.json @@ -13,6 +13,7 @@ "@types/node": "^14.14.37", "babel-eslint": "^10.1.0", "core-js": "^3.6.5", + "uuid": "^8.3.2", "element-ui": "^2.15.1", "fs-extra": "^9.1.0", "less": "^4.1.1", @@ -22,6 +23,7 @@ "vue-property-decorator": "^9.1.2" }, "devDependencies": { + "@types/uuid": "^8.3.1", "@types/chrome": "0.0.133", "@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/parser": "^4.18.0", diff --git a/source/src/background.ts b/source/src/background.ts index a99e7c3..56bf1bf 100644 --- a/source/src/background.ts +++ b/source/src/background.ts @@ -107,12 +107,12 @@ class PortManagement { if (id && id > -1) { let portMan = this.find(id); if (portMan) { - let data = new PluginEvent( - Page.Background, - Page.Content, - Msg.Test, - {url: tab.url} - ); + // let data = new PluginEvent( + // Page.Background, + // Page.Content, + // Msg.Test, + // {url: tab.url} + // ); // portMan.sendContentMsg(data); } } diff --git a/source/src/core/types.ts b/source/src/core/types.ts index a462a01..a8eb5cd 100644 --- a/source/src/core/types.ts +++ b/source/src/core/types.ts @@ -1,7 +1,7 @@ export enum Page { Inject = "Inject", Devtools = "Devtools", - Background = 'Background', + Background = "Background", Content = "Content", Popup = "Popup", Options = "Options", @@ -14,9 +14,9 @@ export enum Msg { MemoryInfo = "memory-info",// TabsInfo = "tabs_info", // 当前页面信息 GetTabID = "GetTabID", // 获取页面ID - Test='Test', + GetObjectItemData = "GetObjectItemData", SetProperty = "set-property", // 设置node属性 - UpdateProperty = 'update-property', // 更新属性 + UpdateProperty = "update-property", // 更新属性 } export class PluginEvent { diff --git a/source/src/devtools/bus.ts b/source/src/devtools/bus.ts index 56fc732..cb00f1e 100644 --- a/source/src/devtools/bus.ts +++ b/source/src/devtools/bus.ts @@ -1,7 +1,8 @@ -import Vue from 'vue' +import Vue from "vue" export enum BusMsg { - ShowPlace = 'ShowPlace', + ShowPlace = "ShowPlace", + RequestObjectData = "RequestObjectData", } export default new Vue(); diff --git a/source/src/devtools/data.ts b/source/src/devtools/data.ts index 3370717..55896ad 100644 --- a/source/src/devtools/data.ts +++ b/source/src/devtools/data.ts @@ -1,3 +1,6 @@ +// @ts-ignore +import {v4} from "uuid" + export enum DataType { Number, String, @@ -10,15 +13,20 @@ export enum DataType { NullOrUndefined, Array, // 暂时在控制台打印下 Object, + ObjectItem, Image, // 图片 Engine,// 引擎的类型:cc.Node, cc.Sprite, cc.Label等。。。 } export class Info { + public id: string | null = null; public type: DataType = DataType.Number; public data: any; public readonly: boolean = false; public path: Array = [];// 属性对应的路径 + constructor() { + this.id = v4(); + } } export class TextData extends Info { @@ -28,10 +36,15 @@ export class TextData extends Info { } } +export interface ObjectItemRequestData { + id: string | null; + data: Property[]; +} + export class EngineData extends Info { - public engineType: string = ''; - public engineUUID: string = ''; - public engineName: string = ''; + public engineType: string = ""; + public engineUUID: string = ""; + public engineName: string = ""; constructor() { super(); @@ -53,18 +66,16 @@ export class ArrayData extends Info { } } -export class ObjectData extends Info { - data: Array = []; +export class ObjectDataItem extends Info { +} + +export class ObjectData extends Info { + data: string = "";// object的简单描述快照,类似chrome的console,{a:'fff',b:xxx} constructor() { super(); this.type = DataType.Object; } - - add(info: Property) { - this.data.push(info); - return this; - } } export class NullOrUndefinedData extends Info { @@ -159,13 +170,13 @@ export class EnumData extends Info { export class TreeData { active: boolean = true; - uuid: string = ''; - name: string = ''; + uuid: string = ""; + name: string = ""; children: Array = []; } export class Property { - public name: string = 'property'; + public name: string = "property"; public value: Info = new Info(); constructor(name: string, info: Info) { @@ -175,7 +186,7 @@ export class Property { } export class Group { - public name: string = 'group'; + public name: string = "group"; public data: Array = []; constructor(name: string) { @@ -187,7 +198,7 @@ export class Group { } sort() { - let order = ['name', 'active', 'enabled', 'uuid', 'position', 'rotation', 'scale', 'anchor', 'size', 'color', 'opacity', 'skew', 'group']; + let order = ["name", "active", "enabled", "uuid", "position", "rotation", "scale", "anchor", "size", "color", "opacity", "skew", "group"]; let orderKeys: Array = []; let otherKeys: Array = []; this.data.forEach(property => { @@ -204,86 +215,3 @@ export class Group { this.data = orderKeys.concat(otherKeys); } } - -export const testData = [ - { - name: "group1", - uuid: 'node/comp uuid', - data: [ - {name: "uuid", value: {type: DataType.String, data: 'abc', path: 'uuid'}}, - {name: "opacity", value: {type: DataType.Number, data: 100}}, - - { - name: "size", - value: { - type: DataType.Vec2, - data: [ - {name: "X", value: {type: DataType.Number, data: 100}}, - {name: "Y", value: {type: DataType.Number, data: 200}}, - ] - } - }, - { - name: "position", - value: { - type: DataType.Vec3, - data: [ - {name: "X", value: {type: DataType.Number, data: 100}}, - {name: "Y", value: {type: DataType.Number, data: 200}}, - {name: "Z", value: {type: DataType.Number, data: 300}}, - ] - } - }, - { - name: "layout", - value: { - type: DataType.Enum, - data: 1, - values: [ - {name: "horizontal", value: 1}, - {name: "vertical", value: 2}, - ] - } - }, - { - name: "text", - value: { - type: DataType.Text, - data: 'aaaaaaaaafsf', - } - } - ] - }, - { - name: "group2", - data: [ - { - name: "bool", value: { - type: DataType.Bool, - data: true, - } - }, - { - name: 'color', - value: { - type: DataType.Color, - data: '#ff0000' - } - }, - { - name: 'array', - value: { - type: DataType.Array, - data: [1, 2, 3, 4] - } - }, { - name: 'object', - value: { - type: DataType.Object, - data: {a: '11111111111111111111111111111111111111111111111111111111111', b: 2, c: 3} - } - } - ] - }, -]; - diff --git a/source/src/devtools/ui/index.vue b/source/src/devtools/ui/index.vue index 6268c30..d9cab73 100644 --- a/source/src/devtools/ui/index.vue +++ b/source/src/devtools/ui/index.vue @@ -54,7 +54,7 @@ import {Component} from "vue-property-decorator"; import properties from "./propertys.vue"; import {Msg, Page, PluginEvent} from "@/core/types" import {connectBackground} from "@/devtools/connectBackground"; -import {EngineData, Info, TreeData} from "@/devtools/data"; +import {EngineData, Info, TreeData, ObjectData, ObjectItemRequestData} from "@/devtools/data"; import Bus, {BusMsg} from "@/devtools/bus"; @Component({ @@ -82,6 +82,9 @@ export default class Index extends Vue { } timerID: number = 0; + + private requestList: Array<{ id: string, cb: Function }> = []; + created() { if (chrome && chrome.runtime) { this._initChromeRuntimeConnect(); @@ -94,6 +97,13 @@ export default class Index extends Vue { console.log(data) this._expand(data.engineUUID); }) + Bus.$on(BusMsg.RequestObjectData, (data: ObjectData, cb: Function) => { + if (this.requestList.find(el => el.id === data.id)) { + return + } + this.requestList.push({id: data.id, cb}); + this.sendMsgToContentScript(Msg.GetObjectItemData, data) + }); } _expand(uuid: string) { @@ -185,7 +195,6 @@ export default class Index extends Vue { return; } if (data.target === Page.Devtools) { - debugger console.log(`[Devtools] ${JSON.stringify(data)}`); PluginEvent.finish(data); let eventData: any = data.data; @@ -214,6 +223,17 @@ export default class Index extends Vue { debugger break } + case Msg.GetObjectItemData: { + let eventData: ObjectItemRequestData = data.data as ObjectItemRequestData; + if (eventData.id !== null) { + let findIndex = this.requestList.findIndex(el => el.id === eventData.id) + if (findIndex > -1) { + let del = this.requestList.splice(findIndex, 1)[0]; + del.cb(eventData.data); + } + } + break + } } } }); @@ -249,7 +269,7 @@ export default class Index extends Vue { this.selectedUUID = data.uuid; let uuid = data.uuid; if (uuid !== undefined) { - this.runToContentScript(Msg.NodeInfo, uuid); + this.sendMsgToContentScript(Msg.NodeInfo, uuid); } } @@ -258,7 +278,7 @@ export default class Index extends Vue { this.timerID = setInterval(() => { this.onBtnClickUpdateTree(); if (this.selectedUUID) { - this.runToContentScript(Msg.NodeInfo, this.selectedUUID); + this.sendMsgToContentScript(Msg.NodeInfo, this.selectedUUID); } }, 300); } else { @@ -266,7 +286,7 @@ export default class Index extends Vue { } } - runToContentScript(msg: Msg, data?: any) { + sendMsgToContentScript(msg: Msg, data?: any) { if (!chrome || !chrome.devtools) { console.log("环境异常,无法执行函数"); return; @@ -296,16 +316,15 @@ export default class Index extends Vue { } onBtnClickUpdateTree() { - this.runToContentScript(Msg.TreeInfo); + this.sendMsgToContentScript(Msg.TreeInfo); } onBtnClickUpdatePage() { - debugger - this.runToContentScript(Msg.Support); + this.sendMsgToContentScript(Msg.Support); } onMemoryTest() { - this.runToContentScript(Msg.MemoryInfo); + this.sendMsgToContentScript(Msg.MemoryInfo); } onNodeExpand(data: TreeData) { diff --git a/source/src/devtools/ui/ui-prop.vue b/source/src/devtools/ui/ui-prop.vue index 1882e2b..d0075ef 100644 --- a/source/src/devtools/ui/ui-prop.vue +++ b/source/src/devtools/ui/ui-prop.vue @@ -76,7 +76,6 @@ - @@ -100,14 +99,17 @@
{{ value.engineName }}
+
+ {{ value.data }} +
-
- + { - valueString() { - try { - return JSON.stringify(this.value.data) - } catch (e) { - return "" + this.fold = false; + this.subData = info; + }) + } else { + this.fold = !this.fold; } } @@ -345,7 +350,7 @@ export default class UiProp extends Vue { font-size: 12px; margin: 3px; - span{ + span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -373,6 +378,13 @@ export default class UiProp extends Vue { } } + .arrayOrObjectDesc { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + user-select: none; + } + .engine { display: flex; flex-direction: row; diff --git a/source/src/inject/index.ts b/source/src/inject/index.ts index da70556..bea2dcf 100644 --- a/source/src/inject/index.ts +++ b/source/src/inject/index.ts @@ -3,12 +3,14 @@ import { ArrayData, BoolData, ColorData, - DataType, EngineData, - Group, ImageData, + DataType, + EngineData, + Group, + ImageData, Info, NullOrUndefinedData, NumberData, - ObjectData, + ObjectData, ObjectItemRequestData, Property, StringData, TreeData, @@ -16,9 +18,9 @@ import { Vec3Data } from "@/devtools/data"; import {Msg, Page, PluginEvent} from "@/core/types" -import {BuildDataOptions, BuildImageOptions, BuildVecOptions} from "@/inject/types"; +import {BuildArrayOptions, BuildImageOptions, BuildObjectOptions, BuildVecOptions} from "@/inject/types"; -declare var cc: any; +declare const cc: any; class CCInspector { @@ -72,6 +74,24 @@ class CCInspector { this.sendMsgToContent(Msg.UpdateProperty, data); break; } + case Msg.GetObjectItemData: { + const data: ObjectData = pluginEvent.data; + let val = this.getValue(data.path); + if (val) { + let itemData: Property[] = this._buildObjectItemData({ + data: data, + path: data.path, + value: val, + filterKey: false, + }); + let result: ObjectItemRequestData = { + id: data.id, + data: itemData, + } + this.sendMsgToContent(Msg.GetObjectItemData, result); + } + break; + } } } }); @@ -248,7 +268,7 @@ class CCInspector { return null; } - _genInfoData(node: any, key: string | number, path: Array) { + _genInfoData(node: any, key: string | number, path: Array, filterKey = true) { let propertyValue = node[key]; let info = null; switch (typeof propertyValue) { @@ -316,7 +336,7 @@ class CCInspector { data: new ObjectData(), path: path, value: propertyValue, - keys: Object.keys(propertyValue), + filterKey: filterKey, }) } } @@ -333,26 +353,12 @@ class CCInspector { return info; } - _buildArrayData(options: BuildDataOptions) { - return this._buildObjectOrArrayData(options); - } - - _buildObjectData(options: BuildDataOptions) { - // todo 只返回一级key,更深层级的key需要的时候,再获取,防止circle object导致的死循环 - - } - - _buildObjectOrArrayData(options: BuildDataOptions) { - let propertyValue: Object = options.value; - let path: Array = options.path; - let data: ObjectData | ArrayData = options.data; - let keys: Array = options.keys; - // 剔除_开头的属性 + _buildArrayData({value, path, data, keys}: BuildArrayOptions) { keys = keys.filter(key => !key.toString().startsWith("_")); for (let i = 0; i < keys.length; i++) { let key = keys[i]; let propPath = path.concat(key.toString()); - let itemData = this._genInfoData(propertyValue, key, propPath); + let itemData = this._genInfoData(value, key, propPath); if (itemData) { data.add(new Property(key.toString(), itemData)) } @@ -360,6 +366,57 @@ class CCInspector { return data; } + _buildObjectItemData({value, path, data, filterKey}: BuildObjectOptions): Property[] { + let keys = Object.keys(value); + if (filterKey) { + keys = this.filterKeys(keys);// 不再进行开发者定义的数据 + } + let ret: Property[] = [] + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + let propPath = path.concat(key.toString()); + let itemData = this._genInfoData(value, key, propPath, filterKey); + if (itemData) { + ret.push(new Property(key, itemData)) + } + } + return ret; + } + + filterKeys(keys: string[]) { + // 剔除_开头的属性 + return keys.filter(key => !key.toString().startsWith("_")); + } + + _buildObjectData({value, path, data, filterKey}: BuildObjectOptions) { + let keys = Object.keys(value); + if (filterKey) { + keys = this.filterKeys(keys) + } + // 只返回一级key,更深层级的key需要的时候,再获取,防止circle object导致的死循环 + let desc: Record = {}; + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + let propPath = path.concat(key.toString()); + let propValue = (value as any)[key]; + let keyDesc = ""; + if (Array.isArray(propValue)) { + // 只收集一级key + propValue.forEach(item => { + + }) + keyDesc = `(${propValue.length}) [...]` + } else if (typeof propValue === "object") { + keyDesc = `${propValue.constructor.name} {...}`; + } else { + keyDesc = propValue; + } + desc[key] = keyDesc; + } + data.data = JSON.stringify(desc); + return data; + } + private getCompName(comp: any): string { const nameKeys = [ "__classname__", // 2.4.0 验证通过 @@ -491,6 +548,19 @@ class CCInspector { } } + getValue(path: string[]) { + let target = this.inspectorGameMemoryStorage; + for (let i = 0; i < path.length; i++) { + let key = path[i]; + if (target.hasOwnProperty(key)) { + target = target[key] + } else { + return null; + } + } + return target; + } + onMemoryInfo() { this.sendMsgToContent(Msg.MemoryInfo, { diff --git a/source/src/inject/types.ts b/source/src/inject/types.ts index 0d9fdf2..8357faa 100644 --- a/source/src/inject/types.ts +++ b/source/src/inject/types.ts @@ -1,10 +1,17 @@ import {ArrayData, ImageData, ObjectData, Vec2Data, Vec3Data} from "@/devtools/data"; -export interface BuildDataOptions { +export interface BuildObjectOptions { path: string[]; value: Object; - data: ObjectData | ArrayData; - keys: string[] | number[]; + data: ObjectData; + filterKey:boolean; +} + +export interface BuildArrayOptions { + path: string[]; + value: Object; + data: ArrayData; + keys: number[]; } export interface BuildVecOptions {