UNPKG

9.41 kBTypeScriptView Raw
1/**
2 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5/**
6 * @module core/context
7 */
8import { Config, Collection, Locale, type LocaleTranslate } from '@ckeditor/ckeditor5-utils';
9import PluginCollection from './plugincollection.js';
10import type Editor from './editor/editor.js';
11import type { LoadedPlugins, PluginConstructor } from './plugin.js';
12import type { EditorConfig } from './editor/editorconfig.js';
13/**
14 * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors}
15 * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`}
16 * in advanced application integrations.
17 *
18 * All configuration options passed to a context will be used as default options for the editor instances initialized in that context.
19 *
20 * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all
21 * editor instances initialized in this context. These will be the same plugin instances for all the editors.
22 *
23 * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins}
24 * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an
25 * editor instance to work and cannot be added to a context.
26 *
27 * **Note:** You can add a context plugin to an editor instance, though.
28 *
29 * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and
30 * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them.
31 *
32 * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)),
33 * enable and configure them using the context.
34 *
35 * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead.
36 * In such a case, a context instance will be created by the editor instance in a transparent way.
37 *
38 * See {@link ~Context.create `Context.create()`} for usage examples.
39 */
40export default class Context {
41 /**
42 * Stores all the configurations specific to this context instance.
43 */
44 readonly config: Config<ContextConfig>;
45 /**
46 * The plugins loaded and in use by this context instance.
47 */
48 readonly plugins: PluginCollection<Context | Editor>;
49 readonly locale: Locale;
50 /**
51 * Shorthand for {@link module:utils/locale~Locale#t}.
52 */
53 readonly t: LocaleTranslate;
54 /**
55 * A list of editors that this context instance is injected to.
56 */
57 readonly editors: Collection<Editor>;
58 /**
59 * The default configuration which is built into the `Context` class.
60 *
61 * It is used in CKEditor 5 builds featuring `Context` to provide the default configuration options which are later used during the
62 * context initialization.
63 *
64 * ```ts
65 * Context.defaultConfig = {
66 * foo: 1,
67 * bar: 2
68 * };
69 *
70 * Context
71 * .create()
72 * .then( context => {
73 * context.config.get( 'foo' ); // -> 1
74 * context.config.get( 'bar' ); // -> 2
75 * } );
76 *
77 * // The default options can be overridden by the configuration passed to create().
78 * Context
79 * .create( { bar: 3 } )
80 * .then( context => {
81 * context.config.get( 'foo' ); // -> 1
82 * context.config.get( 'bar' ); // -> 3
83 * } );
84 * ```
85 *
86 * See also {@link module:core/context~Context.builtinPlugins `Context.builtinPlugins`}
87 * and {@link module:core/editor/editor~Editor.defaultConfig `Editor.defaultConfig`}.
88 */
89 static defaultConfig: ContextConfig;
90 /**
91 * An array of plugins built into the `Context` class.
92 *
93 * It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized
94 * during the context initialization.
95 *
96 * They will be automatically initialized by `Context` unless `config.plugins` is passed.
97 *
98 * ```ts
99 * // Build some context plugins into the Context class first.
100 * Context.builtinPlugins = [ FooPlugin, BarPlugin ];
101 *
102 * // Normally, you need to define config.plugins, but since Context.builtinPlugins was
103 * // defined, now you can call create() without any configuration.
104 * Context
105 * .create()
106 * .then( context => {
107 * context.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.
108 * context.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.
109 * } );
110 * ```
111 *
112 * See also {@link module:core/context~Context.defaultConfig `Context.defaultConfig`}
113 * and {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.
114 */
115 static builtinPlugins: Array<PluginConstructor<Context | Editor>>;
116 /**
117 * Reference to the editor which created the context.
118 * Null when the context was created outside of the editor.
119 *
120 * It is used to destroy the context when removing the editor that has created the context.
121 */
122 private _contextOwner;
123 /**
124 * Creates a context instance with a given configuration.
125 *
126 * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method.
127 *
128 * @param config The context configuration.
129 */
130 constructor(config?: ContextConfig);
131 /**
132 * Loads and initializes plugins specified in the configuration.
133 *
134 * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins.
135 */
136 initPlugins(): Promise<LoadedPlugins>;
137 /**
138 * Destroys the context instance and all editors used with the context,
139 * releasing all resources used by the context.
140 *
141 * @returns A promise that resolves once the context instance is fully destroyed.
142 */
143 destroy(): Promise<unknown>;
144 /**
145 * Adds a reference to the editor which is used with this context.
146 *
147 * When the given editor has created the context, the reference to this editor will be stored
148 * as a {@link ~Context#_contextOwner}.
149 *
150 * This method should only be used by the editor.
151 *
152 * @internal
153 * @param isContextOwner Stores the given editor as a context owner.
154 */
155 _addEditor(editor: Editor, isContextOwner: boolean): void;
156 /**
157 * Removes a reference to the editor which was used with this context.
158 * When the context was created by the given editor, the context will be destroyed.
159 *
160 * This method should only be used by the editor.
161 *
162 * @internal
163 * @return A promise that resolves once the editor is removed from the context or when the context was destroyed.
164 */
165 _removeEditor(editor: Editor): Promise<unknown>;
166 /**
167 * Returns the context configuration which will be copied to the editors created using this context.
168 *
169 * The configuration returned by this method has the plugins configuration removed &ndash; plugins are shared with all editors
170 * through another mechanism.
171 *
172 * This method should only be used by the editor.
173 *
174 * @internal
175 * @returns Configuration as a plain object.
176 */
177 _getEditorConfig(): Partial<EditorConfig>;
178 /**
179 * Creates and initializes a new context instance.
180 *
181 * ```ts
182 * const commonConfig = { ... }; // Configuration for all the plugins and editors.
183 * const editorPlugins = [ ... ]; // Regular plugins here.
184 *
185 * Context
186 * .create( {
187 * // Only context plugins here.
188 * plugins: [ ... ],
189 *
190 * // Configure the language for all the editors (it cannot be overwritten).
191 * language: { ... },
192 *
193 * // Configuration for context plugins.
194 * comments: { ... },
195 * ...
196 *
197 * // Default configuration for editor plugins.
198 * toolbar: { ... },
199 * image: { ... },
200 * ...
201 * } )
202 * .then( context => {
203 * const promises = [];
204 *
205 * promises.push( ClassicEditor.create(
206 * document.getElementById( 'editor1' ),
207 * {
208 * editorPlugins,
209 * context
210 * }
211 * ) );
212 *
213 * promises.push( ClassicEditor.create(
214 * document.getElementById( 'editor2' ),
215 * {
216 * editorPlugins,
217 * context,
218 * toolbar: { ... } // You can overwrite the configuration of the context.
219 * }
220 * ) );
221 *
222 * return Promise.all( promises );
223 * } );
224 * ```
225 *
226 * @param config The context configuration.
227 * @returns A promise resolved once the context is ready. The promise resolves with the created context instance.
228 */
229 static create(config?: ContextConfig): Promise<Context>;
230}
231/**
232 * The context configuration.
233 */
234export type ContextConfig = {
235 plugins?: Array<PluginConstructor<Context | Editor>>;
236 substitutePlugins?: Array<PluginConstructor<Context | Editor>>;
237} & Omit<EditorConfig, 'plugins' | 'substitutePlugins' | 'removePlugins' | 'extraPlugins'>;