import { Container, interfaces } from 'inversify'; import * as React from 'react'; import { useEffect, useRef, useState } from 'react'; import { PipelineDispatcher, PipelineEntitiesSelector, PipelineRegistry, PipelineRenderer } from './pipeline'; import { AbleManager, EntityManager, PlaygroundContext } from '../common'; import { createDefaultPlaygroundConfig, PlaygroundConfig } from './playground-config'; import { Playground } from './playground'; import { PlaygroundContribution, PlaygroundRegistry } from './playground-contribution'; import { bindContributionProvider } from '@gedit/utils'; import { PLAYGROUND_ID_PREFIX, PlaygroundCommandRegistry, PlaygroundId, PlaygroundKeybindingRegistry, PlaygroundMenuRegistry } from './playground-registries'; import { getFrontendApplicationSimpleModuleFromCache } from '@gedit/application-simple/lib/browser'; import PlaygroundFrontendModule from './playground-frontend-module'; import { PlaygroundConfigEntity, PlaygroundConfigEntityData, RulerConfigEntity, RulerConfigEntityData, SelectorBoxConfigData, SelectorBoxConfigEntity, SelectorConfigEntity, SelectorConfigEntityData, SnaplineConfigEntity, SnaplineConfigEntityData, ToolbarConfigEntity, ToolbarConfigEntityData } from './layer/config'; import { SelectorExtendContribution, SelectorExtendContributionRegistry } from './selector-extend-contribution'; let idx = 0; export function createPlaygroundContainer(parent?: interfaces.Container): Container { const child = new Container({defaultScope: 'Singleton'}); if (parent) { child.parent = parent; } else { // 加载一些IDE的初始化模块, 如皮肤、右键菜单等模块, 用于非IDE场景使用Playground child.parent = getFrontendApplicationSimpleModuleFromCache(); child.parent.load(PlaygroundFrontendModule); } bindContributionProvider(child, PlaygroundContribution); bindContributionProvider(child, SelectorExtendContribution); child.bind(PlaygroundConfig).toConstantValue(createDefaultPlaygroundConfig()); child.bind(AbleManager).toSelf(); child.bind(EntityManager).toSelf(); child.bind(PipelineRenderer).toSelf(); child.bind(PlaygroundRegistry).toSelf(); child.bind(SelectorExtendContributionRegistry).toSelf(); child.bind(Playground).toSelf(); child.bind(PipelineEntitiesSelector).toSelf(); child.bind(PlaygroundId).toConstantValue(PLAYGROUND_ID_PREFIX + (idx++)); child.bind(PlaygroundContext).toConstantValue({}); child.bind(PipelineDispatcher).toSelf(); child.bind(PipelineRegistry).toSelf(); child.bind(PlaygroundCommandRegistry).toSelf(); child.bind(PlaygroundKeybindingRegistry).toSelf(); child.bind(PlaygroundMenuRegistry).toSelf(); return child; } export function createPlayground(config?: PlaygroundConfig, parentContainer?: interfaces.Container): Playground { const child = createPlaygroundContainer(parentContainer); child.rebind(PlaygroundConfig).toConstantValue({ ...createDefaultPlaygroundConfig(), ...config, }); return child.get(Playground); } export interface PlaygroundContainerProps extends Omit { className?: string style?: React.CSSProperties parentContainer?: interfaces.Container, onReady?: (playground: Playground) => void rulerConfig?: Partial playgroundConfig?: Partial selectorBoxConfig?: Partial, selectorConfig?: Partial, snaplineConfig?: Partial, toolbarConfig?: Partial, } /** * @param props * @constructor * @example * * function MyPlayground(props: PlaygroundContainerProps): React.JSX.Element { * return ( * * ) * } */ export function PlaygroundContainer(props: PlaygroundContainerProps): React.JSX.Element { // eslint-disable-next-line no-null/no-null const playgroundRef = useRef(null); const [playgroundInstance, savePlayground] = useState(); useEffect(() => { if (playgroundRef.current) { const playground = createPlayground({ ...props, node: playgroundRef.current }, props.parentContainer); savePlayground(playground); return () => { playground.dispose(); }; } }, [playgroundRef]); useEffect(() => { if (playgroundInstance) { playgroundInstance.resize(); } }, [playgroundInstance, props.width, props.height, props.style, props.className]); useEffect(() => { if (playgroundInstance) { if (props.rulerConfig) playgroundInstance.entityManager.getEntity(RulerConfigEntity)?.updateConfig(props.rulerConfig); if (props.playgroundConfig) playgroundInstance.entityManager.getEntity(PlaygroundConfigEntity)?.updateConfig(props.playgroundConfig); if (props.selectorBoxConfig) playgroundInstance.entityManager.getEntity(SelectorBoxConfigEntity)?.updateConfig(props.selectorBoxConfig); if (props.selectorConfig) playgroundInstance.entityManager.getEntity(SelectorConfigEntity)?.updateConfig(props.selectorConfig); if (props.snaplineConfig) playgroundInstance.entityManager.getEntity(SnaplineConfigEntity)?.updateConfig(props.snaplineConfig); if (props.toolbarConfig) playgroundInstance.entityManager.getEntity(ToolbarConfigEntity)?.updateConfig(props.toolbarConfig); } }, [playgroundInstance, props.rulerConfig, props.playgroundConfig, props.selectorBoxConfig, props.selectorConfig, props.snaplineConfig, props.toolbarConfig]); useEffect(() => { if (playgroundInstance) { // Ready 要在配置项之后执行 playgroundInstance.ready(); if (props.onReady) props.onReady(playgroundInstance); } }, [playgroundInstance]); const style = { ...props.style, width: props.width !== undefined ? props.width : props.style?.width, height: props.height !== undefined ? props.height : props.style?.height, }; return (
); }