@ckeditor/ckeditor5-utils 34.1.0 → 35.0.1

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 -760
  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 +217 -257
  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 +0 -3
  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 +383 -631
  37. package/src/env.js +93 -115
  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 -131
  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 +13 -16
  51. package/src/nth.js +8 -11
  52. package/src/objecttomap.js +7 -11
  53. package/src/observablemixin.js +465 -768
  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 +51 -87
  59. package/src/uid.js +34 -38
  60. package/src/unicode.js +28 -43
  61. package/src/version.js +134 -143
package/src/env.js CHANGED
@@ -2,170 +2,150 @@
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
  /* globals navigator:false */
7
-
8
6
  /**
9
7
  * @module utils/env
10
8
  */
11
-
12
9
  const userAgent = navigator.userAgent.toLowerCase();
13
-
14
10
  /**
15
11
  * A namespace containing environment and browser information.
16
12
  *
17
13
  * @namespace
18
14
  */
19
15
  const env = {
20
- /**
21
- * Indicates that the application is running on Macintosh.
22
- *
23
- * @static
24
- * @type {Boolean}
25
- */
26
- isMac: isMac( userAgent ),
27
-
28
- /**
29
- * Indicates that the application is running on Windows.
30
- *
31
- * @static
32
- * @type {Boolean}
33
- */
34
- isWindows: isWindows( userAgent ),
35
-
36
- /**
37
- * Indicates that the application is running in Firefox (Gecko).
38
- *
39
- * @static
40
- * @type {Boolean}
41
- */
42
- isGecko: isGecko( userAgent ),
43
-
44
- /**
45
- * Indicates that the application is running in Safari.
46
- *
47
- * @static
48
- * @type {Boolean}
49
- */
50
- isSafari: isSafari( userAgent ),
51
-
52
- /**
53
- * Indicates the the application is running in iOS.
54
- *
55
- * @static
56
- * @type {Boolean}
57
- */
58
- isiOS: isiOS( userAgent ),
59
-
60
- /**
61
- * Indicates that the application is running on Android mobile device.
62
- *
63
- * @static
64
- * @type {Boolean}
65
- */
66
- isAndroid: isAndroid( userAgent ),
67
-
68
- /**
69
- * Indicates that the application is running in a browser using the Blink engine.
70
- *
71
- * @static
72
- * @type {Boolean}
73
- */
74
- isBlink: isBlink( userAgent ),
75
-
76
- /**
77
- * Environment features information.
78
- *
79
- * @memberOf module:utils/env~env
80
- * @namespace
81
- */
82
- features: {
83
- /**
84
- * Indicates that the environment supports ES2018 Unicode property escapes — like `\p{P}` or `\p{L}`.
85
- * More information about unicode properties might be found
86
- * [in Unicode Standard Annex #44](https://www.unicode.org/reports/tr44/#GC_Values_Table).
87
- *
88
- * @type {Boolean}
89
- */
90
- isRegExpUnicodePropertySupported: isRegExpUnicodePropertySupported()
91
- }
16
+ /**
17
+ * Indicates that the application is running on Macintosh.
18
+ *
19
+ * @static
20
+ * @type {Boolean}
21
+ */
22
+ isMac: isMac(userAgent),
23
+ /**
24
+ * Indicates that the application is running on Windows.
25
+ *
26
+ * @static
27
+ * @type {Boolean}
28
+ */
29
+ isWindows: isWindows(userAgent),
30
+ /**
31
+ * Indicates that the application is running in Firefox (Gecko).
32
+ *
33
+ * @static
34
+ * @type {Boolean}
35
+ */
36
+ isGecko: isGecko(userAgent),
37
+ /**
38
+ * Indicates that the application is running in Safari.
39
+ *
40
+ * @static
41
+ * @type {Boolean}
42
+ */
43
+ isSafari: isSafari(userAgent),
44
+ /**
45
+ * Indicates the the application is running in iOS.
46
+ *
47
+ * @static
48
+ * @type {Boolean}
49
+ */
50
+ isiOS: isiOS(userAgent),
51
+ /**
52
+ * Indicates that the application is running on Android mobile device.
53
+ *
54
+ * @static
55
+ * @type {Boolean}
56
+ */
57
+ isAndroid: isAndroid(userAgent),
58
+ /**
59
+ * Indicates that the application is running in a browser using the Blink engine.
60
+ *
61
+ * @static
62
+ * @type {Boolean}
63
+ */
64
+ isBlink: isBlink(userAgent),
65
+ /**
66
+ * Environment features information.
67
+ *
68
+ * @memberOf module:utils/env~env
69
+ * @namespace
70
+ */
71
+ features: {
72
+ /**
73
+ * Indicates that the environment supports ES2018 Unicode property escapes — like `\p{P}` or `\p{L}`.
74
+ * More information about unicode properties might be found
75
+ * [in Unicode Standard Annex #44](https://www.unicode.org/reports/tr44/#GC_Values_Table).
76
+ *
77
+ * @type {Boolean}
78
+ */
79
+ isRegExpUnicodePropertySupported: isRegExpUnicodePropertySupported()
80
+ }
92
81
  };
93
-
94
82
  export default env;
95
-
96
83
  /**
97
84
  * Checks if User Agent represented by the string is running on Macintosh.
98
85
  *
99
86
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
100
87
  * @returns {Boolean} Whether User Agent is running on Macintosh or not.
101
88
  */
102
- export function isMac( userAgent ) {
103
- return userAgent.indexOf( 'macintosh' ) > -1;
89
+ export function isMac(userAgent) {
90
+ return userAgent.indexOf('macintosh') > -1;
104
91
  }
105
-
106
92
  /**
107
93
  * Checks if User Agent represented by the string is running on Windows.
108
94
  *
109
95
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
110
96
  * @returns {Boolean} Whether User Agent is running on Windows or not.
111
97
  */
112
- export function isWindows( userAgent ) {
113
- return userAgent.indexOf( 'windows' ) > -1;
98
+ export function isWindows(userAgent) {
99
+ return userAgent.indexOf('windows') > -1;
114
100
  }
115
-
116
101
  /**
117
102
  * Checks if User Agent represented by the string is Firefox (Gecko).
118
103
  *
119
104
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
120
105
  * @returns {Boolean} Whether User Agent is Firefox or not.
121
106
  */
122
- export function isGecko( userAgent ) {
123
- return !!userAgent.match( /gecko\/\d+/ );
107
+ export function isGecko(userAgent) {
108
+ return !!userAgent.match(/gecko\/\d+/);
124
109
  }
125
-
126
110
  /**
127
111
  * Checks if User Agent represented by the string is Safari.
128
112
  *
129
113
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
130
114
  * @returns {Boolean} Whether User Agent is Safari or not.
131
115
  */
132
- export function isSafari( userAgent ) {
133
- return userAgent.indexOf( ' applewebkit/' ) > -1 && userAgent.indexOf( 'chrome' ) === -1;
116
+ export function isSafari(userAgent) {
117
+ return userAgent.indexOf(' applewebkit/') > -1 && userAgent.indexOf('chrome') === -1;
134
118
  }
135
-
136
119
  /**
137
120
  * Checks if User Agent represented by the string is running in iOS.
138
121
  *
139
122
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
140
123
  * @returns {Boolean} Whether User Agent is running in iOS or not.
141
124
  */
142
- export function isiOS( userAgent ) {
143
- // "Request mobile site" || "Request desktop site".
144
- return !!userAgent.match( /iphone|ipad/i ) || ( isMac( userAgent ) && navigator.maxTouchPoints > 0 );
125
+ export function isiOS(userAgent) {
126
+ // "Request mobile site" || "Request desktop site".
127
+ return !!userAgent.match(/iphone|ipad/i) || (isMac(userAgent) && navigator.maxTouchPoints > 0);
145
128
  }
146
-
147
129
  /**
148
130
  * Checks if User Agent represented by the string is Android mobile device.
149
131
  *
150
132
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
151
133
  * @returns {Boolean} Whether User Agent is Safari or not.
152
134
  */
153
- export function isAndroid( userAgent ) {
154
- return userAgent.indexOf( 'android' ) > -1;
135
+ export function isAndroid(userAgent) {
136
+ return userAgent.indexOf('android') > -1;
155
137
  }
156
-
157
138
  /**
158
139
  * Checks if User Agent represented by the string is Blink engine.
159
140
  *
160
141
  * @param {String} userAgent **Lowercase** `navigator.userAgent` string.
161
142
  * @returns {Boolean} Whether User Agent is Blink engine or not.
162
143
  */
163
- export function isBlink( userAgent ) {
164
- // The Edge browser before switching to the Blink engine used to report itself as Chrome (and "Edge/")
165
- // but after switching to the Blink it replaced "Edge/" with "Edg/".
166
- return userAgent.indexOf( 'chrome/' ) > -1 && userAgent.indexOf( 'edge/' ) < 0;
144
+ export function isBlink(userAgent) {
145
+ // The Edge browser before switching to the Blink engine used to report itself as Chrome (and "Edge/")
146
+ // but after switching to the Blink it replaced "Edge/" with "Edg/".
147
+ return userAgent.indexOf('chrome/') > -1 && userAgent.indexOf('edge/') < 0;
167
148
  }
168
-
169
149
  /**
170
150
  * Checks if the current environment supports ES2018 Unicode properties like `\p{P}` or `\p{L}`.
171
151
  * More information about unicode properties might be found
@@ -174,17 +154,15 @@ export function isBlink( userAgent ) {
174
154
  * @returns {Boolean}
175
155
  */
176
156
  export function isRegExpUnicodePropertySupported() {
177
- let isSupported = false;
178
-
179
- // Feature detection for Unicode properties. Added in ES2018. Currently Firefox does not support it.
180
- // See https://github.com/ckeditor/ckeditor5-mention/issues/44#issuecomment-487002174.
181
-
182
- try {
183
- // Usage of regular expression literal cause error during build (ckeditor/ckeditor5-dev#534).
184
- isSupported = 'ć'.search( new RegExp( '[\\p{L}]', 'u' ) ) === 0;
185
- } catch ( error ) {
186
- // Firefox throws a SyntaxError when the group is unsupported.
187
- }
188
-
189
- return isSupported;
157
+ let isSupported = false;
158
+ // Feature detection for Unicode properties. Added in ES2018. Currently Firefox does not support it.
159
+ // See https://github.com/ckeditor/ckeditor5-mention/issues/44#issuecomment-487002174.
160
+ try {
161
+ // Usage of regular expression literal cause error during build (ckeditor/ckeditor5-dev#534).
162
+ isSupported = 'ć'.search(new RegExp('[\\p{L}]', 'u')) === 0;
163
+ }
164
+ catch (error) {
165
+ // Firefox throws a SyntaxError when the group is unsupported.
166
+ }
167
+ return isSupported;
190
168
  }
package/src/eventinfo.js CHANGED
@@ -2,78 +2,25 @@
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/eventinfo
8
7
  */
9
-
10
8
  import spy from './spy';
11
-
12
9
  /**
13
10
  * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to
14
11
  * manipulate it.
15
12
  */
16
13
  export default class EventInfo {
17
- /**
18
- * @param {Object} source The emitter.
19
- * @param {String} name The event name.
20
- */
21
- constructor( source, name ) {
22
- /**
23
- * The object that fired the event.
24
- *
25
- * @readonly
26
- * @member {Object}
27
- */
28
- this.source = source;
29
-
30
- /**
31
- * The event name.
32
- *
33
- * @readonly
34
- * @member {String}
35
- */
36
- this.name = name;
37
-
38
- /**
39
- * Path this event has followed. See {@link module:utils/emittermixin~EmitterMixin#delegate}.
40
- *
41
- * @readonly
42
- * @member {Array.<Object>}
43
- */
44
- this.path = [];
45
-
46
- // The following methods are defined in the constructor because they must be re-created per instance.
47
-
48
- /**
49
- * Stops the event emitter to call further callbacks for this event interaction.
50
- *
51
- * @method #stop
52
- */
53
- this.stop = spy();
54
-
55
- /**
56
- * Removes the current callback from future interactions of this event.
57
- *
58
- * @method #off
59
- */
60
- this.off = spy();
61
-
62
- /**
63
- * The value which will be returned by {@link module:utils/emittermixin~EmitterMixin#fire}.
64
- *
65
- * It's `undefined` by default and can be changed by an event listener:
66
- *
67
- * dataController.fire( 'getSelectedContent', ( evt ) => {
68
- * // This listener will make `dataController.fire( 'getSelectedContent' )`
69
- * // always return an empty DocumentFragment.
70
- * evt.return = new DocumentFragment();
71
- *
72
- * // Make sure no other listeners are executed.
73
- * evt.stop();
74
- * } );
75
- *
76
- * @member #return
77
- */
78
- }
14
+ /**
15
+ * @param {Object} source The emitter.
16
+ * @param {String} name The event name.
17
+ */
18
+ constructor(source, name) {
19
+ this.source = source;
20
+ this.name = name;
21
+ this.path = [];
22
+ // The following methods are defined in the constructor because they must be re-created per instance.
23
+ this.stop = spy();
24
+ this.off = spy();
25
+ }
79
26
  }
package/src/fastdiff.js CHANGED
@@ -2,11 +2,6 @@
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
- /**
7
- * @module utils/fastdiff
8
- */
9
-
10
5
  /**
11
6
  * Finds positions of the first and last change in the given string/array and generates a set of changes:
12
7
  *
@@ -94,33 +89,24 @@
94
89
  * be returned instead of changes set. This makes this function compatible with {@link module:utils/diff~diff `diff()`}.
95
90
  * @returns {Array} Array of changes.
96
91
  */
97
- export default function fastDiff( a, b, cmp, atomicChanges = false ) {
98
- // Set the comparator function.
99
- cmp = cmp || function( a, b ) {
100
- return a === b;
101
- };
102
-
103
- // Convert the string (or any array-like object - eg. NodeList) to an array by using the slice() method because,
104
- // unlike Array.from(), it returns array of UTF-16 code units instead of the code points of a string.
105
- // One code point might be a surrogate pair of two code units. All text offsets are expected to be in code units.
106
- // See ckeditor/ckeditor5#3147.
107
- //
108
- // We need to make sure here that fastDiff() works identical to diff().
109
- if ( !Array.isArray( a ) ) {
110
- a = Array.prototype.slice.call( a );
111
- }
112
-
113
- if ( !Array.isArray( b ) ) {
114
- b = Array.prototype.slice.call( b );
115
- }
116
-
117
- // Find first and last change.
118
- const changeIndexes = findChangeBoundaryIndexes( a, b, cmp );
119
-
120
- // Transform into changes array.
121
- return atomicChanges ? changeIndexesToAtomicChanges( changeIndexes, b.length ) : changeIndexesToChanges( b, changeIndexes );
92
+ export default function fastDiff(a, b, cmp, atomicChanges = false) {
93
+ // Set the comparator function.
94
+ cmp = cmp || function (a, b) {
95
+ return a === b;
96
+ };
97
+ // Convert the string (or any array-like object - eg. NodeList) to an array by using the slice() method because,
98
+ // unlike Array.from(), it returns array of UTF-16 code units instead of the code points of a string.
99
+ // One code point might be a surrogate pair of two code units. All text offsets are expected to be in code units.
100
+ // See ckeditor/ckeditor5#3147.
101
+ //
102
+ // We need to make sure here that fastDiff() works identical to diff().
103
+ const arrayA = Array.isArray(a) ? a : Array.prototype.slice.call(a);
104
+ const arrayB = Array.isArray(b) ? b : Array.prototype.slice.call(b);
105
+ // Find first and last change.
106
+ const changeIndexes = findChangeBoundaryIndexes(arrayA, arrayB, cmp);
107
+ // Transform into changes array.
108
+ return atomicChanges ? changeIndexesToAtomicChanges(changeIndexes, arrayB.length) : changeIndexesToChanges(arrayB, changeIndexes);
122
109
  }
123
-
124
110
  // Finds position of the first and last change in the given arrays. For example:
125
111
  //
126
112
  // const indexes = findChangeBoundaryIndexes( [ '1', '2', '3', '4' ], [ '1', '3', '4', '2', '4' ] );
@@ -137,125 +123,107 @@ export default function fastDiff( a, b, cmp, atomicChanges = false ) {
137
123
  // @returns {Number} return.firstIndex Index of the first change in both values (always the same for both).
138
124
  // @returns {Number} result.lastIndexOld Index of the last common value in `arr1`.
139
125
  // @returns {Number} result.lastIndexNew Index of the last common value in `arr2`.
140
- function findChangeBoundaryIndexes( arr1, arr2, cmp ) {
141
- // Find the first difference between passed values.
142
- const firstIndex = findFirstDifferenceIndex( arr1, arr2, cmp );
143
-
144
- // If arrays are equal return -1 indexes object.
145
- if ( firstIndex === -1 ) {
146
- return { firstIndex: -1, lastIndexOld: -1, lastIndexNew: -1 };
147
- }
148
-
149
- // Remove the common part of each value and reverse them to make it simpler to find the last difference between them.
150
- const oldArrayReversed = cutAndReverse( arr1, firstIndex );
151
- const newArrayReversed = cutAndReverse( arr2, firstIndex );
152
-
153
- // Find the first difference between reversed values.
154
- // It should be treated as "how many elements from the end the last difference occurred".
155
- //
156
- // For example:
157
- //
158
- // initial -> after cut -> reversed:
159
- // oldValue: '321ba' -> '21ba' -> 'ab12'
160
- // newValue: '31xba' -> '1xba' -> 'abx1'
161
- // lastIndex: -> 2
162
- //
163
- // So the last change occurred two characters from the end of the arrays.
164
- const lastIndex = findFirstDifferenceIndex( oldArrayReversed, newArrayReversed, cmp );
165
-
166
- // Use `lastIndex` to calculate proper offset, starting from the beginning (`lastIndex` kind of starts from the end).
167
- const lastIndexOld = arr1.length - lastIndex;
168
- const lastIndexNew = arr2.length - lastIndex;
169
-
170
- return { firstIndex, lastIndexOld, lastIndexNew };
126
+ function findChangeBoundaryIndexes(arr1, arr2, cmp) {
127
+ // Find the first difference between passed values.
128
+ const firstIndex = findFirstDifferenceIndex(arr1, arr2, cmp);
129
+ // If arrays are equal return -1 indexes object.
130
+ if (firstIndex === -1) {
131
+ return { firstIndex: -1, lastIndexOld: -1, lastIndexNew: -1 };
132
+ }
133
+ // Remove the common part of each value and reverse them to make it simpler to find the last difference between them.
134
+ const oldArrayReversed = cutAndReverse(arr1, firstIndex);
135
+ const newArrayReversed = cutAndReverse(arr2, firstIndex);
136
+ // Find the first difference between reversed values.
137
+ // It should be treated as "how many elements from the end the last difference occurred".
138
+ //
139
+ // For example:
140
+ //
141
+ // initial -> after cut -> reversed:
142
+ // oldValue: '321ba' -> '21ba' -> 'ab12'
143
+ // newValue: '31xba' -> '1xba' -> 'abx1'
144
+ // lastIndex: -> 2
145
+ //
146
+ // So the last change occurred two characters from the end of the arrays.
147
+ const lastIndex = findFirstDifferenceIndex(oldArrayReversed, newArrayReversed, cmp);
148
+ // Use `lastIndex` to calculate proper offset, starting from the beginning (`lastIndex` kind of starts from the end).
149
+ const lastIndexOld = arr1.length - lastIndex;
150
+ const lastIndexNew = arr2.length - lastIndex;
151
+ return { firstIndex, lastIndexOld, lastIndexNew };
171
152
  }
172
-
173
153
  // Returns a first index on which given arrays differ. If both arrays are the same, -1 is returned.
174
154
  //
175
155
  // @param {Array} arr1
176
156
  // @param {Array} arr2
177
157
  // @param {Function} cmp Comparator function.
178
158
  // @returns {Number}
179
- function findFirstDifferenceIndex( arr1, arr2, cmp ) {
180
- for ( let i = 0; i < Math.max( arr1.length, arr2.length ); i++ ) {
181
- if ( arr1[ i ] === undefined || arr2[ i ] === undefined || !cmp( arr1[ i ], arr2[ i ] ) ) {
182
- return i;
183
- }
184
- }
185
-
186
- return -1; // Return -1 if arrays are equal.
159
+ function findFirstDifferenceIndex(arr1, arr2, cmp) {
160
+ for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
161
+ if (arr1[i] === undefined || arr2[i] === undefined || !cmp(arr1[i], arr2[i])) {
162
+ return i;
163
+ }
164
+ }
165
+ return -1; // Return -1 if arrays are equal.
187
166
  }
188
-
189
167
  // Returns a copy of the given array with `howMany` elements removed starting from the beginning and in reversed order.
190
168
  //
191
169
  // @param {Array} arr Array to be processed.
192
170
  // @param {Number} howMany How many elements from array beginning to remove.
193
171
  // @returns {Array} Shortened and reversed array.
194
- function cutAndReverse( arr, howMany ) {
195
- return arr.slice( howMany ).reverse();
172
+ function cutAndReverse(arr, howMany) {
173
+ return arr.slice(howMany).reverse();
196
174
  }
197
-
198
175
  // Generates changes array based on change indexes from `findChangeBoundaryIndexes` function. This function will
199
176
  // generate array with 0 (no changes), 1 (deletion or insertion) or 2 records (insertion and deletion).
200
177
  //
201
178
  // @param {Array} newArray New array for which change indexes were calculated.
202
179
  // @param {Object} changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.
203
- // @returns {Array.<Object>} Array of changes compatible with {@link module:utils/difftochanges~diffToChanges} format.
204
- function changeIndexesToChanges( newArray, changeIndexes ) {
205
- const result = [];
206
- const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;
207
-
208
- // Order operations as 'insert', 'delete' array to keep compatibility with {@link module:utils/difftochanges~diffToChanges}
209
- // in most cases. However, 'diffToChanges' does not stick to any order so in some cases
210
- // (for example replacing '12345' with 'abcd') it will generate 'delete', 'insert' order.
211
- if ( lastIndexNew - firstIndex > 0 ) {
212
- result.push( {
213
- index: firstIndex,
214
- type: 'insert',
215
- values: newArray.slice( firstIndex, lastIndexNew )
216
- } );
217
- }
218
-
219
- if ( lastIndexOld - firstIndex > 0 ) {
220
- result.push( {
221
- index: firstIndex + ( lastIndexNew - firstIndex ), // Increase index of what was inserted.
222
- type: 'delete',
223
- howMany: lastIndexOld - firstIndex
224
- } );
225
- }
226
-
227
- return result;
180
+ // @returns {Array.<module:utils/difftochanges~Change>} Array of changes compatible with
181
+ // {@link module:utils/difftochanges~diffToChanges} format.
182
+ function changeIndexesToChanges(newArray, changeIndexes) {
183
+ const result = [];
184
+ const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;
185
+ // Order operations as 'insert', 'delete' array to keep compatibility with {@link module:utils/difftochanges~diffToChanges}
186
+ // in most cases. However, 'diffToChanges' does not stick to any order so in some cases
187
+ // (for example replacing '12345' with 'abcd') it will generate 'delete', 'insert' order.
188
+ if (lastIndexNew - firstIndex > 0) {
189
+ result.push({
190
+ index: firstIndex,
191
+ type: 'insert',
192
+ values: newArray.slice(firstIndex, lastIndexNew)
193
+ });
194
+ }
195
+ if (lastIndexOld - firstIndex > 0) {
196
+ result.push({
197
+ index: firstIndex + (lastIndexNew - firstIndex),
198
+ type: 'delete',
199
+ howMany: lastIndexOld - firstIndex
200
+ });
201
+ }
202
+ return result;
228
203
  }
229
-
230
204
  // Generates array with set `equal|insert|delete` operations based on change indexes from `findChangeBoundaryIndexes` function.
231
205
  //
232
206
  // @param {Object} changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.
233
207
  // @param {Number} newLength Length of the new array on which `findChangeBoundaryIndexes` calculated change indexes.
234
- // @returns {Array.<String>} Array of changes compatible with {@link module:utils/diff~diff} format.
235
- function changeIndexesToAtomicChanges( changeIndexes, newLength ) {
236
- const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;
237
-
238
- // No changes.
239
- if ( firstIndex === -1 ) {
240
- return Array( newLength ).fill( 'equal' );
241
- }
242
-
243
- let result = [];
244
- if ( firstIndex > 0 ) {
245
- result = result.concat( Array( firstIndex ).fill( 'equal' ) );
246
- }
247
-
248
- if ( lastIndexNew - firstIndex > 0 ) {
249
- result = result.concat( Array( lastIndexNew - firstIndex ).fill( 'insert' ) );
250
- }
251
-
252
- if ( lastIndexOld - firstIndex > 0 ) {
253
- result = result.concat( Array( lastIndexOld - firstIndex ).fill( 'delete' ) );
254
- }
255
-
256
- if ( lastIndexNew < newLength ) {
257
- result = result.concat( Array( newLength - lastIndexNew ).fill( 'equal' ) );
258
- }
259
-
260
- return result;
208
+ // @returns {Array.<module:utils/diff~DiffResult>} Array of changes compatible with {@link module:utils/diff~diff} format.
209
+ function changeIndexesToAtomicChanges(changeIndexes, newLength) {
210
+ const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;
211
+ // No changes.
212
+ if (firstIndex === -1) {
213
+ return Array(newLength).fill('equal');
214
+ }
215
+ let result = [];
216
+ if (firstIndex > 0) {
217
+ result = result.concat(Array(firstIndex).fill('equal'));
218
+ }
219
+ if (lastIndexNew - firstIndex > 0) {
220
+ result = result.concat(Array(lastIndexNew - firstIndex).fill('insert'));
221
+ }
222
+ if (lastIndexOld - firstIndex > 0) {
223
+ result = result.concat(Array(lastIndexOld - firstIndex).fill('delete'));
224
+ }
225
+ if (lastIndexNew < newLength) {
226
+ result = result.concat(Array(newLength - lastIndexNew).fill('equal'));
227
+ }
228
+ return result;
261
229
  }