created: , updated:

IOC (Inversion of Control) Container

As a developer, I need a centralized way to configure all instances of the editor.

 

The configuration of the "Canvas Editor" rich text editor is managed through a simple "Dependency Injection" container. This container behaves like a registry of keys and values.

 

Terminology "Container", "IOC Container" refers to the Container interface.

Terminology "defaultIOC" or "demoIOC" refers to some exported pre-configured instances of Container, from npm package @andrei-sfia/canvas-editor.

 

You can access the value of a setting corresponding to a key via the "get" method of container, and replace a setting value via the "bind" method of container.

Below is the interface of the Container type:

 

detecting...
1interface Container {
2 clone(): Container;
3
4 get("KEYBOARD_DRIVER"): KeyboardDriver;
5 get("HID_DRIVER"): HIDManager;
6 get("TOOLBAR"): Array<string|null>;
7 get("MEDIA_LIBRARY"): MediaLibraryInterface;
8 get("DOM_FACTORY"): DOMFactoryInterface;
9 get("CSS_DOCUMENT"): CSSDocument;
10 get("TOOLBAR_ITEM_FACTORY"): ToolbarItemFactoryInterface;
11 get("I18N_PREFIX"): string;
12 get("I18N_FUNCTION"): TFunction<["translation", ...string[]], undefined>;
13 get("MIME_TYPE"): MimeTypeInterface;
14 get("DEBUG_MODE"): boolean;
15 get("COLOR_MAPPER"): ThemeColorMapper;
16 get("RENDERER_ALLOWED_HTML_ATTRIBUTES"): Set<string>;
17 get("RENDERER_COMPONENTS_MAPPER"): ContentRendererComponentMapper;
18
19 bind("KEYBOARD_DRIVER", IOCBinding<KeyboardDriver>): Container;
20 bind("HID_DRIVER", IOCBinding<HIDManager>): Container;
21 bind("TOOLBAR", IOCBinding<Array<string|null>>): Container;
22 bind("MEDIA_LIBRARY", IOCBinding<MediaLibraryInterface>): Container;
23 bind("DOM_FACTORY", IOCBinding<DOMFactoryInterface>): Container;
24 bind("CSS_DOCUMENT", IOCBinding<CSSDocument>): Container;
25 bind("TOOLBAR_ITEM_FACTORY", IOCBinding<ToolbarItemFactoryInterface>): Container;
26 bind("I18N_PREFIX", IOCBinding<string>): Container;
27 bind("I18N_FUNCTION", IOCBinding<TFunction<["translation", ...string[]], undefined>>): Container;
28 bind("MIME_TYPE", IOCBinding<MimeTypeInterface>): Container;
29 bind("DEBUG_MODE", IOCBinding<boolean>): Container;
30 bind("COLOR_MAPPER", IOCBinding<ThemeColorMapper>): Container;
31 bind("RENDERER_ALLOWED_HTML_ATTRIBUTES", IOCBinding<Set<string>>): Container;
32 bind("RENDERER_COMPONENTS_MAPPER", IOCBinding<ContentRendererComponentMapper>): Container;
33}
34
35export enum IOCInstance {
36 SINGLETON,
37 NEW
38}
39
40export type IOCBinding<T> = { creation: IOCInstance.SINGLETON, value: T } | { creation: IOCInstance.NEW, factory: ( container: Container ) => T }

 

The @andrei-sfia/canvas-editor package provides two already configured (binded) containers:

 

detecting...
1export const defaultIOC: Container;
2export const demoIOC: Container;

 

Wherever you embed the Editor / EditorSSR component, you can specify as a React prop either one of these two containers (defaultIOC or demoIOC), or an altered clone of one of these containers.

 

In most of the times, you don't want to bind something directly to defaultIOC / demoIOC containers (because it will affect all editor instances), but you want to use this pattern which creates your own container with your custom binded value:

 

detecting...
1const myContainer = defaultIOC.clone().bind("...", ...)

 

This way, you create a new container inheriting the defaultIOC, and you alter the setting on that container copy.