Merge branch '2.x-211223' into 2.x

This commit is contained in:
lihao.ylh 2021-12-29 20:53:33 +08:00
commit f36a17f7cb
33 changed files with 514 additions and 110 deletions

View File

@ -18,6 +18,7 @@
"@ali/lowcode-editor-core": "1.0.74", "@ali/lowcode-editor-core": "1.0.74",
"@ali/lowcode-types": "1.0.74", "@ali/lowcode-types": "1.0.74",
"@ali/lowcode-utils": "1.0.74", "@ali/lowcode-utils": "1.0.74",
"@ali/lowcode-shell": "1.0.74",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5", "enzyme-adapter-react-16": "^1.15.5",

View File

@ -79,7 +79,7 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
const canHoverHook = current?.componentMeta.getMetadata()?.experimental?.callbacks?.onHoverHook; 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) { if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) {

View File

@ -151,7 +151,8 @@ export class BoxResizingInstance extends Component<{
(e as any).trigger = direction; (e as any).trigger = direction;
(e as any).deltaX = moveX; (e as any).deltaX = moveX;
(e as any).deltaY = moveY; (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' typeof metaData.experimental.callbacks.onResizeStart === 'function'
) { ) {
(e as any).trigger = direction; (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' typeof metaData.experimental.callbacks.onResizeEnd === 'function'
) { ) {
(e as any).trigger = direction; (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); const editor = globalContext.get(Editor);

View File

@ -109,7 +109,7 @@ export default class DragResizeEngine {
doc.addEventListener('mouseup', over, true); doc.addEventListener('mouseup', over, true);
}); });
this.emitter.emit('resizestart', e, direction, node); this.emitter.emit('resizeStart', e, direction, node);
this.dragResizing = true; this.dragResizing = true;
this.designer.detecting.enable = false; this.designer.detecting.enable = false;
cursor.addState('ew-resize'); cursor.addState('ew-resize');
@ -121,9 +121,9 @@ export default class DragResizeEngine {
} }
onResizeStart(func: (e: MouseEvent, direction: string, node: any) => any) { onResizeStart(func: (e: MouseEvent, direction: string, node: any) => any) {
this.emitter.on('resizestart', func); this.emitter.on('resizeStart', func);
return () => { return () => {
this.emitter.removeListener('resizestart', func); this.emitter.removeListener('resizeStart', func);
}; };
} }

View File

@ -39,6 +39,7 @@ import {
} from '@ali/lowcode-utils'; } from '@ali/lowcode-utils';
import { import {
DragObjectType, DragObjectType,
DragNodeObject,
isShaken, isShaken,
LocateEvent, LocateEvent,
isDragAnyObject, isDragAnyObject,
@ -1135,11 +1136,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
*/ */
locate(e: LocateEvent): any { locate(e: LocateEvent): any {
const { dragObject } = e; const { dragObject } = e;
const { nodes } = dragObject; const { nodes } = dragObject as DragNodeObject;
const operationalNodes = nodes?.filter((node: any) => { const operationalNodes = nodes?.filter((node) => {
const onMoveHook = node.componentMeta?.getMetadata()?.experimental?.callbacks?.onMoveHook; 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; return canMove;
}); });

View File

@ -19,7 +19,16 @@ import EventEmitter from 'events';
import { isNode, Node, ParentalNode } from './document'; import { isNode, Node, ParentalNode } from './document';
import { Designer } from './designer'; import { Designer } from './designer';
import { intlNode } from './locale'; import { intlNode } from './locale';
import { IconLock, IconUnlock, IconContainer, IconPage, IconComponent, IconRemove, IconClone, IconHidden } from './icons'; import {
IconLock,
IconUnlock,
IconContainer,
IconPage,
IconComponent,
IconRemove,
IconClone,
IconHidden,
} from './icons';
function ensureAList(list?: string | string[]): string[] | null { function ensureAList(list?: string | string[]): string[] | null {
if (!list) { if (!list) {
@ -183,10 +192,10 @@ export class ComponentMeta {
this._title = this._title =
typeof title === 'string' typeof title === 'string'
? { ? {
type: 'i18n', type: 'i18n',
'en-US': this.componentName, 'en-US': this.componentName,
'zh-CN': title, 'zh-CN': title,
} }
: title; : title;
} }
@ -265,7 +274,8 @@ export class ComponentMeta {
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let { disableBehaviors, actions } = this._transformedMetadata?.configure.component || {}; let { disableBehaviors, actions } = this._transformedMetadata?.configure.component || {};
const disabled = const disabled =
ensureAList(disableBehaviors) || (this.isRootComponent(false) ? ['copy', 'remove', 'lock', 'unlock'] : null); ensureAList(disableBehaviors) ||
(this.isRootComponent(false) ? ['copy', 'remove', 'lock', 'unlock'] : null);
actions = builtinComponentActions.concat( actions = builtinComponentActions.concat(
this.designer.getGlobalComponentActions() || [], this.designer.getGlobalComponentActions() || [],
actions || [], actions || [],
@ -291,7 +301,10 @@ export class ComponentMeta {
checkNestingUp(my: Node | NodeData, parent: ParentalNode) { checkNestingUp(my: Node | NodeData, parent: ParentalNode) {
// 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器 // 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器
if (this.parentWhitelist) { if (this.parentWhitelist) {
return this.parentWhitelist(parent, my); return this.parentWhitelist(
parent.internalToShellNode(),
isNode(my) ? my.internalToShellNode() : my,
);
} }
return true; return true;
} }
@ -302,7 +315,10 @@ export class ComponentMeta {
const _target: any = !Array.isArray(target) ? [target] : target; const _target: any = !Array.isArray(target) ? [target] : target;
return _target.every((item: Node | NodeSchema) => { return _target.every((item: Node | NodeSchema) => {
const _item = !isNode(item) ? new Node(my.document, item) : item; const _item = !isNode(item) ? new Node(my.document, item) : item;
return this.childWhitelist && this.childWhitelist(_item, my); return (
this.childWhitelist &&
this.childWhitelist(_item.internalToShellNode(), my.internalToShellNode())
);
}); });
} }
return true; return true;
@ -484,7 +500,7 @@ const builtinComponentActions: ComponentAction[] = [
}, },
}, },
condition: (node: Node) => { condition: (node: Node) => {
return (engineConfig.get('enableCanvasLock', false) && node.isContainer() && !node.isLocked); return engineConfig.get('enableCanvasLock', false) && node.isContainer() && !node.isLocked;
}, },
important: true, important: true,
}, },
@ -498,7 +514,7 @@ const builtinComponentActions: ComponentAction[] = [
}, },
}, },
condition: (node: Node) => { condition: (node: Node) => {
return (engineConfig.get('enableCanvasLock', false) && node.isContainer() && node.isLocked); return engineConfig.get('enableCanvasLock', false) && node.isContainer() && node.isLocked;
}, },
important: true, important: true,
}, },

View File

@ -44,7 +44,8 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
return null; return null;
} }
if (isDynamicSetter(this._setter)) { if (isDynamicSetter(this._setter)) {
return this._setter.call(this, this); const shellThis = this.internalToShellPropEntry();
return this._setter.call(shellThis, shellThis);
} }
return this._setter; return this._setter;
} }

View File

@ -1,6 +1,7 @@
import { obx, computed, makeObservable, runInAction } from '@ali/lowcode-editor-core'; import { obx, computed, makeObservable, runInAction } from '@ali/lowcode-editor-core';
import { GlobalEvent, IEditor, isJSExpression } from '@ali/lowcode-types'; import { GlobalEvent, IEditor, isJSExpression } from '@ali/lowcode-types';
import { uniqueId } from '@ali/lowcode-utils'; import { uniqueId } from '@ali/lowcode-utils';
import { SettingPropEntry as ShellSettingPropEntry } from '@ali/lowcode-shell';
import { SettingEntry } from './setting-entry'; import { SettingEntry } from './setting-entry';
import { Node } from '../../document'; import { Node } from '../../document';
import { ComponentMeta } from '../../component-meta'; import { ComponentMeta } from '../../component-meta';
@ -124,7 +125,11 @@ export class SettingPropEntry implements SettingEntry {
return runInAction(() => { return runInAction(() => {
if (this.type !== 'field') { if (this.type !== 'field') {
const { getValue } = this.extraProps; const { getValue } = this.extraProps;
return getValue ? (getValue(this, undefined) === undefined ? 0 : 1) : 0; return getValue
? getValue(this.internalToShellPropEntry(), undefined) === undefined
? 0
: 1
: 0;
} }
if (this.nodes.length === 1) { if (this.nodes.length === 1) {
return 2; return 2;
@ -160,7 +165,7 @@ export class SettingPropEntry implements SettingEntry {
} }
const { getValue } = this.extraProps; const { getValue } = this.extraProps;
try { try {
return getValue ? getValue(this, val) : val; return getValue ? getValue(this.internalToShellPropEntry(), val) : val;
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
return val; return val;
@ -179,7 +184,7 @@ export class SettingPropEntry implements SettingEntry {
const { setValue } = this.extraProps; const { setValue } = this.extraProps;
if (setValue && !extraOptions?.disableMutator) { if (setValue && !extraOptions?.disableMutator) {
try { try {
setValue(this, val); setValue(this.internalToShellPropEntry(), val);
} catch (e) { } catch (e) {
/* istanbul ignore next */ /* istanbul ignore next */
console.warn(e); console.warn(e);
@ -202,7 +207,7 @@ export class SettingPropEntry implements SettingEntry {
const { setValue } = this.extraProps; const { setValue } = this.extraProps;
if (setValue) { if (setValue) {
try { try {
setValue(this, undefined); setValue(this.internalToShellPropEntry(), undefined);
} catch (e) { } catch (e) {
/* istanbul ignore next */ /* istanbul ignore next */
console.warn(e); console.warn(e);
@ -293,7 +298,12 @@ export class SettingPropEntry implements SettingEntry {
} }
notifyValueChange(oldValue: any, newValue: any) { notifyValueChange(oldValue: any, newValue: any) {
this.editor.emit(GlobalEvent.Node.Prop.Change, { node: this.getNode(), prop: this, oldValue, newValue }); this.editor.emit(GlobalEvent.Node.Prop.Change, {
node: this.getNode(),
prop: this,
oldValue,
newValue,
});
} }
getDefaultValue() { getDefaultValue() {
@ -352,4 +362,8 @@ export class SettingPropEntry implements SettingEntry {
} }
return v; return v;
} }
internalToShellPropEntry() {
return ShellSettingPropEntry.create(this) as any;
}
} }

View File

@ -419,7 +419,11 @@ export class NodeChildren {
const callbacks = owner.componentMeta.getMetadata().experimental?.callbacks; const callbacks = owner.componentMeta.getMetadata().experimental?.callbacks;
if (callbacks?.onSubtreeModified) { if (callbacks?.onSubtreeModified) {
try { try {
callbacks?.onSubtreeModified.call(node, owner, options); callbacks?.onSubtreeModified.call(
node.internalToShellNode(),
owner.internalToShellNode(),
options,
);
} catch (e) { } catch (e) {
console.error('error when excute experimental.callbacks.onSubtreeModified', e); console.error('error when excute experimental.callbacks.onSubtreeModified', e);
} }

View File

@ -19,6 +19,7 @@ import {
} from '@ali/lowcode-types'; } from '@ali/lowcode-types';
import { compatStage } from '@ali/lowcode-utils'; import { compatStage } from '@ali/lowcode-utils';
import { SettingTopEntry } from '@ali/lowcode-designer'; import { SettingTopEntry } from '@ali/lowcode-designer';
import { Node as ShellNode } from '@ali/lowcode-shell';
import { Props, getConvertedExtraKey } from './props/props'; import { Props, getConvertedExtraKey } from './props/props';
import { DocumentModel } from '../document-model'; import { DocumentModel } from '../document-model';
import { NodeChildren } from './node-children'; import { NodeChildren } from './node-children';
@ -299,7 +300,8 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
private didDropIn(dragment: Node) { private didDropIn(dragment: Node) {
const callbacks = this.componentMeta.getMetadata().experimental?.callbacks; const callbacks = this.componentMeta.getMetadata().experimental?.callbacks;
if (callbacks?.onNodeAdd) { if (callbacks?.onNodeAdd) {
callbacks?.onNodeAdd.call(this, dragment, this); const cbThis = this.internalToShellNode();
callbacks?.onNodeAdd.call(cbThis, dragment.internalToShellNode(), cbThis);
} }
if (this._parent) { if (this._parent) {
this._parent.didDropIn(dragment); this._parent.didDropIn(dragment);
@ -309,7 +311,8 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
private didDropOut(dragment: Node) { private didDropOut(dragment: Node) {
const callbacks = this.componentMeta.getMetadata().experimental?.callbacks; const callbacks = this.componentMeta.getMetadata().experimental?.callbacks;
if (callbacks?.onNodeRemove) { if (callbacks?.onNodeRemove) {
callbacks?.onNodeRemove.call(this, dragment, this); const cbThis = this.internalToShellNode();
callbacks?.onNodeRemove.call(cbThis, dragment.internalToShellNode(), cbThis);
} }
if (this._parent) { if (this._parent) {
this._parent.didDropOut(dragment); this._parent.didDropOut(dragment);
@ -361,6 +364,10 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
this._slotFor = slotFor; this._slotFor = slotFor;
} }
internalToShellNode(): ShellNode | null {
return ShellNode.create(this);
}
/** /**
* *
*/ */

View File

@ -29,7 +29,7 @@ const languageMap: { [key: string]: string } = {
const LowcodeConfigKey = 'ali-lowcode-config'; const LowcodeConfigKey = 'ali-lowcode-config';
class AliGlobalLocale { class GlobalLocale {
private emitter = new EventEmitter(); private emitter = new EventEmitter();
@obx.ref private _locale?: string; @obx.ref private _locale?: string;
@ -114,7 +114,7 @@ class AliGlobalLocale {
return this.locale; return this.locale;
} }
onLocaleChange(fn: (locale: string) => void): () => void { onChangeLocale(fn: (locale: string) => void): () => void {
this.emitter.on('localechange', fn); this.emitter.on('localechange', fn);
return () => { return () => {
this.emitter.removeListener('localechange', fn); this.emitter.removeListener('localechange', fn);
@ -135,12 +135,13 @@ function hasLocalStorage(obj: any): obj is WindowLocalStorage {
return obj.localStorage; return obj.localStorage;
} }
let globalLocale: AliGlobalLocale; let globalLocale = new GlobalLocale();
if ((window as any).__aliGlobalLocale) { // let globalLocale: GlobalLocale;
globalLocale = (window as any).__aliGlobalLocale as any; // if ((window as any).__GlobalLocale) {
} else { // globalLocale = (window as any).__GlobalLocale as any;
globalLocale = new AliGlobalLocale(); // } else {
(window as any).__aliGlobalLocale = globalLocale; // globalLocale = new GlobalLocale();
} // (window as any).__GlobalLocale = globalLocale;
// }
export { globalLocale }; export { globalLocale };

View File

@ -1,6 +1,6 @@
import { ReactNode, Component, createElement } from 'react'; import { ReactNode, Component, createElement } from 'react';
import { IntlMessageFormat } from 'intl-messageformat'; import { IntlMessageFormat } from 'intl-messageformat';
import { globalLocale } from './ali-global-locale'; import { globalLocale } from './global-locale';
import { isI18nData } from '@ali/lowcode-types'; import { isI18nData } from '@ali/lowcode-types';
import { observer, computed } from '../utils'; import { observer, computed } from '../utils';

View File

@ -21,4 +21,4 @@ export {
IReactionOptions, IReactionOptions,
} from 'mobx'; } from 'mobx';
export * as mobx from 'mobx'; export * as mobx from 'mobx';
export { observer }; export { observer };

View File

@ -3,5 +3,5 @@
"compilerOptions": { "compilerOptions": {
"outDir": "lib" "outDir": "lib"
}, },
"include": ["./src/"], "include": ["./src/"]
} }

View File

@ -40,7 +40,7 @@ class SettingFieldView extends Component<{ field: SettingField }> {
let stageName; let stageName;
if (display === 'entry') { if (display === 'entry') {
runInAction(() => { runInAction(() => {
stageName = `${field.getNode().id }_${field.name.toString()}`; stageName = `${field.getNode().id}_${field.name.toString()}`;
// 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新 // 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新
stages.container.remove(stageName); stages.container.remove(stageName);
const stage = stages.add({ const stage = stages.add({
@ -62,7 +62,7 @@ class SettingFieldView extends Component<{ field: SettingField }> {
const { condition, defaultValue } = extraProps; const { condition, defaultValue } = extraProps;
let visible; let visible;
try { try {
visible = typeof condition === 'function' ? condition(field) !== false : true; visible = typeof condition === 'function' ? condition(field.internalToShellPropEntry()) !== false : true;
} catch (error) { } catch (error) {
console.error('exception when condition (hidden) is excuted', error); console.error('exception when condition (hidden) is excuted', error);
} }
@ -86,7 +86,7 @@ class SettingFieldView extends Component<{ field: SettingField }> {
if (setter.props) { if (setter.props) {
setterProps = setter.props; setterProps = setter.props;
if (typeof setterProps === 'function') { if (typeof setterProps === 'function') {
setterProps = setterProps(field); setterProps = setterProps(field.internalToShellPropEntry());
} }
} }
if (setter.initialValue != null) { if (setter.initialValue != null) {
@ -132,6 +132,13 @@ class SettingFieldView extends Component<{ field: SettingField }> {
value = field.getValue(); value = field.getValue();
} }
// 当前 field 没有 value 值时,将 initialValue 写入 field
// 之所以用 initialValue而不是 defaultValue 是为了保持跟 props.onInitial 的逻辑一致
if (value == undefined && initialValue != undefined) {
const _initialValue = typeof initialValue === 'function' ? initialValue(field.internalToShellPropEntry()) : initialValue;
field.setValue(_initialValue);
}
let _onChange = extraProps?.onChange; let _onChange = extraProps?.onChange;
let stageName = this.stageName; let stageName = this.stageName;
@ -150,40 +157,40 @@ class SettingFieldView extends Component<{ field: SettingField }> {
...extraProps, ...extraProps,
}, },
!stageName && !stageName &&
createSetterContent(setterType, { createSetterContent(setterType, {
...shallowIntl(setterProps), ...shallowIntl(setterProps),
forceInline: extraProps.forceInline, forceInline: extraProps.forceInline,
key: field.id, key: field.id,
// === injection // === injection
prop: field, // for compatible vision prop: field.internalToShellPropEntry(), // for compatible vision
selected: field.top?.getNode(), selected: field.top?.getNode()?.internalToShellNode(),
field, field: field.internalToShellPropEntry(),
// === IO // === IO
value, // reaction point value, // reaction point
onChange: (value: any) => { onChange: (value: any) => {
this.setState({ this.setState({
// eslint-disable-next-line react/no-unused-state // eslint-disable-next-line react/no-unused-state
value, value,
}); });
field.setValue(value); field.setValue(value);
if (_onChange) _onChange(value, field); if (_onChange) _onChange(value, field);
}, },
onInitial: () => { onInitial: () => {
if (initialValue == null) { if (initialValue == null) {
return; return;
} }
const value = typeof initialValue === 'function' ? initialValue(field) : initialValue; const value = typeof initialValue === 'function' ? initialValue(field.internalToShellPropEntry()) : initialValue;
this.setState({ this.setState({
// eslint-disable-next-line react/no-unused-state // eslint-disable-next-line react/no-unused-state
value, value,
}); });
field.setValue(value); field.setValue(value);
}, },
removeProp: () => { removeProp: () => {
field.parent.clearPropValue(field.name); field.parent.clearPropValue(field.name);
}, },
}), }),
extraProps.forceInline ? 'plain' : extraProps.display, extraProps.forceInline ? 'plain' : extraProps.display,
); );
} }
@ -200,7 +207,7 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
super(props); super(props);
const { field } = this.props; const { field } = this.props;
const { extraProps } = field; const { extraProps } = field;
const { condition, display } = extraProps; const { display } = extraProps;
const { stages } = field.editor.get('skeleton') as Skeleton; const { stages } = field.editor.get('skeleton') as Skeleton;
// const items = field.items; // const items = field.items;
@ -208,7 +215,7 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
let stageName; let stageName;
if (display === 'entry') { if (display === 'entry') {
runInAction(() => { runInAction(() => {
stageName = `${field.getNode().id }_${field.name.toString()}`; stageName = `${field.getNode().id}_${field.name.toString()}`;
// 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新 // 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新
stages.container.remove(stageName); stages.container.remove(stageName);
stages.add({ stages.add({
@ -228,7 +235,7 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
const { field } = this.props; const { field } = this.props;
const { extraProps } = field; const { extraProps } = field;
const { condition, display } = extraProps; const { condition, display } = extraProps;
const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; const visible = field.isSingle && typeof condition === 'function' ? condition(field.internalToShellPropEntry()) !== false : true;
if (!visible) { if (!visible) {
return null; return null;

View File

@ -1,37 +1,45 @@
import { createElement } from 'react'; import { createElement } from 'react';
import { render } from 'react-dom'; import { render } from 'react-dom';
import { globalContext, Editor, engineConfig, EngineOptions } from '@ali/lowcode-editor-core'; import { globalContext, Editor, engineConfig, EngineOptions } from '@ali/lowcode-editor-core';
import * as editorCabin from '@ali/lowcode-editor-core';
import { import {
Designer, Designer,
LowCodePluginManager, LowCodePluginManager,
ILowCodePluginContext, ILowCodePluginContext,
Setters, // Setters,
} from '@ali/lowcode-designer'; } from '@ali/lowcode-designer';
import * as designerCabin from '@ali/lowcode-designer'; import { Skeleton as InnerSkeleton, SettingsPrimaryPane, registerDefaults } from '@ali/lowcode-editor-skeleton';
import { Skeleton, SettingsPrimaryPane, registerDefaults } from '@ali/lowcode-editor-skeleton';
import * as skeletonCabin from '@ali/lowcode-editor-skeleton';
import Outline, { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane'; import Outline, { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane';
import DesignerPlugin from '@ali/lowcode-plugin-designer'; import DesignerPlugin from '@ali/lowcode-plugin-designer';
import {
Hotkey,
Project,
Skeleton,
Setters,
Material,
Event,
} from '@ali/lowcode-shell';
import { getLogger, Logger, isPlainObject } from '@ali/lowcode-utils';
import './modules/live-editing'; import './modules/live-editing';
import { isPlainObject } from '@ali/lowcode-utils';
import utils from './modules/utils'; import utils from './modules/utils';
import * as editorCabin from './modules/editor-cabin';
import * as skeletonCabin from './modules/skeleton-cabin';
import * as designerCabin from './modules/designer-cabin';
export * from './modules/editor-types'; export * from './modules/editor-types';
export * from './modules/skeleton-types'; export * from './modules/skeleton-types';
export * from './modules/designer-types'; export * from './modules/designer-types';
export * from './modules/lowcode-types'; export * from './modules/lowcode-types';
const { hotkey, monitor, getSetter, registerSetter, getSettersMap } = editorCabin;
registerDefaults(); registerDefaults();
const editor = new Editor(); const editor = new Editor();
globalContext.register(editor, Editor); globalContext.register(editor, Editor);
globalContext.register(editor, 'editor'); globalContext.register(editor, 'editor');
const skeleton = new Skeleton(editor); const innerSkeleton = new InnerSkeleton(editor);
editor.set(Skeleton, skeleton); editor.set(Skeleton, innerSkeleton);
editor.set('skeleton' as any, skeleton); editor.set('skeleton' as any, innerSkeleton);
const designer = new Designer({ editor }); const designer = new Designer({ editor });
editor.set(Designer, designer); editor.set(Designer, designer);
@ -40,23 +48,32 @@ editor.set('designer' as any, designer);
const plugins = new LowCodePluginManager(editor).toProxy(); const plugins = new LowCodePluginManager(editor).toProxy();
editor.set('plugins' as any, plugins); editor.set('plugins' as any, plugins);
const { project, currentSelection: selection } = designer; const { project: innerProject, currentSelection: selection } = designer;
const { Workbench } = skeletonCabin; const { Workbench } = skeletonCabin;
const setters: Setters = { // const setters: Setters = {
getSetter, // getSetter,
registerSetter, // registerSetter,
getSettersMap, // getSettersMap,
}; // };
const hotkey = new Hotkey();
const project = new Project(innerProject);
const skeleton = new Skeleton(innerSkeleton);
const setters = new Setters();
const material = new Material(editor);
const config = engineConfig;
const event = new Event(editor, { prefix: 'common' });
const logger = getLogger({ level: 'warn', bizName: 'common' });
export { export {
editor, // editor,
editorCabin, editorCabin,
// skeleton, // skeleton,
skeletonCabin, skeletonCabin,
designer, // designer,
designerCabin, designerCabin,
plugins, plugins,
// setters, setters,
project, project,
// selection, // selection,
/** /**
@ -67,24 +84,33 @@ export {
* *
*/ */
// store, // store,
// hotkey, hotkey,
monitor,
utils, utils,
config,
event,
logger,
// engineConfig, // engineConfig,
}; };
const getSelection = () => designer.currentDocument?.selection; const getSelection = () => designer.currentDocument?.selection;
// TODO: build-plugin-component 的 umd 开发态没有导出 AliLowCodeEngine这里先简单绕过 // TODO: build-plugin-component 的 umd 开发态没有导出 AliLowCodeEngine这里先简单绕过
(window as any).AliLowCodeEngine = { (window as any).AliLowCodeEngine = {
editor, /**
editorCabin, * start
// skeleton, */
skeletonCabin, editor: event,
designer, designer,
/**
* end
*/
editorCabin,
skeletonCabin,
designerCabin, designerCabin,
plugins, plugins,
// setters, skeleton,
project, project,
setters,
material,
// get selection() { // get selection() {
// return getSelection(); // return getSelection();
// }, // },
@ -97,9 +123,12 @@ const getSelection = () => designer.currentDocument?.selection;
*/ */
// store, // store,
// hotkey, // hotkey,
monitor,
init, init,
utils, utils,
config,
event,
logger,
hotkey,
// engineConfig, // engineConfig,
}; };
@ -209,7 +238,7 @@ export async function init(container?: HTMLElement, options?: EngineOptions) {
await plugins.init(); await plugins.init();
render( render(
createElement(Workbench, { createElement(Workbench, {
skeleton, skeleton: innerSkeleton,
className: 'engine-main', className: 'engine-main',
topAreaItemClassName: 'engine-actionitem', topAreaItemClassName: 'engine-actionitem',
}), }),

View File

@ -0,0 +1,4 @@
export {
SettingField,
isSettingField,
} from '@ali/lowcode-designer';

View File

@ -0,0 +1,13 @@
export {
Title,
shallowIntl,
createIntl,
createSetterContent,
// TODO: To be deleted
obx,
computed,
observer,
getSetter,
getSettersMap,
globalLocale,
} from '@ali/lowcode-editor-core';

View File

@ -0,0 +1,6 @@
export {
createSettingFieldView,
PopupContext,
PopupPipe,
Workbench,
} from '@ali/lowcode-editor-skeleton';

View File

@ -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);
}
}

View File

@ -13,6 +13,7 @@ import Detecting from './detecting';
import History from './history'; import History from './history';
import Project from './project'; import Project from './project';
import Prop from './prop'; import Prop from './prop';
import Canvas from './canvas';
import { documentSymbol, editorSymbol, nodeSymbol } from './symbols'; import { documentSymbol, editorSymbol, nodeSymbol } from './symbols';
type IOnChangeOptions = { type IOnChangeOptions = {
@ -34,6 +35,7 @@ export default class DocumentModel {
public selection: Selection; public selection: Selection;
public detecting: Detecting; public detecting: Detecting;
public history: History; public history: History;
public canvas: Canvas;
constructor(document: InnerDocumentModel) { constructor(document: InnerDocumentModel) {
this[documentSymbol] = document; this[documentSymbol] = document;
@ -41,6 +43,7 @@ export default class DocumentModel {
this.selection = new Selection(document); this.selection = new Selection(document);
this.detecting = new Detecting(document); this.detecting = new Detecting(document);
this.history = new History(document); this.history = new History(document);
this.canvas = new Canvas(document.designer);
} }
static create(document: InnerDocumentModel | undefined | null) { static create(document: InnerDocumentModel | undefined | null) {

View File

@ -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);
}
}

View File

@ -12,6 +12,11 @@ export default class Event {
private readonly [editorSymbol]: InnerEditor; private readonly [editorSymbol]: InnerEditor;
private readonly options: EventOptions; private readonly options: EventOptions;
/**
*
*/
readonly names = [];
constructor(editor: InnerEditor, options: EventOptions) { constructor(editor: InnerEditor, options: EventOptions) {
this[editorSymbol] = editor; this[editorSymbol] = editor;
this.options = options; this.options = options;

View File

@ -11,6 +11,7 @@ import Selection from './selection';
import Setters from './setters'; import Setters from './setters';
import Hotkey from './hotkey'; import Hotkey from './hotkey';
import Skeleton from './skeleton'; import Skeleton from './skeleton';
import SettingPropEntry from './setting-prop-entry';
export * from './symbols'; export * from './symbols';
/** /**
@ -33,4 +34,5 @@ export {
Setters, Setters,
Hotkey, Hotkey,
Skeleton, Skeleton,
SettingPropEntry,
}; };

View File

@ -1,5 +1,5 @@
import { NodeChildren as InnerNodeChildren, Node as InnerNode } from '@ali/lowcode-designer'; import { NodeChildren as InnerNodeChildren, Node as InnerNode } from '@ali/lowcode-designer';
import { NodeSchema } from '@ali/lowcode-types'; import { NodeSchema, NodeData, TransformStage } from '@ali/lowcode-types';
import Node from './node'; import Node from './node';
import { nodeSymbol, nodeChildrenSymbol } from './symbols'; import { nodeSymbol, nodeChildrenSymbol } from './symbols';
@ -97,6 +97,14 @@ export default class NodeChildren {
}, initialValue); }, initialValue);
} }
importSchema(data?: NodeData | NodeData[]) {
this[nodeChildrenSymbol].import(data);
}
exportSchema(stage?: TransformStage) {
return this[nodeChildrenSymbol].export(stage);
}
mergeChildren( mergeChildren(
remover: (node: Node, idx: number) => boolean, remover: (node: Node, idx: number) => boolean,
adder: (children: Node[]) => any, adder: (children: Node[]) => any,

View File

@ -5,6 +5,7 @@ import {
} from '@ali/lowcode-designer'; } from '@ali/lowcode-designer';
import { CompositeValue, NodeSchema, TransformStage } from '@ali/lowcode-types'; import { CompositeValue, NodeSchema, TransformStage } from '@ali/lowcode-types';
import Prop from './prop'; import Prop from './prop';
import Props from './props';
import DocumentModel from './document-model'; import DocumentModel from './document-model';
import NodeChildren from './node-children'; import NodeChildren from './node-children';
import ComponentMeta from './component-meta'; import ComponentMeta from './component-meta';
@ -134,6 +135,28 @@ export default class Node {
return Prop.create(this[nodeSymbol].slotFor); return Prop.create(this[nodeSymbol].slotFor);
} }
get props() {
return Props.create(this[nodeSymbol].props);
}
/**
* @deprecated use .children instead
*/
getChildren() {
return this.children;
}
/**
* @deprecated
*/
getDOMNode() {
return this[nodeSymbol].getDOMNode();
}
getRect() {
return this[nodeSymbol].getRect();
}
hasSlots() { hasSlots() {
return this[nodeSymbol].hasSlots(); return this[nodeSymbol].hasSlots();
} }
@ -146,6 +169,13 @@ export default class Node {
return this[nodeSymbol].hasLoop(); return this[nodeSymbol].hasLoop();
} }
/**
* @deprecated use .props instead
*/
getProps() {
return this.props;
}
/** /**
* path * path
* @param path a / a.b / a.0 * @param path a / a.b / a.0

View File

@ -30,6 +30,17 @@ export default class Project {
return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); 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 * document
* @param doc * @param doc

View File

@ -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);
}
}

View File

@ -0,0 +1,56 @@
import { SettingField } from '@ali/lowcode-designer';
import { CompositeValue, FieldConfig } from '@ali/lowcode-types';
import { settingPropEntrySymbol } from './symbols';
import Node from './node';
import SettingTopEntry from './setting-top-entry';
export default class SettingPropEntry {
private readonly [settingPropEntrySymbol]: SettingField;
constructor(prop: SettingField) {
this[settingPropEntrySymbol] = prop;
}
static create(prop: SettingField) {
return new SettingPropEntry(prop);
}
get node(): Node | null {
return Node.create(this[settingPropEntrySymbol].getNode());
}
/**
* @deprecated use .node instead
*/
getNode() {
return this.node;
}
setValue(val: CompositeValue) {
this[settingPropEntrySymbol].setValue(val);
}
getValue() {
return this[settingPropEntrySymbol].getValue();
}
getProps() {
return SettingTopEntry.create(this[settingPropEntrySymbol].getProps() as SettingEntry) as any;
}
isUseVariable() {
return this[settingPropEntrySymbol].isUseVariable();
}
setUseVariable(flag: boolean) {
this[settingPropEntrySymbol].setUseVariable(flag);
}
createField(config: FieldConfig) {
return SettingPropEntry.create(this[settingPropEntrySymbol].createField(config));
}
getMockOrValue() {
return this[settingPropEntrySymbol].getMockOrValue();
}
}

View File

@ -0,0 +1,34 @@
import { SettingEntry } from '@ali/lowcode-designer';
import { settingTopEntrySymbol } from './symbols';
import Node from './node';
export default class SettingTopEntry {
private readonly [settingTopEntrySymbol]: SettingEntry;
constructor(prop: SettingEntry) {
this[settingTopEntrySymbol] = prop;
}
static create(prop: SettingEntry) {
return new SettingTopEntry(prop);
}
get node(): Node | null {
return Node.create(this[settingTopEntrySymbol].getNode());
}
/**
* @deprecated use .node instead
*/
getNode() {
return this.node;
}
getPropValue(propName: string | number) {
return this[settingTopEntrySymbol].getPropValue(propName);
}
setPropValue(propName: string | number, value: any) {
this[settingTopEntrySymbol].setPropValue(propName, value);
}
}

View File

@ -15,6 +15,14 @@ export default class SimulatorHost {
return new SimulatorHost(host); return new SimulatorHost(host);
} }
get contentWindow() {
return this[simulatorHostSymbol].contentWindow;
}
get contentDocument() {
return this[simulatorHostSymbol].contentDocument;
}
set(key: string, value: any) { set(key: string, value: any) {
this[simulatorHostSymbol].set(key, value); this[simulatorHostSymbol].set(key, value);
} }

View File

@ -8,11 +8,15 @@ export const documentSymbol = Symbol('document');
export const editorSymbol = Symbol('editor'); export const editorSymbol = Symbol('editor');
export const nodeSymbol = Symbol('node'); export const nodeSymbol = Symbol('node');
export const nodeChildrenSymbol = Symbol('nodeChildren'); export const nodeChildrenSymbol = Symbol('nodeChildren');
export const propsSymbol = Symbol('props');
export const propSymbol = Symbol('prop'); export const propSymbol = Symbol('prop');
export const settingPropEntrySymbol = Symbol('settingPropEntry');
export const settingTopEntrySymbol = Symbol('settingTopEntry');
export const propsSymbol = Symbol('props');
export const detectingSymbol = Symbol('detecting'); export const detectingSymbol = Symbol('detecting');
export const selectionSymbol = Symbol('selection'); export const selectionSymbol = Symbol('selection');
export const historySymbol = Symbol('history'); export const historySymbol = Symbol('history');
export const canvasSymbol = Symbol('canvas');
export const componentMetaSymbol = Symbol('componentMeta'); export const componentMetaSymbol = Symbol('componentMeta');
export const dropLocationSymbol = Symbol('dropLocation');
export const simulatorHostSymbol = Symbol('simulatorHost'); export const simulatorHostSymbol = Symbol('simulatorHost');
export const simulatorRendererSymbol = Symbol('simulatorRenderer'); export const simulatorRendererSymbol = Symbol('simulatorRenderer');

View File

@ -52,6 +52,11 @@ export interface SettingTarget {
*/ */
get: (propName: string | number) => SettingTarget | null; get: (propName: string | number) => SettingTarget | null;
/**
*
*/
getProps?: () => SettingTarget;
/** /**
* *
*/ */