diff --git a/packages/ckeditor5-watchdog/src/contextwatchdog.ts b/packages/ckeditor5-watchdog/src/contextwatchdog.ts index 056915cb24d..d2b3bc9b924 100644 --- a/packages/ckeditor5-watchdog/src/contextwatchdog.ts +++ b/packages/ckeditor5-watchdog/src/contextwatchdog.ts @@ -24,7 +24,7 @@ import type { } from 'ckeditor5/src/utils'; import Watchdog, { type WatchdogConfig, type WatchdogState } from './watchdog'; -import EditorWatchdog, { type EditorCreatorFunction } from './editorwatchdog'; +import EditorWatchdog, { type WatchdogData, type EditorCreatorFunction } from './editorwatchdog'; import areConnectedThroughProperties from './utils/areconnectedthroughproperties'; import getSubNodes from './utils/getsubnodes'; @@ -36,11 +36,14 @@ const mainQueueId = Symbol( 'MainQueueId' ); * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and * how to use it. */ -export default class ContextWatchdog extends Watchdog { +export default class ContextWatchdog< + TContext extends Context = Context, + TData extends HTMLElement | string = HTMLElement | string +> extends Watchdog { /** * A map of internal watchdogs for added items. */ - protected _watchdogs = new Map(); + protected _watchdogs = new Map>(); /** * The watchdog configuration. @@ -194,10 +197,15 @@ export default class ContextWatchdog extends * @param itemId The item ID. * @returns The item instance or `undefined` if an item with a given ID has not been found. */ - public getItem( itemId: string ): unknown { - const watchdog = this._getWatchdog( itemId ); + public getItem( itemId: string ): unknown | undefined { + try { + const watchdog = this._getWatchdog( itemId ); - return watchdog._item; + return watchdog._item; + } + catch { + return undefined; + } } /** @@ -260,7 +268,7 @@ export default class ContextWatchdog extends * * @param itemConfigurationOrItemConfigurations An item configuration object or an array of item configurations. */ - public add( itemConfigurationOrItemConfigurations: ArrayOrItem ): Promise { + public add( itemConfigurationOrItemConfigurations: ArrayOrItem>> ): Promise { const itemConfigurations = toArray( itemConfigurationOrItemConfigurations ); return Promise.all( itemConfigurations.map( item => { @@ -273,14 +281,14 @@ export default class ContextWatchdog extends throw new Error( 'Context was not created yet. You should call the `ContextWatchdog#create()` method first.' ); } - let watchdog: EditorWatchdog; + let watchdog: EditorWatchdog; if ( this._watchdogs.has( item.id ) ) { throw new Error( `Item with the given id is already added: '${ item.id }'.` ); } if ( item.type === 'editor' ) { - watchdog = new EditorWatchdog( null, this._watchdogConfig ); + watchdog = new EditorWatchdog( null, this._watchdogConfig ); watchdog.setCreator( item.creator ); watchdog._setExcludedProperties( this._contextProps ); @@ -599,7 +607,9 @@ function toArray( elementOrArray: ArrayOrItem ): Array { /** * The watchdog item configuration interface. */ -export interface WatchdogItemConfiguration { +export interface WatchdogItemConfiguration< + TData extends HTMLElement | string | Record = HTMLElement | string | Record +> { /** * id A unique item identificator. @@ -615,7 +625,7 @@ export interface WatchdogItemConfiguration { * A function that initializes the item (the editor). The function takes editor initialization arguments * and should return a promise. For example: `( el, config ) => ClassicEditor.create( el, config )`. */ - creator: EditorCreatorFunction; + creator: EditorCreatorFunction; /** * A function that destroys the item instance (the editor). The function @@ -627,7 +637,7 @@ export interface WatchdogItemConfiguration { * The source element or data that will be passed * as the first argument to the `Editor.create()` method. */ - sourceElementOrData: string | HTMLElement; + sourceElementOrData: TData; /** * An editor configuration. diff --git a/packages/ckeditor5-watchdog/src/editorwatchdog.ts b/packages/ckeditor5-watchdog/src/editorwatchdog.ts index 0c049748726..2164b2fc69e 100644 --- a/packages/ckeditor5-watchdog/src/editorwatchdog.ts +++ b/packages/ckeditor5-watchdog/src/editorwatchdog.ts @@ -24,13 +24,18 @@ import Watchdog, { type WatchdogConfig } from './watchdog'; import { throttle, cloneDeepWith, isElement, type DebouncedFunc } from 'lodash-es'; +export type WatchdogData = TData extends HTMLElement ? TData : TData | Record; + /** * A watchdog for CKEditor 5 editors. * * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and * how to use it. */ -export default class EditorWatchdog extends Watchdog { +export default class EditorWatchdog< + TEditor extends Editor = Editor, + TData extends HTMLElement | string = HTMLElement | string +> extends Watchdog { /** * The current editor instance. */ @@ -45,7 +50,7 @@ export default class EditorWatchdog extends Wat /** * The latest saved editor data represented as a root name -> root data object. */ - private _data?: Record; + protected _data?: Record; /** * The last document version. @@ -55,19 +60,19 @@ export default class EditorWatchdog extends Wat /** * The editor source element or data. */ - private _elementOrData?: HTMLElement | string | Record; + protected _elementOrData?: WatchdogData; /** * The editor configuration. */ - private _config?: EditorConfig; + protected _config?: EditorConfig; /** * The creation method. * * @see #setCreator */ - declare protected _creator: EditorCreatorFunction; + declare protected _creator: EditorCreatorFunction>; /** * The destruction method. @@ -122,7 +127,7 @@ export default class EditorWatchdog extends Wat * watchdog.setCreator( ( element, config ) => ClassicEditor.create( element, config ) ); * ``` */ - public setCreator( creator: EditorCreatorFunction ): void { + public setCreator( creator: EditorCreatorFunction> ): void { this._creator = creator; } @@ -166,7 +171,7 @@ export default class EditorWatchdog extends Wat } ) .then( () => { if ( typeof this._elementOrData === 'string' ) { - return this.create( this._data, this._config, this._config!.context ); + return this.create( this._data as any, this._config, this._config!.context ); } else { const updatedConfig = Object.assign( {}, this._config, { initialData: this._data @@ -188,7 +193,7 @@ export default class EditorWatchdog extends Wat * @param context A context for the editor. */ public create( - elementOrData: HTMLElement | string | Record = this._elementOrData!, + elementOrData: WatchdogData = this._elementOrData!, config: EditorConfig = this._config!, context?: Context ): Promise { @@ -236,7 +241,7 @@ export default class EditorWatchdog extends Wat } ); } - private _destroy(): Promise { + protected _destroy(): Promise { return Promise.resolve() .then( () => { this._stopErrorHandling(); @@ -334,7 +339,7 @@ export type EditorWatchdogRestartEvent = { return: undefined; }; -export type EditorCreatorFunction = ( - elementOrData: HTMLElement | string | Record, +export type EditorCreatorFunction> = ( + elementOrData: TData, config: EditorConfig ) => Promise;