mirror of
https://github.com/tidys/cc-inspector-chrome
synced 2025-04-13 21:51:03 +00:00
适配
This commit is contained in:
parent
a082bda2ae
commit
83798ff401
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ cc-inspector/node_modules/
|
|||||||
cc-inspector/yalc.lock
|
cc-inspector/yalc.lock
|
||||||
cc-inspector/chrome/
|
cc-inspector/chrome/
|
||||||
cc-inspector/dist/
|
cc-inspector/dist/
|
||||||
|
cc-inspector/yarn-error.log
|
||||||
|
14
cc-inspector/.vscode/settings.json
vendored
Normal file
14
cc-inspector/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnSaveMode": "modifications",
|
||||||
|
"files.autoSave": "onFocusChange",
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||||
|
},
|
||||||
|
"[vue]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"files.refactoring.autoSave": false
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
"tiny-emitter": "2.1.0",
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import Vue from "vue"
|
import { TinyEmitter } from 'tiny-emitter';
|
||||||
|
|
||||||
export enum BusMsg {
|
export enum BusMsg {
|
||||||
ShowPlace = "ShowPlace",
|
ShowPlace = "ShowPlace",
|
||||||
@ -7,4 +7,4 @@ export enum BusMsg {
|
|||||||
FoldAllGroup = "FoldAllGroup"
|
FoldAllGroup = "FoldAllGroup"
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Vue();
|
export default new TinyEmitter();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {PluginEvent, Page, Msg} from "@/core/types";
|
import {PluginEvent, Page, Msg} from "../../core/types";
|
||||||
|
|
||||||
class ConnectBackground {
|
class ConnectBackground {
|
||||||
connect: chrome.runtime.Port | null = null;
|
connect: chrome.runtime.Port | null = null;
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
// @ts-ignore
|
import { v4 } from "uuid"
|
||||||
import {v4} from "uuid"
|
|
||||||
|
|
||||||
export enum DataType {
|
export enum DataType {
|
||||||
Number,
|
Number = 'Number',
|
||||||
String,
|
String = 'String',
|
||||||
Text,
|
Text = 'Text',
|
||||||
Vec2,
|
Vec2 = 'Vec2',
|
||||||
Vec3,
|
Vec3 = 'Vec3',
|
||||||
Enum,
|
Enum = 'Enum',
|
||||||
Bool,
|
Bool = 'Bool',
|
||||||
Color,
|
Color = 'Color',
|
||||||
Invalid,
|
Invalid = 'Invalid',
|
||||||
Array, // 暂时在控制台打印下
|
Array = 'Array', // 暂时在控制台打印下
|
||||||
Object,
|
Object = 'Object',
|
||||||
ObjectItem,
|
ObjectItem = 'ObjectItem',
|
||||||
Image, // 图片
|
Image = 'Image', // 图片
|
||||||
Engine,// 引擎的类型:cc.Node, cc.Sprite, cc.Label等。。。
|
Engine = 'Engine',// 引擎的类型:cc.Node, cc.Sprite, cc.Label等。。。
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Info {
|
export class Info {
|
||||||
@ -27,6 +26,9 @@ export class Info {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.id = v4();
|
this.id = v4();
|
||||||
}
|
}
|
||||||
|
public isEnum(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TextData extends Info {
|
export class TextData extends Info {
|
||||||
@ -169,10 +171,14 @@ export class ImageData extends Info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class EnumData extends Info {
|
export class EnumData extends Info {
|
||||||
|
public values: Array<{ name: string, value: any }> = [];
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.type = DataType.Enum;
|
this.type = DataType.Enum;
|
||||||
}
|
}
|
||||||
|
public isEnum(): boolean {
|
||||||
|
return this.type === DataType.Enum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TreeData {
|
export class TreeData {
|
||||||
@ -197,9 +203,9 @@ export class Group {
|
|||||||
public name: string = "group";
|
public name: string = "group";
|
||||||
public data: Array<Property> = [];
|
public data: Array<Property> = [];
|
||||||
|
|
||||||
constructor(name: string,id?:string) {
|
constructor(name: string, id?: string) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.id=id||'';
|
this.id = id || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
addProperty(property: Property) {
|
addProperty(property: Property) {
|
||||||
|
@ -1,20 +1,656 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="devtools">devtools</div>
|
<div id="devtools">
|
||||||
</template>
|
<!-- <el-drawer title="settings" direction="btt" @close="onCloseSettings" :visible.sync="showSettings">
|
||||||
<script lang="ts">
|
<div>
|
||||||
import { defineComponent, onMounted, ref, provide, nextTick } from "vue";
|
<SettingsVue></SettingsVue>
|
||||||
export default defineComponent({
|
</div>
|
||||||
name: "devtools",
|
</el-drawer> -->
|
||||||
components: {},
|
<div class="head" v-show="iframes.length > 1">
|
||||||
setup(props, ctx) {
|
<div class="label">inspect target:</div>
|
||||||
return {};
|
<el-select
|
||||||
|
v-model="frameID"
|
||||||
|
placeholder="please select ..."
|
||||||
|
@change="onChangeFrame"
|
||||||
|
style="flex: 1"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in iframes"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div v-show="isShowDebug" class="find">
|
||||||
|
<div v-if="false">
|
||||||
|
<el-button type="success" @click="onMemoryTest">内存测试</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="false">
|
||||||
|
<span>JS堆栈限制: {{ memory.performance.jsHeapSizeLimit }}</span>
|
||||||
|
<span>JS堆栈大小: {{ memory.performance.totalJSHeapSize }}</span>
|
||||||
|
<span>JS堆栈使用: {{ memory.performance.usedJSHeapSize }}</span>
|
||||||
|
</div>
|
||||||
|
<div ref="left" class="left">
|
||||||
|
<div class="tool-btn">
|
||||||
|
<div style="padding-left: 15px; flex: 1">Node Tree</div>
|
||||||
|
<el-button
|
||||||
|
v-show="isShowRefreshBtn"
|
||||||
|
type="success"
|
||||||
|
class="el-icon-refresh"
|
||||||
|
size="mini"
|
||||||
|
@click="onBtnClickUpdateTree"
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
@click="onClickSettings"
|
||||||
|
class="el-icon-s-tools"
|
||||||
|
></el-button>
|
||||||
|
</div>
|
||||||
|
<!-- <el-input placeholder="enter keywords to filter" v-model="filterText">
|
||||||
|
<template slot="append">
|
||||||
|
<div class="matchCase">
|
||||||
|
<div
|
||||||
|
class="iconfont el-icon-third-font-size"
|
||||||
|
@click.stop="onChangeCase"
|
||||||
|
title="match case"
|
||||||
|
:style="{ color: matchCase ? 'red' : '' }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-input> -->
|
||||||
|
<div class="treeList">
|
||||||
|
<!-- <el-tree
|
||||||
|
:data="treeData"
|
||||||
|
ref="tree"
|
||||||
|
style="display: inline-block"
|
||||||
|
:props="defaultProps"
|
||||||
|
:highlight-current="true"
|
||||||
|
:default-expand-all="false"
|
||||||
|
:default-expanded-keys="expandedKeys"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
node-key="uuid"
|
||||||
|
@node-expand="onNodeExpand"
|
||||||
|
@node-collapse="onNodeCollapse"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
slot-scope="{ node, data }"
|
||||||
|
class="leaf"
|
||||||
|
:class="data.active ? 'leaf-show' : 'leaf-hide'"
|
||||||
|
>
|
||||||
|
<span>{{ node.label }}</span>
|
||||||
|
</span>
|
||||||
|
</el-tree> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ui-divider ref="divider" @move="onDividerMove"></ui-divider>
|
||||||
|
<div ref="right" class="right">
|
||||||
|
<properties v-if="treeItemData" :data="treeItemData"></properties>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-show="!isShowDebug" class="no-find">
|
||||||
|
<span>No games created by cocos creator found!</span>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
class="el-icon-refresh"
|
||||||
|
@click="onBtnClickUpdatePage"
|
||||||
|
>刷新</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType, ref, onMounted, watch } from "vue";
|
||||||
|
import properties from "./ui/propertys.vue";
|
||||||
|
import { Msg, Page, PluginEvent } from "../../core/types";
|
||||||
|
import { connectBackground } from "./connectBackground";
|
||||||
|
import {
|
||||||
|
EngineData,
|
||||||
|
FrameDetails,
|
||||||
|
Info,
|
||||||
|
NodeInfoData,
|
||||||
|
ObjectData,
|
||||||
|
ObjectItemRequestData,
|
||||||
|
TreeData,
|
||||||
|
} from "./data";
|
||||||
|
import Bus, { BusMsg } from "./bus";
|
||||||
|
import SettingsVue from "./ui/settings.vue";
|
||||||
|
import { RefreshType, settings } from "./settings";
|
||||||
|
import UiDivider from "./ui/ui-divider.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: { UiDivider, properties, SettingsVue },
|
||||||
|
name: "devtools",
|
||||||
|
props: {
|
||||||
|
isShowDebug: { type: Boolean, default: false },
|
||||||
|
treeItemData: { type: Object as PropType<NodeInfoData>, default: () => {} },
|
||||||
|
isShowRefreshBtn: { type: Boolean, default: false },
|
||||||
|
showSettings: { type: Boolean, default: false },
|
||||||
|
iframes: {
|
||||||
|
type: Array as PropType<Array<{ label: string; value: number }>>,
|
||||||
|
default: () => [],
|
||||||
},
|
},
|
||||||
});
|
frameID: { type: Number, default: 0 },
|
||||||
</script>
|
},
|
||||||
<style scoped lang="less">
|
setup(props, ctx) {
|
||||||
.devtools {
|
function _checkSelectedUUID() {
|
||||||
widows: 10px;
|
if (this.selectedUUID) {
|
||||||
height: 10px;
|
const b = this._findUuidInTree(this.treeData, this.selectedUUID);
|
||||||
background-color: rebeccapurple;
|
if (b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.selectedUUID = null;
|
||||||
|
this.treeItemData = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _findUuidInTree(data: TreeData[], targetUUID: string) {
|
||||||
|
function circle(tree: TreeData[]) {
|
||||||
|
for (let i = 0; i < tree.length; i++) {
|
||||||
|
let item: TreeData = tree[i];
|
||||||
|
if (item.uuid === targetUUID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (circle(item.children)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return circle(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMsgToContentScript(msg: Msg, data?: any) {
|
||||||
|
if (!chrome || !chrome.devtools) {
|
||||||
|
console.log("环境异常,无法执行函数");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connectBackground.postMessageToBackground(msg, data);
|
||||||
|
}
|
||||||
|
const requestList: Array<{ id: string; cb: Function }> = [];
|
||||||
|
|
||||||
|
function _expand(uuid: string) {
|
||||||
|
let expandKeys: Array<string> = [];
|
||||||
|
|
||||||
|
function circle(array: any) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let item = array[i];
|
||||||
|
expandKeys.push(item.uuid);
|
||||||
|
if (item.uuid === uuid) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
let find = circle(item.children);
|
||||||
|
if (find) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
expandKeys.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
circle(this.treeData);
|
||||||
|
|
||||||
|
expandKeys.forEach((key) => {
|
||||||
|
if (!this.expandedKeys.find((el) => el === key)) {
|
||||||
|
this.expandedKeys.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 高亮uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onMsgNodeInfo(eventData: NodeInfoData) {
|
||||||
|
this.isShowDebug = true;
|
||||||
|
this.treeItemData = eventData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onMsgMemoryInfo(eventData: any) {
|
||||||
|
this.memory = eventData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onMsgSupport(isCocosGame: boolean) {
|
||||||
|
this.isShowDebug = isCocosGame;
|
||||||
|
if (isCocosGame) {
|
||||||
|
syncSettings();
|
||||||
|
this.onBtnClickUpdateTree();
|
||||||
|
} else {
|
||||||
|
this._clearTimer();
|
||||||
|
this.treeData = [];
|
||||||
|
this.treeItemData = null;
|
||||||
|
this.selectedUUID = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _onMsgGetObjectItemData(requestData: ObjectItemRequestData) {
|
||||||
|
if (requestData.id !== null) {
|
||||||
|
let findIndex = this.requestList.findIndex(
|
||||||
|
(el) => el.id === requestData.id
|
||||||
|
);
|
||||||
|
if (findIndex > -1) {
|
||||||
|
let del = this.requestList.splice(findIndex, 1)[0];
|
||||||
|
del.cb(requestData.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onMsgUpdateFrames(details: FrameDetails[]) {
|
||||||
|
// 先把iframes里面无效的清空了
|
||||||
|
this.iframes = this.iframes.filter((item) => {
|
||||||
|
details.find((el) => el.frameID === item.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 同步配置
|
||||||
|
details.forEach((item) => {
|
||||||
|
let findItem = this.iframes.find((el) => el.value === item.frameID);
|
||||||
|
if (findItem) {
|
||||||
|
findItem.label = item.url;
|
||||||
|
} else {
|
||||||
|
this.iframes.push({
|
||||||
|
label: item.url,
|
||||||
|
value: item.frameID,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 第一次获取到frame配置后,自动获取frame数据
|
||||||
|
if (
|
||||||
|
this.frameID === null &&
|
||||||
|
this.iframes.length > 0 &&
|
||||||
|
!this.iframes.find((el) => el.value === this.frameID)
|
||||||
|
) {
|
||||||
|
this.frameID = this.iframes[0].value;
|
||||||
|
this.onChangeFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onMsgUpdateProperty(data: Info) {
|
||||||
|
const uuid = data.path[0];
|
||||||
|
const key = data.path[1];
|
||||||
|
const value = data.data;
|
||||||
|
let treeArray: Array<TreeData> = [];
|
||||||
|
|
||||||
|
function circle(array: Array<TreeData>) {
|
||||||
|
array.forEach((item) => {
|
||||||
|
treeArray.push(item);
|
||||||
|
circle(item.children);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新指定uuid节点的tree的name
|
||||||
|
circle(this.treeData);
|
||||||
|
let ret = treeArray.find((el) => el.uuid === uuid);
|
||||||
|
if (ret) {
|
||||||
|
if (key === "name") {
|
||||||
|
ret.name = value;
|
||||||
|
}
|
||||||
|
if (key === "active") {
|
||||||
|
ret.active = !!value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 问题:没有上下文的权限,只能操作DOM
|
||||||
|
function _executeScript(para: Object) {
|
||||||
|
let tabID = chrome.devtools.inspectedWindow.tabId;
|
||||||
|
//@ts-ignore
|
||||||
|
chrome.tabs.executeScript(
|
||||||
|
tabID,
|
||||||
|
{ code: `var CCInspectorPara='${JSON.stringify(para)}';` },
|
||||||
|
() => {
|
||||||
|
//@ts-ignore
|
||||||
|
chrome.tabs.executeScript(tabID, { file: "js/execute.js" });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _inspectedCode() {
|
||||||
|
let injectCode = "";
|
||||||
|
chrome.devtools.inspectedWindow.eval(
|
||||||
|
injectCode,
|
||||||
|
(result, isException) => {
|
||||||
|
if (isException) {
|
||||||
|
console.error(isException);
|
||||||
|
} else {
|
||||||
|
console.log(`执行结果:${result}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function _onMsgTreeInfo(treeData: Array<TreeData>) {
|
||||||
|
this.isShowDebug = true;
|
||||||
|
if (!Array.isArray(treeData)) {
|
||||||
|
treeData = [treeData];
|
||||||
|
}
|
||||||
|
this.treeData = treeData;
|
||||||
|
if (this._checkSelectedUUID()) {
|
||||||
|
this.updateNodeInfo();
|
||||||
|
this.$nextTick(() => {
|
||||||
|
//@ts-ignore
|
||||||
|
this.$refs.tree.setCurrentKey(this.selectedUUID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _initChromeRuntimeConnect() {
|
||||||
|
const msgFunctionMap: Record<string, Function> = {};
|
||||||
|
msgFunctionMap[Msg.TreeInfo] = this._onMsgTreeInfo;
|
||||||
|
msgFunctionMap[Msg.Support] = this._onMsgSupport;
|
||||||
|
msgFunctionMap[Msg.NodeInfo] = this._onMsgNodeInfo;
|
||||||
|
msgFunctionMap[Msg.MemoryInfo] = this._onMsgMemoryInfo;
|
||||||
|
msgFunctionMap[Msg.UpdateProperty] = this._onMsgUpdateProperty;
|
||||||
|
msgFunctionMap[Msg.UpdateFrames] = this._onMsgUpdateFrames;
|
||||||
|
msgFunctionMap[Msg.GetObjectItemData] = this._onMsgGetObjectItemData;
|
||||||
|
// 接收来自background.js的消息数据
|
||||||
|
connectBackground.onBackgroundMessage(
|
||||||
|
(data: PluginEvent, sender: any) => {
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.target === Page.Devtools) {
|
||||||
|
console.log("[Devtools]", data);
|
||||||
|
PluginEvent.finish(data);
|
||||||
|
const { msg } = data;
|
||||||
|
if (msg) {
|
||||||
|
const func = msgFunctionMap[msg];
|
||||||
|
if (func) {
|
||||||
|
func(data.data);
|
||||||
|
} else {
|
||||||
|
console.warn(`没有${msg}消息的函数`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (chrome && chrome.runtime) {
|
||||||
|
_initChromeRuntimeConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
"message",
|
||||||
|
function (event) {
|
||||||
|
console.log("on vue:" + JSON.stringify(event));
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
Bus.on(BusMsg.ShowPlace, (data: EngineData) => {
|
||||||
|
console.log(data);
|
||||||
|
_expand(data.engineUUID);
|
||||||
|
});
|
||||||
|
Bus.on(BusMsg.RequestObjectData, (data: ObjectData, cb: Function) => {
|
||||||
|
if (!data.id || requestList.find((el) => el.id === data.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestList.push({ id: data.id, cb });
|
||||||
|
sendMsgToContentScript(Msg.GetObjectItemData, data);
|
||||||
|
});
|
||||||
|
Bus.on(BusMsg.LogData, (data: string[]) => {
|
||||||
|
sendMsgToContentScript(Msg.LogData, data);
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
syncSettings();
|
||||||
|
});
|
||||||
|
const treeData = ref<Array<TreeData>>([]);
|
||||||
|
const expandedKeys = ref<Array<string>>([]);
|
||||||
|
const memory = ref<{
|
||||||
|
performance: {
|
||||||
|
jsHeapSizeLimit?: number;
|
||||||
|
totalJSHeapSize?: number;
|
||||||
|
usedJSHeapSize?: number;
|
||||||
|
};
|
||||||
|
console: Object;
|
||||||
|
}>({
|
||||||
|
performance: {},
|
||||||
|
console: {},
|
||||||
|
});
|
||||||
|
// el-tree的渲染key
|
||||||
|
const defaultProps = ref<{ children: string; label: string }>({
|
||||||
|
children: "children",
|
||||||
|
label: "name",
|
||||||
|
});
|
||||||
|
const filterText = ref<string>("");
|
||||||
|
watch(filterText, (val) => {
|
||||||
|
// TODO: 过滤树
|
||||||
|
updateFilterText(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
const matchCase = ref<boolean>(false);
|
||||||
|
|
||||||
|
function onEnableTreeWatch(watch: boolean, time = 300) {
|
||||||
|
if (watch) {
|
||||||
|
this._clearTimer();
|
||||||
|
this.timerID = setInterval(() => {
|
||||||
|
this.onBtnClickUpdateTree();
|
||||||
|
}, time);
|
||||||
|
} else {
|
||||||
|
this._clearTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let timerID: number | null = null;
|
||||||
|
|
||||||
|
function _clearTimer() {
|
||||||
|
if (this.timerID !== null) {
|
||||||
|
clearInterval(this.timerID);
|
||||||
|
this.timerID = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function syncSettings() {
|
||||||
|
if (settings.data) {
|
||||||
|
const { refreshType, refreshTime } = settings.data;
|
||||||
|
switch (refreshType) {
|
||||||
|
case RefreshType.Auto: {
|
||||||
|
this.isShowRefreshBtn = false;
|
||||||
|
this.onEnableTreeWatch(true, refreshTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RefreshType.Manual: {
|
||||||
|
this.isShowRefreshBtn = true;
|
||||||
|
this.onEnableTreeWatch(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateNodeInfo() {
|
||||||
|
if (this.selectedUUID) {
|
||||||
|
sendMsgToContentScript(Msg.NodeInfo, this.selectedUUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let selectedUUID: string | null = null;
|
||||||
|
function updateFilterText(val: any) {
|
||||||
|
(this.$refs?.tree as any)?.filter(val);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
memory,
|
||||||
|
defaultProps,
|
||||||
|
filterText,
|
||||||
|
matchCase,
|
||||||
|
expandedKeys,
|
||||||
|
treeData,
|
||||||
|
onChangeCase() {
|
||||||
|
this.matchCase = !this.matchCase;
|
||||||
|
updateFilterText(this.filterText);
|
||||||
|
},
|
||||||
|
handleNodeClick(data: TreeData) {
|
||||||
|
this.selectedUUID = data.uuid;
|
||||||
|
this.updateNodeInfo();
|
||||||
|
},
|
||||||
|
filterNode(value: any, data: any) {
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (this.matchCase) {
|
||||||
|
// 严格匹配大写
|
||||||
|
return data?.name?.indexOf(value) !== -1;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
data?.name?.toLowerCase().indexOf(value.toLowerCase()) !== -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDividerMove(event: MouseEvent) {
|
||||||
|
const leftDiv: HTMLDivElement = this.$refs.left as HTMLDivElement;
|
||||||
|
if (leftDiv) {
|
||||||
|
let width = leftDiv.clientWidth;
|
||||||
|
width += event.movementX;
|
||||||
|
if (width >= 300 && width < document.body.clientWidth - 100) {
|
||||||
|
leftDiv.style.width = `${width}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onBtnClickUpdateTree() {
|
||||||
|
sendMsgToContentScript(Msg.TreeInfo, this.frameID);
|
||||||
|
},
|
||||||
|
|
||||||
|
onBtnClickUpdatePage() {
|
||||||
|
sendMsgToContentScript(Msg.Support);
|
||||||
|
},
|
||||||
|
onCloseSettings() {
|
||||||
|
syncSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
onMemoryTest() {
|
||||||
|
sendMsgToContentScript(Msg.MemoryInfo);
|
||||||
|
},
|
||||||
|
onClickSettings() {
|
||||||
|
this.showSettings = true;
|
||||||
|
},
|
||||||
|
onChangeFrame() {
|
||||||
|
sendMsgToContentScript(Msg.UseFrame, this.frameID);
|
||||||
|
},
|
||||||
|
onNodeExpand(data: TreeData) {
|
||||||
|
if (data.hasOwnProperty("uuid") && data.uuid) {
|
||||||
|
this.expandedKeys.push(data.uuid);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onNodeCollapse(data: TreeData) {
|
||||||
|
if (data.hasOwnProperty("uuid")) {
|
||||||
|
let index = this.expandedKeys.findIndex((el) => el === data.uuid);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.expandedKeys.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
@import "../../index.less";
|
||||||
|
|
||||||
|
#devtools {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.head {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1px 0;
|
||||||
|
border-bottom: solid 1px grey;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin: 0 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.no-find {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.find {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
.tool-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matchCase {
|
||||||
|
width: 30px;
|
||||||
|
height: 26px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeList {
|
||||||
|
margin-top: 3px;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-height: 20px;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.leaf {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaf-show {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaf-hide {
|
||||||
|
color: #c7bbbb;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background: #999;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
flex: 1;
|
||||||
|
background: #e5e9f2;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: overlay;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
background: #999;
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,33 +1,31 @@
|
|||||||
import Manifest from '../manifest.json'
|
import { ChromeConst } from "cc-plugin/src/chrome/const";
|
||||||
import {connectBackground} from "@/devtools/connectBackground";
|
import { connectBackground } from "./connectBackground";
|
||||||
import {PluginEvent, Msg, Page} from "@/core/types";
|
import { PluginEvent, Msg, Page } from "../../core/types";
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
if (chrome && chrome.devtools) {
|
if (chrome && chrome.devtools) {
|
||||||
// 对应的是Elements面板的边栏
|
// 对应的是Elements面板的边栏
|
||||||
chrome.devtools.panels.elements.createSidebarPane('Cocos', function (sidebar) {
|
chrome.devtools.panels.elements.createSidebarPane('Cocos', function (sidebar) {
|
||||||
sidebar.setObject({some_data: "some data to show!"});
|
sidebar.setObject({ some_data: "some data to show!" });
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建devtools-panel
|
// 创建devtools-panel
|
||||||
chrome.devtools.panels.create("Cocos", "icons/48.png", Manifest.devtools_page, (panel: chrome.devtools.panels.ExtensionPanel) => {
|
chrome.devtools.panels.create("Cocos", "icons/48.png", ChromeConst.html.devtools, (panel: chrome.devtools.panels.ExtensionPanel) => {
|
||||||
console.log("[CC-Inspector] Dev Panel Created!");
|
console.log("[CC-Inspector] Dev Panel Created!");
|
||||||
panel.onShown.addListener((window) => {
|
panel.onShown.addListener((window) => {
|
||||||
// 面板显示,查询是否是cocos游戏
|
// 面板显示,查询是否是cocos游戏
|
||||||
console.log("panel show");
|
console.log("panel show");
|
||||||
// connectBackground.postMessageToBackground(Msg.Support, null)
|
// connectBackground.postMessageToBackground(Msg.Support, null)
|
||||||
});
|
});
|
||||||
panel.onHidden.addListener(() => {
|
panel.onHidden.addListener(() => {
|
||||||
// 面板隐藏
|
// 面板隐藏
|
||||||
console.log("panel hide");
|
console.log("panel hide");
|
||||||
});
|
});
|
||||||
panel.onSearch.addListener(function (action, query) {
|
panel.onSearch.addListener(function (action, query) {
|
||||||
// ctrl+f 查找触发
|
// ctrl+f 查找触发
|
||||||
console.log("panel search!");
|
console.log("panel search!");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
|||||||
const Key = "settings";
|
const Key = "settings";
|
||||||
|
|
||||||
export const RefreshManual = "manual";
|
export const enum RefreshType{
|
||||||
export const RefreshAuto = "auto";
|
Auto = "auto",
|
||||||
|
Manual = "manual",
|
||||||
|
}
|
||||||
|
|
||||||
interface SettingsData {
|
interface SettingsData {
|
||||||
refreshType: string;
|
refreshType: string;
|
||||||
@ -10,7 +12,7 @@ interface SettingsData {
|
|||||||
|
|
||||||
let defaultData: SettingsData = {
|
let defaultData: SettingsData = {
|
||||||
refreshTime: 500,
|
refreshTime: 500,
|
||||||
refreshType: RefreshManual,
|
refreshType: RefreshType.Manual,
|
||||||
}
|
}
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
@ -33,7 +35,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isManualRefresh() {
|
isManualRefresh() {
|
||||||
return this.data?.refreshType === RefreshManual;
|
return this.data?.refreshType === RefreshType.Manual;
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
|
@ -1,631 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div id="devtools">
|
|
||||||
<el-drawer
|
|
||||||
title="settings"
|
|
||||||
direction="btt"
|
|
||||||
@close="onCloseSettings"
|
|
||||||
:visible.sync="showSettings">
|
|
||||||
<div>
|
|
||||||
<settings-vue></settings-vue>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
<div class="head" v-show="iframes.length>1">
|
|
||||||
<div class="label">inspect target:</div>
|
|
||||||
<el-select v-model="frameID" placeholder="please select ..." @change="onChangeFrame" style="flex:1;">
|
|
||||||
<el-option v-for="item in iframes" :key="item.value" :label="item.label" :value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div v-show="isShowDebug" class="find">
|
|
||||||
<div v-if="false">
|
|
||||||
<el-button type="success" @click="onMemoryTest">内存测试</el-button>
|
|
||||||
</div>
|
|
||||||
<div v-if="false">
|
|
||||||
<span>JS堆栈限制: {{ memory.performance.jsHeapSizeLimit }}</span>
|
|
||||||
<span>JS堆栈大小: {{ memory.performance.totalJSHeapSize }}</span>
|
|
||||||
<span>JS堆栈使用: {{ memory.performance.usedJSHeapSize }}</span>
|
|
||||||
</div>
|
|
||||||
<div ref="left" class="left">
|
|
||||||
<div class="tool-btn">
|
|
||||||
<div style="padding-left: 15px;flex:1;">Node Tree</div>
|
|
||||||
<el-button v-show="isShowRefreshBtn" type="success" class="el-icon-refresh"
|
|
||||||
size="mini"
|
|
||||||
@click="onBtnClickUpdateTree"></el-button>
|
|
||||||
<el-button @click="onClickSettings" class="el-icon-s-tools"></el-button>
|
|
||||||
</div>
|
|
||||||
<el-input placeholder="enter keywords to filter" v-model="filterText">
|
|
||||||
<template slot="append">
|
|
||||||
<div class="matchCase ">
|
|
||||||
<div class="iconfont el-icon-third-font-size" @click.stop="onChangeCase"
|
|
||||||
title="match case"
|
|
||||||
:style="{'color':matchCase?'red':''}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<div class="treeList">
|
|
||||||
<el-tree :data="treeData"
|
|
||||||
ref="tree"
|
|
||||||
style="display: inline-block;"
|
|
||||||
:props="defaultProps"
|
|
||||||
:highlight-current="true"
|
|
||||||
:default-expand-all="false"
|
|
||||||
:default-expanded-keys="expandedKeys"
|
|
||||||
:filter-node-method="filterNode"
|
|
||||||
:expand-on-click-node="false"
|
|
||||||
node-key="uuid"
|
|
||||||
@node-expand="onNodeExpand"
|
|
||||||
@node-collapse="onNodeCollapse"
|
|
||||||
@node-click="handleNodeClick">
|
|
||||||
<!-- :render-content="renderContent"-->
|
|
||||||
|
|
||||||
<span slot-scope="{node,data}" class="leaf" :class="data.active?'leaf-show':'leaf-hide'">
|
|
||||||
<span>{{ node.label }}</span>
|
|
||||||
<!-- <el-button v-if="!!data||true"> 显示</el-button>-->
|
|
||||||
</span>
|
|
||||||
</el-tree>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ui-divider ref="divider" @move="onDividerMove"></ui-divider>
|
|
||||||
<div ref="right" class="right">
|
|
||||||
<properties v-if="treeItemData" :data="treeItemData"></properties>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-show="!isShowDebug" class="no-find">
|
|
||||||
<span>No games created by cocos creator found!</span>
|
|
||||||
<el-button type="success" class="el-icon-refresh" @click="onBtnClickUpdatePage">刷新</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from "vue";
|
|
||||||
import {Component, Watch} from "vue-property-decorator";
|
|
||||||
import properties from "./propertys.vue";
|
|
||||||
import {Msg, Page, PluginEvent} from "@/core/types"
|
|
||||||
import {connectBackground} from "@/devtools/connectBackground";
|
|
||||||
import {
|
|
||||||
EngineData,
|
|
||||||
FrameDetails,
|
|
||||||
Info,
|
|
||||||
NodeInfoData,
|
|
||||||
ObjectData,
|
|
||||||
ObjectItemRequestData,
|
|
||||||
TreeData
|
|
||||||
} from "@/devtools/data";
|
|
||||||
import Bus, {BusMsg} from "@/devtools/bus";
|
|
||||||
import settingsVue from "./settings.vue"
|
|
||||||
import {RefreshAuto, RefreshManual, settings} from "@/devtools/settings";
|
|
||||||
import UiDivider from "@/devtools/ui/ui-divider.vue";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
components: {
|
|
||||||
UiDivider,
|
|
||||||
properties,
|
|
||||||
settingsVue,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
export default class Index extends Vue {
|
|
||||||
private isShowDebug: boolean = false;
|
|
||||||
treeItemData: NodeInfoData | null = null;
|
|
||||||
treeData: Array<TreeData> = []
|
|
||||||
expandedKeys: Array<string> = [];
|
|
||||||
selectedUUID: string | null = null;
|
|
||||||
|
|
||||||
filterText: string | null = null;
|
|
||||||
|
|
||||||
iframes: Array<{ label: string, value: number }> = []
|
|
||||||
frameID: number | null = null;
|
|
||||||
|
|
||||||
@Watch("filterText")
|
|
||||||
updateFilterText(val: any) {
|
|
||||||
(this.$refs?.tree as any)?.filter(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
private matchCase = false;
|
|
||||||
|
|
||||||
onChangeCase() {
|
|
||||||
this.matchCase = !this.matchCase;
|
|
||||||
this.updateFilterText(this.filterText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private showSettings = false;
|
|
||||||
|
|
||||||
onClickSettings() {
|
|
||||||
this.showSettings = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDividerMove(event: MouseEvent) {
|
|
||||||
const leftDiv: HTMLDivElement = this.$refs.left as HTMLDivElement;
|
|
||||||
if (leftDiv) {
|
|
||||||
let width = leftDiv.clientWidth;
|
|
||||||
width += event.movementX;
|
|
||||||
if (width >= 300 && width < document.body.clientWidth - 100) {
|
|
||||||
leftDiv.style.width = `${width}px`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private syncSettings() {
|
|
||||||
if (settings.data) {
|
|
||||||
const {refreshType, refreshTime} = settings.data;
|
|
||||||
switch (refreshType) {
|
|
||||||
case RefreshAuto: {
|
|
||||||
this.isShowRefreshBtn = false;
|
|
||||||
this.onEnableTreeWatch(true, refreshTime)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RefreshManual: {
|
|
||||||
this.isShowRefreshBtn = true;
|
|
||||||
this.onEnableTreeWatch(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private isShowRefreshBtn = false;
|
|
||||||
|
|
||||||
onCloseSettings() {
|
|
||||||
this.syncSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// el-tree的渲染key
|
|
||||||
defaultProps = {
|
|
||||||
children: "children",
|
|
||||||
label: "name"
|
|
||||||
};
|
|
||||||
memory = {
|
|
||||||
performance: {},
|
|
||||||
console: {},
|
|
||||||
}
|
|
||||||
timerID: number | null = null;
|
|
||||||
|
|
||||||
|
|
||||||
private requestList: Array<{ id: string, cb: Function }> = [];
|
|
||||||
|
|
||||||
created() {
|
|
||||||
if (chrome && chrome.runtime) {
|
|
||||||
this._initChromeRuntimeConnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("message", function (event) {
|
|
||||||
console.log("on vue:" + JSON.stringify(event));
|
|
||||||
}, false);
|
|
||||||
Bus.$on(BusMsg.ShowPlace, (data: EngineData) => {
|
|
||||||
console.log(data)
|
|
||||||
this._expand(data.engineUUID);
|
|
||||||
})
|
|
||||||
Bus.$on(BusMsg.RequestObjectData, (data: ObjectData, cb: Function) => {
|
|
||||||
if (!data.id || this.requestList.find(el => el.id === data.id)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.requestList.push({id: data.id, cb});
|
|
||||||
this.sendMsgToContentScript(Msg.GetObjectItemData, data)
|
|
||||||
});
|
|
||||||
Bus.$on(BusMsg.LogData, (data: string[]) => {
|
|
||||||
this.sendMsgToContentScript(Msg.LogData, data);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
filterNode(value: any, data: any) {
|
|
||||||
if (!value) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (this.matchCase) {
|
|
||||||
// 严格匹配大写
|
|
||||||
return data?.name?.indexOf(value) !== -1;
|
|
||||||
} else {
|
|
||||||
return data?.name?.toLowerCase().indexOf(value.toLowerCase()) !== -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeFrame() {
|
|
||||||
this.sendMsgToContentScript(Msg.UseFrame, this.frameID)
|
|
||||||
}
|
|
||||||
|
|
||||||
_expand(uuid: string) {
|
|
||||||
|
|
||||||
let expandKeys: Array<string> = [];
|
|
||||||
|
|
||||||
function circle(array: any) {
|
|
||||||
for (let i = 0; i < array.length; i++) {
|
|
||||||
let item = array[i];
|
|
||||||
expandKeys.push(item.uuid);
|
|
||||||
if (item.uuid === uuid) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
let find = circle(item.children);
|
|
||||||
if (find) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
expandKeys.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
circle(this.treeData)
|
|
||||||
|
|
||||||
expandKeys.forEach(key => {
|
|
||||||
if (!this.expandedKeys.find(el => el === key)) {
|
|
||||||
this.expandedKeys.push(key)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 高亮uuid
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
renderContent(h: Function, options: any) {
|
|
||||||
let {node, data, store} = options;
|
|
||||||
return h("span", {class: ""}, data.name)
|
|
||||||
// return(<span>1111</span>)
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgTreeInfo(treeData: Array<TreeData>) {
|
|
||||||
this.isShowDebug = true;
|
|
||||||
if (!Array.isArray(treeData)) {
|
|
||||||
treeData = [treeData]
|
|
||||||
}
|
|
||||||
this.treeData = treeData;
|
|
||||||
if (this._checkSelectedUUID()) {
|
|
||||||
this.updateNodeInfo();
|
|
||||||
this.$nextTick(() => {
|
|
||||||
//@ts-ignore
|
|
||||||
this.$refs.tree.setCurrentKey(this.selectedUUID);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_checkSelectedUUID() {
|
|
||||||
if (this.selectedUUID) {
|
|
||||||
const b = this._findUuidInTree(this.treeData, this.selectedUUID)
|
|
||||||
if (b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.selectedUUID = null;
|
|
||||||
this.treeItemData = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_findUuidInTree(data: TreeData[], targetUUID: string) {
|
|
||||||
|
|
||||||
function circle(tree: TreeData[]) {
|
|
||||||
for (let i = 0; i < tree.length; i++) {
|
|
||||||
let item: TreeData = tree[i];
|
|
||||||
if (item.uuid === targetUUID) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (circle(item.children)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return circle(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgNodeInfo(eventData: NodeInfoData) {
|
|
||||||
this.isShowDebug = true;
|
|
||||||
this.treeItemData = eventData;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgMemoryInfo(eventData: any) {
|
|
||||||
this.memory = eventData;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgSupport(isCocosGame: boolean) {
|
|
||||||
this.isShowDebug = isCocosGame;
|
|
||||||
if (isCocosGame) {
|
|
||||||
this.syncSettings();
|
|
||||||
this.onBtnClickUpdateTree();
|
|
||||||
} else {
|
|
||||||
this._clearTimer();
|
|
||||||
this.treeData = [];
|
|
||||||
this.treeItemData = null;
|
|
||||||
this.selectedUUID = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.syncSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
_initChromeRuntimeConnect() {
|
|
||||||
const msgFunctionMap: Record<string, Function> = {};
|
|
||||||
msgFunctionMap[Msg.TreeInfo] = this._onMsgTreeInfo;
|
|
||||||
msgFunctionMap[Msg.Support] = this._onMsgSupport;
|
|
||||||
msgFunctionMap[Msg.NodeInfo] = this._onMsgNodeInfo;
|
|
||||||
msgFunctionMap[Msg.MemoryInfo] = this._onMsgMemoryInfo;
|
|
||||||
msgFunctionMap[Msg.UpdateProperty] = this._onMsgUpdateProperty;
|
|
||||||
msgFunctionMap[Msg.UpdateFrames] = this._onMsgUpdateFrames;
|
|
||||||
msgFunctionMap[Msg.GetObjectItemData] = this._onMsgGetObjectItemData;
|
|
||||||
// 接收来自background.js的消息数据
|
|
||||||
connectBackground.onBackgroundMessage((data: PluginEvent, sender: any) => {
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.target === Page.Devtools) {
|
|
||||||
console.log("[Devtools]", data);
|
|
||||||
PluginEvent.finish(data);
|
|
||||||
const {msg} = data;
|
|
||||||
if (msg) {
|
|
||||||
const func = msgFunctionMap[msg];
|
|
||||||
if (func) {
|
|
||||||
func(data.data)
|
|
||||||
} else {
|
|
||||||
console.warn(`没有${msg}消息的函数`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgGetObjectItemData(requestData: ObjectItemRequestData) {
|
|
||||||
if (requestData.id !== null) {
|
|
||||||
let findIndex = this.requestList.findIndex(el => el.id === requestData.id)
|
|
||||||
if (findIndex > -1) {
|
|
||||||
let del = this.requestList.splice(findIndex, 1)[0];
|
|
||||||
del.cb(requestData.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgUpdateFrames(details: FrameDetails[]) {
|
|
||||||
// 先把iframes里面无效的清空了
|
|
||||||
this.iframes = this.iframes.filter(item => {
|
|
||||||
details.find(el => el.frameID === item.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 同步配置
|
|
||||||
details.forEach(item => {
|
|
||||||
let findItem = this.iframes.find(el => el.value === item.frameID);
|
|
||||||
if (findItem) {
|
|
||||||
findItem.label = item.url;
|
|
||||||
} else {
|
|
||||||
this.iframes.push({
|
|
||||||
label: item.url,
|
|
||||||
value: item.frameID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 第一次获取到frame配置后,自动获取frame数据
|
|
||||||
if (this.frameID === null && this.iframes.length > 0 && !this.iframes.find(el => el.value === this.frameID)) {
|
|
||||||
this.frameID = this.iframes[0].value;
|
|
||||||
this.onChangeFrame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMsgUpdateProperty(data: Info) {
|
|
||||||
const uuid = data.path[0];
|
|
||||||
const key = data.path[1];
|
|
||||||
const value = data.data;
|
|
||||||
let treeArray: Array<TreeData> = [];
|
|
||||||
|
|
||||||
function circle(array: Array<TreeData>) {
|
|
||||||
array.forEach(item => {
|
|
||||||
treeArray.push(item);
|
|
||||||
circle(item.children);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新指定uuid节点的tree的name
|
|
||||||
circle(this.treeData)
|
|
||||||
let ret = treeArray.find(el => el.uuid === uuid);
|
|
||||||
if (ret) {
|
|
||||||
if (key === "name") {
|
|
||||||
ret.name = value;
|
|
||||||
}
|
|
||||||
if (key === "active") {
|
|
||||||
ret.active = !!value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNodeClick(data: TreeData) {
|
|
||||||
this.selectedUUID = data.uuid;
|
|
||||||
this.updateNodeInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateNodeInfo() {
|
|
||||||
if (this.selectedUUID) {
|
|
||||||
this.sendMsgToContentScript(Msg.NodeInfo, this.selectedUUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onEnableTreeWatch(watch: boolean, time = 300) {
|
|
||||||
if (watch) {
|
|
||||||
this._clearTimer();
|
|
||||||
this.timerID = setInterval(() => {
|
|
||||||
this.onBtnClickUpdateTree();
|
|
||||||
}, time);
|
|
||||||
} else {
|
|
||||||
this._clearTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _clearTimer() {
|
|
||||||
if (this.timerID !== null) {
|
|
||||||
clearInterval(this.timerID);
|
|
||||||
this.timerID = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMsgToContentScript(msg: Msg, data?: any) {
|
|
||||||
if (!chrome || !chrome.devtools) {
|
|
||||||
console.log("环境异常,无法执行函数");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
connectBackground.postMessageToBackground(msg, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 问题:没有上下文的权限,只能操作DOM
|
|
||||||
_executeScript(para: Object) {
|
|
||||||
let tabID = chrome.devtools.inspectedWindow.tabId;
|
|
||||||
//@ts-ignore
|
|
||||||
chrome.tabs.executeScript(tabID, {code: `var CCInspectorPara='${JSON.stringify(para)}';`}, () => {
|
|
||||||
//@ts-ignore
|
|
||||||
chrome.tabs.executeScript(tabID, {file: "js/execute.js"})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_inspectedCode() {
|
|
||||||
let injectCode = "";
|
|
||||||
chrome.devtools.inspectedWindow.eval(injectCode, (result, isException) => {
|
|
||||||
if (isException) {
|
|
||||||
console.error(isException);
|
|
||||||
} else {
|
|
||||||
console.log(`执行结果:${result}`)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onBtnClickUpdateTree() {
|
|
||||||
this.sendMsgToContentScript(Msg.TreeInfo, this.frameID);
|
|
||||||
}
|
|
||||||
|
|
||||||
onBtnClickUpdatePage() {
|
|
||||||
this.sendMsgToContentScript(Msg.Support);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMemoryTest() {
|
|
||||||
this.sendMsgToContentScript(Msg.MemoryInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
onNodeExpand(data: TreeData) {
|
|
||||||
if (data.hasOwnProperty("uuid") && data.uuid) {
|
|
||||||
this.expandedKeys.push(data.uuid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onNodeCollapse(data: TreeData) {
|
|
||||||
if (data.hasOwnProperty("uuid")) {
|
|
||||||
let index = this.expandedKeys.findIndex(el => el === data.uuid);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.expandedKeys.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
@import "../../index.less";
|
|
||||||
|
|
||||||
#devtools {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.head {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1px 0;
|
|
||||||
border-bottom: solid 1px grey;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
margin: 0 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-find {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.find {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: row;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 300px;
|
|
||||||
|
|
||||||
.tool-btn {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.matchCase {
|
|
||||||
width: 30px;
|
|
||||||
height: 26px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.treeList {
|
|
||||||
margin-top: 3px;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 4px;
|
|
||||||
min-height: 20px;
|
|
||||||
overflow: auto;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.leaf {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaf-show {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaf-hide {
|
|
||||||
color: #c7bbbb;
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
background: #999;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #333;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
flex: 1;
|
|
||||||
background: #e5e9f2;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: overlay;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
background: #999;
|
|
||||||
border-radius: 2px;
|
|
||||||
height: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #333;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,67 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="property-group">
|
<div class="property-group">
|
||||||
<div class="header" @click="onClickHeader"
|
<div
|
||||||
@mouseenter="showLogBtn=true"
|
class="header"
|
||||||
@mouseleave="showLogBtn=false">
|
@click="onClickHeader"
|
||||||
<div style="margin: 0 5px;">
|
@mouseenter="showLogBtn = true"
|
||||||
|
@mouseleave="showLogBtn = false"
|
||||||
|
>
|
||||||
|
<div style="margin: 0 5px">
|
||||||
<i v-if="fold" class="el-icon-caret-right"></i>
|
<i v-if="fold" class="el-icon-caret-right"></i>
|
||||||
<i v-if="!fold" class="el-icon-caret-bottom"></i>
|
<i v-if="!fold" class="el-icon-caret-bottom"></i>
|
||||||
</div>
|
</div>
|
||||||
<div style="flex:1;">
|
<div style="flex: 1">
|
||||||
{{ group.name }}
|
{{ group.name }}
|
||||||
</div>
|
</div>
|
||||||
<el-button style="margin-right: 10px;"
|
<el-button
|
||||||
v-show="showLogBtn"
|
style="margin-right: 10px"
|
||||||
type="success" icon="el-icon-chat-dot-round" @click.stop="onLog">
|
v-show="showLogBtn"
|
||||||
|
type="success"
|
||||||
|
icon="el-icon-chat-dot-round"
|
||||||
|
@click.stop="onLog"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" v-show="!fold">
|
<div class="content" v-show="!fold">
|
||||||
<ui-prop v-for="(item, index) in group.data" :key="index"
|
<ui-prop
|
||||||
:name="item.name" :value="item.value">
|
v-for="(item, index) in group.data"
|
||||||
|
:key="index"
|
||||||
|
:name="item.name"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
</ui-prop>
|
</ui-prop>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import { defineComponent, ref, PropType } from "vue";
|
||||||
import Component from "vue-class-component";
|
import { Group } from "../data";
|
||||||
import {Prop} from "vue-property-decorator";
|
import UiProp from "./ui-prop.vue";
|
||||||
import {Group} from "@/devtools/data";
|
import Bus, { BusMsg } from "../bus";
|
||||||
import UiProp from "@/devtools/ui/ui-prop.vue";
|
|
||||||
import Bus, {BusMsg} from "@/devtools/bus";
|
|
||||||
|
|
||||||
@Component({
|
export default defineComponent({
|
||||||
name: "property-group",
|
name: "property-group",
|
||||||
components: {UiProp}
|
components: { UiProp },
|
||||||
})
|
props: {
|
||||||
export default class PropertyGroup extends Vue {
|
group: {
|
||||||
private fold = false;
|
type: Object as PropType<Group>,
|
||||||
private showLogBtn = false;
|
default: () => {
|
||||||
@Prop({
|
return new Group("test");
|
||||||
default: () => {
|
},
|
||||||
return new Group("test")
|
},
|
||||||
}
|
},
|
||||||
})
|
setup(props, context) {
|
||||||
group!: Group;
|
Bus.on(BusMsg.FoldAllGroup, (b: boolean) => {
|
||||||
|
fold.value = b;
|
||||||
|
});
|
||||||
|
const fold = ref(false);
|
||||||
|
const showLogBtn = ref(false);
|
||||||
|
return {
|
||||||
|
showLogBtn,
|
||||||
|
fold,
|
||||||
|
onLog() {
|
||||||
|
Bus.emit(BusMsg.LogData, [props.group.id]);
|
||||||
|
},
|
||||||
|
|
||||||
created() {
|
onClickHeader() {
|
||||||
Bus.$on(BusMsg.FoldAllGroup, (b: boolean) => {
|
fold.value = !fold.value;
|
||||||
this.fold = b;
|
},
|
||||||
})
|
};
|
||||||
}
|
},
|
||||||
|
});
|
||||||
mounted() {
|
|
||||||
}
|
|
||||||
|
|
||||||
onLog() {
|
|
||||||
Bus.$emit(BusMsg.LogData, [this.group.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickHeader() {
|
|
||||||
this.fold = !this.fold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -1,54 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="prop">
|
<div id="prop">
|
||||||
<property-group v-for="(group, index) in data.group" :key="index" :group="group"></property-group>
|
<PropertyGroup
|
||||||
|
v-for="(group, index) in data.group"
|
||||||
|
:key="index"
|
||||||
|
:group="group"
|
||||||
|
></PropertyGroup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue"
|
import { defineComponent, PropType, watch } from "vue";
|
||||||
|
import UiProp from "./ui-prop.vue";
|
||||||
|
import { Group, NodeInfoData } from "../data";
|
||||||
|
import PropertyGroup from "../ui/property-group.vue";
|
||||||
|
import Bus, { BusMsg } from "../bus";
|
||||||
|
|
||||||
import {Component, Prop, Watch} from "vue-property-decorator"
|
export default defineComponent({
|
||||||
import UiProp from "./ui-prop.vue"
|
components: { PropertyGroup, UiProp },
|
||||||
import {Group, NodeInfoData} from "@/devtools/data";
|
props: {
|
||||||
import PropertyGroup from "@/devtools/ui/property-group.vue";
|
data: {
|
||||||
import Bus, {BusMsg} from "@/devtools/bus";
|
type: Object as PropType<NodeInfoData>,
|
||||||
|
default: () => {
|
||||||
@Component({
|
return {};
|
||||||
components: {PropertyGroup, UiProp},
|
},
|
||||||
})
|
},
|
||||||
export default class properties extends Vue {
|
},
|
||||||
@Prop({
|
setup(props, context) {
|
||||||
default: () => {
|
function _evalCode(code: string) {
|
||||||
return {};
|
if (chrome && chrome.devtools) {
|
||||||
|
chrome.devtools.inspectedWindow.eval(code);
|
||||||
|
} else {
|
||||||
|
console.log(code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
watch(props.data, (newValue: NodeInfoData, oldValue: NodeInfoData) => {
|
||||||
data!: NodeInfoData;
|
if (newValue.uuid !== oldValue.uuid) {
|
||||||
|
// 切换node,全部展开属性
|
||||||
|
Bus.emit(BusMsg.FoldAllGroup, false);
|
||||||
@Watch("data")
|
}
|
||||||
watchData(newValue: NodeInfoData, oldValue: NodeInfoData) {
|
});
|
||||||
if (newValue.uuid !== oldValue.uuid) {
|
return {};
|
||||||
// 切换node,全部展开属性
|
},
|
||||||
Bus.$emit(BusMsg.FoldAllGroup, false)
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_evalCode(code: string) {
|
|
||||||
if (chrome && chrome.devtools) {
|
|
||||||
chrome.devtools.inspectedWindow.eval(code);
|
|
||||||
} else {
|
|
||||||
console.log(code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
#prop {
|
#prop {
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -6,24 +6,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import { defineComponent } from "vue";
|
||||||
import Component from "vue-class-component";
|
|
||||||
import {Prop} from "vue-property-decorator";
|
|
||||||
|
|
||||||
@Component({
|
export default defineComponent({
|
||||||
name: "SettingsProp",
|
name: "SettingsProp",
|
||||||
components: {}
|
props: {
|
||||||
})
|
label: {
|
||||||
export default class SettingsProp extends Vue {
|
type: String,
|
||||||
@Prop()
|
default: "",
|
||||||
label!: string;
|
},
|
||||||
|
},
|
||||||
created() {
|
});
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<settings-prop label="refresh">
|
<settings-prop label="refresh">
|
||||||
<el-select v-model="refreshType" @change="onCommonSave" style="flex:1;">
|
<el-select v-model="refreshType" @change="onCommonSave" style="flex: 1">
|
||||||
<el-option v-for="item in refreshOptions" :key="item.value" :label="item.label" :value="item.value">
|
<el-option
|
||||||
|
v-for="item in refreshOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</settings-prop>
|
</settings-prop>
|
||||||
<settings-prop label="refresh time: " v-show="isRefreshAuto()">
|
<settings-prop label="refresh time: " v-show="isRefreshAuto()">
|
||||||
<el-input-number style="flex:1;" :min=100 v-model="refreshTime" @change="onCommonSave"></el-input-number>
|
<el-input-number
|
||||||
|
style="flex: 1"
|
||||||
|
:min="100"
|
||||||
|
v-model="refreshTime"
|
||||||
|
@change="onCommonSave"
|
||||||
|
></el-input-number>
|
||||||
<span>ms</span>
|
<span>ms</span>
|
||||||
</settings-prop>
|
</settings-prop>
|
||||||
|
|
||||||
@ -22,54 +32,42 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import { defineComponent, onMounted, ref, toRaw } from "vue";
|
||||||
import Component from "vue-class-component";
|
import { RefreshType, settings } from "../settings";
|
||||||
import {Prop} from "vue-property-decorator";
|
import SettingsProp from "./settings-prop.vue";
|
||||||
import {RefreshAuto, RefreshManual, settings} from "@/devtools/settings";
|
|
||||||
import SettingsProp from "@/devtools/ui/settings-prop.vue";
|
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
@Component({
|
name: "settings",
|
||||||
name: "Settings",
|
components: { SettingsProp },
|
||||||
components: {SettingsProp}
|
props: {},
|
||||||
})
|
setup(props, ctx) {
|
||||||
export default class Settings extends Vue {
|
const refreshOptions = ref<Array<{ label: string; value: RefreshType }>>([
|
||||||
name: string = "settings";
|
{ label: "auto", value: RefreshType.Auto },
|
||||||
refreshOptions = [
|
{ label: "manual", value: RefreshType.Manual },
|
||||||
{label: "auto", value: RefreshAuto},
|
]);
|
||||||
{label: "manual", value: RefreshManual}
|
const refreshType = ref(settings.data?.refreshType || "");
|
||||||
]
|
const refreshTime = ref(settings.data?.refreshTime || 500);
|
||||||
refreshType = "";
|
return {
|
||||||
refreshTime = 500;
|
refreshType,
|
||||||
|
refreshTime,
|
||||||
isRefreshAuto() {
|
refreshOptions,
|
||||||
return this.refreshType === RefreshAuto;
|
isRefreshAuto() {
|
||||||
}
|
return refreshType.value === RefreshType.Auto;
|
||||||
|
},
|
||||||
created() {
|
onChangeRefreshType() {},
|
||||||
this.refreshType = settings.data?.refreshType || "";
|
onCommonSave() {
|
||||||
this.refreshTime = settings.data?.refreshTime || 500;
|
if (settings.data) {
|
||||||
}
|
settings.data.refreshType = toRaw(refreshType.value);
|
||||||
|
settings.data.refreshTime = toRaw(refreshTime.value);
|
||||||
onChangeRefreshType() {
|
settings.save();
|
||||||
|
}
|
||||||
}
|
},
|
||||||
|
};
|
||||||
onCommonSave() {
|
},
|
||||||
if (settings.data) {
|
});
|
||||||
settings.data.refreshType = this.refreshType;
|
|
||||||
settings.data.refreshTime = this.refreshTime;
|
|
||||||
settings.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.settings {
|
.settings {
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,47 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ui-divider" :class="{'ui-divider-move':isMove}"
|
<div
|
||||||
@mousedown="onDividerMouseDown">
|
class="ui-divider"
|
||||||
</div>
|
:class="{ 'ui-divider-move': isMove }"
|
||||||
|
@mousedown="onDividerMouseDown"
|
||||||
|
></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import Component from "vue-class-component";
|
|
||||||
import {Prop, Emit} from "vue-property-decorator";
|
|
||||||
|
|
||||||
@Component({
|
export default defineComponent({
|
||||||
name: "ui-divider",
|
name: "ui-divider",
|
||||||
components: {}
|
emits: ["move"],
|
||||||
})
|
setup(props, { emit }) {
|
||||||
export default class UiDivider extends Vue {
|
const isMove = ref(false);
|
||||||
private isMove = false;
|
function onDividerMove(event: MouseEvent) {
|
||||||
|
emit("move", event);
|
||||||
created() {
|
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Emit("move")
|
|
||||||
onDividerMove(event: MouseEvent) {
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDividerMouseDown(event: MouseEvent) {
|
|
||||||
this.isMove = true;
|
|
||||||
document.addEventListener("mousemove", this.onDividerMove);
|
|
||||||
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
function onMouseUp() {
|
|
||||||
self.isMove = false;
|
|
||||||
document.removeEventListener("mouseup", onMouseUp);
|
|
||||||
document.removeEventListener("mousemove", self.onDividerMove);
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
isMove,
|
||||||
|
onDividerMouseDown(event: MouseEvent) {
|
||||||
|
isMove.value = true;
|
||||||
|
document.addEventListener("mousemove", onDividerMove);
|
||||||
|
function onMouseUp() {
|
||||||
|
isMove.value = false;
|
||||||
|
document.removeEventListener("mouseup", onMouseUp);
|
||||||
|
document.removeEventListener("mousemove", onDividerMove);
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("mouseup", onMouseUp)
|
document.addEventListener("mouseup", onMouseUp);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -1,78 +1,116 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="ui-prop">
|
<div id="ui-prop">
|
||||||
<div class="normal-data" style="display: flex;flex-direction: row;align-items: center;min-height: 30px;margin: 0;">
|
<div
|
||||||
<div @mousedown="onPropNameMouseDown" class="key"
|
class="normal-data"
|
||||||
@click="onClickFold"
|
style="
|
||||||
:style="{'cursor':isArrayOrObject()?'pointer':''}"
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 30px;
|
||||||
|
margin: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
@mousedown="onPropNameMouseDown"
|
||||||
|
class="key"
|
||||||
|
@click="onClickFold"
|
||||||
|
:style="{ cursor: isArrayOrObject() ? 'pointer' : '' }"
|
||||||
>
|
>
|
||||||
<i class="data-arrow"
|
<i
|
||||||
v-if="arrow"
|
class="data-arrow"
|
||||||
:class="fold?'el-icon-caret-right':'el-icon-caret-bottom'"
|
v-if="arrow"
|
||||||
:style="{'visibility':isArrayOrObject()?'visible':'hidden','margin-left':indent*10+'px'}">
|
:class="fold ? 'el-icon-caret-right' : 'el-icon-caret-bottom'"
|
||||||
|
:style="{
|
||||||
|
visibility: isArrayOrObject() ? 'visible' : 'hidden',
|
||||||
|
'margin-left': indent * 10 + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
</i>
|
</i>
|
||||||
<div class="text" ref="propText">
|
<div class="text" ref="propText">
|
||||||
<el-popover placement="top" trigger="hover" :disabled="!isShowTooltip()">
|
<el-popover
|
||||||
|
placement="top"
|
||||||
|
trigger="hover"
|
||||||
|
:disabled="!isShowTooltip()"
|
||||||
|
>
|
||||||
<div>{{ name }}</div>
|
<div>{{ name }}</div>
|
||||||
<span slot="reference">{{ name }}</span>
|
<span>{{ name }}</span>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<div v-if="isInvalid()" class="invalid">
|
<div v-if="isInvalid()" class="invalid">
|
||||||
{{ value.data }}
|
{{ value.data }}
|
||||||
</div>
|
</div>
|
||||||
<el-input v-if="isString()" v-model="value.data"
|
<el-input
|
||||||
:disabled="value.readonly"
|
v-if="isString()"
|
||||||
@change="onChangeValue">
|
v-model="value.data"
|
||||||
|
:disabled="value.readonly"
|
||||||
|
@change="onChangeValue"
|
||||||
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-input v-if="isText()"
|
<el-input
|
||||||
type="textarea"
|
v-if="isText()"
|
||||||
:autosize="{minRows:3,maxRows:5}"
|
type="textarea"
|
||||||
placeholder="请输入内容"
|
:autosize="{ minRows: 3, maxRows: 5 }"
|
||||||
:disabled="value.readonly"
|
placeholder="请输入内容"
|
||||||
@change="onChangeValue"
|
:disabled="value.readonly"
|
||||||
v-model="value.data">
|
@change="onChangeValue"
|
||||||
|
v-model="value.data"
|
||||||
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-input-number v-if="isNumber()"
|
<el-input-number
|
||||||
style="width: 100%;text-align: left"
|
v-if="isNumber()"
|
||||||
v-model="value.data"
|
style="width: 100%; text-align: left"
|
||||||
:step="step"
|
v-model="value.data"
|
||||||
:disabled="value.readonly"
|
:step="step"
|
||||||
@change="onChangeValue"
|
:disabled="value.readonly"
|
||||||
controls-position="right"
|
@change="onChangeValue"
|
||||||
|
controls-position="right"
|
||||||
></el-input-number>
|
></el-input-number>
|
||||||
|
|
||||||
<div v-if="isVec2()||isVec3()" class="vec">
|
<div v-if="isVec2() || isVec3()" class="vec">
|
||||||
<ui-prop v-for="(vec, index) in value.data"
|
<ui-prop
|
||||||
:key="index"
|
v-for="(vec, index) in value.data"
|
||||||
:arrow="false"
|
:key="index"
|
||||||
:value="vec.value"
|
:arrow="false"
|
||||||
:name="vec.name">
|
:value="vec.value"
|
||||||
|
:name="vec.name"
|
||||||
|
>
|
||||||
</ui-prop>
|
</ui-prop>
|
||||||
</div>
|
</div>
|
||||||
<el-select v-model="value.data"
|
<el-select
|
||||||
:disabled="value.readonly"
|
v-model="value.data"
|
||||||
v-if="isEnum()" style="width: 100%;"
|
:disabled="value.readonly"
|
||||||
@change="onChangeValue">
|
v-if="isEnum()"
|
||||||
<el-option v-for="(opt, index) in value.values"
|
style="width: 100%"
|
||||||
:key="index"
|
@change="onChangeValue"
|
||||||
:label="opt.name"
|
>
|
||||||
:value="opt.value">
|
<el-option
|
||||||
|
v-for="(opt, index) in value.values"
|
||||||
|
:key="index"
|
||||||
|
:label="opt.name"
|
||||||
|
:value="opt.value"
|
||||||
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-checkbox v-model="value.data"
|
<el-checkbox
|
||||||
v-if="isBool()"
|
v-model="value.data"
|
||||||
:disabled="value.readonly"
|
v-if="isBool()"
|
||||||
@change="onChangeValue">
|
:disabled="value.readonly"
|
||||||
|
@change="onChangeValue"
|
||||||
|
>
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
<div class="color" v-if="isColor()">
|
<div class="color" v-if="isColor()">
|
||||||
<el-color-picker style="position: absolute;"
|
<el-color-picker
|
||||||
:disabled="value.readonly"
|
style="position: absolute"
|
||||||
v-model="value.data" @change="onChangeValue">
|
:disabled="value.readonly"
|
||||||
|
v-model="value.data"
|
||||||
|
@change="onChangeValue"
|
||||||
|
>
|
||||||
</el-color-picker>
|
</el-color-picker>
|
||||||
<div class="hex" :style="{color:colorReverse(value.data)}">{{ value.data }}</div>
|
<div class="hex" :style="{ color: colorReverse(value.data) }">
|
||||||
|
{{ value.data }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div v-if="isArrayOrObject()" class="array-object">-->
|
<!-- <div v-if="isArrayOrObject()" class="array-object">-->
|
||||||
<!-- <div class="text">-->
|
<!-- <div class="text">-->
|
||||||
@ -82,12 +120,24 @@
|
|||||||
<div v-if="isImage()" class="image-property">
|
<div v-if="isImage()" class="image-property">
|
||||||
<el-popover v-if="isImage()" placement="top" trigger="hover">
|
<el-popover v-if="isImage()" placement="top" trigger="hover">
|
||||||
<div
|
<div
|
||||||
style="width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;justify-content: center;">
|
style="
|
||||||
<img :src="value.data" alt="图片" style="max-width: 100px;max-height: 100px;object-fit: contain;">
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="value.data"
|
||||||
|
alt="图片"
|
||||||
|
style="max-width: 100px; max-height: 100px; object-fit: contain"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<img :src="value.data" slot="reference" style="height: 36px;" alt="图片">
|
<img :src="value.data" style="height: 36px" alt="图片" />
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<div style="flex:1;display: flex; flex-direction: row-reverse;">
|
<div style="flex: 1; display: flex; flex-direction: row-reverse">
|
||||||
<el-button @click="onShowValueInConsole">log</el-button>
|
<el-button @click="onShowValueInConsole">log</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -97,26 +147,32 @@
|
|||||||
<div class="type">{{ value.engineType }}</div>
|
<div class="type">{{ value.engineType }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="name">{{ value.engineName }}</div>
|
<div class="name">{{ value.engineName }}</div>
|
||||||
<el-button @click="onPlaceInTree" type="primary" icon="el-icon-place"></el-button>
|
<el-button
|
||||||
|
@click="onPlaceInTree"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-place"
|
||||||
|
></el-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isObject()&&fold" class="objectDesc">
|
<div v-if="isObject() && fold" class="objectDesc">
|
||||||
{{ value.data }}
|
{{ value.data }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isArray()" class="array">
|
<div v-if="isArray()" class="array">Array({{ value.data.length }})</div>
|
||||||
Array({{ value.data.length }})
|
|
||||||
</div>
|
|
||||||
<div class="slot" v-if="false">
|
<div class="slot" v-if="false">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isArrayOrObject()">
|
<div v-if="isArrayOrObject()">
|
||||||
<div v-show="!fold&&subData" style="display: flex;flex-direction: column;">
|
<div
|
||||||
<ui-prop v-for="(arr,index) in subData"
|
v-show="!fold && subData"
|
||||||
:key="index"
|
style="display: flex; flex-direction: column"
|
||||||
:indent="indent+1"
|
>
|
||||||
:value="arr.value"
|
<ui-prop
|
||||||
:name="getName(isArray(),arr)"
|
v-for="(arr, index) in subData"
|
||||||
|
:key="index"
|
||||||
|
:indent="indent + 1"
|
||||||
|
:value="arr.value"
|
||||||
|
:name="getName(isArray(), arr)"
|
||||||
>
|
>
|
||||||
</ui-prop>
|
</ui-prop>
|
||||||
</div>
|
</div>
|
||||||
@ -125,224 +181,219 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
toRaw,
|
||||||
|
watch,
|
||||||
|
onUnmounted,
|
||||||
|
onMounted,
|
||||||
|
PropType,
|
||||||
|
} from "vue";
|
||||||
|
import { DataType, EngineData, EnumData, Info, Property } from "../data";
|
||||||
|
import { connectBackground } from "../connectBackground";
|
||||||
|
import { Msg } from "../../../core/types";
|
||||||
|
import Bus, { BusMsg } from "../bus";
|
||||||
|
|
||||||
import Vue from "vue"
|
export default defineComponent({
|
||||||
import {Component, Prop, Watch} from "vue-property-decorator"
|
|
||||||
import {DataType, EngineData, Info, Property} from "../data"
|
|
||||||
import {connectBackground} from "@/devtools/connectBackground";
|
|
||||||
import {Msg} from "@/core/types";
|
|
||||||
import Bus, {BusMsg} from "../bus"
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
name: "UiProp",
|
name: "UiProp",
|
||||||
components: {}
|
props: {
|
||||||
})
|
name: {
|
||||||
export default class UiProp extends Vue {
|
type: String,
|
||||||
@Prop({default: ""})
|
default: "",
|
||||||
name: string | undefined;
|
},
|
||||||
|
indent: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
arrow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Object as PropType<Info | EngineData | EnumData>,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
@Prop({default: 0})
|
setup(props, ctx) {
|
||||||
indent!: number;
|
let clientX: number = 0;
|
||||||
|
|
||||||
@Prop({default: true})
|
onMounted(() => {
|
||||||
arrow!: boolean;
|
watchValue();
|
||||||
|
});
|
||||||
@Prop()
|
function watchValue() {
|
||||||
value!: Info;
|
this.fold = true;
|
||||||
|
if (this.isArray()) {
|
||||||
@Watch("value")
|
this.subData = this.value.data;
|
||||||
watchValue() {
|
} else {
|
||||||
this.fold = true;
|
this.subData = null;
|
||||||
if (this.isArray()) {
|
|
||||||
this.subData = this.value.data;
|
|
||||||
} else {
|
|
||||||
this.subData = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isInvalid() {
|
|
||||||
return this.value && (this.value.type === DataType.Invalid);
|
|
||||||
}
|
|
||||||
|
|
||||||
isString() {
|
|
||||||
return this.value && (this.value.type === DataType.String);
|
|
||||||
}
|
|
||||||
|
|
||||||
isText() {
|
|
||||||
return this.value && (this.value.type === DataType.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
isNumber() {
|
|
||||||
return this.value && (this.value.type === DataType.Number);
|
|
||||||
}
|
|
||||||
|
|
||||||
isVec2() {
|
|
||||||
return this.value && (this.value.type === DataType.Vec2);
|
|
||||||
}
|
|
||||||
|
|
||||||
isVec3() {
|
|
||||||
return this.value && (this.value.type === DataType.Vec3);
|
|
||||||
}
|
|
||||||
|
|
||||||
isEnum() {
|
|
||||||
return this.value && (this.value.type === DataType.Enum);
|
|
||||||
}
|
|
||||||
|
|
||||||
isBool() {
|
|
||||||
return this.value && (this.value.type === DataType.Bool);
|
|
||||||
}
|
|
||||||
|
|
||||||
isColor() {
|
|
||||||
return this.value && (this.value.type === DataType.Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
isArrayOrObject() {
|
|
||||||
return this.value && (this.value.type === DataType.Array || this.value.type === DataType.Object)
|
|
||||||
}
|
|
||||||
|
|
||||||
isObject() {
|
|
||||||
return this.value && (this.value.type === DataType.Object)
|
|
||||||
}
|
|
||||||
|
|
||||||
isArray() {
|
|
||||||
return this.value && (this.value.type === DataType.Array)
|
|
||||||
}
|
|
||||||
|
|
||||||
isImage() {
|
|
||||||
return this.value && (this.value.type === DataType.Image)
|
|
||||||
}
|
|
||||||
|
|
||||||
isImageValid() {
|
|
||||||
return !!this.value.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
isEngine() {
|
|
||||||
return this.value && (this.value.type === DataType.Engine)
|
|
||||||
}
|
|
||||||
|
|
||||||
onPlaceInTree() {
|
|
||||||
Bus.$emit(BusMsg.ShowPlace, this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.watchValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
isShowTooltip() {
|
|
||||||
const el: HTMLDivElement = this.$refs.propText as HTMLDivElement;
|
|
||||||
if (el) {
|
|
||||||
if (el.scrollWidth > el.offsetWidth) {
|
|
||||||
// 出现了省略号
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
const fold = ref(true);
|
||||||
}
|
watch(props.value, () => {
|
||||||
|
watchValue();
|
||||||
|
});
|
||||||
|
const subData = ref<Property[]>([]);
|
||||||
|
|
||||||
getEngineTypeIcon() {
|
return {
|
||||||
const value = this.value as EngineData;
|
fold,
|
||||||
switch (value.engineType) {
|
subData,
|
||||||
case "cc_Sprite": {
|
isInvalid() {
|
||||||
return "el-icon-picture-outline";
|
return this.value && this.value.type === DataType.Invalid;
|
||||||
}
|
},
|
||||||
case "cc_Label": {
|
isString() {
|
||||||
return "el-icon-third-text";
|
return this.value && this.value.type === DataType.String;
|
||||||
}
|
},
|
||||||
case "cc_Node": {
|
isText() {
|
||||||
return "el-icon-third-node"
|
return this.value && this.value.type === DataType.Text;
|
||||||
}
|
},
|
||||||
}
|
isNumber() {
|
||||||
return "el-icon-third-unknow";
|
return this.value && this.value.type === DataType.Number;
|
||||||
}
|
},
|
||||||
|
isVec2() {
|
||||||
|
return this.value && this.value.type === DataType.Vec2;
|
||||||
|
},
|
||||||
|
isVec3() {
|
||||||
|
return this.value && this.value.type === DataType.Vec3;
|
||||||
|
},
|
||||||
|
isEnum() {
|
||||||
|
return this.value && this.value.type === DataType.Enum;
|
||||||
|
},
|
||||||
|
isBool() {
|
||||||
|
return this.value && this.value.type === DataType.Bool;
|
||||||
|
},
|
||||||
|
isColor() {
|
||||||
|
return this.value && this.value.type === DataType.Color;
|
||||||
|
},
|
||||||
|
isArrayOrObject() {
|
||||||
|
return (
|
||||||
|
this.value &&
|
||||||
|
(this.value.type === DataType.Array ||
|
||||||
|
this.value.type === DataType.Object)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
isObject() {
|
||||||
|
return this.value && this.value.type === DataType.Object;
|
||||||
|
},
|
||||||
|
isArray() {
|
||||||
|
return this.value && this.value.type === DataType.Array;
|
||||||
|
},
|
||||||
|
isImage() {
|
||||||
|
return this.value && this.value.type === DataType.Image;
|
||||||
|
},
|
||||||
|
isImageValid() {
|
||||||
|
return !!this.value.data;
|
||||||
|
},
|
||||||
|
isEngine() {
|
||||||
|
return this.value && this.value.type === DataType.Engine;
|
||||||
|
},
|
||||||
|
onPlaceInTree() {
|
||||||
|
Bus.emit(BusMsg.ShowPlace, this.value);
|
||||||
|
},
|
||||||
|
isShowTooltip() {
|
||||||
|
const el: HTMLDivElement = this.$refs.propText as HTMLDivElement;
|
||||||
|
if (el) {
|
||||||
|
if (el.scrollWidth > el.offsetWidth) {
|
||||||
|
// 出现了省略号
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
getEngineTypeIcon() {
|
||||||
|
const value = this.value as EngineData;
|
||||||
|
switch (value.engineType) {
|
||||||
|
case "cc_Sprite": {
|
||||||
|
return "el-icon-picture-outline";
|
||||||
|
}
|
||||||
|
case "cc_Label": {
|
||||||
|
return "el-icon-third-text";
|
||||||
|
}
|
||||||
|
case "cc_Node": {
|
||||||
|
return "el-icon-third-node";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "el-icon-third-unknow";
|
||||||
|
},
|
||||||
|
getName(isArray: boolean, arr: Property) {
|
||||||
|
const type = arr.value.type;
|
||||||
|
if (isArray) {
|
||||||
|
return `[${arr.name}]`;
|
||||||
|
} else {
|
||||||
|
return arr.name;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClickFold() {
|
||||||
|
if (this.isObject() && this.fold && !this.subData) {
|
||||||
|
// 请求object的item数据
|
||||||
|
Bus.emit(BusMsg.RequestObjectData, this.value, (info: Property[]) => {
|
||||||
|
this.fold = false;
|
||||||
|
this.subData = info;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.fold = !this.fold;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
getName(isArray: boolean, arr: UiProp) {
|
onShowValueInConsole() {
|
||||||
const type = arr.value.type;
|
if (Array.isArray(this.value.path)) {
|
||||||
if (isArray) {
|
let uuid = this.value.path[0];
|
||||||
return `[${arr.name}]`
|
let key = this.value.path[1]; // todo 暂时只支持一级key
|
||||||
} else {
|
if (uuid && key) {
|
||||||
return arr.name;
|
chrome.devtools.inspectedWindow.eval(
|
||||||
}
|
`window.CCInspector.logValue('${uuid}','${key}')`
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
private fold = true;
|
onChangeValue() {
|
||||||
|
if (!this.value.readonly) {
|
||||||
|
connectBackground.postMessageToBackground(
|
||||||
|
Msg.SetProperty,
|
||||||
|
this.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPropNameMouseDown(event: MouseEvent) {
|
||||||
|
document.addEventListener("mousemove", this._onMouseMove);
|
||||||
|
document.addEventListener("mouseup", this._onMouseUp);
|
||||||
|
document.addEventListener("onselectstart", this._onSelect);
|
||||||
|
},
|
||||||
|
|
||||||
private subData: Property[] | null = null;
|
colorReverse(OldColorValue: string) {
|
||||||
|
OldColorValue = "0x" + OldColorValue.replace(/#/g, "");
|
||||||
|
var str = "000000" + (0xffffff - parseInt(OldColorValue)).toString(16);
|
||||||
|
return "#" + str.substring(str.length - 6, str.length);
|
||||||
|
},
|
||||||
|
_onMouseMove(event: MouseEvent) {
|
||||||
|
let x = event.clientX;
|
||||||
|
let calcStep = this.step || 0;
|
||||||
|
if (x > this.clientX) {
|
||||||
|
calcStep = Math.abs(calcStep);
|
||||||
|
} else {
|
||||||
|
calcStep = -Math.abs(calcStep);
|
||||||
|
}
|
||||||
|
this.$emit("movestep", calcStep);
|
||||||
|
this.clientX = x;
|
||||||
|
},
|
||||||
|
|
||||||
onClickFold() {
|
_onMouseUp(event: MouseEvent) {
|
||||||
if (this.isObject() && this.fold && !this.subData) {
|
document.removeEventListener("mousemove", this._onMouseMove);
|
||||||
// 请求object的item数据
|
document.removeEventListener("mouseup", this._onMouseUp);
|
||||||
Bus.$emit(BusMsg.RequestObjectData, this.value, (info: Property[]) => {
|
document.removeEventListener("onselectstart", this._onSelect);
|
||||||
|
},
|
||||||
this.fold = false;
|
_onSelect() {
|
||||||
this.subData = info;
|
return false;
|
||||||
})
|
},
|
||||||
} else {
|
};
|
||||||
this.fold = !this.fold;
|
},
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
onShowValueInConsole() {
|
|
||||||
if (Array.isArray(this.value.path)) {
|
|
||||||
let uuid = this.value.path[0];
|
|
||||||
let key = this.value.path[1]; // todo 暂时只支持一级key
|
|
||||||
if (uuid && key) {
|
|
||||||
chrome.devtools.inspectedWindow.eval(`window.CCInspector.logValue('${uuid}','${key}')`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeValue() {
|
|
||||||
if (!this.value.readonly) {
|
|
||||||
connectBackground.postMessageToBackground(Msg.SetProperty, this.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Prop({default: 1})
|
|
||||||
step: number | undefined;
|
|
||||||
|
|
||||||
|
|
||||||
clientX: number = 0;
|
|
||||||
|
|
||||||
onPropNameMouseDown(event: MouseEvent) {
|
|
||||||
document.addEventListener("mousemove", this._onMouseMove);
|
|
||||||
document.addEventListener("mouseup", this._onMouseUp);
|
|
||||||
document.addEventListener("onselectstart", this._onSelect);
|
|
||||||
}
|
|
||||||
|
|
||||||
colorReverse(OldColorValue: string) {
|
|
||||||
OldColorValue = "0x" + OldColorValue.replace(/#/g, "");
|
|
||||||
var str = "000000" + (0xFFFFFF - parseInt(OldColorValue)).toString(16);
|
|
||||||
return "#" + str.substring(str.length - 6, str.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSelect() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMouseMove(event: MouseEvent) {
|
|
||||||
let x = event.clientX;
|
|
||||||
let calcStep = this.step || 0;
|
|
||||||
if (x > this.clientX) {
|
|
||||||
calcStep = Math.abs(calcStep);
|
|
||||||
} else {
|
|
||||||
calcStep = -Math.abs(calcStep);
|
|
||||||
}
|
|
||||||
this.$emit("movestep", calcStep);
|
|
||||||
this.clientX = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMouseUp(event: MouseEvent) {
|
|
||||||
document.removeEventListener("mousemove", this._onMouseMove);
|
|
||||||
document.removeEventListener("mouseup", this._onMouseUp);
|
|
||||||
document.removeEventListener("onselectstart", this._onSelect);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@ -362,7 +413,6 @@ export default class UiProp extends Vue {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
|
||||||
.key {
|
.key {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
float: left;
|
float: left;
|
||||||
@ -436,7 +486,7 @@ export default class UiProp extends Vue {
|
|||||||
.engine {
|
.engine {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
border: solid #409EFF 1px;
|
border: solid #409eff 1px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
@ -463,7 +513,6 @@ export default class UiProp extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user