@ckeditor/ckeditor5-utils 47.6.1 → 48.0.0-alpha.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 (154) hide show
  1. package/LICENSE.md +1 -1
  2. package/{src → dist}/dom/global.d.ts +1 -1
  3. package/{src → dist}/dom/rect.d.ts +8 -0
  4. package/dist/index.css +3 -0
  5. package/dist/index.css.map +1 -0
  6. package/dist/index.js +24 -5
  7. package/dist/index.js.map +1 -1
  8. package/{src → dist}/version.d.ts +1 -1
  9. package/package.json +20 -38
  10. package/src/abortabledebounce.js +0 -22
  11. package/src/areconnectedthroughproperties.js +0 -71
  12. package/src/ckeditorerror.js +0 -187
  13. package/src/collection.js +0 -620
  14. package/src/collectstylesheets.js +0 -52
  15. package/src/comparearrays.js +0 -47
  16. package/src/config.js +0 -167
  17. package/src/count.js +0 -25
  18. package/src/crc32.js +0 -61
  19. package/src/decodelicensekey.js +0 -30
  20. package/src/delay.js +0 -25
  21. package/src/diff.js +0 -115
  22. package/src/difftochanges.js +0 -79
  23. package/src/dom/createelement.js +0 -40
  24. package/src/dom/emittermixin.js +0 -237
  25. package/src/dom/findclosestscrollableancestor.js +0 -31
  26. package/src/dom/getancestors.js +0 -26
  27. package/src/dom/getborderwidths.js +0 -24
  28. package/src/dom/getcommonancestor.js +0 -25
  29. package/src/dom/getdatafromelement.js +0 -19
  30. package/src/dom/getpositionedancestor.js +0 -22
  31. package/src/dom/getrangefrommouseevent.js +0 -33
  32. package/src/dom/getvisualviewportoffset.js +0 -21
  33. package/src/dom/global.js +0 -35
  34. package/src/dom/indexof.js +0 -21
  35. package/src/dom/insertat.js +0 -17
  36. package/src/dom/iscomment.js +0 -13
  37. package/src/dom/isnode.js +0 -21
  38. package/src/dom/isrange.js +0 -13
  39. package/src/dom/istext.js +0 -13
  40. package/src/dom/isvalidattributename.js +0 -22
  41. package/src/dom/isvisible.js +0 -30
  42. package/src/dom/iswindow.js +0 -22
  43. package/src/dom/position.js +0 -322
  44. package/src/dom/rect.js +0 -498
  45. package/src/dom/remove.js +0 -18
  46. package/src/dom/resizeobserver.js +0 -134
  47. package/src/dom/scroll.js +0 -406
  48. package/src/dom/setdatainelement.js +0 -19
  49. package/src/dom/tounit.js +0 -16
  50. package/src/elementreplacer.js +0 -47
  51. package/src/emittermixin.js +0 -443
  52. package/src/env.js +0 -158
  53. package/src/eventinfo.js +0 -63
  54. package/src/fastdiff.js +0 -248
  55. package/src/first.js +0 -17
  56. package/src/focustracker.js +0 -329
  57. package/src/formathtml.js +0 -164
  58. package/src/index.js +0 -78
  59. package/src/inserttopriorityarray.js +0 -28
  60. package/src/isfeatureblockedbylicensekey.js +0 -17
  61. package/src/isiterable.js +0 -16
  62. package/src/keyboard.js +0 -256
  63. package/src/keystrokehandler.js +0 -126
  64. package/src/language.js +0 -21
  65. package/src/legacyerrors.js +0 -18
  66. package/src/locale.js +0 -135
  67. package/src/mapsequal.js +0 -27
  68. package/src/mix.js +0 -5
  69. package/src/nth.js +0 -24
  70. package/src/objecttomap.js +0 -27
  71. package/src/observablemixin.js +0 -575
  72. package/src/parsebase64encodedobject.js +0 -22
  73. package/src/priorities.js +0 -22
  74. package/src/retry.js +0 -48
  75. package/src/splicearray.js +0 -37
  76. package/src/spy.js +0 -21
  77. package/src/toarray.js +0 -7
  78. package/src/tomap.js +0 -29
  79. package/src/translation-service.js +0 -209
  80. package/src/uid.js +0 -45
  81. package/src/unicode.js +0 -85
  82. package/src/version.js +0 -177
  83. package/src/wait.js +0 -29
  84. /package/{src → dist}/abortabledebounce.d.ts +0 -0
  85. /package/{src → dist}/areconnectedthroughproperties.d.ts +0 -0
  86. /package/{src → dist}/ckeditorerror.d.ts +0 -0
  87. /package/{src → dist}/collection.d.ts +0 -0
  88. /package/{src → dist}/collectstylesheets.d.ts +0 -0
  89. /package/{src → dist}/comparearrays.d.ts +0 -0
  90. /package/{src → dist}/config.d.ts +0 -0
  91. /package/{src → dist}/count.d.ts +0 -0
  92. /package/{src → dist}/crc32.d.ts +0 -0
  93. /package/{src → dist}/decodelicensekey.d.ts +0 -0
  94. /package/{src → dist}/delay.d.ts +0 -0
  95. /package/{src → dist}/diff.d.ts +0 -0
  96. /package/{src → dist}/difftochanges.d.ts +0 -0
  97. /package/{src → dist}/dom/createelement.d.ts +0 -0
  98. /package/{src → dist}/dom/emittermixin.d.ts +0 -0
  99. /package/{src → dist}/dom/findclosestscrollableancestor.d.ts +0 -0
  100. /package/{src → dist}/dom/getancestors.d.ts +0 -0
  101. /package/{src → dist}/dom/getborderwidths.d.ts +0 -0
  102. /package/{src → dist}/dom/getcommonancestor.d.ts +0 -0
  103. /package/{src → dist}/dom/getdatafromelement.d.ts +0 -0
  104. /package/{src → dist}/dom/getpositionedancestor.d.ts +0 -0
  105. /package/{src → dist}/dom/getrangefrommouseevent.d.ts +0 -0
  106. /package/{src → dist}/dom/getvisualviewportoffset.d.ts +0 -0
  107. /package/{src → dist}/dom/indexof.d.ts +0 -0
  108. /package/{src → dist}/dom/insertat.d.ts +0 -0
  109. /package/{src → dist}/dom/iscomment.d.ts +0 -0
  110. /package/{src → dist}/dom/isnode.d.ts +0 -0
  111. /package/{src → dist}/dom/isrange.d.ts +0 -0
  112. /package/{src → dist}/dom/istext.d.ts +0 -0
  113. /package/{src → dist}/dom/isvalidattributename.d.ts +0 -0
  114. /package/{src → dist}/dom/isvisible.d.ts +0 -0
  115. /package/{src → dist}/dom/iswindow.d.ts +0 -0
  116. /package/{src → dist}/dom/position.d.ts +0 -0
  117. /package/{src → dist}/dom/remove.d.ts +0 -0
  118. /package/{src → dist}/dom/resizeobserver.d.ts +0 -0
  119. /package/{src → dist}/dom/scroll.d.ts +0 -0
  120. /package/{src → dist}/dom/setdatainelement.d.ts +0 -0
  121. /package/{src → dist}/dom/tounit.d.ts +0 -0
  122. /package/{src → dist}/elementreplacer.d.ts +0 -0
  123. /package/{src → dist}/emittermixin.d.ts +0 -0
  124. /package/{src → dist}/env.d.ts +0 -0
  125. /package/{src → dist}/eventinfo.d.ts +0 -0
  126. /package/{src → dist}/fastdiff.d.ts +0 -0
  127. /package/{src → dist}/first.d.ts +0 -0
  128. /package/{src → dist}/focustracker.d.ts +0 -0
  129. /package/{src → dist}/formathtml.d.ts +0 -0
  130. /package/{src → dist}/index.d.ts +0 -0
  131. /package/{src → dist}/inserttopriorityarray.d.ts +0 -0
  132. /package/{src → dist}/isfeatureblockedbylicensekey.d.ts +0 -0
  133. /package/{src → dist}/isiterable.d.ts +0 -0
  134. /package/{src → dist}/keyboard.d.ts +0 -0
  135. /package/{src → dist}/keystrokehandler.d.ts +0 -0
  136. /package/{src → dist}/language.d.ts +0 -0
  137. /package/{src → dist}/legacyerrors.d.ts +0 -0
  138. /package/{src → dist}/locale.d.ts +0 -0
  139. /package/{src → dist}/mapsequal.d.ts +0 -0
  140. /package/{src → dist}/mix.d.ts +0 -0
  141. /package/{src → dist}/nth.d.ts +0 -0
  142. /package/{src → dist}/objecttomap.d.ts +0 -0
  143. /package/{src → dist}/observablemixin.d.ts +0 -0
  144. /package/{src → dist}/parsebase64encodedobject.d.ts +0 -0
  145. /package/{src → dist}/priorities.d.ts +0 -0
  146. /package/{src → dist}/retry.d.ts +0 -0
  147. /package/{src → dist}/splicearray.d.ts +0 -0
  148. /package/{src → dist}/spy.d.ts +0 -0
  149. /package/{src → dist}/toarray.d.ts +0 -0
  150. /package/{src → dist}/tomap.d.ts +0 -0
  151. /package/{src → dist}/translation-service.d.ts +0 -0
  152. /package/{src → dist}/uid.d.ts +0 -0
  153. /package/{src → dist}/unicode.d.ts +0 -0
  154. /package/{src → dist}/wait.d.ts +0 -0
@@ -1,47 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/comparearrays
7
- */
8
- /**
9
- * Compares how given arrays relate to each other. One array can be: same as another array, prefix of another array
10
- * or completely different. If arrays are different, first index at which they differ is returned. Otherwise,
11
- * a flag specifying the relation is returned. Flags are negative numbers, so whenever a number >= 0 is returned
12
- * it means that arrays differ.
13
- *
14
- * ```ts
15
- * compareArrays( [ 0, 2 ], [ 0, 2 ] ); // 'same'
16
- * compareArrays( [ 0, 2 ], [ 0, 2, 1 ] ); // 'prefix'
17
- * compareArrays( [ 0, 2 ], [ 0 ] ); // 'extension'
18
- * compareArrays( [ 0, 2 ], [ 1, 2 ] ); // 0
19
- * compareArrays( [ 0, 2 ], [ 0, 1 ] ); // 1
20
- * ```
21
- *
22
- * @param a Array that is compared.
23
- * @param b Array to compare with.
24
- * @returns How array `a` is related to `b`.
25
- */
26
- export function compareArrays(a, b) {
27
- const minLen = Math.min(a.length, b.length);
28
- for (let i = 0; i < minLen; i++) {
29
- if (a[i] != b[i]) {
30
- // The arrays are different.
31
- return i;
32
- }
33
- }
34
- // Both arrays were same at all points.
35
- if (a.length == b.length) {
36
- // If their length is also same, they are the same.
37
- return 'same';
38
- }
39
- else if (a.length < b.length) {
40
- // Compared array is shorter so it is a prefix of the other array.
41
- return 'prefix';
42
- }
43
- else {
44
- // Compared array is longer so it is an extension of the other array.
45
- return 'extension';
46
- }
47
- }
package/src/config.js DELETED
@@ -1,167 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/config
7
- */
8
- import { isPlainObject, isElement, cloneDeepWith } from 'es-toolkit/compat';
9
- /**
10
- * Handles a configuration dictionary.
11
- *
12
- * @typeParam Cfg A type of the configuration dictionary.
13
- */
14
- export class Config {
15
- /**
16
- * Store for the whole configuration.
17
- */
18
- _config;
19
- /**
20
- * Creates an instance of the {@link ~Config} class.
21
- *
22
- * @param configurations The initial configurations to be set. Usually, provided by the user.
23
- * @param defaultConfigurations The default configurations. Usually, provided by the system.
24
- */
25
- constructor(configurations, defaultConfigurations) {
26
- this._config = Object.create(null);
27
- // Set default configuration.
28
- if (defaultConfigurations) {
29
- // Clone the configuration to make sure that the properties will not be shared
30
- // between editors and make the watchdog feature work correctly.
31
- this.define(cloneConfig(defaultConfigurations));
32
- }
33
- // Set initial configuration.
34
- if (configurations) {
35
- this._setObjectToTarget(this._config, configurations);
36
- }
37
- }
38
- set(name, value) {
39
- this._setToTarget(this._config, name, value);
40
- }
41
- define(name, value) {
42
- const isDefine = true;
43
- this._setToTarget(this._config, name, value, isDefine);
44
- }
45
- /**
46
- * Gets the value for a configuration entry.
47
- *
48
- * ```ts
49
- * config.get( 'name' );
50
- * ```
51
- *
52
- * Deep configurations can be retrieved by separating each part with a dot.
53
- *
54
- * ```ts
55
- * config.get( 'toolbar.collapsed' );
56
- * ```
57
- *
58
- * @param name The configuration name. Configuration names are case-sensitive.
59
- * @returns The configuration value or `undefined` if the configuration entry was not found.
60
- */
61
- get(name) {
62
- return this._getFromSource(this._config, name);
63
- }
64
- /**
65
- * Iterates over all top level configuration names.
66
- */
67
- *names() {
68
- for (const name of Object.keys(this._config)) {
69
- yield name;
70
- }
71
- }
72
- /**
73
- * Saves passed configuration to the specified target (nested object).
74
- *
75
- * @param target Nested config object.
76
- * @param name The configuration name or an object from which take properties as
77
- * configuration entries. Configuration names are case-sensitive.
78
- * @param value The configuration value. Used if a name is passed.
79
- * @param isDefine Define if passed configuration should overwrite existing one.
80
- */
81
- _setToTarget(target, name, value, isDefine = false) {
82
- // In case of an object, iterate through it and call `_setToTarget` again for each property.
83
- if (isPlainObject(name)) {
84
- this._setObjectToTarget(target, name, isDefine);
85
- return;
86
- }
87
- // The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].
88
- const parts = name.split('.');
89
- // Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.
90
- name = parts.pop();
91
- // Iterate over parts to check if currently stored configuration has proper structure.
92
- for (const part of parts) {
93
- // If there is no object for specified part then create one.
94
- if (!isPlainObject(target[part])) {
95
- target[part] = Object.create(null);
96
- }
97
- // Nested object becomes a target.
98
- target = target[part];
99
- }
100
- // In case of value is an object.
101
- if (isPlainObject(value)) {
102
- // We take care of proper config structure.
103
- if (!isPlainObject(target[name])) {
104
- target[name] = Object.create(null);
105
- }
106
- target = target[name];
107
- // And iterate through this object calling `_setToTarget` again for each property.
108
- this._setObjectToTarget(target, value, isDefine);
109
- return;
110
- }
111
- // Do nothing if we are defining configuration for non empty name.
112
- if (isDefine && typeof target[name] != 'undefined') {
113
- return;
114
- }
115
- target[name] = value;
116
- }
117
- /**
118
- * Get specified configuration from specified source (nested object).
119
- *
120
- * @param source level of nested object.
121
- * @param name The configuration name. Configuration names are case-sensitive.
122
- * @returns The configuration value or `undefined` if the configuration entry was not found.
123
- */
124
- _getFromSource(source, name) {
125
- // The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].
126
- const parts = name.split('.');
127
- // Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.
128
- name = parts.pop();
129
- // Iterate over parts to check if currently stored configuration has proper structure.
130
- for (const part of parts) {
131
- if (!isPlainObject(source[part])) {
132
- source = null;
133
- break;
134
- }
135
- // Nested object becomes a source.
136
- source = source[part];
137
- }
138
- // Always returns undefined for non existing configuration.
139
- return source ? cloneConfig(source[name]) : undefined;
140
- }
141
- /**
142
- * Iterates through passed object and calls {@link #_setToTarget} method with object key and value for each property.
143
- *
144
- * @param target Nested config object.
145
- * @param configuration Configuration data set
146
- * @param isDefine Defines if passed configuration is default configuration or not.
147
- */
148
- _setObjectToTarget(target, configuration, isDefine) {
149
- Object.keys(configuration).forEach(key => {
150
- this._setToTarget(target, key, configuration[key], isDefine);
151
- });
152
- }
153
- }
154
- /**
155
- * Clones configuration object or value.
156
- */
157
- function cloneConfig(source) {
158
- return cloneDeepWith(source, leaveItemReferences);
159
- }
160
- /**
161
- * A customized function for cloneDeepWith.
162
- * In case if it's a DOM Element it will leave references to DOM Elements instead of cloning them.
163
- * If it's a function it will leave reference to actuall function.
164
- */
165
- function leaveItemReferences(value) {
166
- return isElement(value) || typeof value === 'function' ? value : undefined;
167
- }
package/src/count.js DELETED
@@ -1,25 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/count
7
- */
8
- /**
9
- * Returns the number of items return by the iterator.
10
- *
11
- * ```ts
12
- * count( [ 1, 2, 3, 4, 5 ] ); // 5;
13
- * ```
14
- *
15
- * @param iterable Any iterable.
16
- * @returns Number of items returned by that iterable.
17
- */
18
- export function count(iterable) {
19
- let count = 0;
20
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
21
- for (const _ of iterable) {
22
- count++;
23
- }
24
- return count;
25
- }
package/src/crc32.js DELETED
@@ -1,61 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/crc32
7
- */
8
- /**
9
- * Generates a CRC lookup table.
10
- * This function creates and returns a 256-element array of pre-computed CRC values for quick CRC calculation.
11
- * It uses the polynomial 0xEDB88320 to compute each value in the loop, optimizing future CRC calculations.
12
- */
13
- function makeCrcTable() {
14
- const crcTable = [];
15
- for (let n = 0; n < 256; n++) {
16
- let c = n;
17
- for (let k = 0; k < 8; k++) {
18
- if (c & 1) {
19
- c = 0xEDB88320 ^ (c >>> 1);
20
- }
21
- else {
22
- c = c >>> 1;
23
- }
24
- }
25
- crcTable[n] = c;
26
- }
27
- return crcTable;
28
- }
29
- /**
30
- * Calculates CRC-32 checksum for a given inputData to verify the integrity of data.
31
- *
32
- * @param inputData Accepts a single value (string, number, boolean), an array of strings, or an array of all of the above types.
33
- * Non-string values are converted to strings before calculating the checksum.
34
- * The checksum calculation is based on the concatenated string representation of the input values:
35
- * * `crc32('foo')` is equivalent to `crc32(['foo'])`
36
- * * `crc32(123)` is equivalent to `crc32(['123'])`
37
- * * `crc32(true)` is equivalent to `crc32(['true'])`
38
- * * `crc32(['foo', 123, true])` produces the same result as `crc32('foo123true')`
39
- * * Nested arrays of strings are flattened, so `crc32([['foo', 'bar'], 'baz'])` is equivalent to `crc32(['foobar', 'baz'])`
40
- *
41
- * @returns The CRC-32 checksum, returned as a hexadecimal string.
42
- */
43
- export function crc32(inputData) {
44
- const dataArray = Array.isArray(inputData) ? inputData : [inputData];
45
- const crcTable = makeCrcTable();
46
- let crc = 0 ^ (-1);
47
- // Convert data to a single string.
48
- const dataString = dataArray.map(item => {
49
- if (Array.isArray(item)) {
50
- return item.join('');
51
- }
52
- return String(item);
53
- }).join('');
54
- // Calculate the CRC for the resulting string.
55
- for (let i = 0; i < dataString.length; i++) {
56
- const byte = dataString.charCodeAt(i);
57
- crc = (crc >>> 8) ^ crcTable[(crc ^ byte) & 0xFF];
58
- }
59
- crc = (crc ^ (-1)) >>> 0; // Force unsigned integer.
60
- return crc.toString(16).padStart(8, '0');
61
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/decodelicensekey
7
- */
8
- import { parseBase64EncodedObject } from './parsebase64encodedobject.js';
9
- /**
10
- * Parses the provided license key and returns the decoded object, or null if the decoding was unsuccessful.
11
- *
12
- * @param licenseKey The license key to decode.
13
- */
14
- export function decodeLicenseKey(licenseKey) {
15
- if (!licenseKey) {
16
- return null;
17
- }
18
- const encodedPayload = getLicenseKeyPayload(licenseKey);
19
- if (!encodedPayload) {
20
- return null;
21
- }
22
- return parseBase64EncodedObject(encodedPayload);
23
- }
24
- function getLicenseKeyPayload(licenseKey) {
25
- const parts = licenseKey.split('.');
26
- if (parts.length != 3) {
27
- return null;
28
- }
29
- return parts[1];
30
- }
package/src/delay.js DELETED
@@ -1,25 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/delay
7
- */
8
- /**
9
- * Returns a function wrapper that will trigger a function after a specified wait time.
10
- * The timeout can be canceled by calling the cancel function on the returned wrapped function.
11
- *
12
- * @param func The function to wrap.
13
- * @param wait The timeout in ms.
14
- */
15
- export function delay(func, wait) {
16
- let timer;
17
- function delayed(...args) {
18
- delayed.cancel();
19
- timer = setTimeout(() => func(...args), wait);
20
- }
21
- delayed.cancel = () => {
22
- clearTimeout(timer);
23
- };
24
- return delayed;
25
- }
package/src/diff.js DELETED
@@ -1,115 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/diff
7
- */
8
- import { fastDiff } from './fastdiff.js';
9
- // The following code is based on the "O(NP) Sequence Comparison Algorithm"
10
- // by Sun Wu, Udi Manber, Gene Myers, Webb Miller.
11
- /**
12
- * Calculates the difference between two arrays or strings producing an array containing a list of changes
13
- * necessary to transform input into output.
14
- *
15
- * ```ts
16
- * diff( 'aba', 'acca' ); // [ 'equal', 'insert', 'insert', 'delete', 'equal' ]
17
- * ```
18
- *
19
- * This function is based on the "O(NP) Sequence Comparison Algorithm" by Sun Wu, Udi Manber, Gene Myers, Webb Miller.
20
- * Unfortunately, while it gives the most precise results, its to complex for longer strings/arrow (above 200 items).
21
- * Therefore, `diff()` automatically switches to {@link module:utils/fastdiff~fastDiff `fastDiff()`} when detecting
22
- * such a scenario. The return formats of both functions are identical.
23
- *
24
- * @param a Input array or string.
25
- * @param b Output array or string.
26
- * @param cmp Optional function used to compare array values, by default === is used.
27
- * @returns Array of changes.
28
- */
29
- export function diff(a, b, cmp) {
30
- // Set the comparator function.
31
- cmp = cmp || function (a, b) {
32
- return a === b;
33
- };
34
- const aLength = a.length;
35
- const bLength = b.length;
36
- // Perform `fastDiff` for longer strings/arrays (see #269).
37
- if (aLength > 200 || bLength > 200 || aLength + bLength > 300) {
38
- return diff.fastDiff(a, b, cmp, true);
39
- }
40
- // Temporary action type statics.
41
- let _insert, _delete;
42
- // Swapped the arrays to use the shorter one as the first one.
43
- if (bLength < aLength) {
44
- const tmp = a;
45
- a = b;
46
- b = tmp;
47
- // We swap the action types as well.
48
- _insert = 'delete';
49
- _delete = 'insert';
50
- }
51
- else {
52
- _insert = 'insert';
53
- _delete = 'delete';
54
- }
55
- const m = a.length;
56
- const n = b.length;
57
- const delta = n - m;
58
- // Edit scripts, for each diagonal.
59
- const es = {};
60
- // Furthest points, the furthest y we can get on each diagonal.
61
- const fp = {};
62
- function snake(k) {
63
- // We use -1 as an alternative below to handle initial values ( instead of filling the fp with -1 first ).
64
- // Furthest points (y) on the diagonal below k.
65
- const y1 = (fp[k - 1] !== undefined ? fp[k - 1] : -1) + 1;
66
- // Furthest points (y) on the diagonal above k.
67
- const y2 = fp[k + 1] !== undefined ? fp[k + 1] : -1;
68
- // The way we should go to get further.
69
- const dir = y1 > y2 ? -1 : 1;
70
- // Clone previous changes array (if any).
71
- if (es[k + dir]) {
72
- es[k] = es[k + dir].slice(0);
73
- }
74
- // Create changes array.
75
- if (!es[k]) {
76
- es[k] = [];
77
- }
78
- // Push the action.
79
- es[k].push(y1 > y2 ? _insert : _delete);
80
- // Set the beginning coordinates.
81
- let y = Math.max(y1, y2);
82
- let x = y - k;
83
- // Traverse the diagonal as long as the values match.
84
- while (x < m && y < n && cmp(a[x], b[y])) {
85
- x++;
86
- y++;
87
- // Push no change action.
88
- es[k].push('equal');
89
- }
90
- return y;
91
- }
92
- let p = 0;
93
- let k;
94
- // Traverse the graph until we reach the end of the longer string.
95
- do {
96
- // Updates furthest points and edit scripts for diagonals below delta.
97
- for (k = -p; k < delta; k++) {
98
- fp[k] = snake(k);
99
- }
100
- // Updates furthest points and edit scripts for diagonals above delta.
101
- for (k = delta + p; k > delta; k--) {
102
- fp[k] = snake(k);
103
- }
104
- // Updates furthest point and edit script for the delta diagonal.
105
- // note that the delta diagonal is the one which goes through the sink (m, n).
106
- fp[delta] = snake(delta);
107
- p++;
108
- } while (fp[delta] !== n);
109
- // Return the final list of edit changes.
110
- // We remove the first item that represents the action for the injected nulls.
111
- return es[delta].slice(1);
112
- }
113
- // Store the API in static property to easily overwrite it in tests.
114
- // Too bad dependency injection does not work in Webpack + ES 6 (const) + Babel.
115
- diff.fastDiff = fastDiff;
@@ -1,79 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/difftochanges
7
- */
8
- /**
9
- * Creates a set of changes which need to be applied to the input in order to transform
10
- * it into the output. This function can be used with strings or arrays.
11
- *
12
- * ```ts
13
- * const input = Array.from( 'abc' );
14
- * const output = Array.from( 'xaby' );
15
- * const changes = diffToChanges( diff( input, output ), output );
16
- *
17
- * changes.forEach( change => {
18
- * if ( change.type == 'insert' ) {
19
- * input.splice( change.index, 0, ...change.values );
20
- * } else if ( change.type == 'delete' ) {
21
- * input.splice( change.index, change.howMany );
22
- * }
23
- * } );
24
- *
25
- * input.join( '' ) == output.join( '' ); // -> true
26
- * ```
27
- *
28
- * @typeParam T The type of output array element.
29
- * @param diff Result of {@link module:utils/diff~diff}.
30
- * @param output The string or array which was passed as diff's output.
31
- * @returns Set of changes (insert or delete) which need to be applied to the input
32
- * in order to transform it into the output.
33
- */
34
- export function diffToChanges(diff, output) {
35
- const changes = [];
36
- let index = 0;
37
- let lastOperation = null;
38
- diff.forEach(change => {
39
- if (change == 'equal') {
40
- pushLast();
41
- index++;
42
- }
43
- else if (change == 'insert') {
44
- if (lastOperation && lastOperation.type == 'insert') {
45
- lastOperation.values.push(output[index]);
46
- }
47
- else {
48
- pushLast();
49
- lastOperation = {
50
- type: 'insert',
51
- index,
52
- values: [output[index]]
53
- };
54
- }
55
- index++;
56
- }
57
- else /* if ( change == 'delete' ) */ {
58
- if (lastOperation && lastOperation.type == 'delete') {
59
- lastOperation.howMany++;
60
- }
61
- else {
62
- pushLast();
63
- lastOperation = {
64
- type: 'delete',
65
- index,
66
- howMany: 1
67
- };
68
- }
69
- }
70
- });
71
- pushLast();
72
- return changes;
73
- function pushLast() {
74
- if (lastOperation) {
75
- changes.push(lastOperation);
76
- lastOperation = null;
77
- }
78
- }
79
- }
@@ -1,40 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module utils/dom/createelement
7
- */
8
- import { isIterable } from '../isiterable.js';
9
- import { isString } from 'es-toolkit/compat';
10
- /**
11
- * Creates an HTML or SVG element with attributes and children elements.
12
- *
13
- * ```ts
14
- * createElement( document, 'p' ); // <p>
15
- * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' } ); // <mask>
16
- * ```
17
- *
18
- * @param doc Document used to create the element.
19
- * @param name Name of the element.
20
- * @param attributes Object where keys represent attribute keys and values represent attribute values.
21
- * @param children Child or any iterable of children. Strings will be automatically turned into Text nodes.
22
- * @returns HTML or SVG element.
23
- */
24
- export function createElement(doc, name, attributes = {}, children = []) {
25
- const namespace = attributes && attributes.xmlns;
26
- const element = namespace ? doc.createElementNS(namespace, name) : doc.createElement(name);
27
- for (const key in attributes) {
28
- element.setAttribute(key, attributes[key]);
29
- }
30
- if (isString(children) || !isIterable(children)) {
31
- children = [children];
32
- }
33
- for (let child of children) {
34
- if (isString(child)) {
35
- child = doc.createTextNode(child);
36
- }
37
- element.appendChild(child);
38
- }
39
- return element;
40
- }