From af6742ddef70f94ee6fb0defc34ca8d1c42eb8c9 Mon Sep 17 00:00:00 2001 From: "mario.gk" Date: Tue, 5 May 2020 11:54:18 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E4=B8=8A=E4=BB=A3=E7=90=86=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/vision-preset/src/bundle/bundle.ts | 16 ++ packages/vision-preset/src/editor.ts | 18 +- packages/vision-preset/src/exchange.ts | 9 + packages/vision-preset/src/index.ts | 13 +- packages/vision-preset/src/project.ts | 17 ++ packages/vision-preset/src/viewport.ts | 278 ++++++++++++++++++++ 6 files changed, 341 insertions(+), 10 deletions(-) create mode 100644 packages/vision-preset/src/project.ts create mode 100644 packages/vision-preset/src/viewport.ts diff --git a/packages/vision-preset/src/bundle/bundle.ts b/packages/vision-preset/src/bundle/bundle.ts index 6e00f7e58..d74c3de12 100644 --- a/packages/vision-preset/src/bundle/bundle.ts +++ b/packages/vision-preset/src/bundle/bundle.ts @@ -100,6 +100,22 @@ export default class Bundle { cp.setView(view); } + /** + * TODO dirty fix + */ + addComponentBundle(bundles: any) { + /** + * Normal Component bundle: [ Prototype, PrototypeView ] + * Component without Prototype.js: [ View ] + */ + if (bundles.length >= 2) { + const prototype = bundles[0]; + const prototypeView = bundles[1]; + prototype.setView(prototypeView); + this.registerPrototype(prototype); + } + } + private recursivelyRegisterViews(list: any[], viewName?: string): void { list.forEach((item: any) => { if (Array.isArray(item.module)) { diff --git a/packages/vision-preset/src/editor.ts b/packages/vision-preset/src/editor.ts index 96cc11e03..61d3b0843 100644 --- a/packages/vision-preset/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -80,15 +80,15 @@ skeleton.add({ type: 'Panel', content: SettingsPrimaryPane, }); -skeleton.add({ - area: 'leftArea', - name: 'outlinePane', - type: 'PanelDock', - content: Outline, - panelProps: { - area: 'leftFixedArea', - }, -}); +// skeleton.add({ +// area: 'leftArea', +// name: 'outlinePane', +// type: 'PanelDock', +// content: Outline, +// panelProps: { +// area: 'leftFixedArea', +// }, +// }); skeleton.add({ area: 'topArea', diff --git a/packages/vision-preset/src/exchange.ts b/packages/vision-preset/src/exchange.ts index df71cff14..6e1f8c13e 100644 --- a/packages/vision-preset/src/exchange.ts +++ b/packages/vision-preset/src/exchange.ts @@ -12,4 +12,13 @@ export default { const nodes = designer.currentSelection?.getNodes(); return nodes?.[0]; }, + /** + * TODO dirty fix + */ + onIntoView(func: (node: any, insertion: any) => any) { + // this.emitter.on('intoview', func); + return () => { + // this.emitter.removeListener('intoview', func); + }; + } } diff --git a/packages/vision-preset/src/index.ts b/packages/vision-preset/src/index.ts index 2c4db40e9..b3eaa9b01 100644 --- a/packages/vision-preset/src/index.ts +++ b/packages/vision-preset/src/index.ts @@ -1,11 +1,12 @@ import * as utils from '@ali/ve-utils'; import Popup from '@ali/ve-popups'; import Icons from '@ali/ve-icons'; +import logger from '@ali/vu-logger'; import { render } from 'react-dom'; import I18nUtil from '@ali/ve-i18n-util'; import { hotkey as Hotkey } from '@ali/lowcode-editor-core'; import { createElement } from 'react'; -import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS } from './base/const'; +import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS, VERSION as Version } from './base/const'; import Bus from './bus'; import { skeleton } from './editor'; import { Workbench } from '@ali/lowcode-editor-skeleton'; @@ -21,6 +22,8 @@ import * as Field from './fields'; import Prop from './prop'; import Env from './env'; import DragEngine from './drag-engine'; +import Viewport from './viewport'; +import Project from './project'; import { designer, editor } from './editor'; import './vision.less'; @@ -101,6 +104,10 @@ const VisualEngine = { Bundle, Pages, DragEngine, + Viewport, + Version, + Project, + logger, }; (window as any).VisualEngine = VisualEngine; @@ -144,6 +151,10 @@ export { Bundle, Pages, DragEngine, + Viewport, + Version, + Project, + logger, }; diff --git a/packages/vision-preset/src/project.ts b/packages/vision-preset/src/project.ts new file mode 100644 index 000000000..ba5d2309b --- /dev/null +++ b/packages/vision-preset/src/project.ts @@ -0,0 +1,17 @@ +class Project { + private schema: any; + + constructor() { + this.schema = {}; + } + + getSchema() { + return this.schema; + } + + setSchema(schema: any) { + this.schema = schema; + } +} + +export default new Project(); diff --git a/packages/vision-preset/src/viewport.ts b/packages/vision-preset/src/viewport.ts new file mode 100644 index 000000000..0b5ec7cb7 --- /dev/null +++ b/packages/vision-preset/src/viewport.ts @@ -0,0 +1,278 @@ +import { EventEmitter } from 'events'; + +const domReady = require('domready'); +import Flags from './flags'; + +function enterFullscreen() { + const elem = document.documentElement; + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } +} + +function exitFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + } +} + +function isFullscreen() { + return document.fullscreen || false; +} + +interface IStyleResourceConfig { + media?: string; + type?: string; + content?: string; +} + +class StyleResource { + config: IStyleResourceConfig; + styleElement: HTMLStyleElement; + mounted: boolean; + inited: boolean; + + constructor(config: IStyleResourceConfig) { + this.config = config || {}; + } + + matchDevice(device: string) { + const media = this.config.media; + + if (!media || media === 'ALL' || media === '*') { + return true; + } + + return media.toUpperCase() === device.toUpperCase(); + } + + init() { + if (this.inited) { + return; + } + + this.inited = true; + + const { type, content } = this.config; + + let styleElement; + if (type === 'URL') { + styleElement = document.createElement('link'); + styleElement.href = content || ''; + styleElement.rel = 'stylesheet'; + } else { + styleElement = document.createElement('style'); + styleElement.setAttribute('type', 'text/css'); + if (styleElement.styleSheet) { + styleElement.styleSheet.cssText = content; + } else { + styleElement.appendChild(document.createTextNode(content || '')); + } + } + this.styleElement = styleElement; + } + + apply() { + if (this.mounted) { + return; + } + + this.init(); + document.head.appendChild(this.styleElement); + this.mounted = true; + } + + unmount() { + if (!this.mounted) { + return; + } + document.head.removeChild(this.styleElement); + this.mounted = false; + } +} + +export class Viewport { + preview: boolean; + focused: boolean; + slateFixed: boolean; + emitter: EventEmitter; + device: string; + focusTarget: any; + cssResourceSet: StyleResource[]; + + constructor() { + this.preview = false; + this.emitter = new EventEmitter(); + document.addEventListener('webkitfullscreenchange', () => { + this.emitter.emit('fullscreenchange', this.isFullscreen()); + }); + domReady(() => this.applyMediaCSS()); + } + + setFullscreen(flag: boolean) { + const fullscreen = this.isFullscreen(); + if (fullscreen && !flag) { + exitFullscreen(); + } else if (!fullscreen && flag) { + enterFullscreen(); + } + } + + toggleFullscreen() { + if (this.isFullscreen()) { + exitFullscreen(); + } else { + enterFullscreen(); + } + } + + isFullscreen() { + return isFullscreen(); + } + + setFocus(flag: boolean) { + if (this.focused && !flag) { + this.focused = false; + Flags.remove('view-focused'); + this.emitter.emit('focuschange', false); + } else if (!this.focused && flag) { + this.focused = true; + Flags.add('view-focused'); + this.emitter.emit('focuschange', true); + } + } + + setFocusTarget(focusTarget: any) { + this.focusTarget = focusTarget; + } + + returnFocus() { + if (this.focusTarget) { + this.focusTarget.focus(); + } + } + + isFocus() { + return this.focused; + } + + setPreview(flag: boolean) { + if (this.preview && !flag) { + this.preview = false; + Flags.setPreviewMode(false); + this.emitter.emit('preview', false); + this.changeViewport(); + } else if (!this.preview && flag) { + this.preview = true; + Flags.setPreviewMode(true); + this.emitter.emit('preview', true); + this.changeViewport(); + } + } + + togglePreview() { + if (this.isPreview()) { + this.setPreview(false); + } else { + this.setPreview(true); + } + } + + isPreview() { + return this.preview; + } + + setDevice(device = 'pc') { + if (this.getDevice() !== device) { + this.device = device; + Flags.setSimulator(device); + this.applyMediaCSS(); + this.emitter.emit('devicechange', device); + this.changeViewport(); + } + } + + getDevice() { + return this.device || 'pc'; + } + + changeViewport() { + this.emitter.emit('viewportchange', this.getViewport()); + } + + getViewport() { + return `${this.isPreview() ? 'preview' : 'design'}-${this.getDevice()}`; + } + + applyMediaCSS() { + if (!document.head || !this.cssResourceSet) { + return; + } + const device = this.getDevice(); + this.cssResourceSet.forEach((item) => { + if (item.matchDevice(device)) { + item.apply(); + } else { + item.unmount(); + } + }); + } + + setGlobalCSS(resourceSet: IStyleResourceConfig[]) { + if (this.cssResourceSet) { + this.cssResourceSet.forEach((item) => { + item.unmount(); + }); + } + this.cssResourceSet = resourceSet.map((item: IStyleResourceConfig) => new StyleResource(item)).reverse(); + this.applyMediaCSS(); + } + + setWithShell(shell: string) { + Flags.setWithShell(shell); + } + + onFullscreenChange(func: () => any) { + this.emitter.on('fullscreenchange', func); + return () => { + this.emitter.removeListener('fullscreenchange', func); + }; + } + + onPreview(func: () => any) { + this.emitter.on('preview', func); + return () => { + this.emitter.removeListener('preview', func); + }; + } + + onDeviceChange(func: () => any) { + this.emitter.on('devicechange', func); + return () => { + this.emitter.removeListener('devicechange', func); + }; + } + + onSlateFixedChange(func: (flag: boolean) => any) { + this.emitter.on('slatefixed', func); + return () => { + this.emitter.removeListener('slatefixed', func); + }; + } + + onViewportChange(func: () => any) { + this.emitter.on('viewportchange', func); + return () => { + this.emitter.removeListener('viewportchange', func); + }; + } + + onFocusChange(func: (flag: boolean) => any) { + this.emitter.on('focuschange', func); + return () => { + this.emitter.removeListener('focuschange', func); + }; + } +} + +export default new Viewport(); From af0f2dfc6a08dae1954ba3018d93407755a3f6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Tue, 5 May 2020 12:09:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BC=A0=E5=85=A5=E7=BB=84=E4=BB=B6children=E7=9A=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC[],=20=E5=AF=B9=E4=B9=8B=E5=89=8D=E7=9A=84?= =?UTF-8?q?=E9=9D=9E=E5=81=A5=E5=A3=AE=E7=BB=84=E4=BB=B6=E5=81=9A=E5=85=BC?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react-simulator-renderer/src/renderer-view.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx index 7b41312c8..e964c2be9 100644 --- a/packages/react-simulator-renderer/src/renderer-view.tsx +++ b/packages/react-simulator-renderer/src/renderer-view.tsx @@ -7,7 +7,7 @@ import './renderer.less'; // patch cloneElement avoid lost keyProps const originCloneElement = window.React.cloneElement; -(window as any).React.cloneElement = (child: any, { _leaf, ...props}: any = {}) => { +(window as any).React.cloneElement = (child: any, { _leaf, ...props }: any = {}) => { if (child.ref && props.ref) { const dRef = props.ref; const cRef = child.ref; @@ -18,7 +18,7 @@ const originCloneElement = window.React.cloneElement; } else { try { cRef.current = x; - } catch (e) { } + } catch (e) {} } } if (dRef) { @@ -27,13 +27,13 @@ const originCloneElement = window.React.cloneElement; } else { try { dRef.current = x; - } catch (e) { } + } catch (e) {} } } - } - }; + }; + } return originCloneElement(child, props); -} +}; export default class SimulatorRendererView extends Component<{ renderer: SimulatorRenderer }> { render() { @@ -87,7 +87,7 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> { return createElement( Component, viewProps, - children == null ? null : Array.isArray(children) ? children : [children], + children == null ? [] : Array.isArray(children) ? children : [children], ); }} onCompGetRef={(schema: any, ref: ReactInstance | null) => { From 88348f761200300301fd553684359d698c200cd2 Mon Sep 17 00:00:00 2001 From: "xiaoxian.xlf" Date: Tue, 5 May 2020 14:07:48 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20settingfield=E6=B7=BB=E5=8A=A0props?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=B0=E5=8C=BA=E7=BB=84=E4=BB=B6=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E7=B1=BB=E5=9E=8B=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/src/designer/setting/setting-prop-entry.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index a231eaf2b..2e11f82b5 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -180,6 +180,11 @@ export class SettingPropEntry implements SettingEntry { return this.top; } + // add settingfield props + get props() { + return this.top; + } + onValueChange(func: () => any) { this.emitter.on('valuechange', func);