@ckeditor/ckeditor5-utils 34.2.0 → 35.1.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 (61) hide show
  1. package/CHANGELOG.md +324 -0
  2. package/LICENSE.md +1 -1
  3. package/package.json +19 -8
  4. package/src/areconnectedthroughproperties.js +54 -71
  5. package/src/ckeditorerror.js +92 -114
  6. package/src/collection.js +594 -762
  7. package/src/comparearrays.js +22 -28
  8. package/src/config.js +193 -223
  9. package/src/count.js +8 -12
  10. package/src/diff.js +85 -110
  11. package/src/difftochanges.js +47 -57
  12. package/src/dom/createelement.js +17 -25
  13. package/src/dom/emittermixin.js +202 -263
  14. package/src/dom/getancestors.js +9 -13
  15. package/src/dom/getborderwidths.js +10 -13
  16. package/src/dom/getcommonancestor.js +9 -15
  17. package/src/dom/getdatafromelement.js +5 -9
  18. package/src/dom/getpositionedancestor.js +9 -14
  19. package/src/dom/global.js +15 -4
  20. package/src/dom/indexof.js +7 -11
  21. package/src/dom/insertat.js +2 -4
  22. package/src/dom/iscomment.js +2 -5
  23. package/src/dom/isnode.js +10 -12
  24. package/src/dom/isrange.js +2 -4
  25. package/src/dom/istext.js +2 -4
  26. package/src/dom/isvisible.js +2 -4
  27. package/src/dom/iswindow.js +11 -16
  28. package/src/dom/position.js +220 -410
  29. package/src/dom/rect.js +335 -414
  30. package/src/dom/remove.js +5 -8
  31. package/src/dom/resizeobserver.js +109 -342
  32. package/src/dom/scroll.js +151 -183
  33. package/src/dom/setdatainelement.js +5 -9
  34. package/src/dom/tounit.js +10 -12
  35. package/src/elementreplacer.js +30 -44
  36. package/src/emittermixin.js +368 -634
  37. package/src/env.js +109 -116
  38. package/src/eventinfo.js +12 -65
  39. package/src/fastdiff.js +96 -128
  40. package/src/first.js +8 -12
  41. package/src/focustracker.js +77 -133
  42. package/src/index.js +0 -9
  43. package/src/inserttopriorityarray.js +9 -30
  44. package/src/isiterable.js +2 -4
  45. package/src/keyboard.js +117 -196
  46. package/src/keystrokehandler.js +72 -88
  47. package/src/language.js +9 -15
  48. package/src/locale.js +61 -158
  49. package/src/mapsequal.js +12 -17
  50. package/src/mix.js +17 -16
  51. package/src/nth.js +8 -11
  52. package/src/objecttomap.js +7 -11
  53. package/src/observablemixin.js +474 -778
  54. package/src/priorities.js +20 -32
  55. package/src/spy.js +3 -6
  56. package/src/toarray.js +2 -13
  57. package/src/tomap.js +8 -10
  58. package/src/translation-service.js +57 -93
  59. package/src/uid.js +34 -38
  60. package/src/unicode.js +28 -43
  61. package/src/version.js +134 -143
package/src/dom/remove.js CHANGED
@@ -2,20 +2,17 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module utils/dom/remove
8
7
  */
9
-
10
8
  /**
11
9
  * Removes given node from parent.
12
10
  *
13
11
  * @param {Node} node Node to remove.
14
12
  */
15
- export default function remove( node ) {
16
- const parent = node.parentNode;
17
-
18
- if ( parent ) {
19
- parent.removeChild( node );
20
- }
13
+ export default function remove(node) {
14
+ const parent = node.parentNode;
15
+ if (parent) {
16
+ parent.removeChild(node);
17
+ }
21
18
  }
@@ -2,20 +2,10 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module utils/dom/resizeobserver
8
7
  */
9
-
10
- /* globals setTimeout, clearTimeout */
11
-
12
- import mix from '../mix';
13
8
  import global from './global';
14
- import Rect from './rect';
15
- import DomEmitterMixin from './emittermixin';
16
-
17
- const RESIZE_CHECK_INTERVAL = 100;
18
-
19
9
  /**
20
10
  * A helper class which instances allow performing custom actions when native DOM elements are resized.
21
11
  *
@@ -27,352 +17,129 @@ const RESIZE_CHECK_INTERVAL = 100;
27
17
  * console.log( entry.contentRect.width ); // -> e.g. '423px'
28
18
  * } );
29
19
  *
30
- * By default, it uses the [native DOM resize observer](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
31
- * under the hood and in browsers that do not support the native API yet, a polyfilled observer is
32
- * used instead.
20
+ * It uses the [native DOM resize observer](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
21
+ * under the hood.
33
22
  */
34
23
  export default class ResizeObserver {
35
- /**
36
- * Creates an instance of the `ResizeObserver` class.
37
- *
38
- * @param {HTMLElement} element A DOM element that is to be observed for resizing. Note that
39
- * the element must be visible (i.e. not detached from DOM) for the observer to work.
40
- * @param {Function} callback A function called when the observed element was resized. It passes
41
- * the [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry)
42
- * object with information about the resize event.
43
- */
44
- constructor( element, callback ) {
45
- // **Note**: For the maximum performance, this class ensures only a single instance of the native
46
- // (or polyfilled) observer is used no matter how many instances of this class were created.
47
- if ( !ResizeObserver._observerInstance ) {
48
- ResizeObserver._createObserver();
49
- }
50
-
51
- /**
52
- * The element observer by this observer.
53
- *
54
- * @readonly
55
- * @private
56
- * @member {HTMLElement}
57
- */
58
- this._element = element;
59
-
60
- /**
61
- * The callback executed each time {@link #_element} is resized.
62
- *
63
- * @readonly
64
- * @private
65
- * @member {Function}
66
- */
67
- this._callback = callback;
68
-
69
- ResizeObserver._addElementCallback( element, callback );
70
- ResizeObserver._observerInstance.observe( element );
71
- }
72
-
73
- /**
74
- * Destroys the observer which disables the `callback` passed to the {@link #constructor}.
75
- */
76
- destroy() {
77
- ResizeObserver._deleteElementCallback( this._element, this._callback );
78
- }
79
-
80
- /**
81
- * Registers a new resize callback for the DOM element.
82
- *
83
- * @private
84
- * @static
85
- * @param {HTMLElement} element
86
- * @param {Function} callback
87
- */
88
- static _addElementCallback( element, callback ) {
89
- if ( !ResizeObserver._elementCallbacks ) {
90
- ResizeObserver._elementCallbacks = new Map();
91
- }
92
-
93
- let callbacks = ResizeObserver._elementCallbacks.get( element );
94
-
95
- if ( !callbacks ) {
96
- callbacks = new Set();
97
- ResizeObserver._elementCallbacks.set( element, callbacks );
98
- }
99
-
100
- callbacks.add( callback );
101
- }
102
-
103
- /**
104
- * Removes a resize callback from the DOM element. If no callbacks are left
105
- * for the element, it removes the element from the native observer.
106
- *
107
- * @private
108
- * @static
109
- * @param {HTMLElement} element
110
- * @param {Function} callback
111
- */
112
- static _deleteElementCallback( element, callback ) {
113
- const callbacks = ResizeObserver._getElementCallbacks( element );
114
-
115
- // Remove the element callback. Check if exist first in case someone
116
- // called destroy() twice.
117
- if ( callbacks ) {
118
- callbacks.delete( callback );
119
-
120
- // If no callbacks left for the element, also remove the element.
121
- if ( !callbacks.size ) {
122
- ResizeObserver._elementCallbacks.delete( element );
123
- ResizeObserver._observerInstance.unobserve( element );
124
- }
125
- }
126
-
127
- if ( ResizeObserver._elementCallbacks && !ResizeObserver._elementCallbacks.size ) {
128
- ResizeObserver._observerInstance = null;
129
- ResizeObserver._elementCallbacks = null;
130
- }
131
- }
132
-
133
- /**
134
- * Returns are registered resize callbacks for the DOM element.
135
- *
136
- * @private
137
- * @static
138
- * @param {HTMLElement} element
139
- * @returns {Set.<HTMLElement>|null}
140
- */
141
- static _getElementCallbacks( element ) {
142
- if ( !ResizeObserver._elementCallbacks ) {
143
- return null;
144
- }
145
-
146
- return ResizeObserver._elementCallbacks.get( element );
147
- }
148
-
149
- /**
150
- * Creates the single native observer shared across all `ResizeObserver` instances.
151
- * If the browser does not support the native API, it creates a polyfill.
152
- *
153
- * @private
154
- * @static
155
- */
156
- static _createObserver() {
157
- let ObserverConstructor;
158
-
159
- // TODO: One day, the `ResizeObserver` API will be supported in all modern web browsers.
160
- // When it happens, this module will no longer make sense and should be removed and
161
- // the native implementation should be used across the project to save bytes.
162
- // Check out https://caniuse.com/#feat=resizeobserver.
163
- if ( typeof global.window.ResizeObserver === 'function' ) {
164
- ObserverConstructor = global.window.ResizeObserver;
165
- } else {
166
- ObserverConstructor = ResizeObserverPolyfill;
167
- }
168
-
169
- ResizeObserver._observerInstance = new ObserverConstructor( entries => {
170
- for ( const entry of entries ) {
171
- const callbacks = ResizeObserver._getElementCallbacks( entry.target );
172
-
173
- if ( callbacks ) {
174
- for ( const callback of callbacks ) {
175
- callback( entry );
176
- }
177
- }
178
- }
179
- } );
180
- }
24
+ /**
25
+ * Creates an instance of the `ResizeObserver` class.
26
+ *
27
+ * @param {Element} element A DOM element that is to be observed for resizing. Note that
28
+ * the element must be visible (i.e. not detached from DOM) for the observer to work.
29
+ * @param {Function} callback A function called when the observed element was resized. It passes
30
+ * the [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry)
31
+ * object with information about the resize event.
32
+ */
33
+ constructor(element, callback) {
34
+ // **Note**: For the maximum performance, this class ensures only a single instance of the native
35
+ // observer is used no matter how many instances of this class were created.
36
+ if (!ResizeObserver._observerInstance) {
37
+ ResizeObserver._createObserver();
38
+ }
39
+ this._element = element;
40
+ this._callback = callback;
41
+ ResizeObserver._addElementCallback(element, callback);
42
+ ResizeObserver._observerInstance.observe(element);
43
+ }
44
+ /**
45
+ * Destroys the observer which disables the `callback` passed to the {@link #constructor}.
46
+ */
47
+ destroy() {
48
+ ResizeObserver._deleteElementCallback(this._element, this._callback);
49
+ }
50
+ /**
51
+ * Registers a new resize callback for the DOM element.
52
+ *
53
+ * @private
54
+ * @static
55
+ * @param {Element} element
56
+ * @param {Function} callback
57
+ */
58
+ static _addElementCallback(element, callback) {
59
+ if (!ResizeObserver._elementCallbacks) {
60
+ ResizeObserver._elementCallbacks = new Map();
61
+ }
62
+ let callbacks = ResizeObserver._elementCallbacks.get(element);
63
+ if (!callbacks) {
64
+ callbacks = new Set();
65
+ ResizeObserver._elementCallbacks.set(element, callbacks);
66
+ }
67
+ callbacks.add(callback);
68
+ }
69
+ /**
70
+ * Removes a resize callback from the DOM element. If no callbacks are left
71
+ * for the element, it removes the element from the native observer.
72
+ *
73
+ * @private
74
+ * @static
75
+ * @param {Element} element
76
+ * @param {Function} callback
77
+ */
78
+ static _deleteElementCallback(element, callback) {
79
+ const callbacks = ResizeObserver._getElementCallbacks(element);
80
+ // Remove the element callback. Check if exist first in case someone
81
+ // called destroy() twice.
82
+ if (callbacks) {
83
+ callbacks.delete(callback);
84
+ // If no callbacks left for the element, also remove the element.
85
+ if (!callbacks.size) {
86
+ ResizeObserver._elementCallbacks.delete(element);
87
+ ResizeObserver._observerInstance.unobserve(element);
88
+ }
89
+ }
90
+ if (ResizeObserver._elementCallbacks && !ResizeObserver._elementCallbacks.size) {
91
+ ResizeObserver._observerInstance = null;
92
+ ResizeObserver._elementCallbacks = null;
93
+ }
94
+ }
95
+ /**
96
+ * Returns are registered resize callbacks for the DOM element.
97
+ *
98
+ * @private
99
+ * @static
100
+ * @param {Element} element
101
+ * @returns {Set.<Function>|null|undefined}
102
+ */
103
+ static _getElementCallbacks(element) {
104
+ if (!ResizeObserver._elementCallbacks) {
105
+ return null;
106
+ }
107
+ return ResizeObserver._elementCallbacks.get(element);
108
+ }
109
+ /**
110
+ * Creates the single native observer shared across all `ResizeObserver` instances.
111
+ *
112
+ * @private
113
+ * @static
114
+ */
115
+ static _createObserver() {
116
+ ResizeObserver._observerInstance = new global.window.ResizeObserver(entries => {
117
+ for (const entry of entries) {
118
+ const callbacks = ResizeObserver._getElementCallbacks(entry.target);
119
+ if (callbacks) {
120
+ for (const callback of callbacks) {
121
+ callback(entry);
122
+ }
123
+ }
124
+ }
125
+ });
126
+ }
181
127
  }
182
-
183
128
  /**
184
- * The single native observer instance (or polyfill in browsers that do not support the API)
185
- * shared across all {@link module:utils/dom/resizeobserver~ResizeObserver} instances.
129
+ * The single native observer instance shared across all {@link module:utils/dom/resizeobserver~ResizeObserver} instances.
186
130
  *
187
131
  * @static
188
- * @protected
132
+ * @private
189
133
  * @readonly
190
- * @property {Object|null} module:utils/dom/resizeobserver~ResizeObserver#_observerInstance
134
+ * @property {Object|null}
191
135
  */
192
136
  ResizeObserver._observerInstance = null;
193
-
194
137
  /**
195
138
  * A mapping of native DOM elements and their callbacks shared across all
196
139
  * {@link module:utils/dom/resizeobserver~ResizeObserver} instances.
197
140
  *
198
141
  * @static
199
142
  * @private
200
- * @readonly
201
- * @property {Map.<HTMLElement,Set>|null} module:utils/dom/resizeobserver~ResizeObserver#_elementCallbacks
143
+ * @property {Map.<Element,Set>|null}
202
144
  */
203
145
  ResizeObserver._elementCallbacks = null;
204
-
205
- /**
206
- * A polyfill class for the native [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
207
- *
208
- * @private
209
- * @mixes module:utils/domemittermixin~DomEmitterMixin
210
- */
211
- class ResizeObserverPolyfill {
212
- /**
213
- * Creates an instance of the {@link module:utils/dom/resizeobserver~ResizeObserverPolyfill} class.
214
- *
215
- * It synchronously reacts to resize of the window to check if observed elements' geometry changed.
216
- *
217
- * Additionally, the polyfilled observer uses a timeout to check if observed elements' geometry has changed
218
- * in some other way (dynamic layouts, scrollbars showing up, etc.), so its response can also be asynchronous.
219
- *
220
- * @param {Function} callback A function called when any observed element was resized. Refer to the
221
- * native [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) API to
222
- * learn more.
223
- */
224
- constructor( callback ) {
225
- /**
226
- * A function called when any observed {@link #_elements element} was resized.
227
- *
228
- * @readonly
229
- * @protected
230
- * @member {Function}
231
- */
232
- this._callback = callback;
233
-
234
- /**
235
- * DOM elements currently observed by the observer instance.
236
- *
237
- * @readonly
238
- * @protected
239
- * @member {Set}
240
- */
241
- this._elements = new Set();
242
-
243
- /**
244
- * Cached DOM {@link #_elements elements} bounding rects to compare to upon the next check.
245
- *
246
- * @readonly
247
- * @protected
248
- * @member {Map.<HTMLElement,module:utils/dom/rect~Rect>}
249
- */
250
- this._previousRects = new Map();
251
-
252
- /**
253
- * An UID of the current timeout upon which the observed elements rects
254
- * will be compared to the {@link #_previousRects previous rects} from the past.
255
- *
256
- * @readonly
257
- * @protected
258
- * @member {Map.<HTMLElement,module:utils/dom/rect~Rect>}
259
- */
260
- this._periodicCheckTimeout = null;
261
- }
262
-
263
- /**
264
- * Starts observing a DOM element.
265
- *
266
- * Learn more in the
267
- * [native method documentation](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver/observe).
268
- *
269
- * @param {HTMLElement} element
270
- */
271
- observe( element ) {
272
- this._elements.add( element );
273
-
274
- this._checkElementRectsAndExecuteCallback();
275
-
276
- if ( this._elements.size === 1 ) {
277
- this._startPeriodicCheck();
278
- }
279
- }
280
-
281
- /**
282
- * Stops observing a DOM element.
283
- *
284
- * Learn more in the
285
- * [native method documentation](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver/unobserve).
286
- *
287
- * @param {HTMLElement} element
288
- */
289
- unobserve( element ) {
290
- this._elements.delete( element );
291
- this._previousRects.delete( element );
292
-
293
- if ( !this._elements.size ) {
294
- this._stopPeriodicCheck();
295
- }
296
- }
297
-
298
- /**
299
- * When called, the observer calls the {@link #_callback resize callback} for all observed
300
- * {@link #_elements elements} but also starts checking periodically for changes in the elements' geometry.
301
- * If some are detected, {@link #_callback resize callback} is called for relevant elements that were resized.
302
- *
303
- * @protected
304
- */
305
- _startPeriodicCheck() {
306
- const periodicCheck = () => {
307
- this._checkElementRectsAndExecuteCallback();
308
- this._periodicCheckTimeout = setTimeout( periodicCheck, RESIZE_CHECK_INTERVAL );
309
- };
310
-
311
- this.listenTo( global.window, 'resize', () => {
312
- this._checkElementRectsAndExecuteCallback();
313
- } );
314
-
315
- this._periodicCheckTimeout = setTimeout( periodicCheck, RESIZE_CHECK_INTERVAL );
316
- }
317
-
318
- /**
319
- * Stops checking for changes in all observed {@link #_elements elements} geometry.
320
- *
321
- * @protected
322
- */
323
- _stopPeriodicCheck() {
324
- clearTimeout( this._periodicCheckTimeout );
325
- this.stopListening();
326
- this._previousRects.clear();
327
- }
328
-
329
- /**
330
- * Checks if the geometry of any of the {@link #_elements element} has changed. If so, executes
331
- * the {@link #_callback resize callback} with element geometry data.
332
- *
333
- * @protected
334
- */
335
- _checkElementRectsAndExecuteCallback() {
336
- const entries = [];
337
-
338
- for ( const element of this._elements ) {
339
- if ( this._hasRectChanged( element ) ) {
340
- entries.push( {
341
- target: element,
342
- contentRect: this._previousRects.get( element )
343
- } );
344
- }
345
- }
346
-
347
- if ( entries.length ) {
348
- this._callback( entries );
349
- }
350
- }
351
-
352
- /**
353
- * Compares the DOM element geometry to the {@link #_previousRects cached geometry} from the past.
354
- * Returns `true` if geometry has changed or the element is checked for the first time.
355
- *
356
- * @protected
357
- * @param {HTMLElement} element
358
- * @returns {Boolean}
359
- */
360
- _hasRectChanged( element ) {
361
- if ( !element.ownerDocument.body.contains( element ) ) {
362
- return false;
363
- }
364
-
365
- const currentRect = new Rect( element );
366
- const previousRect = this._previousRects.get( element );
367
-
368
- // The first check should always yield true despite no Previous rect to compare to.
369
- // The native ResizeObserver does that and... that makes sense. Sort of.
370
- const hasChanged = !previousRect || !previousRect.isEqual( currentRect );
371
-
372
- this._previousRects.set( element, currentRect );
373
-
374
- return hasChanged;
375
- }
376
- }
377
-
378
- mix( ResizeObserverPolyfill, DomEmitterMixin );