1+ import { RTEPlugin as Plugin , rtePluginInitializer } from "./RTE" ;
2+ import {
3+ IConfig ,
4+ IDisplayOnOptions ,
5+ IDynamicFunction ,
6+ IElementTypeOptions ,
7+ IOnFunction ,
8+ IRteElementType ,
9+ IRteParam ,
10+ } from "./RTE/types" ;
11+ import { InitializationData } from "./types" ;
12+ import UiLocation from "./uiLocation" ;
13+
14+ type PluginConfigCallback = ( sdk : UiLocation ) => Promise < IConfig > | IConfig ;
15+
16+ interface PluginDefinition {
17+ id : string ;
18+ config : Partial < IConfig > ;
19+ callbacks : Partial < IOnFunction > ;
20+ asyncConfigCallback ?: PluginConfigCallback ;
21+ childBuilders : PluginBuilder [ ] ;
22+ }
23+
24+ class PluginBuilder {
25+ private id : string ;
26+ private _config : Partial < IConfig > = { } ;
27+ private _callbacks : Partial < IOnFunction > = { } ;
28+ private _asyncConfigCallback ?: PluginConfigCallback ;
29+ private _childBuilders : PluginBuilder [ ] = [ ] ;
30+
31+ constructor ( id : string ) {
32+ this . id = id ;
33+ this . _config . title = id ;
34+ }
35+
36+ title ( title : string ) : PluginBuilder {
37+ this . _config . title = title ;
38+ return this ;
39+ }
40+ icon ( icon : React . ReactElement | null ) : PluginBuilder {
41+ this . _config . icon = icon ;
42+ return this ;
43+ }
44+ display ( display : IDisplayOnOptions | IDisplayOnOptions [ ] ) : PluginBuilder {
45+ this . _config . display = display ;
46+ return this ;
47+ }
48+ elementType (
49+ elementType :
50+ | IElementTypeOptions
51+ | IElementTypeOptions [ ]
52+ | IDynamicFunction
53+ ) : PluginBuilder {
54+ this . _config . elementType = elementType ;
55+ return this ;
56+ }
57+ render ( renderFn : ( element : React . ReactElement , attrs : { [ key : string ] : any } , path : number [ ] , rte : IRteParam ) => React . ReactElement ) : PluginBuilder {
58+ this . _config . render = renderFn ;
59+ return this ;
60+ }
61+ shouldOverride (
62+ shouldOverrideFn : ( element : IRteElementType ) => boolean
63+ ) : PluginBuilder {
64+ this . _config . shouldOverride = shouldOverrideFn ;
65+ return this ;
66+ }
67+ on < T extends keyof IOnFunction > (
68+ type : T ,
69+ callback : IOnFunction [ T ]
70+ ) : PluginBuilder {
71+ this . _callbacks [ type ] = callback ;
72+ return this ;
73+ }
74+ configure ( callback : PluginConfigCallback ) : PluginBuilder {
75+ this . _asyncConfigCallback = callback ;
76+ return this ;
77+ }
78+ addPlugins ( ...builders : PluginBuilder [ ] ) : PluginBuilder {
79+ this . _childBuilders . push ( ...builders ) ;
80+ return this ;
81+ }
82+
83+ /**
84+ * Builds and returns a definition of the RTE Plugin, ready to be materialized
85+ * into a concrete RTEPlugin instance later when the SDK and Plugin Factory are available.
86+ * This method no longer performs the actual creation of RTEPlugin instances.
87+ */
88+ build ( ) : PluginDefinition {
89+ return {
90+ id : this . id ,
91+ config : this . _config ,
92+ callbacks : this . _callbacks ,
93+ asyncConfigCallback : this . _asyncConfigCallback ,
94+ childBuilders : this . _childBuilders ,
95+ } ;
96+ }
97+ }
98+
99+ async function materializePlugin (
100+ pluginDef : PluginDefinition ,
101+ sdk : UiLocation
102+ ) : Promise < Plugin > {
103+ let finalConfig : Partial < IConfig > = { ...pluginDef . config } ;
104+ if ( pluginDef . asyncConfigCallback ) {
105+ const dynamicConfig = await Promise . resolve (
106+ pluginDef . asyncConfigCallback ( sdk )
107+ ) ;
108+ finalConfig = { ...finalConfig , ...dynamicConfig } ;
109+ }
110+
111+ const plugin = rtePluginInitializer (
112+ pluginDef . id ,
113+ ( rte : IRteParam | void ) => {
114+ return finalConfig ;
115+ }
116+ ) ;
117+
118+ Object . entries ( pluginDef . callbacks ) . forEach ( ( [ type , callback ] ) => {
119+ plugin . on ( type as keyof IOnFunction , callback ) ;
120+ } ) ;
121+
122+ if ( pluginDef . childBuilders . length > 0 ) {
123+ const childPlugins = await Promise . all (
124+ pluginDef . childBuilders . map ( ( childBuilder ) =>
125+ materializePlugin ( childBuilder . build ( ) , sdk )
126+ )
127+ ) ;
128+ plugin . addPlugins ( ...childPlugins ) ;
129+ }
130+
131+ return plugin ;
132+ }
133+
134+ function registerPlugins (
135+ ...pluginDefinitions : PluginDefinition [ ]
136+ ) : (
137+ context : InitializationData ,
138+ rte : IRteParam
139+ ) => Promise < { [ key : string ] : Plugin } > {
140+ const definitionsToProcess = [ ...pluginDefinitions ] ;
141+ const plugins = async ( context : InitializationData , rte : IRteParam ) => {
142+ try {
143+ const sdk = new UiLocation ( context ) ;
144+ const materializedPlugins : { [ key : string ] : Plugin } = { } ;
145+ for ( const def of definitionsToProcess ) {
146+ const pluginInstance = await materializePlugin ( def , sdk ) ;
147+ materializedPlugins [ def . id ] = pluginInstance ;
148+ }
149+ rte . sdk = sdk ;
150+ return materializedPlugins ;
151+ } catch ( err ) {
152+ console . error ( "Error during plugin registration:" , err ) ;
153+ throw err ;
154+ }
155+ } ;
156+ return plugins ;
157+ }
158+
159+ export {
160+ IConfig ,
161+ IDisplayOnOptions ,
162+ IDynamicFunction ,
163+ IElementTypeOptions ,
164+ IOnFunction ,
165+ IRteElementType ,
166+ IRteParam ,
167+ Plugin ,
168+ PluginBuilder ,
169+ PluginDefinition ,
170+ registerPlugins
171+ } ;
0 commit comments