@ckeditor/ckeditor5-utils 41.3.1 → 41.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/index-content.css +4 -0
  2. package/dist/index-editor.css +4 -0
  3. package/dist/index.css +4 -0
  4. package/dist/index.js +5491 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/abortabledebounce.d.ts +21 -0
  7. package/dist/types/areconnectedthroughproperties.d.ts +15 -0
  8. package/dist/types/ckeditorerror.d.ts +127 -0
  9. package/dist/types/collection.d.ts +437 -0
  10. package/dist/types/comparearrays.d.ts +34 -0
  11. package/dist/types/config.d.ts +167 -0
  12. package/dist/types/count.d.ts +22 -0
  13. package/dist/types/delay.d.ts +23 -0
  14. package/dist/types/diff.d.ts +35 -0
  15. package/dist/types/difftochanges.d.ts +63 -0
  16. package/dist/types/dom/createelement.d.ts +61 -0
  17. package/dist/types/dom/emittermixin.d.ts +146 -0
  18. package/dist/types/dom/findclosestscrollableancestor.d.ts +15 -0
  19. package/dist/types/dom/getancestors.d.ts +21 -0
  20. package/dist/types/dom/getborderwidths.d.ts +28 -0
  21. package/dist/types/dom/getcommonancestor.d.ts +16 -0
  22. package/dist/types/dom/getdatafromelement.d.ts +18 -0
  23. package/dist/types/dom/getpositionedancestor.d.ts +14 -0
  24. package/dist/types/dom/global.d.ts +36 -0
  25. package/dist/types/dom/indexof.d.ts +18 -0
  26. package/dist/types/dom/insertat.d.ts +19 -0
  27. package/dist/types/dom/iscomment.d.ts +15 -0
  28. package/dist/types/dom/isnode.d.ts +15 -0
  29. package/dist/types/dom/isrange.d.ts +15 -0
  30. package/dist/types/dom/istext.d.ts +15 -0
  31. package/dist/types/dom/isvalidattributename.d.ts +14 -0
  32. package/dist/types/dom/isvisible.d.ts +22 -0
  33. package/dist/types/dom/iswindow.d.ts +15 -0
  34. package/dist/types/dom/position.d.ts +215 -0
  35. package/dist/types/dom/rect.d.ts +199 -0
  36. package/dist/types/dom/remove.d.ts +17 -0
  37. package/dist/types/dom/resizeobserver.d.ts +78 -0
  38. package/dist/types/dom/scroll.d.ts +77 -0
  39. package/dist/types/dom/setdatainelement.d.ts +18 -0
  40. package/dist/types/dom/tounit.d.ts +26 -0
  41. package/dist/types/elementreplacer.d.ts +35 -0
  42. package/dist/types/emittermixin.d.ts +316 -0
  43. package/dist/types/env.d.ts +137 -0
  44. package/dist/types/eventinfo.d.ts +62 -0
  45. package/dist/types/fastdiff.d.ts +116 -0
  46. package/dist/types/first.d.ts +15 -0
  47. package/dist/types/focustracker.d.ts +79 -0
  48. package/dist/types/index.d.ts +68 -0
  49. package/dist/types/inserttopriorityarray.d.ts +34 -0
  50. package/dist/types/isiterable.d.ts +18 -0
  51. package/dist/types/keyboard.d.ts +130 -0
  52. package/dist/types/keystrokehandler.d.ts +91 -0
  53. package/dist/types/language.d.ts +21 -0
  54. package/dist/types/locale.d.ts +145 -0
  55. package/dist/types/mapsequal.d.ts +19 -0
  56. package/dist/types/mix.d.ts +89 -0
  57. package/dist/types/nth.d.ts +20 -0
  58. package/dist/types/objecttomap.d.ts +27 -0
  59. package/dist/types/observablemixin.d.ts +564 -0
  60. package/dist/types/priorities.d.ts +37 -0
  61. package/dist/types/retry.d.ts +37 -0
  62. package/dist/types/splicearray.d.ts +30 -0
  63. package/dist/types/spy.d.ts +25 -0
  64. package/dist/types/toarray.d.ts +29 -0
  65. package/dist/types/tomap.d.ts +23 -0
  66. package/dist/types/translation-service.d.ts +178 -0
  67. package/dist/types/uid.d.ts +19 -0
  68. package/dist/types/unicode.d.ts +58 -0
  69. package/dist/types/verifylicense.d.ts +19 -0
  70. package/dist/types/version.d.ts +14 -0
  71. package/dist/types/wait.d.ts +20 -0
  72. package/package.json +2 -1
  73. package/src/env.d.ts +16 -0
  74. package/src/env.js +16 -0
  75. package/src/locale.d.ts +1 -1
  76. package/src/version.d.ts +1 -1
  77. package/src/version.js +2 -2
@@ -0,0 +1,564 @@
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
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
7
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
8
+ */
9
+ /**
10
+ * @module utils/observablemixin
11
+ */
12
+ import { type Emitter } from './emittermixin.js';
13
+ import type { Constructor, Mixed } from './mix.js';
14
+ /**
15
+ * A mixin that injects the "observable properties" and data binding functionality described in the
16
+ * {@link ~Observable} interface.
17
+ *
18
+ * This function creates a class that inherits from the provided `base` and implements `Observable` interface.
19
+ *
20
+ * ```ts
21
+ * class BaseClass { ... }
22
+ *
23
+ * class MyClass extends ObservableMixin( BaseClass ) {
24
+ * // This class derives from `BaseClass` and implements the `Observable` interface.
25
+ * }
26
+ * ```
27
+ *
28
+ * Read more about the concept of observables in the:
29
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
30
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
31
+ * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
32
+ *
33
+ * @label EXTENDS
34
+ */
35
+ export default function ObservableMixin<Base extends Constructor<Emitter>>(base: Base): Mixed<Base, Observable>;
36
+ /**
37
+ * A mixin that injects the "observable properties" and data binding functionality described in the
38
+ * {@link ~Observable} interface.
39
+ *
40
+ * This function creates a class that implements `Observable` interface.
41
+ *
42
+ * ```ts
43
+ * class MyClass extends ObservableMixin() {
44
+ * // This class implements the `Observable` interface.
45
+ * }
46
+ * ```
47
+ *
48
+ * Read more about the concept of observables in the:
49
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
50
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
51
+ * * {@glink framework/deep-dive/observables Observables deep dive} guide.
52
+ *
53
+ * @label NO_ARGUMENTS
54
+ */
55
+ export default function ObservableMixin(): {
56
+ new (): Observable;
57
+ prototype: Observable;
58
+ };
59
+ /**
60
+ * An interface which adds "observable properties" and data binding functionality.
61
+ *
62
+ * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~Observable} mixin.
63
+ *
64
+ * ```ts
65
+ * class MyClass extends ObservableMixin( OtherBaseClass ) {
66
+ * // This class now implements the `Observable` interface.
67
+ * }
68
+ * ```
69
+ *
70
+ * Read more about the usage of this interface in the:
71
+ * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}
72
+ * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,
73
+ * * {@glink framework/deep-dive/observables Observables deep-dive} guide.
74
+ */
75
+ export interface Observable extends Emitter {
76
+ /**
77
+ * Creates and sets the value of an observable property of this object. Such a property becomes a part
78
+ * of the state and is observable.
79
+ *
80
+ * This method throws the `observable-set-cannot-override` error if the observable instance already
81
+ * has a property with the given property name. This prevents from mistakenly overriding existing
82
+ * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
83
+ *
84
+ * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
85
+ *
86
+ * ```ts
87
+ * public declare myProp: number;
88
+ *
89
+ * constructor() {
90
+ * this.set( 'myProp', 2 );
91
+ * }
92
+ * ```
93
+ *
94
+ * @label KEY_VALUE
95
+ * @param name The property's name.
96
+ * @param value The property's value.
97
+ */
98
+ set<K extends keyof this & string>(name: K, value: this[K]): void;
99
+ /**
100
+ * Creates and sets the value of an observable properties of this object. Such a property becomes a part
101
+ * of the state and is observable.
102
+ *
103
+ * It accepts a single object literal containing key/value pairs with properties to be set.
104
+ *
105
+ * This method throws the `observable-set-cannot-override` error if the observable instance already
106
+ * has a property with the given property name. This prevents from mistakenly overriding existing
107
+ * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.
108
+ *
109
+ * In TypeScript, those properties should be declared in class using `declare` keyword. In example:
110
+ *
111
+ * ```ts
112
+ * public declare myProp1: number;
113
+ * public declare myProp2: string;
114
+ *
115
+ * constructor() {
116
+ * this.set( {
117
+ * 'myProp1: 2,
118
+ * 'myProp2: 'foo'
119
+ * } );
120
+ * }
121
+ * ```
122
+ * @label OBJECT
123
+ * @param values An object with `name=>value` pairs.
124
+ */
125
+ set(values: object & {
126
+ readonly [K in keyof this]?: unknown;
127
+ }): void;
128
+ /**
129
+ * Binds {@link #set observable properties} to other objects implementing the
130
+ * {@link module:utils/observablemixin~Observable} interface.
131
+ *
132
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
133
+ * covering the topic of property bindings with some additional examples.
134
+ *
135
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
136
+ *
137
+ * A simple property binding could be as follows:
138
+ *
139
+ * ```ts
140
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
141
+ * ```
142
+ *
143
+ * or even shorter:
144
+ *
145
+ * ```ts
146
+ * button.bind( 'isEnabled' ).to( command );
147
+ * ```
148
+ *
149
+ * which works in the following way:
150
+ *
151
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
152
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
153
+ *
154
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
155
+ *
156
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
157
+ *
158
+ * ```ts
159
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
160
+ * ```
161
+ *
162
+ * It is possible to bind more than one property at a time to shorten the code:
163
+ *
164
+ * ```ts
165
+ * button.bind( 'isEnabled', 'value' ).to( command );
166
+ * ```
167
+ *
168
+ * which corresponds to:
169
+ *
170
+ * ```ts
171
+ * button.bind( 'isEnabled' ).to( command );
172
+ * button.bind( 'value' ).to( command );
173
+ * ```
174
+ *
175
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
176
+ *
177
+ * ```ts
178
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
179
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
180
+ * ```
181
+ *
182
+ * Using a custom callback allows processing the value before passing it to the target property:
183
+ *
184
+ * ```ts
185
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
186
+ * ```
187
+ *
188
+ * It is also possible to bind to the same property in an array of observables.
189
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
190
+ * must be enabled for the button to become enabled, use the following code:
191
+ *
192
+ * ```ts
193
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
194
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
195
+ * ```
196
+ *
197
+ * @label SINGLE_BIND
198
+ * @param bindProperty Observable property that will be bound to other observable(s).
199
+ * @returns The bind chain with the `to()` and `toMany()` methods.
200
+ */
201
+ bind<K extends keyof this & string>(bindProperty: K): SingleBindChain<K, this[K]>;
202
+ /**
203
+ * Binds {@link #set observable properties} to other objects implementing the
204
+ * {@link module:utils/observablemixin~Observable} interface.
205
+ *
206
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
207
+ * covering the topic of property bindings with some additional examples.
208
+ *
209
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
210
+ *
211
+ * A simple property binding could be as follows:
212
+ *
213
+ * ```ts
214
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
215
+ * ```
216
+ *
217
+ * or even shorter:
218
+ *
219
+ * ```ts
220
+ * button.bind( 'isEnabled' ).to( command );
221
+ * ```
222
+ *
223
+ * which works in the following way:
224
+ *
225
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
226
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
227
+ *
228
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
229
+ *
230
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
231
+ *
232
+ * ```ts
233
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
234
+ * ```
235
+ *
236
+ * It is possible to bind more than one property at a time to shorten the code:
237
+ *
238
+ * ```ts
239
+ * button.bind( 'isEnabled', 'value' ).to( command );
240
+ * ```
241
+ *
242
+ * which corresponds to:
243
+ *
244
+ * ```ts
245
+ * button.bind( 'isEnabled' ).to( command );
246
+ * button.bind( 'value' ).to( command );
247
+ * ```
248
+ *
249
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
250
+ *
251
+ * ```ts
252
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
253
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
254
+ * ```
255
+ *
256
+ * Using a custom callback allows processing the value before passing it to the target property:
257
+ *
258
+ * ```ts
259
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
260
+ * ```
261
+ *
262
+ * It is also possible to bind to the same property in an array of observables.
263
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
264
+ * must be enabled for the button to become enabled, use the following code:
265
+ *
266
+ * ```ts
267
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
268
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
269
+ * ```
270
+ *
271
+ * @label DUAL_BIND
272
+ * @param bindProperty1 Observable property that will be bound to other observable(s).
273
+ * @param bindProperty2 Observable property that will be bound to other observable(s).
274
+ * @returns The bind chain with the `to()` and `toMany()` methods.
275
+ */
276
+ bind<K1 extends keyof this & string, K2 extends keyof this & string>(bindProperty1: K1, bindProperty2: K2): DualBindChain<K1, this[K1], K2, this[K2]>;
277
+ /**
278
+ * Binds {@link #set observable properties} to other objects implementing the
279
+ * {@link module:utils/observablemixin~Observable} interface.
280
+ *
281
+ * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide
282
+ * covering the topic of property bindings with some additional examples.
283
+ *
284
+ * Consider two objects: a `button` and an associated `command` (both `Observable`).
285
+ *
286
+ * A simple property binding could be as follows:
287
+ *
288
+ * ```ts
289
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled' );
290
+ * ```
291
+ *
292
+ * or even shorter:
293
+ *
294
+ * ```ts
295
+ * button.bind( 'isEnabled' ).to( command );
296
+ * ```
297
+ *
298
+ * which works in the following way:
299
+ *
300
+ * * `button.isEnabled` **instantly equals** `command.isEnabled`,
301
+ * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.
302
+ *
303
+ * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.
304
+ *
305
+ * You can also "rename" the property in the binding by specifying the new name in the `to()` chain:
306
+ *
307
+ * ```ts
308
+ * button.bind( 'isEnabled' ).to( command, 'isWorking' );
309
+ * ```
310
+ *
311
+ * It is possible to bind more than one property at a time to shorten the code:
312
+ *
313
+ * ```ts
314
+ * button.bind( 'isEnabled', 'value' ).to( command );
315
+ * ```
316
+ *
317
+ * which corresponds to:
318
+ *
319
+ * ```ts
320
+ * button.bind( 'isEnabled' ).to( command );
321
+ * button.bind( 'value' ).to( command );
322
+ * ```
323
+ *
324
+ * The binding can include more than one observable, combining multiple data sources in a custom callback:
325
+ *
326
+ * ```ts
327
+ * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',
328
+ * ( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );
329
+ * ```
330
+ *
331
+ * Using a custom callback allows processing the value before passing it to the target property:
332
+ *
333
+ * ```ts
334
+ * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );
335
+ * ```
336
+ *
337
+ * It is also possible to bind to the same property in an array of observables.
338
+ * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them
339
+ * must be enabled for the button to become enabled, use the following code:
340
+ *
341
+ * ```ts
342
+ * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',
343
+ * ( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );
344
+ * ```
345
+ *
346
+ * @label MANY_BIND
347
+ * @param bindProperties Observable properties that will be bound to other observable(s).
348
+ * @returns The bind chain with the `to()` and `toMany()` methods.
349
+ */
350
+ bind(...bindProperties: Array<keyof this & string>): MultiBindChain;
351
+ /**
352
+ * Removes the binding created with {@link #bind}.
353
+ *
354
+ * ```ts
355
+ * // Removes the binding for the 'a' property.
356
+ * A.unbind( 'a' );
357
+ *
358
+ * // Removes bindings for all properties.
359
+ * A.unbind();
360
+ * ```
361
+ *
362
+ * @param unbindProperties Observable properties to be unbound. All the bindings will
363
+ * be released if no properties are provided.
364
+ */
365
+ unbind(...unbindProperties: Array<keyof this & string>): void;
366
+ /**
367
+ * Turns the given methods of this object into event-based ones. This means that the new method will fire an event
368
+ * (named after the method) and the original action will be plugged as a listener to that event.
369
+ *
370
+ * Read more in the {@glink framework/deep-dive/observables#decorating-object-methods dedicated} guide
371
+ * covering the topic of decorating methods with some additional examples.
372
+ *
373
+ * Decorating the method does not change its behavior (it only adds an event),
374
+ * but it allows to modify it later on by listening to the method's event.
375
+ *
376
+ * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:
377
+ *
378
+ * ```ts
379
+ * class Foo extends ObservableMixin() {
380
+ * constructor() {
381
+ * super();
382
+ * this.decorate( 'method' );
383
+ * }
384
+ *
385
+ * method() {
386
+ * console.log( 'called!' );
387
+ * }
388
+ * }
389
+ *
390
+ * const foo = new Foo();
391
+ * foo.on( 'method', ( evt ) => {
392
+ * evt.stop();
393
+ * }, { priority: 'high' } );
394
+ *
395
+ * foo.method(); // Nothing is logged.
396
+ * ```
397
+ *
398
+ *
399
+ * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener
400
+ * has been used to execute this particular callback before the one which calls the original method
401
+ * (which uses the "normal" priority).
402
+ *
403
+ * It is also possible to change the returned value:
404
+ *
405
+ * ```ts
406
+ * foo.on( 'method', ( evt ) => {
407
+ * evt.return = 'Foo!';
408
+ * } );
409
+ *
410
+ * foo.method(); // -> 'Foo'
411
+ * ```
412
+ *
413
+ * Finally, it is possible to access and modify the arguments the method is called with:
414
+ *
415
+ * ```ts
416
+ * method( a, b ) {
417
+ * console.log( `${ a }, ${ b }` );
418
+ * }
419
+ *
420
+ * // ...
421
+ *
422
+ * foo.on( 'method', ( evt, args ) => {
423
+ * args[ 0 ] = 3;
424
+ *
425
+ * console.log( args[ 1 ] ); // -> 2
426
+ * }, { priority: 'high' } );
427
+ *
428
+ * foo.method( 1, 2 ); // -> '3, 2'
429
+ * ```
430
+ *
431
+ * @param methodName Name of the method to decorate.
432
+ */
433
+ decorate(methodName: keyof this & string): void;
434
+ }
435
+ /**
436
+ * Fired when a property changed value.
437
+ *
438
+ * ```ts
439
+ * observable.set( 'prop', 1 );
440
+ *
441
+ * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
442
+ * console.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );
443
+ * } );
444
+ *
445
+ * observable.prop = 2; // -> 'prop has changed from 1 to 2'
446
+ * ```
447
+ *
448
+ * @eventName ~Observable#change:\{property\}
449
+ * @param {String} name The property name.
450
+ * @param {*} value The new property value.
451
+ * @param {*} oldValue The previous property value.
452
+ */
453
+ export type ObservableChangeEvent<TValue = any> = {
454
+ name: 'change' | `change:${string}`;
455
+ args: [name: string, value: TValue, oldValue: TValue];
456
+ };
457
+ /**
458
+ * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).
459
+ *
460
+ * You can control the final value of the property by using
461
+ * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.
462
+ *
463
+ * ```ts
464
+ * observable.set( 'prop', 1 );
465
+ *
466
+ * observable.on<ObservableSetEvent<number>>( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {
467
+ * console.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );
468
+ * console.log( `Current property value is ${ observable[ propertyName ] }` );
469
+ *
470
+ * // Let's override the value.
471
+ * evt.return = 3;
472
+ * } );
473
+ *
474
+ * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {
475
+ * console.log( `Value has changed from ${ oldValue } to ${ newValue }` );
476
+ * } );
477
+ *
478
+ * observable.prop = 2; // -> 'Value is going to be changed from 1 to 2'
479
+ * // -> 'Current property value is 1'
480
+ * // -> 'Value has changed from 1 to 3'
481
+ * ```
482
+ *
483
+ * **Note:** The event is fired even when the new value is the same as the old value.
484
+ *
485
+ * @eventName ~Observable#set:\{property\}
486
+ * @param {String} name The property name.
487
+ * @param {*} value The new property value.
488
+ * @param {*} oldValue The previous property value.
489
+ */
490
+ export type ObservableSetEvent<TValue = any> = {
491
+ name: 'set' | `set:${string}`;
492
+ args: [name: string, value: TValue, oldValue: TValue];
493
+ return: TValue;
494
+ };
495
+ /**
496
+ * Utility type that creates an event describing type from decorated method.
497
+ *
498
+ * ```ts
499
+ * class Foo extends ObservableMixin() {
500
+ * constructor() {
501
+ * super();
502
+ * this.decorate( 'method' );
503
+ * }
504
+ *
505
+ * method( a: number, b: number ): number {
506
+ * return a + b;
507
+ * }
508
+ * }
509
+ *
510
+ * type FooMethodEvent = DecoratedMethodEvent<Foo, 'method'>;
511
+ *
512
+ * const foo = new Foo();
513
+ *
514
+ * foo.on<FooMethodEvent>( 'method', ( evt, [ a, b ] ) => {
515
+ * // `a` and `b` are inferred as numbers.
516
+ * } )
517
+ * ```
518
+ */
519
+ export type DecoratedMethodEvent<TObservable extends Observable & {
520
+ [N in TName]: (...args: Array<any>) => any;
521
+ }, TName extends keyof TObservable & string> = {
522
+ name: TName;
523
+ args: [Parameters<TObservable[TName]>];
524
+ return: ReturnType<TObservable[TName]>;
525
+ };
526
+ interface SingleBindChain<TKey extends string, TVal> {
527
+ toMany<O extends Observable, K extends keyof O>(observables: ReadonlyArray<O>, key: K, callback: (...values: Array<O[K]>) => TVal): void;
528
+ to<O extends ObservableWithProperty<TKey, TVal>>(observable: O): void;
529
+ to<O extends ObservableWithProperty<TKey>>(observable: O, callback: (value: O[TKey]) => TVal): void;
530
+ to<O extends ObservableWithProperty<K, TVal>, K extends keyof O>(observable: O, key: K): void;
531
+ to<O extends Observable, K extends keyof O>(observable: O, key: K, callback: (value: O[K]) => TVal): void;
532
+ to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, callback: (value1: O1[TKey], value2: O2[TKey]) => TVal): void;
533
+ to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2>(observable1: O1, key1: K1, observable2: O2, key2: K2, callback: (value1: O1[K1], value2: O2[K2]) => TVal): void;
534
+ to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey]) => TVal): void;
535
+ to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3]) => TVal): void;
536
+ to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>, O4 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, observable4: O4, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey]) => TVal): void;
537
+ to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3, O4 extends Observable, K4 extends keyof O4>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4]) => TVal): void;
538
+ to<O1 extends ObservableWithProperty<TKey>, O2 extends ObservableWithProperty<TKey>, O3 extends ObservableWithProperty<TKey>, O4 extends ObservableWithProperty<TKey>, O5 extends ObservableWithProperty<TKey>>(observable1: O1, observable2: O2, observable3: O3, observable4: O4, observable5: O5, callback: (value1: O1[TKey], value2: O2[TKey], value3: O3[TKey], value4: O4[TKey], value5: O5[TKey]) => TVal): void;
539
+ to<O1 extends Observable, K1 extends keyof O1, O2 extends Observable, K2 extends keyof O2, O3 extends Observable, K3 extends keyof O3, O4 extends Observable, K4 extends keyof O4, O5 extends Observable, K5 extends keyof O5>(observable1: O1, key1: K1, observable2: O2, key2: K2, observable3: O3, key3: K3, observable4: O4, key4: K4, observable5: O5, key5: K5, callback: (value1: O1[K1], value2: O2[K2], value3: O3[K3], value4: O4[K4], value5: O5[K5]) => TVal): void;
540
+ }
541
+ /**
542
+ * A helper type that can be used as a constraint, ensuring the type is both observable and have the given property.
543
+ *
544
+ * ```ts
545
+ * // Ensures that `obj` is `Observable` and have property named 'abc'.
546
+ * function f<O extends ObservableWithProperty<'abc'>>( obj: O ) {}
547
+ *
548
+ * // Ensures that `obj` is `Observable` and have property named 'abc' with value `number`.
549
+ * function f<O extends ObservableWithProperty<'abc', number>>( obj: O ) {}
550
+ * ```
551
+ */
552
+ export type ObservableWithProperty<TKey extends PropertyKey, TVal = any> = undefined extends TVal ? Observable & {
553
+ [P in TKey]?: TVal;
554
+ } : Observable & {
555
+ [P in TKey]: TVal;
556
+ };
557
+ interface DualBindChain<TKey1 extends string, TVal1, TKey2 extends string, TVal2> {
558
+ to<O extends ObservableWithProperty<K1, TVal1> & ObservableWithProperty<K2, TVal2>, K1 extends keyof O, K2 extends keyof O>(observable: O, key1: K1, key2: K2): void;
559
+ to<O extends ObservableWithProperty<TKey1, TVal1> & ObservableWithProperty<TKey2, TVal2>>(observable: O): void;
560
+ }
561
+ interface MultiBindChain {
562
+ to<O extends Observable>(observable: O, ...properties: Array<keyof O>): void;
563
+ }
564
+ export {};
@@ -0,0 +1,37 @@
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
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
7
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
8
+ */
9
+ /**
10
+ * @module utils/priorities
11
+ */
12
+ /**
13
+ * String representing a priority value.
14
+ */
15
+ export type PriorityString = 'highest' | 'high' | 'normal' | 'low' | 'lowest' | number;
16
+ /**
17
+ * Provides group of constants to use instead of hardcoding numeric priority values.
18
+ */
19
+ export interface PrioritiesType {
20
+ /**
21
+ * Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.
22
+ *
23
+ * @param priority Priority to convert.
24
+ * @returns Converted priority.
25
+ */
26
+ get(priority?: PriorityString): number;
27
+ readonly highest: number;
28
+ readonly high: number;
29
+ readonly normal: number;
30
+ readonly low: number;
31
+ readonly lowest: number;
32
+ }
33
+ /**
34
+ * Provides group of constants to use instead of hardcoding numeric priority values.
35
+ */
36
+ declare const priorities: PrioritiesType;
37
+ export default priorities;
@@ -0,0 +1,37 @@
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
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
7
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
8
+ */
9
+ /**
10
+ * Tries calling the given callback until it sucessfully resolves.
11
+ *
12
+ * If the callback fails `maxRetries` times, the returned promise is rejected with the last error.
13
+ *
14
+ * @typeParam TResult The result of a successful callback invocation.
15
+ * @param callback The function to call until it succeeds.
16
+ * @param options.maxRetries Maximum number of retries.
17
+ * @param options.retryDelay The time in milliseconds between attempts. By default it implements exponential back-off policy.
18
+ * @param options.signal The signal to abort further retries. The callback itself is not aborted automatically.
19
+ */
20
+ export default function retry<TResult>(callback: () => Promise<TResult>, options?: {
21
+ maxAttempts?: number;
22
+ retryDelay?: (attempt: number) => number;
23
+ signal?: AbortSignal;
24
+ }): Promise<TResult>;
25
+ /**
26
+ * Creates a function that calculates exponential back-off delay. Pass it as `options.retryDelay` to {@link ~retry}.
27
+ *
28
+ * @param options.delay Base delay between invocations. Defaults to 1s.
29
+ * @param options.factor How much to increase the delay. Defaults to 2x.
30
+ * @param options.maxDelay Maximum timeout. Even if higher timeout is calculated, it cannot get higher than this value. Default to 10s.
31
+ * @returns The function calculating the delay.
32
+ */
33
+ export declare function exponentialDelay(options?: {
34
+ delay?: number;
35
+ factor?: number;
36
+ maxDelay?: number;
37
+ }): (attempt: number) => number;
@@ -0,0 +1,30 @@
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
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
7
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
8
+ */
9
+ /**
10
+ * Splices one array into another. To be used instead of `Array.prototype.splice` as the latter may
11
+ * throw "Maximum call stack size exceeded" when passed huge number of items to insert.
12
+ *
13
+ * Note: in contrary to Array.splice, this function does not modify the original `target`.
14
+ *
15
+ * ```ts
16
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 0, 0 ); // [ 3, 4, 1, 2 ]
17
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 1 ); // [ 1, 3, 4 ]
18
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 0 ); // [ 1, 3, 4, 2 ]
19
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 2, 0 ); // [ 1, 2, 3, 4 ]
20
+ * spliceArray( [ 1, 2 ], [], 0, 1 ); // [ 2 ]
21
+ * ```
22
+ *
23
+ * @param target Array to be spliced.
24
+ * @param source Array of elements to be inserted to target.
25
+ * @param start Index at which nodes should be inserted/removed.
26
+ * @param count Number of items.
27
+ *
28
+ * @returns New spliced array.
29
+ */
30
+ export default function spliceArray<T>(target: ReadonlyArray<T>, source: ReadonlyArray<T>, start: number, count: number): Array<T>;