diff --git a/packages/editor-framework/package.json b/packages/editor-framework/package.json index e76f5e372..8866b4a77 100644 --- a/packages/editor-framework/package.json +++ b/packages/editor-framework/package.json @@ -24,12 +24,17 @@ ], "author": "xiayang.xy", "dependencies": { + "debug": "^4.1.1", + "events": "^3.1.0", + "intl-messageformat": "^7.8.4", + "lodash": "^4.17.15", "prop-types": "^15.5.8" }, "devDependencies": { "@alib/build-scripts": "^0.1.3", "@alifd/next": "1.x", "@ice/spec": "^0.1.1", + "@types/lodash": "^4.14.149", "@types/react": "^16.9.13", "@types/react-dom": "^16.9.4", "build-plugin-component": "^0.2.0", diff --git a/packages/editor-framework/src/context.ts b/packages/editor-framework/src/context.ts new file mode 100644 index 000000000..78d3ce177 --- /dev/null +++ b/packages/editor-framework/src/context.ts @@ -0,0 +1,3 @@ +import { createContext } from 'react'; +const context = createContext({}); +export default context; diff --git a/packages/editor-framework/src/editor.ts b/packages/editor-framework/src/editor.ts new file mode 100644 index 000000000..daeeb2182 --- /dev/null +++ b/packages/editor-framework/src/editor.ts @@ -0,0 +1,62 @@ +import EventEmitter from 'events'; +import Debug from 'debug'; +let instance = null; + +const debug = Debug('editor'); +EventEmitter.defaultMaxListeners = 100; + +export interface editor { + +}; + +export class Editor extends EventEmitter { + static getInstance = () => { + if (!instance) { + instance = new Editor(); + } + return instance; + }; + + constructor(config) { + super(); + instance = this; + Object.assign(this, config); + } + + init() { + + } + + destroy() { + + } + + get(key:string):any { + return this[key]; + } + + set(key, val) { + if (typeof key === 'string') { + this[key] = val; + } else if (typeof key === 'object') { + Object.keys(key).forEach(item => { + this[item] = key[item]; + }); + } + } + + batchOn(events, lisenter) { + if (!Array.isArray(events)) return; + events.forEach(event => this.on(event, lisenter)); + } + + batchOnce(events, lisenter) { + if (!Array.isArray(events)) return; + events.forEach(event => this.once(event, lisenter)); + } + + batchOff(events, lisenter) { + if (!Array.isArray(events)) return; + events.forEach(event => this.off(event, lisenter)); + } +} diff --git a/packages/editor-framework/src/index.scss b/packages/editor-framework/src/index.scss deleted file mode 100644 index 3a0f72cfb..000000000 --- a/packages/editor-framework/src/index.scss +++ /dev/null @@ -1,4 +0,0 @@ -/* write style here */ -.TSDemo { - -} diff --git a/packages/editor-framework/src/index.ts b/packages/editor-framework/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/editor-framework/src/index.tsx b/packages/editor-framework/src/index.tsx deleted file mode 100644 index 9752a43b7..000000000 --- a/packages/editor-framework/src/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - -export default function TSDemo(props) { - const { type, ...others } = props; - - return ( -
Hello TSDemo
- ); -} - -TSDemo.propTypes = { -}; - -TSDemo.defaultProps = { -}; diff --git a/packages/editor-framework/src/plugin.ts b/packages/editor-framework/src/plugin.ts new file mode 100644 index 000000000..e42aa73cc --- /dev/null +++ b/packages/editor-framework/src/plugin.ts @@ -0,0 +1,87 @@ +import { PureComponent } from 'react'; + +import EditorContext from './context'; +import { isEmpty, generateI18n, goldlog } from './utils'; + +export interface pluginProps { + config: object, + editor: object, + locale: string, + messages: object +} + + + +export class Plugin extends PureComponent { + static displayName = 'lowcode-editor-plugin'; + static defaultProps = { + config: {} + }; + static contextType = EditorContext; + constructor(props, context) { + super(props, context); + if (isEmpty(props.config) || !props.config.addonKey) { + console.warn('luna addon has wrong config'); + return; + } + + + const { locale, messages, editor } = props; + // 注册插件 + this.editor = editor; + this.i18n = generateI18n(locale, messages); + this.pluginKey = props.config.pluginKey; + editor.plugins = editor.plugins || {}; + editor.plugins[this.pluginKey] = this; + } + + async componentWillUnmount() { + // 销毁插件 + if (this.editor && this.editor.plugins) { + delete this.editor.plugins[this.pluginKey]; + } + } + + open = () => { + return true; + }; + + close = () => { + return true; + }; + + goldlog = (goKey:string, params:any) => { + const { pluginKey, config = {} } = this.props.config || {}; + goldlog( + goKey, + { + pluginKey, + package: config.package, + version: config.version, + ...this.editor.logParams, + ...params + }, + 'addon' + ); + }; + + get utils() { + return this.editor.utils; + } + + get constants() { + return this.editor.constants; + } + + get history() { + return this.editor.history; + } + + get location() { + return this.editor.location; + } + + render() { + return null; + } +} diff --git a/packages/editor-framework/src/utils.ts b/packages/editor-framework/src/utils.ts new file mode 100644 index 000000000..5cc738bca --- /dev/null +++ b/packages/editor-framework/src/utils.ts @@ -0,0 +1,75 @@ + +import IntlMessageFormat from 'intl-messageformat'; +import _isEmpty from 'lodash/isEmpty'; + +export const isEmpty = _isEmpty; + +/** + * 用于构造国际化字符串处理函数 + * @param {*} locale 国际化标识,例如 zh-CN、en-US + * @param {*} messages 国际化语言包 + */ +export function generateI18n(locale = 'zh-CN', messages = {}) { + return (key, values = {}) => { + if (!messages || !messages[key]) return ''; + const formater = new IntlMessageFormat(messages[key], locale); + return formater.format(values); + }; +} + +/** + * 序列化参数 + * @param {*} obj 参数 + */ +export function serializeParams(obj:object):string { + if (typeof obj !== 'object') return ''; + + const res:Array = []; + Object.entries(obj).forEach(([key, val]) => { + if (val === null || val === undefined || val === '') return; + if (typeof val === 'object') { + res.push(`${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(val))}`); + } else { + res.push(`${encodeURIComponent(key)}=${encodeURIComponent(val)}`); + } + }); + return res.join('&'); +} + +/** + * 黄金令箭埋点 + * @param {String} gmKey 为黄金令箭业务类型 + * @param {Object} params 参数 + * @param {String} logKey 属性串 + */ +export function goldlog(gmKey, params = {}, logKey = 'other') { + const sendIDEMessage = window.sendIDEMessage || window.parent.sendIDEMessage; + const goKey = serializeParams({ + sdkVersion: pkg.version, + env: getEnv(), + ...params + }); + if (sendIDEMessage) { + sendIDEMessage({ + action: 'goldlog', + data: { + logKey: `/iceluna.core.${logKey}`, + gmKey, + goKey + } + }); + } + window.goldlog && window.goldlog.record(`/iceluna.core.${logKey}`, gmKey, goKey, 'POST'); +} + +/** + * 获取当前编辑器环境 + */ +export function getEnv() { + const userAgent = navigator.userAgent; + const isVscode = /Electron\//.test(userAgent); + if (isVscode) return ENV.VSCODE; + const isTheia = window.is_theia === true; + if (isTheia) return ENV.WEBIDE; + return ENV.WEB; +} \ No newline at end of file