diff --git a/packages/designer/package.json b/packages/designer/package.json index dda1156b7..d3e73d3a0 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -18,6 +18,7 @@ "@ali/lowcode-editor-core": "1.0.74", "@ali/lowcode-types": "1.0.74", "@ali/lowcode-utils": "1.0.74", + "@ali/lowcode-shell": "1.0.74", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-detecting.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-detecting.tsx index 37602d28f..595048dba 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-detecting.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-detecting.tsx @@ -79,7 +79,7 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> { const canHoverHook = current?.componentMeta.getMetadata()?.experimental?.callbacks?.onHoverHook; - const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current) : true; + const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current.internalToShellNode()) : true; if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) { diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx index b870aef7d..720cff9d9 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-resizing.tsx @@ -151,7 +151,8 @@ export class BoxResizingInstance extends Component<{ (e as any).trigger = direction; (e as any).deltaX = moveX; (e as any).deltaY = moveY; - metaData.experimental.callbacks.onResize(e, node); + const cbNode = node?.isNode ? node.internalToShellNode() : node; + metaData.experimental.callbacks.onResize(e, cbNode); } }; @@ -164,7 +165,8 @@ export class BoxResizingInstance extends Component<{ typeof metaData.experimental.callbacks.onResizeStart === 'function' ) { (e as any).trigger = direction; - metaData.experimental.callbacks.onResizeStart(e, node); + const cbNode = node?.isNode ? node.internalToShellNode() : node; + metaData.experimental.callbacks.onResizeStart(e, cbNode); } }; @@ -177,7 +179,8 @@ export class BoxResizingInstance extends Component<{ typeof metaData.experimental.callbacks.onResizeEnd === 'function' ) { (e as any).trigger = direction; - metaData.experimental.callbacks.onResizeEnd(e, node); + const cbNode = node?.isNode ? node.internalToShellNode() : node; + metaData.experimental.callbacks.onResizeEnd(e, cbNode); } const editor = globalContext.get(Editor); diff --git a/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts index 162ada1b7..b52c0fd22 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts +++ b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts @@ -109,7 +109,7 @@ export default class DragResizeEngine { doc.addEventListener('mouseup', over, true); }); - this.emitter.emit('resizestart', e, direction, node); + this.emitter.emit('resizeStart', e, direction, node); this.dragResizing = true; this.designer.detecting.enable = false; cursor.addState('ew-resize'); @@ -121,9 +121,9 @@ export default class DragResizeEngine { } onResizeStart(func: (e: MouseEvent, direction: string, node: any) => any) { - this.emitter.on('resizestart', func); + this.emitter.on('resizeStart', func); return () => { - this.emitter.removeListener('resizestart', func); + this.emitter.removeListener('resizeStart', func); }; } diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 0671cc730..0a4f83b15 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -39,6 +39,7 @@ import { } from '@ali/lowcode-utils'; import { DragObjectType, + DragNodeObject, isShaken, LocateEvent, isDragAnyObject, @@ -1135,11 +1136,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost { + const operationalNodes = nodes?.filter((node) => { const onMoveHook = node.componentMeta?.getMetadata()?.experimental?.callbacks?.onMoveHook; - const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node) : true; + const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node.internalToShellNode()) : true; return canMove; }); diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 404f95dc7..57894f1a0 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -419,7 +419,11 @@ export class NodeChildren { const callbacks = owner.componentMeta.getMetadata().experimental?.callbacks; if (callbacks?.onSubtreeModified) { try { - callbacks?.onSubtreeModified.call(node, owner, options); + callbacks?.onSubtreeModified.call( + node.internalToShellNode(), + owner.internalToShellNode(), + options, + ); } catch (e) { console.error('error when excute experimental.callbacks.onSubtreeModified', e); } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 4af456ab5..0d03761ba 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -19,6 +19,7 @@ import { } from '@ali/lowcode-types'; import { compatStage } from '@ali/lowcode-utils'; import { SettingTopEntry } from '@ali/lowcode-designer'; +import { Node as ShellNode } from '@ali/lowcode-shell'; import { Props, getConvertedExtraKey } from './props/props'; import { DocumentModel } from '../document-model'; import { NodeChildren } from './node-children'; @@ -299,7 +300,8 @@ export class Node { private didDropIn(dragment: Node) { const callbacks = this.componentMeta.getMetadata().experimental?.callbacks; if (callbacks?.onNodeAdd) { - callbacks?.onNodeAdd.call(this, dragment, this); + const cbThis = this.internalToShellNode(); + callbacks?.onNodeAdd.call(cbThis, dragment.internalToShellNode(), cbThis); } if (this._parent) { this._parent.didDropIn(dragment); @@ -309,7 +311,8 @@ export class Node { private didDropOut(dragment: Node) { const callbacks = this.componentMeta.getMetadata().experimental?.callbacks; if (callbacks?.onNodeRemove) { - callbacks?.onNodeRemove.call(this, dragment, this); + const cbThis = this.internalToShellNode(); + callbacks?.onNodeRemove.call(cbThis, dragment.internalToShellNode(), cbThis); } if (this._parent) { this._parent.didDropOut(dragment); @@ -361,6 +364,10 @@ export class Node { this._slotFor = slotFor; } + internalToShellNode(): ShellNode | null { + return ShellNode.create(this); + } + /** * 关联属性 */ diff --git a/packages/shell/src/canvas.ts b/packages/shell/src/canvas.ts new file mode 100644 index 000000000..4caa06b06 --- /dev/null +++ b/packages/shell/src/canvas.ts @@ -0,0 +1,21 @@ +import { Designer, Prop as InnerProp } from '@ali/lowcode-designer'; +import { CompositeValue, TransformStage } from '@ali/lowcode-types'; +import { designerSymbol } from './symbols'; +import DropLocation from './drop-location'; + +export default class Canvas { + private readonly [designerSymbol]: Designer; + + constructor(designer: Designer) { + this[designerSymbol] = designer; + } + + static create(designer: Designer) { + if (!designer) return null; + return new Canvas(designer); + } + + get dropLocation() { + return DropLocation.create(this[designerSymbol].dropLocation || null); + } +} \ No newline at end of file diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index d0bfba04f..fba2f3e81 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -13,6 +13,7 @@ import Detecting from './detecting'; import History from './history'; import Project from './project'; import Prop from './prop'; +import Canvas from './canvas'; import { documentSymbol, editorSymbol, nodeSymbol } from './symbols'; type IOnChangeOptions = { @@ -34,6 +35,7 @@ export default class DocumentModel { public selection: Selection; public detecting: Detecting; public history: History; + public canvas: Canvas; constructor(document: InnerDocumentModel) { this[documentSymbol] = document; @@ -41,6 +43,7 @@ export default class DocumentModel { this.selection = new Selection(document); this.detecting = new Detecting(document); this.history = new History(document); + this.canvas = new Canvas(document.designer); } static create(document: InnerDocumentModel | undefined | null) { diff --git a/packages/shell/src/drop-location.ts b/packages/shell/src/drop-location.ts new file mode 100644 index 000000000..84d9e75d0 --- /dev/null +++ b/packages/shell/src/drop-location.ts @@ -0,0 +1,22 @@ +import { + DropLocation as InnerDropLocation, +} from '@ali/lowcode-designer'; +import { dropLocationSymbol } from './symbols'; +import Node from './node'; + +export default class DropLocation { + private readonly [dropLocationSymbol]: InnerDropLocation; + + constructor(dropLocation: InnerDropLocation) { + this[dropLocationSymbol] = dropLocation; + } + + static create(dropLocation: InnerDropLocation | null) { + if (!dropLocation) return null; + return new DropLocation(dropLocation); + } + + get target() { + return Node.create(this[dropLocationSymbol].target); + } +} diff --git a/packages/shell/src/event.ts b/packages/shell/src/event.ts index 781f01254..1956b5768 100644 --- a/packages/shell/src/event.ts +++ b/packages/shell/src/event.ts @@ -12,6 +12,11 @@ export default class Event { private readonly [editorSymbol]: InnerEditor; private readonly options: EventOptions; + /** + * 内核触发的事件名 + */ + readonly names = []; + constructor(editor: InnerEditor, options: EventOptions) { this[editorSymbol] = editor; this.options = options; diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index 3ae3a502e..0fb4e7bd3 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -5,6 +5,7 @@ import { } from '@ali/lowcode-designer'; import { CompositeValue, NodeSchema, TransformStage } from '@ali/lowcode-types'; import Prop from './prop'; +import Props from './props'; import DocumentModel from './document-model'; import NodeChildren from './node-children'; import ComponentMeta from './component-meta'; @@ -134,6 +135,17 @@ export default class Node { return Prop.create(this[nodeSymbol].slotFor); } + get props() { + return Props.create(this[nodeSymbol].props); + } + + /** + * @deprecated use .children instead + */ + getChildren() { + return this.children; + } + hasSlots() { return this[nodeSymbol].hasSlots(); } @@ -146,6 +158,13 @@ export default class Node { return this[nodeSymbol].hasLoop(); } + /** + * @deprecated use .props instead + */ + getProps() { + return this.props; + } + /** * 获取指定 path 的属性模型实例 * @param path 属性路径,支持 a / a.b / a.0 等格式 diff --git a/packages/shell/src/project.ts b/packages/shell/src/project.ts index faa83c336..1a367cd73 100644 --- a/packages/shell/src/project.ts +++ b/packages/shell/src/project.ts @@ -30,6 +30,17 @@ export default class Project { return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); } + get simulatorHost() { + return SimulatorHost.create(this[projectSymbol].simulator as any || this[simulatorHostSymbol]); + } + + /** + * @deprecated use simulatorHost instead. + */ + get simulator() { + return this.simulatorHost; + } + /** * 打开一个 document * @param doc diff --git a/packages/shell/src/props.ts b/packages/shell/src/props.ts new file mode 100644 index 000000000..0392fd84c --- /dev/null +++ b/packages/shell/src/props.ts @@ -0,0 +1,88 @@ +import { Props as InnerProps, getConvertedExtraKey } from '@ali/lowcode-designer'; +import { CompositeValue, TransformStage } from '@ali/lowcode-types'; +import { propsSymbol } from './symbols'; +import Node from './node'; +import Prop from './prop'; + +export default class Props { + private readonly [propsSymbol]: InnerProps; + + constructor(props: InnerProps) { + this[propsSymbol] = props; + } + + static create(props: InnerProps | undefined | null) { + if (!props) return null; + return new Props(props); + } + + get id() { + return this[propsSymbol].id; + } + + get path() { + return this[propsSymbol].path; + } + + get node(): Node | null { + return Node.create(this[propsSymbol].getNode()); + } + + /** + * 获取指定 path 的属性模型实例 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getProp(path: string): Prop | null { + return Prop.create(this[propsSymbol].getProp(path)); + } + + /** + * 获取指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getPropValue(path: string) { + return this.getProp(path)?.getValue(); + } + + /** + * 获取指定 path 的属性模型实例, + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getExtraProp(path: string): Prop | null { + return Prop.create(this[propsSymbol].getProp(getConvertedExtraKey(path))); + } + + /** + * 获取指定 path 的属性模型实例, + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getExtraPropValue(path: string) { + return this.getExtraProp(path)?.getValue(); + } + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setPropValue(path: string, value: CompositeValue) { + return this.getProp(path)?.setValue(value); + } + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setExtraPropValue(path: string, value: CompositeValue) { + return this.getExtraProp(path)?.setValue(value); + } +} \ No newline at end of file diff --git a/packages/shell/src/simulator-host.ts b/packages/shell/src/simulator-host.ts index 006321350..6af489c70 100644 --- a/packages/shell/src/simulator-host.ts +++ b/packages/shell/src/simulator-host.ts @@ -15,6 +15,14 @@ export default class SimulatorHost { return new SimulatorHost(host); } + get contentWindow() { + return this[simulatorHostSymbol].contentWindow; + } + + get contentDocument() { + return this[simulatorHostSymbol].contentDocument; + } + set(key: string, value: any) { this[simulatorHostSymbol].set(key, value); } diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index a7724e994..94dac51ed 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -13,6 +13,8 @@ export const propSymbol = Symbol('prop'); export const detectingSymbol = Symbol('detecting'); export const selectionSymbol = Symbol('selection'); export const historySymbol = Symbol('history'); +export const canvasSymbol = Symbol('canvas'); export const componentMetaSymbol = Symbol('componentMeta'); +export const dropLocationSymbol = Symbol('dropLocation'); export const simulatorHostSymbol = Symbol('simulatorHost'); export const simulatorRendererSymbol = Symbol('simulatorRenderer'); \ No newline at end of file