From 4f7179bd26587ae249223fc32bcbac0bfab6802c Mon Sep 17 00:00:00 2001 From: kangwei Date: Tue, 12 May 2020 19:15:29 +0800 Subject: [PATCH] feat: support global inline editing --- .../live-editing/live-editing.ts | 6 +- packages/designer/src/component-meta.ts | 2 +- packages/vision-preset/src/editor.ts | 22 +----- packages/vision-preset/src/vc-live-editing.ts | 72 +++++++++++++++++++ 4 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 packages/vision-preset/src/vc-live-editing.ts diff --git a/packages/designer/src/builtin-simulator/live-editing/live-editing.ts b/packages/designer/src/builtin-simulator/live-editing/live-editing.ts index 57b01ff2f..828790e57 100644 --- a/packages/designer/src/builtin-simulator/live-editing/live-editing.ts +++ b/packages/designer/src/builtin-simulator/live-editing/live-editing.ts @@ -44,7 +44,7 @@ export class LiveEditing { let setterPropElement = getSetterPropElement(targetElement, rootElement); let propTarget = setterPropElement?.dataset.setterProp; - let matched: LiveTextEditingConfig & { propElement?: HTMLElement; } | undefined; + let matched: (LiveTextEditingConfig & { propElement?: HTMLElement; }) | undefined | null; if (liveTextEditing) { if (propTarget) { // 已埋点命中 data-setter-prop="proptarget", 从 liveTextEditing 读取配置(mode|onSaveContent) @@ -151,9 +151,9 @@ export class LiveEditing { } } -export type SpecificRule = (target: EditingTarget) => LiveTextEditingConfig & { +export type SpecificRule = (target: EditingTarget) => (LiveTextEditingConfig & { propElement?: HTMLElement; -}; +}) | null; export interface SaveHandler { condition: (prop: Prop) => boolean; diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 8a60b489b..411a23ae3 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -175,7 +175,7 @@ export class ComponentMeta { }); } collectLiveTextEditing(this.configure); - this._liveTextEditing = liveTextEditing; + this._liveTextEditing = liveTextEditing.length > 0 ? liveTextEditing : undefined; const { configure = {} } = this._transformedMetadata; this._acceptable = false; diff --git a/packages/vision-preset/src/editor.ts b/packages/vision-preset/src/editor.ts index 4f88b5f6b..f0de5a15e 100644 --- a/packages/vision-preset/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -10,6 +10,7 @@ import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton'; import { i18nReducer } from './i18n-reducer'; import { InstanceNodeSelector } from './components'; +import { liveEditingRule } from './vc-live-editing'; export const editor = new Editor(); globalContext.register(editor, Editor); @@ -160,26 +161,7 @@ skeleton.add({ content: OutlineBackupPane, }); -LiveEditing.addLiveEditingSpecificRule((target) => { - // TODO: enhance for legao specific - const contentValue = target.node.getPropValue('content'); - return null; -}); - -// skeleton.add({ -// name: 'sourceEditor', -// type: 'PanelDock', -// props: { -// align: 'top', -// icon: 'code', -// description: '组件库', -// }, -// panelProps: { -// width: 500 -// // area: 'leftFixedArea' -// }, -// content: SourceEditor, -// }); +LiveEditing.addLiveEditingSpecificRule(liveEditingRule); // 实例节点选择器,线框高亮 addBuiltinComponentAction({ diff --git a/packages/vision-preset/src/vc-live-editing.ts b/packages/vision-preset/src/vc-live-editing.ts new file mode 100644 index 000000000..9f1ec6410 --- /dev/null +++ b/packages/vision-preset/src/vc-live-editing.ts @@ -0,0 +1,72 @@ +import { EditingTarget, Node as DocNode } from '@ali/lowcode-designer'; +import Env from './env'; +import { isJSExpression } from '@ali/lowcode-types'; +const I18nUtil = require('@ali/ve-i18n-util'); + +interface I18nObject { + type?: string; + use?: string; + key?: string; + [lang: string]: string | undefined; +} + +function getI18nText(obj: I18nObject) { + let locale = Env.getLocale(); + if (obj.key) { + return I18nUtil.get(obj.key, locale); + } + if (locale !== 'zh_CN' && locale !== 'zh_TW' && !obj[locale]) { + locale = 'en_US'; + } + return obj[obj.use || locale] || obj.zh_CN; +} + +function getText(node: DocNode, prop: string) { + const p = node.getProp(prop, false); + if (!p || p.isUnset()) { + return null; + } + const v = p.getValue(); + if (v == null) { + return null; + } + if (p.type === 'literal') { + return v; + } + if ((v as any).type === 'i18n') { + return getI18nText(v as any); + } + if (isJSExpression(v)) { + return v.mock; + } +} + +export function liveEditingRule(target: EditingTarget) { + // for vision components specific + const { node, rootElement, event } = target; + + const targetElement = event.target as HTMLElement; + + if (!Array.from(targetElement.childNodes).every(item => item.nodeType === Node.TEXT_NODE)) { + return null; + } + + const innerText = targetElement.innerText; + const propTarget = ['title', 'label', 'text', 'content'].find(prop => { + // TODO: enhance compare text logic + return getText(node, prop) === innerText; + }); + + if (propTarget) { + return { + propElement: targetElement, + propTarget, + }; + } + return null; +} + +// TODO: +export function liveEditingSaveHander() { + +}