mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-15 16:39:45 +08:00
feat(editor): editorService.add支持添加多个组件
This commit is contained in:
parent
5ccb5f1ec9
commit
b6fa064b0b
@ -72,7 +72,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
.keydown([ctrl, 'v'], (e) => {
|
.keydown([ctrl, 'v'], (e) => {
|
||||||
e.inputEvent.preventDefault();
|
e.inputEvent.preventDefault();
|
||||||
nodes.value && services?.editorService.paste();
|
nodes.value && services?.editorService.paste({ offsetX: 10, offsetY: 10 });
|
||||||
})
|
})
|
||||||
.keydown([ctrl, 'x'], (e) => {
|
.keydown([ctrl, 'x'], (e) => {
|
||||||
e.inputEvent.preventDefault();
|
e.inputEvent.preventDefault();
|
||||||
|
@ -32,12 +32,14 @@ import {
|
|||||||
change2Fixed,
|
change2Fixed,
|
||||||
COPY_STORAGE_KEY,
|
COPY_STORAGE_KEY,
|
||||||
Fixed2Other,
|
Fixed2Other,
|
||||||
|
fixNodePosition,
|
||||||
getInitPositionStyle,
|
getInitPositionStyle,
|
||||||
getNodeIndex,
|
getNodeIndex,
|
||||||
isFixed,
|
isFixed,
|
||||||
setLayout,
|
setLayout,
|
||||||
} from '../utils/editor';
|
} from '../utils/editor';
|
||||||
import { beforeAdd, beforePaste, beforeRemove, notifyAddToStage } from '../utils/operator';
|
import { beforePaste, beforeRemove, getAddParent } from '../utils/operator';
|
||||||
|
import { propsService } from '..';
|
||||||
|
|
||||||
import BaseService from './BaseService';
|
import BaseService from './BaseService';
|
||||||
|
|
||||||
@ -60,6 +62,7 @@ class Editor extends BaseService {
|
|||||||
[
|
[
|
||||||
'getLayout',
|
'getLayout',
|
||||||
'select',
|
'select',
|
||||||
|
'doAdd',
|
||||||
'add',
|
'add',
|
||||||
'remove',
|
'remove',
|
||||||
'update',
|
'update',
|
||||||
@ -281,34 +284,30 @@ class Editor extends BaseService {
|
|||||||
this.set('nodes', nodes);
|
this.set('nodes', nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public async doAdd(node: MNode, parent: MContainer): Promise<MNode> {
|
||||||
* 批量向容器添加节点
|
const root = this.get<MApp>('root');
|
||||||
* @param configs 将要添加的节点数组
|
const curNode = this.get<MNode>('node');
|
||||||
* @returns 添加后的节点
|
|
||||||
*/
|
|
||||||
public async multiAdd(configs: MNode[]): Promise<MNode[]> {
|
|
||||||
const stage = this.get<StageCore | null>('stage');
|
const stage = this.get<StageCore | null>('stage');
|
||||||
const newNodes: MNode[] = await Promise.all(
|
|
||||||
configs.map(async (configItem: MNode): Promise<MNode> => {
|
|
||||||
// 新增元素到配置
|
|
||||||
const { parentNode, newNode, layout } = await beforeAdd(configItem as AddMNode);
|
|
||||||
// 将新增元素事件通知到stage以更新渲染
|
|
||||||
await notifyAddToStage(parentNode, newNode, layout);
|
|
||||||
return newNode;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
const newNodeIds: Id[] = newNodes.map((node) => node.id);
|
|
||||||
|
|
||||||
// 增加历史记录 多选不可能选中page
|
if ((parent?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
|
||||||
this.addModifiedNodeId(newNodeIds.join('-'));
|
throw new Error('app下不能添加组件');
|
||||||
this.pushHistoryState();
|
}
|
||||||
|
|
||||||
// 触发选中样式
|
const layout = await this.getLayout(toRaw(parent), node as MNode);
|
||||||
stage?.multiSelect(newNodeIds);
|
node.style = getInitPositionStyle(node.style, layout);
|
||||||
|
|
||||||
this.emit('multiAdd', newNodes);
|
await stage?.add({ config: cloneDeep(node), parent: cloneDeep(parent), root: cloneDeep(root) });
|
||||||
|
|
||||||
return newNodes;
|
node.style = fixNodePosition(node, parent, stage);
|
||||||
|
|
||||||
|
await stage?.update({ config: cloneDeep(node), root: cloneDeep(root) });
|
||||||
|
|
||||||
|
// 新增节点添加到配置中
|
||||||
|
parent?.items?.push(node);
|
||||||
|
|
||||||
|
this.addModifiedNodeId(node.id);
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,30 +316,47 @@ class Editor extends BaseService {
|
|||||||
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
||||||
* @returns 添加后的节点
|
* @returns 添加后的节点
|
||||||
*/
|
*/
|
||||||
public async add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode> {
|
public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
|
||||||
const stage = this.get<StageCore | null>('stage');
|
const stage = this.get<StageCore | null>('stage');
|
||||||
// 新增元素到配置
|
|
||||||
const { parentNode, newNode, layout, isPage } = await beforeAdd(addNode, parent);
|
|
||||||
// 将新增元素事件通知到stage以更新渲染
|
|
||||||
await notifyAddToStage(parentNode, newNode, layout);
|
|
||||||
// 更新编辑器选中元素
|
|
||||||
await this.select(newNode);
|
|
||||||
// 增加历史记录
|
|
||||||
this.addModifiedNodeId(newNode.id);
|
|
||||||
if (!isPage) {
|
|
||||||
this.pushHistoryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPage) {
|
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(addNode);
|
||||||
this.state.pageLength += 1;
|
if (!parentNode) throw new Error('未找到父元素');
|
||||||
|
|
||||||
|
// 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
|
||||||
|
const addNodes = [];
|
||||||
|
if (!Array.isArray(addNode)) {
|
||||||
|
const { type, inputEvent, ...config } = addNode;
|
||||||
|
|
||||||
|
if (!type) throw new Error('组件类型不能为空');
|
||||||
|
|
||||||
|
addNodes.push({ ...toRaw(await propsService.getPropsValue(type, config)) });
|
||||||
} else {
|
} else {
|
||||||
// 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
|
addNodes.push(...addNode);
|
||||||
stage?.select(newNode.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('add', newNode);
|
const newNodes = await Promise.all(addNodes.map((node) => this.doAdd(node, parentNode)));
|
||||||
|
|
||||||
return newNode;
|
if (newNodes.length > 1) {
|
||||||
|
const newNodeIds = newNodes.map((node) => node.id);
|
||||||
|
// 触发选中样式
|
||||||
|
stage?.multiSelect(newNodeIds);
|
||||||
|
await this.multiSelect(newNodeIds);
|
||||||
|
} else {
|
||||||
|
await this.select(newNodes[0]);
|
||||||
|
|
||||||
|
if (isPage(newNodes[0])) {
|
||||||
|
this.state.pageLength += 1;
|
||||||
|
} else {
|
||||||
|
// 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
|
||||||
|
stage?.select(newNodes[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushHistoryState();
|
||||||
|
|
||||||
|
this.emit('add', newNodes);
|
||||||
|
|
||||||
|
return newNodes.length > 1 ? newNodes[0] : newNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -492,14 +508,14 @@ class Editor extends BaseService {
|
|||||||
* @param position 粘贴的坐标
|
* @param position 粘贴的坐标
|
||||||
* @returns 添加后的组件节点配置
|
* @returns 添加后的组件节点配置
|
||||||
*/
|
*/
|
||||||
public async paste(position: PastePosition = {}): Promise<MNode[] | void> {
|
public async paste(position: PastePosition = {}): Promise<MNode | MNode[]> {
|
||||||
const config = await storageService.getItem(COPY_STORAGE_KEY);
|
const config: MNode[] = await storageService.getItem(COPY_STORAGE_KEY);
|
||||||
|
|
||||||
if (!config) return;
|
if (!Array.isArray(config)) return [];
|
||||||
|
|
||||||
const pasteConfigs = await beforePaste(position, config);
|
const pasteConfigs = await beforePaste(position, config);
|
||||||
|
|
||||||
return await this.multiAdd(pasteConfigs);
|
return this.add(pasteConfigs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -590,7 +606,7 @@ class Editor extends BaseService {
|
|||||||
return srcValue;
|
return srcValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
newConfig.style = getInitPositionStyle(newConfig.style, layout, target, stage);
|
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
||||||
|
|
||||||
target.items.push(newConfig);
|
target.items.push(newConfig);
|
||||||
|
|
||||||
@ -633,7 +649,7 @@ class Editor extends BaseService {
|
|||||||
const node = toRaw(this.get('node'));
|
const node = toRaw(this.get('node'));
|
||||||
if (!node || isPage(node)) return;
|
if (!node || isPage(node)) return;
|
||||||
|
|
||||||
const { style, id } = node;
|
const { style, id, type } = node;
|
||||||
if (!style || style.position !== 'absolute') return;
|
if (!style || style.position !== 'absolute') return;
|
||||||
|
|
||||||
if (top && !isNumber(style.top)) return;
|
if (top && !isNumber(style.top)) return;
|
||||||
@ -641,6 +657,7 @@ class Editor extends BaseService {
|
|||||||
|
|
||||||
this.update({
|
this.update({
|
||||||
id,
|
id,
|
||||||
|
type,
|
||||||
style: {
|
style: {
|
||||||
...style,
|
...style,
|
||||||
left: Number(style.left) + left,
|
left: Number(style.left) + left,
|
||||||
|
@ -88,10 +88,10 @@ export const getRelativeStyle = (style: Record<string, any> = {}): Record<string
|
|||||||
left: 0,
|
left: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getMiddleTop = (style: Record<string, any> = {}, parentNode: MNode, stage: StageCore) => {
|
const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) => {
|
||||||
let height = style.height || 0;
|
let height = node.style?.height || 0;
|
||||||
|
|
||||||
if (!stage || typeof style.top !== 'undefined' || !parentNode.style) return style.top;
|
if (!stage || typeof node.style?.top !== 'undefined' || !parentNode.style) return node.style?.top;
|
||||||
|
|
||||||
if (!isNumber(height)) {
|
if (!isNumber(height)) {
|
||||||
height = 0;
|
height = 0;
|
||||||
@ -103,20 +103,15 @@ const getMiddleTop = (style: Record<string, any> = {}, parentNode: MNode, stage:
|
|||||||
const { scrollTop = 0, wrapperHeight } = stage.mask;
|
const { scrollTop = 0, wrapperHeight } = stage.mask;
|
||||||
return (wrapperHeight - height) / 2 + scrollTop;
|
return (wrapperHeight - height) / 2 + scrollTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (parentHeight - height) / 2;
|
return (parentHeight - height) / 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getInitPositionStyle = (
|
export const getInitPositionStyle = (style: Record<string, any> = {}, layout: Layout) => {
|
||||||
style: Record<string, any> = {},
|
|
||||||
layout: Layout,
|
|
||||||
parentNode: MNode,
|
|
||||||
stage: StageCore,
|
|
||||||
) => {
|
|
||||||
if (layout === Layout.ABSOLUTE) {
|
if (layout === Layout.ABSOLUTE) {
|
||||||
return {
|
return {
|
||||||
...style,
|
...style,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: getMiddleTop(style, parentNode, stage),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,3 +225,15 @@ export const fixNodeLeft = (config: MNode, parent: MContainer, doc?: Document) =
|
|||||||
|
|
||||||
return config.style.left;
|
return config.style.left;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const fixNodePosition = (config: MNode, parent: MContainer, stage: StageCore | null) => {
|
||||||
|
if (config.style?.position !== 'absolute') {
|
||||||
|
return config.style;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...(config.style || {}),
|
||||||
|
top: getMiddleTop(config, parent, stage),
|
||||||
|
left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -8,8 +8,8 @@ import { isPage } from '@tmagic/utils';
|
|||||||
import editorService from '../services/editor';
|
import editorService from '../services/editor';
|
||||||
import historyService from '../services/history';
|
import historyService from '../services/history';
|
||||||
import propsService from '../services/props';
|
import propsService from '../services/props';
|
||||||
import { AddMNode, Layout, PastePosition } from '../type';
|
import { AddMNode, PastePosition } from '../type';
|
||||||
import { fixNodeLeft, generatePageNameByApp, getInitPositionStyle, getNodeIndex } from '../utils/editor';
|
import { generatePageNameByApp, getInitPositionStyle, getNodeIndex } from '../utils/editor';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 粘贴前置操作:返回分配了新id以及校准了坐标的配置
|
* 粘贴前置操作:返回分配了新id以及校准了坐标的配置
|
||||||
@ -17,7 +17,7 @@ import { fixNodeLeft, generatePageNameByApp, getInitPositionStyle, getNodeIndex
|
|||||||
* @param config 待粘贴的元素配置(复制时保存的那份配置)
|
* @param config 待粘贴的元素配置(复制时保存的那份配置)
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const beforePaste = async (position: PastePosition, config: MNode[]) => {
|
export const beforePaste = async (position: PastePosition, config: MNode[]): Promise<MNode[]> => {
|
||||||
if (!config[0]?.style) return config;
|
if (!config[0]?.style) return config;
|
||||||
const curNode = editorService.get<MContainer>('node');
|
const curNode = editorService.get<MContainer>('node');
|
||||||
// 将数组中第一个元素的坐标作为参照点
|
// 将数组中第一个元素的坐标作为参照点
|
||||||
@ -69,54 +69,6 @@ export const beforePaste = async (position: PastePosition, config: MNode[]) => {
|
|||||||
return pasteConfigs;
|
return pasteConfigs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增元素前置操作,实现了在编辑器中新增元素节点,并返回新增元素信息以供stage更新
|
|
||||||
* @param addNode 待添加元素的配置
|
|
||||||
* @param parent 父级容器(可选)
|
|
||||||
* @returns 新增的元素,父级元素,布局方式,是否为根页面
|
|
||||||
*/
|
|
||||||
export const beforeAdd = async (
|
|
||||||
addNode: AddMNode,
|
|
||||||
parent?: MContainer | null,
|
|
||||||
): Promise<{ parentNode: MContainer; newNode: MNode; layout: Layout; isPage: boolean }> => {
|
|
||||||
// 加入inputEvent是为给业务扩展时可以获取到更多的信息,只有在使用拖拽添加组件时才有改对象
|
|
||||||
const { type, inputEvent, ...config } = addNode;
|
|
||||||
const curNode = editorService.get<MContainer>('node');
|
|
||||||
|
|
||||||
let parentNode: MContainer | undefined;
|
|
||||||
const isPage = type === NodeType.PAGE;
|
|
||||||
|
|
||||||
if (isPage) {
|
|
||||||
parentNode = editorService.get<MApp>('root');
|
|
||||||
// 由于支持中间件扩展,在parent参数为undefined时,parent会变成next函数
|
|
||||||
} else if (parent && typeof parent !== 'function') {
|
|
||||||
parentNode = parent;
|
|
||||||
} else if (curNode.items) {
|
|
||||||
parentNode = curNode;
|
|
||||||
} else {
|
|
||||||
parentNode = editorService.getParentById(curNode.id, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parentNode) throw new Error('未找到父元素');
|
|
||||||
|
|
||||||
const layout = await editorService.getLayout(toRaw(parentNode), addNode as MNode);
|
|
||||||
const newNode = { ...toRaw(await propsService.getPropsValue(type, config)) };
|
|
||||||
newNode.style = getInitPositionStyle(newNode.style, layout, parentNode, editorService.get<StageCore>('stage'));
|
|
||||||
|
|
||||||
if ((parentNode?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && newNode.type !== NodeType.PAGE) {
|
|
||||||
throw new Error('app下不能添加组件');
|
|
||||||
}
|
|
||||||
// 新增节点添加到配置中
|
|
||||||
parentNode?.items?.push(newNode);
|
|
||||||
// 返回新增信息以供stage更新
|
|
||||||
return {
|
|
||||||
parentNode,
|
|
||||||
newNode,
|
|
||||||
layout,
|
|
||||||
isPage,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将元素粘贴到容器内时,将相对于画布坐标转换为相对于容器的坐标
|
* 将元素粘贴到容器内时,将相对于画布坐标转换为相对于容器的坐标
|
||||||
* @param position PastePosition 粘贴时相对于画布的坐标
|
* @param position PastePosition 粘贴时相对于画布的坐标
|
||||||
@ -135,27 +87,6 @@ export const getPositionInContainer = (position: PastePosition = {}, id: Id) =>
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 将新增元素事件通知到stage以更新渲染
|
|
||||||
* @param parentNode 父元素
|
|
||||||
* @param newNode 当前新增元素
|
|
||||||
* @param layout 布局方式
|
|
||||||
*/
|
|
||||||
export const notifyAddToStage = async (parentNode: MContainer, newNode: MNode, layout: Layout) => {
|
|
||||||
const stage = editorService.get<StageCore | null>('stage');
|
|
||||||
const root = editorService.get<MApp>('root');
|
|
||||||
|
|
||||||
await stage?.add({ config: cloneDeep(newNode), parent: cloneDeep(parentNode), root: cloneDeep(root) });
|
|
||||||
|
|
||||||
if (layout === Layout.ABSOLUTE) {
|
|
||||||
const fixedLeft = fixNodeLeft(newNode, parentNode, stage?.renderer.contentWindow?.document);
|
|
||||||
if (typeof fixedLeft !== 'undefined' && newNode.style) {
|
|
||||||
newNode.style.left = fixedLeft;
|
|
||||||
await stage?.update({ config: cloneDeep(newNode), root: cloneDeep(root) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除前置操作:实现了在编辑器中删除元素节点,并返回父级元素信息以供stage更新
|
* 删除前置操作:实现了在编辑器中删除元素节点,并返回父级元素信息以供stage更新
|
||||||
* @param node 待删除的节点
|
* @param node 待删除的节点
|
||||||
@ -208,3 +139,25 @@ export const beforeRemove = async (node: MNode): Promise<MContainer | void> => {
|
|||||||
}
|
}
|
||||||
return parent;
|
return parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getAddParent = (addNode: AddMNode | MNode[]) => {
|
||||||
|
const curNode = editorService.get<MContainer>('node');
|
||||||
|
|
||||||
|
let parentNode;
|
||||||
|
if (!Array.isArray(addNode) && isPage(addNode as MNode)) {
|
||||||
|
parentNode = editorService.get<MApp>('root');
|
||||||
|
} else if (curNode.items) {
|
||||||
|
parentNode = curNode;
|
||||||
|
} else {
|
||||||
|
parentNode = editorService.getParentById(curNode.id, false);
|
||||||
|
}
|
||||||
|
return parentNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDefaultConfig = async (addNode: AddMNode, parentNode: MContainer) => {
|
||||||
|
const { type, inputEvent, ...config } = addNode;
|
||||||
|
const layout = await editorService.getLayout(toRaw(parentNode), addNode as MNode);
|
||||||
|
const newNode = { ...toRaw(await propsService.getPropsValue(type, config)) };
|
||||||
|
newNode.style = getInitPositionStyle(newNode.style, layout);
|
||||||
|
return newNode;
|
||||||
|
};
|
||||||
|
@ -208,7 +208,9 @@ describe('add', () => {
|
|||||||
// 添加后会选中这个节点
|
// 添加后会选中这个节点
|
||||||
const node = editorService.get('node');
|
const node = editorService.get('node');
|
||||||
const parent = editorService.get('parent');
|
const parent = editorService.get('parent');
|
||||||
expect(node.id).toBe(newNode.id);
|
if (!Array.isArray(newNode)) {
|
||||||
|
expect(node.id).toBe(newNode.id);
|
||||||
|
}
|
||||||
expect(parent.items).toHaveLength(3);
|
expect(parent.items).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -222,7 +224,9 @@ describe('add', () => {
|
|||||||
});
|
});
|
||||||
const node = editorService.get('node');
|
const node = editorService.get('node');
|
||||||
const parent = editorService.get('parent');
|
const parent = editorService.get('parent');
|
||||||
expect(node.id).toBe(newNode.id);
|
if (!Array.isArray(newNode)) {
|
||||||
|
expect(node.id).toBe(newNode.id);
|
||||||
|
}
|
||||||
expect(parent.items).toHaveLength(3);
|
expect(parent.items).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -237,7 +241,9 @@ describe('add', () => {
|
|||||||
rootNode,
|
rootNode,
|
||||||
);
|
);
|
||||||
const node = editorService.get('node');
|
const node = editorService.get('node');
|
||||||
expect(node.id).toBe(newNode.id);
|
if (!Array.isArray(newNode)) {
|
||||||
|
expect(node.id).toBe(newNode.id);
|
||||||
|
}
|
||||||
expect(rootNode.items.length).toBe(2);
|
expect(rootNode.items.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ export default class StageCore extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []) {
|
public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []): NodeJS.Timeout {
|
||||||
return globalThis.setTimeout(() => {
|
return globalThis.setTimeout(() => {
|
||||||
this.addContainerHighlightClassName(event, exclude);
|
this.addContainerHighlightClassName(event, exclude);
|
||||||
}, this.containerHighlightDuration);
|
}, this.containerHighlightDuration);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user