!79 [inula-dev-tools]<feat>节点树组件合入
Merge pull request !79 from 涂旭辉/master
This commit is contained in:
commit
9f8bd3245f
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import 'assets.less';
|
||||||
|
|
||||||
|
.treeContainer {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.treeItem {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
line-height: 1.125rem;
|
||||||
|
align-items: center;
|
||||||
|
display: inline-flex;
|
||||||
|
&:hover {
|
||||||
|
background-color: @select-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeIcon {
|
||||||
|
color: @arrow-color;
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.componentName {
|
||||||
|
white-space: nowrap;
|
||||||
|
color: @component-name-color;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.componentKeyName {
|
||||||
|
color: @component-key-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.componentKeyValue {
|
||||||
|
color: @component-key-value-color;
|
||||||
|
max-width: 100px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-flex;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedItemChild {
|
||||||
|
background-color: @select-item-child-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
background-color: @select-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Badge {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
color: #000000;
|
||||||
|
padding: 0 0.25rem;
|
||||||
|
line-height: normal;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
font-family: @attr-name-font-family;
|
||||||
|
font-size: 9px;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useState, useEffect, useCallback, memo } from 'openinula';
|
||||||
|
import styles from './VTree.less';
|
||||||
|
import Triangle from '../svgs/Triangle';
|
||||||
|
import { createRegExp } from '../utils/regExpUtil';
|
||||||
|
import { SizeObserver } from './SizeObserver';
|
||||||
|
import { RenderInfoType, VList } from './VList';
|
||||||
|
import { postMessageToBackground } from '../panelConnection';
|
||||||
|
import { Highlight, RemoveHighlight } from '../utils/constants';
|
||||||
|
import { NameObj } from '../parser/parseVNode';
|
||||||
|
|
||||||
|
export interface IData {
|
||||||
|
id: number;
|
||||||
|
name: NameObj;
|
||||||
|
indentation: number;
|
||||||
|
userKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IItem {
|
||||||
|
indentationLength: number;
|
||||||
|
hasChild: boolean;
|
||||||
|
onCollapse: (data: IData) => void;
|
||||||
|
onClick: (id: IData) => void;
|
||||||
|
onMouseEnter: (id: IData) => void;
|
||||||
|
onMouseLeave: (id: IData) => void;
|
||||||
|
isCollapsed: boolean;
|
||||||
|
isSelect: boolean;
|
||||||
|
highlightValue: string;
|
||||||
|
data: IData;
|
||||||
|
isSelectedItemChild: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Item(props: IItem) {
|
||||||
|
const {
|
||||||
|
hasChild,
|
||||||
|
onCollapse,
|
||||||
|
isCollapsed,
|
||||||
|
data,
|
||||||
|
onClick,
|
||||||
|
indentationLength,
|
||||||
|
onMouseEnter,
|
||||||
|
onMouseLeave,
|
||||||
|
isSelect,
|
||||||
|
highlightValue = '',
|
||||||
|
isSelectedItemChild,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const { name, userKey, indentation } = data;
|
||||||
|
|
||||||
|
const isShowKey = userKey !== '';
|
||||||
|
const showIcon = hasChild ? <Triangle director={isCollapsed ? 'right' : 'down'} /> : '';
|
||||||
|
const handleClickCollapse = () => {
|
||||||
|
onCollapse(data);
|
||||||
|
};
|
||||||
|
const handleClick = () => {
|
||||||
|
onClick(data);
|
||||||
|
};
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
onMouseEnter(data);
|
||||||
|
};
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
onMouseLeave(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemAttr: Record<string, any> = {
|
||||||
|
className: isSelectedItemChild ? styles.selectedItemChild : styles.treeItem,
|
||||||
|
onClick: handleClick,
|
||||||
|
onMouseEnter: handleMouseEnter,
|
||||||
|
onMouseLeave: handleMouseLeave,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isSelect) {
|
||||||
|
itemAttr.tabIndex = 0;
|
||||||
|
itemAttr.className = styles.treeItem + ' ' + styles.select;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelectedItemChild) {
|
||||||
|
itemAttr.className = styles.treeItem + ' ' + styles.selectedItemChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pushBadge = (showName: Array<any>, badgeName: string) => {
|
||||||
|
showName.push(' ');
|
||||||
|
showName.push(<div className={`${styles.Badge}`}>{badgeName}</div>);
|
||||||
|
};
|
||||||
|
|
||||||
|
const pushItemName = (showName: Array<any>, cutName: string, char: string) => {
|
||||||
|
const index = cutName.search(char);
|
||||||
|
if (index > -1) {
|
||||||
|
const notHighlightStr = cutName.slice(0, index);
|
||||||
|
showName.push(`<${notHighlightStr}`);
|
||||||
|
showName.push(<mark>{char}</mark>);
|
||||||
|
showName.push(`${cutName.slice(index + char.length)}>`);
|
||||||
|
} else {
|
||||||
|
showName.push(`<${cutName}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const pushBadgeName = (showName: Array<any>, cutName: string, char: string) => {
|
||||||
|
const index = cutName.search(char);
|
||||||
|
if (index > -1) {
|
||||||
|
const notHighlightStr = cutName.slice(0, index);
|
||||||
|
showName.push(
|
||||||
|
<div className={`${styles.Badge}`}>
|
||||||
|
{notHighlightStr}
|
||||||
|
{<mark>{char}</mark>}
|
||||||
|
{cutName.slice(index + char.length)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
pushBadge(showName, cutName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const reg = createRegExp(highlightValue);
|
||||||
|
const heightCharacters = name.itemName.match(reg);
|
||||||
|
const showName = [];
|
||||||
|
|
||||||
|
const addShowName = (showName: Array<string>, name: NameObj) => {
|
||||||
|
showName.push(`<${name.itemName}>`);
|
||||||
|
name.badge.forEach(key => {
|
||||||
|
showName.push(<div className={`${styles.Badge}`}>{key}</div>);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (heightCharacters) {
|
||||||
|
// 高亮第一次匹配即可
|
||||||
|
const char = heightCharacters[0];
|
||||||
|
pushItemName(showName, name.itemName, char);
|
||||||
|
if (name.badge.length > 0) {
|
||||||
|
name.badge.forEach(key => {
|
||||||
|
pushBadgeName(showName, key, char);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addShowName(showName, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div {...itemAttr}>
|
||||||
|
<div
|
||||||
|
style={{marginLeft: indentation * indentationLength}}
|
||||||
|
className={styles.treeIcon}
|
||||||
|
onclick={handleClickCollapse}
|
||||||
|
>
|
||||||
|
{showIcon}
|
||||||
|
</div>
|
||||||
|
<span className={styles.componentName}>{showName}</span>
|
||||||
|
{isShowKey && (
|
||||||
|
<>
|
||||||
|
<span className={styles.componentKeyName}> key</span>
|
||||||
|
{'="'}
|
||||||
|
<span className={styles.componentKeyValue}>{userKey}</span>
|
||||||
|
{'"'}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function VTree(props: {
|
||||||
|
data: IData[];
|
||||||
|
maxDeep: number;
|
||||||
|
highlightValue: string;
|
||||||
|
scrollToItem: IData;
|
||||||
|
onRendered: (renderInfo: RenderInfoType<IData>) => void;
|
||||||
|
collapsedNodes?: IData[];
|
||||||
|
onCollapseNode?: (item: IData[]) => void;
|
||||||
|
selectItem: IData;
|
||||||
|
onSelectItem: (item: IData) => void;
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
maxDeep,
|
||||||
|
highlightValue,
|
||||||
|
scrollToItem,
|
||||||
|
onRendered,
|
||||||
|
onCollapseNode,
|
||||||
|
onSelectItem
|
||||||
|
} = props;
|
||||||
|
const [collapseNode, setCollapseNode] = useState(props.collapsedNodes || []);
|
||||||
|
const [selectItem, setSelectItem] = useState(props.selectItem);
|
||||||
|
const [childItems, setChildItems] = useState<Array<IData>>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectItem(scrollToItem);
|
||||||
|
}, [scrollToItem]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.selectItem !== selectItem) {
|
||||||
|
setSelectItem(props.selectItem);
|
||||||
|
}
|
||||||
|
}, [props.selectItem]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCollapseNode(props.collapsedNodes || []);
|
||||||
|
}, [props.collapsedNodes]);
|
||||||
|
|
||||||
|
const changeCollapseNode = (item: IData) => {
|
||||||
|
const nodes: IData[] = [...collapseNode];
|
||||||
|
const index = nodes.indexOf(item);
|
||||||
|
if (index === -1) {
|
||||||
|
nodes.push(item);
|
||||||
|
} else {
|
||||||
|
nodes.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCollapseNode(nodes);
|
||||||
|
|
||||||
|
if (onCollapseNode) {
|
||||||
|
onCollapseNode(nodes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getChildItem = (item: IData): Array<IData> => {
|
||||||
|
const index = data.indexOf(item);
|
||||||
|
const childList: Array<IData> = [];
|
||||||
|
|
||||||
|
for (let i = index + 1; i < data.length; i++) {
|
||||||
|
if (data[i].indentation > item.indentation) {
|
||||||
|
childList.push(data[i]);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return childList;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClickItem = useCallback(
|
||||||
|
(item: IData) => {
|
||||||
|
const childItem = getChildItem(item);
|
||||||
|
setSelectItem(item);
|
||||||
|
setChildItems(childItem);
|
||||||
|
if (onSelectItem) {
|
||||||
|
onSelectItem(item);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[onSelectItem]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMouseEnterItem = useCallback(
|
||||||
|
item => {
|
||||||
|
postMessageToBackground(Highlight, item);
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMouseLeaveItem = () => {
|
||||||
|
postMessageToBackground(RemoveHighlight);
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentCollapseIndentation: null | number = null;
|
||||||
|
// 过滤掉折叠的 item,不展示在 VList 中
|
||||||
|
const filter = (item: IData) => {
|
||||||
|
if (currentCollapseIndentation !== null) {
|
||||||
|
// 缩进更大,不显示
|
||||||
|
if (item.indentation > currentCollapseIndentation) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// 缩进小,说明完成了收起节点的子节点处理
|
||||||
|
currentCollapseIndentation = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const isCollapsed = collapseNode.includes(item);
|
||||||
|
if (isCollapsed) {
|
||||||
|
// 该节点需要收起子节点
|
||||||
|
currentCollapseIndentation = item.indentation;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showList = data.filter(filter);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SizeObserver className={styles.treeContainer}>
|
||||||
|
{(width: number, height: number) => {
|
||||||
|
return (
|
||||||
|
<VList
|
||||||
|
data={showList}
|
||||||
|
maxDeep={maxDeep}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
itemHeight={17.5}
|
||||||
|
scrollToItem={selectItem}
|
||||||
|
onRendered={onRendered}
|
||||||
|
>
|
||||||
|
{(item: IData, indentationLength: number) => {
|
||||||
|
const isCollapsed = collapseNode.includes(item);
|
||||||
|
const index = showList.indexOf(item);
|
||||||
|
// 如果收起,一定有 child
|
||||||
|
// 不收起场景,如果存在下一个节点,并且节点缩进比自己大,说明下个节点是子节点,节点本身需要显示展开收起图标
|
||||||
|
const hasChild = isCollapsed || showList[index + 1]?.indentation > item.indentation;
|
||||||
|
return (
|
||||||
|
<Item
|
||||||
|
indentationLength={indentationLength}
|
||||||
|
hasChild={hasChild}
|
||||||
|
onCollapse={changeCollapseNode}
|
||||||
|
onClick={handleClickItem}
|
||||||
|
onMouseEnter={handleMouseEnterItem}
|
||||||
|
onMouseLeave={handleMouseLeaveItem}
|
||||||
|
isCollapsed={collapseNode.includes(item)}
|
||||||
|
isSelect={selectItem === item}
|
||||||
|
highlightValue={highlightValue}
|
||||||
|
data={item}
|
||||||
|
isSelectedItemChild={childItems.includes(item)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</VList>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</SizeObserver>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(VTree);
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@arrow-color: rgb(95, 99, 104);
|
||||||
|
@divider-color: rgb(202, 205, 209);
|
||||||
|
@attr-name-color: rgb(200, 0, 0);
|
||||||
|
@component-name-color: rgb(136, 18, 128);
|
||||||
|
@component-key-color: rgb(153, 69, 0);
|
||||||
|
@component-key-value-color: rgb(26, 26, 166);
|
||||||
|
@component-attr-color: rgb(200, 0, 0);
|
||||||
|
@select-color: rgb(144 199 248 / 60%);
|
||||||
|
@select-item-child-color: rgb(141 199 248 / 40%);
|
||||||
|
@hover-color: black;
|
||||||
|
|
||||||
|
@top-height: 2.625rem;
|
||||||
|
@divider-width: 0.2px;
|
||||||
|
@common-font-size: 12px;
|
||||||
|
|
||||||
|
@divider-style: @divider-color solid @divider-width;
|
||||||
|
@attr-name-font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './panelConnection';
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { packagePayload } from '../utils/transferUtils';
|
||||||
|
import { DevToolPanel, InitDevToolPageConnection } from '../utils/constants';
|
||||||
|
|
||||||
|
let connection;
|
||||||
|
const callbacks = [];
|
||||||
|
|
||||||
|
export function addBackgroundMessageListener(func: (message) => void) {
|
||||||
|
callbacks.push(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeBackgroundMessageListener(func: (message) => void) {
|
||||||
|
const index = callbacks.indexOf(func);
|
||||||
|
if (index !== -1) {
|
||||||
|
callbacks.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initBackgroundConnection(type) {
|
||||||
|
if (!isDev) {
|
||||||
|
try {
|
||||||
|
connection = chrome.runtime.connect({ name: type });
|
||||||
|
const notice = message => {
|
||||||
|
callbacks.forEach(func => {
|
||||||
|
func(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 监听 background 消息
|
||||||
|
connection.onMessage.addListener(notice);
|
||||||
|
// 页面打开后发送初始化请求
|
||||||
|
postMessageToBackground(InitDevToolPageConnection);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('create connection failer');
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let reconnectionTimes = 0;
|
||||||
|
export function postMessageToBackground(
|
||||||
|
type: string,
|
||||||
|
data?: any,
|
||||||
|
inulaX?: boolean
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const payload = data
|
||||||
|
? { type, tabId: chrome.devtools.inspectedWindow.tabId, data }
|
||||||
|
: { type, tabId: chrome.devtools.inspectedWindow.tabId };
|
||||||
|
connection.postMessage(packagePayload(payload, DevToolPanel));
|
||||||
|
} catch (e) {
|
||||||
|
// 可能出现 port 关闭的场景,需要重新建立连接,增加可靠性
|
||||||
|
if (reconnectionTimes === 20) {
|
||||||
|
reconnectionTimes = 0;
|
||||||
|
console.error('reconnect failed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error(e);
|
||||||
|
reconnectionTimes++;
|
||||||
|
// 重新连接
|
||||||
|
initBackgroundConnection(inulaX ? 'panelX' : 'panel');
|
||||||
|
// 初始化成功后才会重新发送消息
|
||||||
|
postMessageToBackground(type, data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"strict": true,
|
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
@ -16,6 +15,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*.ts", "./src/index.d.ts", "./src/**/*.tsx", "./externals.d.ts"
|
"./src/**/*.ts", "./src/index.d.ts", "./src/**/*.tsx", "./externals.d.ts", "./global.d.ts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue