diff --git a/packages/core/src/EventHelper.ts b/packages/core/src/EventHelper.ts index 7ff163da..366c4e39 100644 --- a/packages/core/src/EventHelper.ts +++ b/packages/core/src/EventHelper.ts @@ -32,7 +32,7 @@ import { type EventActionItem, type EventConfig, } from '@tmagic/schema'; -import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX } from '@tmagic/utils'; +import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX, getIdFromEl } from '@tmagic/utils'; import type { default as TMagicApp } from './App'; import type { default as TMagicNode } from './Node'; @@ -49,14 +49,16 @@ const getDirectComponent = (element: HTMLElement | null, app: TMagicApp): TMagic return; } - if (!element.id) { + const id = getIdFromEl()(element); + + if (!id) { return getDirectComponent(element.parentElement, app); } const node = app.getNode( - element.id, - element.dataset.iteratorContainerId?.split(','), - element.dataset.iteratorIndex?.split(',').map((i) => globalThis.parseInt(i, 10)), + id, + element.dataset.tmagicIteratorContainerId?.split(','), + element.dataset.tmagicIteratorIndex?.split(',').map((i) => globalThis.parseInt(i, 10)), ); return node; diff --git a/packages/editor/src/editorProps.ts b/packages/editor/src/editorProps.ts index e377e6e8..e51f3143 100644 --- a/packages/editor/src/editorProps.ts +++ b/packages/editor/src/editorProps.ts @@ -10,6 +10,7 @@ import StageCore, { RenderType, type UpdateDragEl, } from '@tmagic/stage'; +import { getIdFromEl } from '@tmagic/utils'; import type { ComponentGroup, @@ -114,7 +115,7 @@ export const defaultEditorProps = { eventMethodList: () => ({}), datasourceValues: () => ({}), datasourceConfigs: () => ({}), - canSelect: (el: HTMLElement) => Boolean(el.id), + canSelect: (el: HTMLElement) => Boolean(getIdFromEl()(el)), isContainer: (el: HTMLElement) => el.classList.contains('magic-ui-container'), codeOptions: () => ({}), }; diff --git a/packages/editor/src/fields/UISelect.vue b/packages/editor/src/fields/UISelect.vue index 3b9b5c73..1d9f8c0d 100644 --- a/packages/editor/src/fields/UISelect.vue +++ b/packages/editor/src/fields/UISelect.vue @@ -48,8 +48,9 @@ import { throttle } from 'lodash-es'; import { TMagicButton, TMagicTooltip } from '@tmagic/design'; import type { FieldProps, FormItem, FormState } from '@tmagic/form'; import type { Id } from '@tmagic/schema'; +import { getIdFromEl } from '@tmagic/utils'; -import { Services, UI_SELECT_MODE_EVENT_NAME } from '@editor/type'; +import { type Services, UI_SELECT_MODE_EVENT_NAME } from '@editor/type'; defineOptions({ name: 'MFieldsUISelect', @@ -71,11 +72,12 @@ const cancelHandler = () => { globalThis.document.removeEventListener(UI_SELECT_MODE_EVENT_NAME, clickHandler as EventListener); }; -const clickHandler = ({ detail }: Event & { detail: any }) => { - if (detail.id) { - props.model[props.name] = detail.id; - emit('change', detail.id); - mForm?.$emit('field-change', props.prop, detail.id); +const clickHandler = ({ detail }: Event & { detail: HTMLElement }) => { + const id = getIdFromEl()(detail); + if (id) { + props.model[props.name] = id; + emit('change', id); + mForm?.$emit('field-change', props.prop, id); } if (cancelHandler) { @@ -104,21 +106,24 @@ const deleteHandler = () => { }; const selectNode = async (id: Id) => { - await services?.editorService.select(id); - services?.editorService.get('stage')?.select(id); - services?.stageOverlayService.get('stage')?.select(id); + if (!services) return; + await services.editorService.select(id); + services.editorService.get('stage')?.select(id); + services.stageOverlayService.get('stage')?.select(id); }; const highlight = throttle((id: Id) => { - services?.editorService.highlight(id); - services?.editorService.get('stage')?.highlight(id); - services?.stageOverlayService.get('stage')?.highlight(id); + if (!services) return; + services.editorService.highlight(id); + services.editorService.get('stage')?.highlight(id); + services.stageOverlayService.get('stage')?.highlight(id); }, 150); const unhighlight = () => { - services?.editorService.set('highlightNode', null); - services?.editorService.get('stage')?.clearHighlight(); - services?.stageOverlayService.get('stage')?.clearHighlight(); + if (!services) return; + services.editorService.set('highlightNode', null); + services.editorService.get('stage')?.clearHighlight(); + services.stageOverlayService.get('stage')?.clearHighlight(); }; diff --git a/packages/editor/src/hooks/use-stage.ts b/packages/editor/src/hooks/use-stage.ts index 00ae2883..d2c6b1bf 100644 --- a/packages/editor/src/hooks/use-stage.ts +++ b/packages/editor/src/hooks/use-stage.ts @@ -2,6 +2,7 @@ import { computed, watch } from 'vue'; import type { MNode } from '@tmagic/schema'; import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage'; +import { getIdFromEl } from '@tmagic/utils'; import editorService from '@editor/services/editor'; import uiService from '@editor/services/ui'; @@ -71,27 +72,32 @@ export const useStage = (stageOptions: StageOptions) => { }); stage.on('select', (el: HTMLElement) => { - if (`${editorService.get('node')?.id}` === el.id && editorService.get('nodes').length === 1) return; - editorService.select(el.id); + const id = getIdFromEl()(el); + if (`${editorService.get('node')?.id}` === id && editorService.get('nodes').length === 1) return; + id && editorService.select(id); }); stage.on('highlight', (el: HTMLElement) => { - editorService.highlight(el.id); + const id = getIdFromEl()(el); + id && editorService.highlight(id); }); stage.on('multi-select', (els: HTMLElement[]) => { - editorService.multiSelect(els.map((el) => el.id)); + const ids = els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[]; + editorService.multiSelect(ids); }); stage.on('update', (ev: UpdateEventData) => { if (ev.parentEl) { for (const data of ev.data) { - editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id); + const id = getIdFromEl()(data.el); + const pId = getIdFromEl()(ev.parentEl); + id && pId && editorService.moveToContainer({ id, style: data.style }, pId); } return; } - editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style }))); + editorService.update(ev.data.map((data) => ({ id: getIdFromEl()(data.el) || '', style: data.style }))); }); stage.on('sort', (ev: SortEventData) => { @@ -99,7 +105,7 @@ export const useStage = (stageOptions: StageOptions) => { }); stage.on('remove', (ev: RemoveEventData) => { - const nodes = ev.data.map(({ el }) => editorService.getNodeById(el.id)); + const nodes = ev.data.map(({ el }) => editorService.getNodeById(getIdFromEl()(el) || '')); editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[]); }); diff --git a/packages/editor/src/layouts/workspace/viewer/NodeListMenu.vue b/packages/editor/src/layouts/workspace/viewer/NodeListMenu.vue index 14a98e7f..86a9c2bd 100644 --- a/packages/editor/src/layouts/workspace/viewer/NodeListMenu.vue +++ b/packages/editor/src/layouts/workspace/viewer/NodeListMenu.vue @@ -26,6 +26,7 @@ import { computed, inject, nextTick, ref, watch } from 'vue'; import { TMagicTooltip } from '@tmagic/design'; import type { MNode } from '@tmagic/schema'; +import { getIdFromEl } from '@tmagic/utils'; import FloatingBox from '@editor/components/FloatingBox.vue'; import Tree from '@editor/components/Tree.vue'; @@ -61,7 +62,7 @@ const unWatch = watch( stage.on('select', (el: HTMLElement, event: MouseEvent) => { const els = stage.renderer.getElementsFromPoint(event) || []; - const ids = els.map((el) => el.id).filter((id) => Boolean(id)); + const ids = els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[]; buttonVisible.value = ids.length > 3; diff --git a/packages/editor/src/layouts/workspace/viewer/Stage.vue b/packages/editor/src/layouts/workspace/viewer/Stage.vue index 67e7665d..d7e14881 100644 --- a/packages/editor/src/layouts/workspace/viewer/Stage.vue +++ b/packages/editor/src/layouts/workspace/viewer/Stage.vue @@ -46,7 +46,7 @@ import { cloneDeep } from 'lodash-es'; import type { MApp, MContainer } from '@tmagic/schema'; import StageCore, { getOffset, Runtime } from '@tmagic/stage'; -import { calcValueByFontsize } from '@tmagic/utils'; +import { calcValueByFontsize, getIdFromEl } from '@tmagic/utils'; import ScrollViewer from '@editor/components/ScrollViewer.vue'; import { useStage } from '@editor/hooks/use-stage'; @@ -200,8 +200,9 @@ const dropHandler = async (e: DragEvent) => { const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`); let parent: MContainer | undefined | null = page.value; - if (parentEl) { - parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer; + const parentId = getIdFromEl()(parentEl); + if (parentId) { + parent = services?.editorService.getNodeById(parentId, false) as MContainer; } if (parent && stageContainer.value && stage) { diff --git a/packages/editor/src/services/editor.ts b/packages/editor/src/services/editor.ts index 05fc26d0..6d691e58 100644 --- a/packages/editor/src/services/editor.ts +++ b/packages/editor/src/services/editor.ts @@ -23,7 +23,7 @@ import { Writable } from 'type-fest'; import { Target, type TargetOptions, Watcher } from '@tmagic/dep'; import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { NodeType } from '@tmagic/schema'; -import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; +import { calcValueByFontsize, getElById, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; import BaseService from '@editor/services//BaseService'; import propsService from '@editor/services//props'; @@ -759,7 +759,7 @@ class Editor extends BaseService { const doc = stage?.renderer.contentWindow?.document; if (doc) { - const el = doc.getElementById(`${node.id}`); + const el = getElById()(doc, node.id); const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent; if (parentEl && el) { node.style.left = calcValueByFontsize(doc, (parentEl.clientWidth - el.clientWidth) / 2); diff --git a/packages/editor/src/services/stageOverlay.ts b/packages/editor/src/services/stageOverlay.ts index 0524d6c4..ca74f544 100644 --- a/packages/editor/src/services/stageOverlay.ts +++ b/packages/editor/src/services/stageOverlay.ts @@ -2,6 +2,7 @@ import { reactive } from 'vue'; import type { Writable } from 'type-fest'; import StageCore from '@tmagic/stage'; +import { getIdFromEl } from '@tmagic/utils'; import { useStage } from '@editor/hooks/use-stage'; import BaseService from '@editor/services//BaseService'; @@ -169,7 +170,8 @@ class StageOverlay extends BaseService { }); if (await stageOptions?.canSelect?.(contentEl)) { - subStage?.select(contentEl.id); + const id = getIdFromEl()(contentEl); + id && subStage?.select(id); } } diff --git a/packages/editor/src/utils/editor.ts b/packages/editor/src/utils/editor.ts index e7af210c..e01d340a 100644 --- a/packages/editor/src/utils/editor.ts +++ b/packages/editor/src/utils/editor.ts @@ -21,9 +21,10 @@ import serialize from 'serialize-javascript'; import type { Id, MApp, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { NodeType } from '@tmagic/schema'; import type StageCore from '@tmagic/stage'; -import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; +import { calcValueByFontsize, getElById, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; import { Layout } from '@editor/type'; + export const COPY_STORAGE_KEY = '$MagicEditorCopyData'; export const COPY_CODE_STORAGE_KEY = '$MagicEditorCopyCode'; export const COPY_DS_STORAGE_KEY = '$MagicEditorCopyDataSource'; @@ -239,8 +240,8 @@ export const getGuideLineFromCache = (key: string): number[] => { export const fixNodeLeft = (config: MNode, parent: MContainer, doc?: Document) => { if (!doc || !config.style || !isNumber(config.style.left)) return config.style?.left; - const el = doc.getElementById(`${config.id}`); - const parentEl = doc.getElementById(`${parent.id}`); + const el = getElById()(doc, `${config.id}`); + const parentEl = getElById()(doc, `${parent.id}`); const left = Number(config.style?.left) || 0; if (el && parentEl) { diff --git a/packages/editor/src/utils/index.ts b/packages/editor/src/utils/index.ts index 6caf2fe8..fc7f297b 100644 --- a/packages/editor/src/utils/index.ts +++ b/packages/editor/src/utils/index.ts @@ -22,3 +22,7 @@ export * from './logger'; export * from './editor'; export * from './operator'; export * from './data-source'; +export * from './idle-task'; +export * from './scroll-viewer'; +export * from './tree'; +export * from './undo-redo'; diff --git a/packages/editor/src/utils/operator.ts b/packages/editor/src/utils/operator.ts index 6fb2486a..a5564b48 100644 --- a/packages/editor/src/utils/operator.ts +++ b/packages/editor/src/utils/operator.ts @@ -2,7 +2,7 @@ import { toRaw } from 'vue'; import { isEmpty } from 'lodash-es'; import { Id, MContainer, MNode, NodeType } from '@tmagic/schema'; -import { calcValueByFontsize, isPage, isPageFragment } from '@tmagic/utils'; +import { calcValueByFontsize, getElById, isPage, isPageFragment } from '@tmagic/utils'; import editorService from '@editor/services/editor'; import propsService from '@editor/services/props'; @@ -73,7 +73,8 @@ export const beforePaste = (position: PastePosition, config: MNode[], doc?: Docu */ export const getPositionInContainer = (position: PastePosition = {}, id: Id, doc?: Document) => { let { left = 0, top = 0 } = position; - const parentEl = editorService.get('stage')?.renderer?.contentWindow?.document.getElementById(`${id}`); + const stageDoc = editorService.get('stage')?.renderer?.contentWindow?.document; + const parentEl = stageDoc && getElById()(stageDoc, `${id}`); const parentElRect = parentEl?.getBoundingClientRect(); left = left - calcValueByFontsize(doc, parentElRect?.left || 0); top = top - calcValueByFontsize(doc, parentElRect?.top || 0); diff --git a/packages/stage/src/ActionManager.ts b/packages/stage/src/ActionManager.ts index e63d92c0..b6ba2ce8 100644 --- a/packages/stage/src/ActionManager.ts +++ b/packages/stage/src/ActionManager.ts @@ -23,7 +23,7 @@ import type { MoveableOptions, OnDragStart } from 'moveable'; import { Env } from '@tmagic/core'; import type { Id } from '@tmagic/schema'; -import { addClassName, getDocument, removeClassNameByClassName } from '@tmagic/utils'; +import { addClassName, getDocument, getIdFromEl, removeClassNameByClassName } from '@tmagic/utils'; import { AbleActionEventType, @@ -99,13 +99,14 @@ export default class ActionManager extends EventEmitter { } const el = await this.getElementFromPoint(event); - if (!el) { + const id = getIdFromEl()(el); + if (!id) { this.clearHighlight(); return; } this.emit('mousemove', event); - this.highlight(el.id); + this.highlight(id); }, throttleTime); constructor(config: ActionManagerConfig) { @@ -118,7 +119,7 @@ export default class ActionManager extends EventEmitter { this.disabledMultiSelect = config.disabledMultiSelect ?? false; this.getTargetElement = config.getTargetElement; this.getElementsFromPoint = config.getElementsFromPoint; - this.canSelect = config.canSelect || ((el: HTMLElement) => !!el.id); + this.canSelect = config.canSelect || ((el: HTMLElement) => Boolean(getIdFromEl()(el))); this.getRenderDocument = config.getRenderDocument; this.isContainer = config.isContainer; @@ -187,7 +188,7 @@ export default class ActionManager extends EventEmitter { */ public isSelectedEl(el: HTMLElement): boolean { // 有可能dom已经重新渲染,不再是原来的dom了,所以这里判断id,而不是判断el === this.selectedDom - return el.id === this.selectedEl?.id; + return getIdFromEl()(el) === getIdFromEl()(this.selectedEl); } public setSelectedEl(el: HTMLElement | null): void { @@ -224,7 +225,7 @@ export default class ActionManager extends EventEmitter { let stopped = false; const stop = () => (stopped = true); for (const el of els) { - if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && (await this.isElCanSelect(el, event, stop))) { + if (!getIdFromEl()(el)?.startsWith(GHOST_EL_ID_PREFIX) && (await this.isElCanSelect(el, event, stop))) { if (stopped) break; return el; } @@ -344,7 +345,11 @@ export default class ActionManager extends EventEmitter { const els = this.getElementsFromPoint(event); for (const el of els) { - if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && (await this.isContainer?.(el)) && !excludeElList.includes(el)) { + if ( + !getIdFromEl()(el)?.startsWith(GHOST_EL_ID_PREFIX) && + (await this.isContainer?.(el)) && + !excludeElList.includes(el) + ) { addClassName(el, doc, this.containerHighlightClassName); break; } @@ -477,9 +482,9 @@ export default class ActionManager extends EventEmitter { if (typeof options === 'function') { const cfg: CustomizeMoveableOptionsCallbackConfig = { targetEl: this.selectedEl, - targetElId: this.selectedEl?.id, + targetElId: getIdFromEl()(this.selectedEl), targetEls: this.selectedElList, - targetElIds: this.selectedElList?.map((item) => item.id), + targetElIds: this.selectedElList?.map((item) => getIdFromEl()(item) || ''), isMulti, document: this.getRenderDocument(), }; @@ -507,7 +512,7 @@ export default class ActionManager extends EventEmitter { } // 判断元素是否已在多选列表 - const existIndex = this.selectedElList.findIndex((selectedDom) => selectedDom.id === el.id); + const existIndex = this.selectedElList.findIndex((selectedDom) => getIdFromEl()(selectedDom) === getIdFromEl()(el)); if (existIndex !== -1) { // 再次点击取消选中 if (this.selectedElList.length > 1) { diff --git a/packages/stage/src/DragResizeHelper.ts b/packages/stage/src/DragResizeHelper.ts index 9a4ce8b5..19714372 100644 --- a/packages/stage/src/DragResizeHelper.ts +++ b/packages/stage/src/DragResizeHelper.ts @@ -32,13 +32,15 @@ import type { } from 'moveable'; import MoveableHelper from 'moveable-helper'; -import { calcValueByFontsize } from '@tmagic/utils'; +import { calcValueByFontsize, getIdFromEl, setIdToEl } from '@tmagic/utils'; import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, Mode, ZIndex } from './const'; import TargetShadow from './TargetShadow'; import type { DragResizeHelperConfig, Rect, TargetElement } from './types'; import { getAbsolutePosition, getBorderWidth, getMarginValue, getOffset } from './util'; +const getId = getIdFromEl(); + /** * 拖拽/改变大小等操作发生时,moveable会抛出各种状态事件,DragResizeHelper负责响应这些事件,对目标节点target和拖拽节点targetShadow进行修改; * 其中目标节点是DragResizeHelper直接改的,targetShadow作为直接被操作的拖拽框,是调用moveableHelper改的; @@ -239,15 +241,15 @@ export default class DragResizeHelper { events.forEach((ev) => { const { width, height, beforeTranslate } = ev.drag; const frameSnapShot = this.framesSnapShot.find( - (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''), + (frameItem) => frameItem.id === getId(ev.target)?.replace(DRAG_EL_ID_PREFIX, ''), ); if (!frameSnapShot) return; const targeEl = this.targetList.find( - (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''), + (targetItem) => targetItem.id === getId(ev.target)?.replace(DRAG_EL_ID_PREFIX, ''), ); if (!targeEl) return; // 元素与其所属组同时加入多选列表时,只更新父元素 - const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id); + const isParentIncluded = this.targetList.find((targetItem) => getId(targetItem) === getId(targeEl.parentElement)); if (!isParentIncluded) { // 更新页面元素位置 @@ -277,15 +279,18 @@ export default class DragResizeHelper { // 拖动过程更新 events.forEach((ev) => { const frameSnapShot = this.framesSnapShot.find( - (frameItem) => ev.target.id.startsWith(DRAG_EL_ID_PREFIX) && ev.target.id.endsWith(frameItem.id), + (frameItem) => getId(ev.target)?.startsWith(DRAG_EL_ID_PREFIX) && getId(ev.target)?.endsWith(frameItem.id), ); if (!frameSnapShot) return; const targeEl = this.targetList.find( - (targetItem) => ev.target.id.startsWith(DRAG_EL_ID_PREFIX) && ev.target.id.endsWith(targetItem.id), + (targetItem) => + getId(ev.target)?.startsWith(DRAG_EL_ID_PREFIX) && + getId(targetItem) && + getId(ev.target)?.endsWith(getId(targetItem)!), ); if (!targeEl) return; // 元素与其所属组同时加入多选列表时,只更新父元素 - const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id); + const isParentIncluded = this.targetList.find((targetItem) => getId(targetItem) === getId(targeEl.parentElement)); if (!isParentIncluded) { // 更新页面元素位置 const { marginLeft, marginTop } = getMarginValue(targeEl); @@ -312,7 +317,7 @@ export default class DragResizeHelper { const shadowEls = this.getShadowEls(); if (shadowEls.length) { - shadowEl = shadowEls.find((item) => item.id.endsWith(el.id)); + shadowEl = shadowEls.find((item) => getId(item)?.endsWith(getId(el) || '')); } if (parentEl && this.mode === Mode.ABSOLUTE && shadowEl) { @@ -348,14 +353,18 @@ export default class DragResizeHelper { events.forEach((ev) => { // 实际目标元素 const matchEventTarget = this.targetList.find( - (targetItem) => ev.target.id.startsWith(DRAG_EL_ID_PREFIX) && ev.target.id.endsWith(targetItem.id), + (targetItem) => + getId(ev.target)?.startsWith(DRAG_EL_ID_PREFIX) && getId(ev.target)?.endsWith(getId(targetItem) || ''), ); if (!matchEventTarget) return; - this.framesSnapShot.push({ - left: matchEventTarget.offsetLeft, - top: matchEventTarget.offsetTop, - id: matchEventTarget.id, - }); + + const id = getId(matchEventTarget); + id && + this.framesSnapShot.push({ + left: matchEventTarget.offsetLeft, + top: matchEventTarget.offsetTop, + id, + }); }); } @@ -370,7 +379,7 @@ export default class DragResizeHelper { const ghostEl = el.cloneNode(true) as HTMLElement; this.setGhostElChildrenId(ghostEl); const { top, left } = getAbsolutePosition(el, getOffset(el)); - ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`; + setIdToEl()(ghostEl, `${GHOST_EL_ID_PREFIX}${getId(el)}`); ghostEl.style.zIndex = ZIndex.GHOST_EL; ghostEl.style.opacity = '.5'; ghostEl.style.position = 'absolute'; @@ -384,8 +393,10 @@ export default class DragResizeHelper { private setGhostElChildrenId(el: Element): void { for (const child of Array.from(el.children)) { - if (child.id) { - child.id = `${GHOST_EL_ID_PREFIX}${child.id}`; + const el = child as HTMLElement; + const id = getId(el); + if (id) { + setIdToEl()(el, `${GHOST_EL_ID_PREFIX}${id}`); } if (child.children.length) { diff --git a/packages/stage/src/StageCore.ts b/packages/stage/src/StageCore.ts index 77bd773b..5509c332 100644 --- a/packages/stage/src/StageCore.ts +++ b/packages/stage/src/StageCore.ts @@ -21,6 +21,7 @@ import { EventEmitter } from 'events'; import type { MoveableOptions, OnDragStart } from 'moveable'; import type { Id } from '@tmagic/schema'; +import { getIdFromEl } from '@tmagic/utils'; import ActionManager from './ActionManager'; import { DEFAULT_ZOOM } from './const'; @@ -336,13 +337,14 @@ export default class StageCore extends EventEmitter { private initActionManagerEvent(): void { this.actionManager .on('before-select', (el: HTMLElement, event?: MouseEvent) => { - this.select(el.id, event); + const id = getIdFromEl()(el); + id && this.select(id, event); }) .on('select', (selectedEl: HTMLElement, event: MouseEvent) => { this.emit('select', selectedEl, event); }) .on('before-multi-select', (els: HTMLElement[]) => { - this.multiSelect(els.map((el) => el.id)); + this.multiSelect(els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[]); }) .on('multi-select', (selectedElList: HTMLElement[], event: MouseEvent) => { this.emit('multi-select', selectedElList, event); diff --git a/packages/stage/src/StageDragResize.ts b/packages/stage/src/StageDragResize.ts index 9f926efe..6f80cdb6 100644 --- a/packages/stage/src/StageDragResize.ts +++ b/packages/stage/src/StageDragResize.ts @@ -19,6 +19,8 @@ /* eslint-disable no-param-reassign */ import Moveable, { MoveableOptions } from 'moveable'; +import { getIdFromEl } from '@tmagic/utils'; + import { Mode, StageDragStatus } from './const'; import DragResizeHelper from './DragResizeHelper'; import MoveableOptionsManager from './MoveableOptionsManager'; @@ -328,10 +330,12 @@ export default class StageDragResize extends MoveableOptionsManager { this.emit('sort', up(deltaTop, this.target)); } } else { - this.emit('sort', { - src: this.target.id, - dist: this.target.id, - }); + const id = getIdFromEl()(this.target); + id && + this.emit('sort', { + src: id, + dist: id, + }); } } diff --git a/packages/stage/src/StageMultiDragResize.ts b/packages/stage/src/StageMultiDragResize.ts index b4e1dc80..92651af7 100644 --- a/packages/stage/src/StageMultiDragResize.ts +++ b/packages/stage/src/StageMultiDragResize.ts @@ -18,6 +18,8 @@ import Moveable from 'moveable'; +import { getIdFromEl } from '@tmagic/utils'; + import { DRAG_EL_ID_PREFIX, Mode, StageDragStatus } from './const'; import DragResizeHelper from './DragResizeHelper'; import MoveableOptionsManager from './MoveableOptionsManager'; @@ -132,7 +134,8 @@ export default class StageMultiDragResize extends MoveableOptionsManager { const { inputTarget, targets } = e; // 如果有多个元素被选中,同时点击的元素在选中元素中的其中一项,可能是多选态切换为该元素的单选态,抛事件给上一层继续判断是否切换 if (targets.length > 1 && targets.includes(inputTarget)) { - this.emit('change-to-select', inputTarget.id.replace(DRAG_EL_ID_PREFIX, ''), e.inputEvent); + const id = getIdFromEl()(inputTarget as HTMLElement)?.replace(DRAG_EL_ID_PREFIX, ''); + id && this.emit('change-to-select', id, e.inputEvent); } }); } diff --git a/packages/stage/src/StageRender.ts b/packages/stage/src/StageRender.ts index af0ccd0e..d145ef44 100644 --- a/packages/stage/src/StageRender.ts +++ b/packages/stage/src/StageRender.ts @@ -19,7 +19,7 @@ import { EventEmitter } from 'events'; import { Id } from '@tmagic/schema'; -import { getHost, injectStyle, isSameDomain } from '@tmagic/utils'; +import { getElById, getHost, injectStyle, isSameDomain } from '@tmagic/utils'; import { DEFAULT_ZOOM, RenderType } from './const'; import style from './style.css?raw'; @@ -152,7 +152,7 @@ export default class StageRender extends EventEmitter { } public getTargetElement(id: Id): HTMLElement | null { - return this.getDocument()?.getElementById(`${id}`) || null; + return getElById()(this.getDocument(), id); } /** diff --git a/packages/stage/src/TargetShadow.ts b/packages/stage/src/TargetShadow.ts index 572d51db..11cbee05 100644 --- a/packages/stage/src/TargetShadow.ts +++ b/packages/stage/src/TargetShadow.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { guid } from '@tmagic/utils'; +import { getElById, getIdFromEl, guid, setIdToEl } from '@tmagic/utils'; import { Mode, ZIndex } from './const'; import type { TargetElement as ShadowElement, TargetShadowConfig, UpdateDragEl } from './types'; @@ -93,7 +93,7 @@ export default class TargetShadow { private updateEl(target: ShadowElement, src?: ShadowElement): ShadowElement { const el = src || globalThis.document.createElement('div'); - el.id = `${this.idPrefix}_${target.id}`; + setIdToEl()(el, `${this.idPrefix}_${getIdFromEl()(target)}`); el.style.cssText = getTargetElStyle(target, this.zIndex); @@ -108,7 +108,7 @@ export default class TargetShadow { el.style.transform = `translate3d(${-this.scrollLeft}px, ${-this.scrollTop}px, 0)`; } - if (!globalThis.document.getElementById(el.id)) { + if (!getElById()(globalThis.document, getIdFromEl()(el))) { this.container.append(el); } diff --git a/packages/ui-react/src/button/Button.tsx b/packages/ui-react/src/button/Button.tsx index 49818f43..b88ae9c6 100644 --- a/packages/ui-react/src/button/Button.tsx +++ b/packages/ui-react/src/button/Button.tsx @@ -34,7 +34,11 @@ const Page: React.FC = ({ config }) => { const MagicUiText = app.resolveComponent('text'); return ( -