@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.
- package/CHANGELOG.md +324 -0
- package/LICENSE.md +1 -1
- package/package.json +19 -8
- package/src/areconnectedthroughproperties.js +54 -71
- package/src/ckeditorerror.js +92 -114
- package/src/collection.js +594 -762
- package/src/comparearrays.js +22 -28
- package/src/config.js +193 -223
- package/src/count.js +8 -12
- package/src/diff.js +85 -110
- package/src/difftochanges.js +47 -57
- package/src/dom/createelement.js +17 -25
- package/src/dom/emittermixin.js +202 -263
- package/src/dom/getancestors.js +9 -13
- package/src/dom/getborderwidths.js +10 -13
- package/src/dom/getcommonancestor.js +9 -15
- package/src/dom/getdatafromelement.js +5 -9
- package/src/dom/getpositionedancestor.js +9 -14
- package/src/dom/global.js +15 -4
- package/src/dom/indexof.js +7 -11
- package/src/dom/insertat.js +2 -4
- package/src/dom/iscomment.js +2 -5
- package/src/dom/isnode.js +10 -12
- package/src/dom/isrange.js +2 -4
- package/src/dom/istext.js +2 -4
- package/src/dom/isvisible.js +2 -4
- package/src/dom/iswindow.js +11 -16
- package/src/dom/position.js +220 -410
- package/src/dom/rect.js +335 -414
- package/src/dom/remove.js +5 -8
- package/src/dom/resizeobserver.js +109 -342
- package/src/dom/scroll.js +151 -183
- package/src/dom/setdatainelement.js +5 -9
- package/src/dom/tounit.js +10 -12
- package/src/elementreplacer.js +30 -44
- package/src/emittermixin.js +368 -634
- package/src/env.js +109 -116
- package/src/eventinfo.js +12 -65
- package/src/fastdiff.js +96 -128
- package/src/first.js +8 -12
- package/src/focustracker.js +77 -133
- package/src/index.js +0 -9
- package/src/inserttopriorityarray.js +9 -30
- package/src/isiterable.js +2 -4
- package/src/keyboard.js +117 -196
- package/src/keystrokehandler.js +72 -88
- package/src/language.js +9 -15
- package/src/locale.js +61 -158
- package/src/mapsequal.js +12 -17
- package/src/mix.js +17 -16
- package/src/nth.js +8 -11
- package/src/objecttomap.js +7 -11
- package/src/observablemixin.js +474 -778
- package/src/priorities.js +20 -32
- package/src/spy.js +3 -6
- package/src/toarray.js +2 -13
- package/src/tomap.js +8 -10
- package/src/translation-service.js +57 -93
- package/src/uid.js +34 -38
- package/src/unicode.js +28 -43
- package/src/version.js +134 -143
package/src/priorities.js
CHANGED
|
@@ -2,43 +2,31 @@
|
|
|
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/priorities
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* String representing a priority value.
|
|
12
|
-
*
|
|
13
|
-
* @typedef {'highest'|'high'|'normal'|'low'|'lowest'} module:utils/priorities~PriorityString
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
5
|
/**
|
|
17
6
|
* Provides group of constants to use instead of hardcoding numeric priority values.
|
|
18
7
|
*
|
|
19
8
|
* @namespace
|
|
20
9
|
*/
|
|
21
10
|
const priorities = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.
|
|
13
|
+
*
|
|
14
|
+
* @static
|
|
15
|
+
* @param {module:utils/priorities~PriorityString|Number} [priority] Priority to convert.
|
|
16
|
+
* @returns {Number} Converted priority.
|
|
17
|
+
*/
|
|
18
|
+
get(priority = 'normal') {
|
|
19
|
+
if (typeof priority != 'number') {
|
|
20
|
+
return this[priority] || this.normal;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return priority;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
highest: 100000,
|
|
27
|
+
high: 1000,
|
|
28
|
+
normal: 0,
|
|
29
|
+
low: -1000,
|
|
30
|
+
lowest: -100000
|
|
42
31
|
};
|
|
43
|
-
|
|
44
32
|
export default priorities;
|
package/src/spy.js
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
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/spy
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
9
|
* Creates a spy function (ala Sinon.js) that can be used to inspect call to it.
|
|
12
10
|
*
|
|
@@ -17,9 +15,8 @@
|
|
|
17
15
|
* @returns {Function} The spy function.
|
|
18
16
|
*/
|
|
19
17
|
function spy() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
return function spy() {
|
|
19
|
+
spy.called = true;
|
|
20
|
+
};
|
|
23
21
|
}
|
|
24
|
-
|
|
25
22
|
export default spy;
|
package/src/toarray.js
CHANGED
|
@@ -2,17 +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/toarray
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Transforms any value to an array. If the provided value is already an array, it is returned unchanged.
|
|
12
|
-
*
|
|
13
|
-
* @param {*} data The value to transform to an array.
|
|
14
|
-
* @returns {Array} An array created from data.
|
|
15
|
-
*/
|
|
16
|
-
export default function toArray( data ) {
|
|
17
|
-
return Array.isArray( data ) ? data : [ data ];
|
|
5
|
+
export default function toArray(data) {
|
|
6
|
+
return Array.isArray(data) ? data : [data];
|
|
18
7
|
}
|
package/src/tomap.js
CHANGED
|
@@ -2,14 +2,11 @@
|
|
|
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/tomap
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
import objectToMap from './objecttomap';
|
|
11
9
|
import isIterable from './isiterable';
|
|
12
|
-
|
|
13
10
|
/**
|
|
14
11
|
* Transforms object or iterable to map. Iterable needs to be in the format acceptable by the `Map` constructor.
|
|
15
12
|
*
|
|
@@ -17,13 +14,14 @@ import isIterable from './isiterable';
|
|
|
17
14
|
* map = toMap( [ [ 'foo', 1 ], [ 'bar', 2 ] ] );
|
|
18
15
|
* map = toMap( anotherMap );
|
|
19
16
|
*
|
|
20
|
-
* @param {Object|Iterable} data Object or iterable to transform.
|
|
17
|
+
* @param {Object|Iterable|null} data Object or iterable to transform.
|
|
21
18
|
* @returns {Map} Map created from data.
|
|
22
19
|
*/
|
|
23
|
-
export default function toMap(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
export default function toMap(data) {
|
|
21
|
+
if (isIterable(data)) {
|
|
22
|
+
return new Map(data);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return objectToMap(data);
|
|
26
|
+
}
|
|
29
27
|
}
|
|
@@ -2,20 +2,16 @@
|
|
|
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
|
-
/* globals window */
|
|
7
|
-
|
|
5
|
+
/* eslint-disable no-var */
|
|
8
6
|
/**
|
|
9
7
|
* @module utils/translation-service
|
|
10
8
|
*/
|
|
11
|
-
|
|
12
9
|
import CKEditorError from './ckeditorerror';
|
|
13
|
-
|
|
10
|
+
import global from './dom/global';
|
|
14
11
|
/* istanbul ignore else */
|
|
15
|
-
if (
|
|
16
|
-
|
|
12
|
+
if (!global.window.CKEDITOR_TRANSLATIONS) {
|
|
13
|
+
global.window.CKEDITOR_TRANSLATIONS = {};
|
|
17
14
|
}
|
|
18
|
-
|
|
19
15
|
/**
|
|
20
16
|
* Adds translations to existing ones or overrides the existing translations. These translations will later
|
|
21
17
|
* be available for the {@link module:utils/locale~Locale#t `t()`} function.
|
|
@@ -68,15 +64,15 @@ if ( !window.CKEDITOR_TRANSLATIONS ) {
|
|
|
68
64
|
* the one below:
|
|
69
65
|
*
|
|
70
66
|
* function addTranslations( language, translations, getPluralForm ) {
|
|
71
|
-
* if ( !window.CKEDITOR_TRANSLATIONS ) {
|
|
72
|
-
* window.CKEDITOR_TRANSLATIONS = {};
|
|
67
|
+
* if ( !global.window.CKEDITOR_TRANSLATIONS ) {
|
|
68
|
+
* global.window.CKEDITOR_TRANSLATIONS = {};
|
|
73
69
|
* }
|
|
74
70
|
|
|
75
|
-
* if ( !window.CKEDITOR_TRANSLATIONS[ language ] ) {
|
|
76
|
-
* window.CKEDITOR_TRANSLATIONS[ language ] = {};
|
|
71
|
+
* if ( !global.window.CKEDITOR_TRANSLATIONS[ language ] ) {
|
|
72
|
+
* global.window.CKEDITOR_TRANSLATIONS[ language ] = {};
|
|
77
73
|
* }
|
|
78
74
|
*
|
|
79
|
-
* const languageTranslations = window.CKEDITOR_TRANSLATIONS[ language ];
|
|
75
|
+
* const languageTranslations = global.window.CKEDITOR_TRANSLATIONS[ language ];
|
|
80
76
|
*
|
|
81
77
|
* languageTranslations.dictionary = languageTranslations.dictionary || {};
|
|
82
78
|
* languageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;
|
|
@@ -89,21 +85,17 @@ if ( !window.CKEDITOR_TRANSLATIONS ) {
|
|
|
89
85
|
* @param {Object.<String,*>} translations An object with translations which will be added to the dictionary.
|
|
90
86
|
* For each message ID the value should be either a translation or an array of translations if the message
|
|
91
87
|
* should support plural forms.
|
|
92
|
-
* @param {Function} getPluralForm A function that returns the plural form index (a number).
|
|
88
|
+
* @param {Function} [getPluralForm] A function that returns the plural form index (a number).
|
|
93
89
|
*/
|
|
94
|
-
export function add(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
languageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;
|
|
103
|
-
|
|
104
|
-
Object.assign( languageTranslations.dictionary, translations );
|
|
90
|
+
export function add(language, translations, getPluralForm) {
|
|
91
|
+
if (!global.window.CKEDITOR_TRANSLATIONS[language]) {
|
|
92
|
+
global.window.CKEDITOR_TRANSLATIONS[language] = {};
|
|
93
|
+
}
|
|
94
|
+
const languageTranslations = global.window.CKEDITOR_TRANSLATIONS[language];
|
|
95
|
+
languageTranslations.dictionary = languageTranslations.dictionary || {};
|
|
96
|
+
languageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;
|
|
97
|
+
Object.assign(languageTranslations.dictionary, translations);
|
|
105
98
|
}
|
|
106
|
-
|
|
107
99
|
/**
|
|
108
100
|
* **Note:** This method is internal, use {@link module:utils/locale~Locale#t the `t()` function} instead to translate
|
|
109
101
|
* the editor UI parts.
|
|
@@ -135,82 +127,54 @@ export function add( language, translations, getPluralForm ) {
|
|
|
135
127
|
* @param {Number} [quantity] The number of elements for which a plural form should be picked from the target language dictionary.
|
|
136
128
|
* @returns {String} Translated sentence.
|
|
137
129
|
*/
|
|
138
|
-
export function _translate(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if ( typeof dictionary[ messageId ] === 'string' ) {
|
|
173
|
-
return dictionary[ messageId ];
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const pluralFormIndex = Number( getPluralForm( quantity ) );
|
|
177
|
-
|
|
178
|
-
// Note: The `translate` function is not responsible for replacing `%0, %1, ...` with values.
|
|
179
|
-
return dictionary[ messageId ][ pluralFormIndex ];
|
|
130
|
+
export function _translate(language, message, quantity = 1) {
|
|
131
|
+
if (typeof quantity !== 'number') {
|
|
132
|
+
/**
|
|
133
|
+
* An incorrect value was passed to the translation function. This was probably caused
|
|
134
|
+
* by an incorrect message interpolation of a plural form. Note that for messages supporting plural forms
|
|
135
|
+
* the second argument of the `t()` function should always be a number or an array with a number as the first element.
|
|
136
|
+
*
|
|
137
|
+
* @error translation-service-quantity-not-a-number
|
|
138
|
+
*/
|
|
139
|
+
throw new CKEditorError('translation-service-quantity-not-a-number', null, { quantity });
|
|
140
|
+
}
|
|
141
|
+
const numberOfLanguages = getNumberOfLanguages();
|
|
142
|
+
if (numberOfLanguages === 1) {
|
|
143
|
+
// Override the language to the only supported one.
|
|
144
|
+
// This can't be done in the `Locale` class, because the translations comes after the `Locale` class initialization.
|
|
145
|
+
language = Object.keys(global.window.CKEDITOR_TRANSLATIONS)[0];
|
|
146
|
+
}
|
|
147
|
+
const messageId = message.id || message.string;
|
|
148
|
+
if (numberOfLanguages === 0 || !hasTranslation(language, messageId)) {
|
|
149
|
+
if (quantity !== 1) {
|
|
150
|
+
// Return the default plural form that was passed in the `message.plural` parameter.
|
|
151
|
+
return message.plural;
|
|
152
|
+
}
|
|
153
|
+
return message.string;
|
|
154
|
+
}
|
|
155
|
+
const dictionary = global.window.CKEDITOR_TRANSLATIONS[language].dictionary;
|
|
156
|
+
const getPluralForm = global.window.CKEDITOR_TRANSLATIONS[language].getPluralForm || (n => n === 1 ? 0 : 1);
|
|
157
|
+
const translation = dictionary[messageId];
|
|
158
|
+
if (typeof translation === 'string') {
|
|
159
|
+
return translation;
|
|
160
|
+
}
|
|
161
|
+
const pluralFormIndex = Number(getPluralForm(quantity));
|
|
162
|
+
// Note: The `translate` function is not responsible for replacing `%0, %1, ...` with values.
|
|
163
|
+
return translation[pluralFormIndex];
|
|
180
164
|
}
|
|
181
|
-
|
|
182
165
|
/**
|
|
183
166
|
* Clears dictionaries for test purposes.
|
|
184
167
|
*
|
|
185
168
|
* @protected
|
|
186
169
|
*/
|
|
187
170
|
export function _clear() {
|
|
188
|
-
|
|
171
|
+
global.window.CKEDITOR_TRANSLATIONS = {};
|
|
189
172
|
}
|
|
190
|
-
|
|
191
173
|
// Checks whether the dictionary exists and translation in that dictionary exists.
|
|
192
|
-
function hasTranslation(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
!!window.CKEDITOR_TRANSLATIONS[ language ].dictionary[ messageId ]
|
|
196
|
-
);
|
|
174
|
+
function hasTranslation(language, messageId) {
|
|
175
|
+
return (!!global.window.CKEDITOR_TRANSLATIONS[language] &&
|
|
176
|
+
!!global.window.CKEDITOR_TRANSLATIONS[language].dictionary[messageId]);
|
|
197
177
|
}
|
|
198
|
-
|
|
199
178
|
function getNumberOfLanguages() {
|
|
200
|
-
|
|
179
|
+
return Object.keys(global.window.CKEDITOR_TRANSLATIONS).length;
|
|
201
180
|
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* The internationalization message interface. A message that implements this interface can be passed to the `t()` function
|
|
205
|
-
* to be translated to the target UI language.
|
|
206
|
-
*
|
|
207
|
-
* @typedef {Object} module:utils/translation-service~Message
|
|
208
|
-
*
|
|
209
|
-
* @property {String} string The message string to translate. Acts as a default translation if the translation for a given language
|
|
210
|
-
* is not defined. When the message is supposed to support plural forms, the string should be the English singular form of the message.
|
|
211
|
-
* @property {String} [id] The message ID. If passed, the message ID is taken from this property instead of the `message.string`.
|
|
212
|
-
* This property is useful when various messages share the same message string, for example, the `editor` string in `in the editor`
|
|
213
|
-
* and `my editor` sentences.
|
|
214
|
-
* @property {String} [plural] The plural form of the message. This property should be skipped when a message is not supposed
|
|
215
|
-
* to support plural forms. Otherwise it should always be set to a string with the English plural form of the message.
|
|
216
|
-
*/
|
package/src/uid.js
CHANGED
|
@@ -2,16 +2,13 @@
|
|
|
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/uid
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
// A hash table of hex numbers to avoid using toString() in uid() which is costly.
|
|
11
9
|
// [ '00', '01', '02', ..., 'fe', 'ff' ]
|
|
12
|
-
const HEX_NUMBERS = new Array(
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const HEX_NUMBERS = new Array(256).fill('')
|
|
11
|
+
.map((_, index) => ('0' + (index).toString(16)).slice(-2));
|
|
15
12
|
/**
|
|
16
13
|
* Returns a unique id. The id starts with an "e" character and a randomly generated string of
|
|
17
14
|
* 32 alphanumeric characters.
|
|
@@ -23,37 +20,36 @@ const HEX_NUMBERS = new Array( 256 ).fill()
|
|
|
23
20
|
* @returns {String} An unique id string.
|
|
24
21
|
*/
|
|
25
22
|
export default function uid() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
HEX_NUMBERS[ r4 >> 24 & 0xFF ];
|
|
23
|
+
// Let's create some positive random 32bit integers first.
|
|
24
|
+
//
|
|
25
|
+
// 1. Math.random() is a float between 0 and 1.
|
|
26
|
+
// 2. 0x100000000 is 2^32 = 4294967296.
|
|
27
|
+
// 3. >>> 0 enforces integer (in JS all numbers are floating point).
|
|
28
|
+
//
|
|
29
|
+
// For instance:
|
|
30
|
+
// Math.random() * 0x100000000 = 3366450031.853859
|
|
31
|
+
// but
|
|
32
|
+
// Math.random() * 0x100000000 >>> 0 = 3366450031.
|
|
33
|
+
const r1 = Math.random() * 0x100000000 >>> 0;
|
|
34
|
+
const r2 = Math.random() * 0x100000000 >>> 0;
|
|
35
|
+
const r3 = Math.random() * 0x100000000 >>> 0;
|
|
36
|
+
const r4 = Math.random() * 0x100000000 >>> 0;
|
|
37
|
+
// Make sure that id does not start with number.
|
|
38
|
+
return 'e' +
|
|
39
|
+
HEX_NUMBERS[r1 >> 0 & 0xFF] +
|
|
40
|
+
HEX_NUMBERS[r1 >> 8 & 0xFF] +
|
|
41
|
+
HEX_NUMBERS[r1 >> 16 & 0xFF] +
|
|
42
|
+
HEX_NUMBERS[r1 >> 24 & 0xFF] +
|
|
43
|
+
HEX_NUMBERS[r2 >> 0 & 0xFF] +
|
|
44
|
+
HEX_NUMBERS[r2 >> 8 & 0xFF] +
|
|
45
|
+
HEX_NUMBERS[r2 >> 16 & 0xFF] +
|
|
46
|
+
HEX_NUMBERS[r2 >> 24 & 0xFF] +
|
|
47
|
+
HEX_NUMBERS[r3 >> 0 & 0xFF] +
|
|
48
|
+
HEX_NUMBERS[r3 >> 8 & 0xFF] +
|
|
49
|
+
HEX_NUMBERS[r3 >> 16 & 0xFF] +
|
|
50
|
+
HEX_NUMBERS[r3 >> 24 & 0xFF] +
|
|
51
|
+
HEX_NUMBERS[r4 >> 0 & 0xFF] +
|
|
52
|
+
HEX_NUMBERS[r4 >> 8 & 0xFF] +
|
|
53
|
+
HEX_NUMBERS[r4 >> 16 & 0xFF] +
|
|
54
|
+
HEX_NUMBERS[r4 >> 24 & 0xFF];
|
|
59
55
|
}
|
package/src/unicode.js
CHANGED
|
@@ -2,24 +2,21 @@
|
|
|
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
|
* Set of utils to handle unicode characters.
|
|
8
7
|
*
|
|
9
8
|
* @module utils/unicode
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* Checks whether given `character` is a combining mark.
|
|
14
12
|
*
|
|
15
13
|
* @param {String} character Character to check.
|
|
16
14
|
* @returns {Boolean}
|
|
17
15
|
*/
|
|
18
|
-
export function isCombiningMark(
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
export function isCombiningMark(character) {
|
|
17
|
+
// eslint-disable-next-line no-misleading-character-class
|
|
18
|
+
return !!character && character.length == 1 && /[\u0300-\u036f\u1ab0-\u1aff\u1dc0-\u1dff\u20d0-\u20ff\ufe20-\ufe2f]/.test(character);
|
|
21
19
|
}
|
|
22
|
-
|
|
23
20
|
/**
|
|
24
21
|
* Checks whether given `character` is a high half of surrogate pair.
|
|
25
22
|
*
|
|
@@ -29,10 +26,9 @@ export function isCombiningMark( character ) {
|
|
|
29
26
|
* @param {String} character Character to check.
|
|
30
27
|
* @returns {Boolean}
|
|
31
28
|
*/
|
|
32
|
-
export function isHighSurrogateHalf(
|
|
33
|
-
|
|
29
|
+
export function isHighSurrogateHalf(character) {
|
|
30
|
+
return !!character && character.length == 1 && /[\ud800-\udbff]/.test(character);
|
|
34
31
|
}
|
|
35
|
-
|
|
36
32
|
/**
|
|
37
33
|
* Checks whether given `character` is a low half of surrogate pair.
|
|
38
34
|
*
|
|
@@ -42,10 +38,9 @@ export function isHighSurrogateHalf( character ) {
|
|
|
42
38
|
* @param {String} character Character to check.
|
|
43
39
|
* @returns {Boolean}
|
|
44
40
|
*/
|
|
45
|
-
export function isLowSurrogateHalf(
|
|
46
|
-
|
|
41
|
+
export function isLowSurrogateHalf(character) {
|
|
42
|
+
return !!character && character.length == 1 && /[\udc00-\udfff]/.test(character);
|
|
47
43
|
}
|
|
48
|
-
|
|
49
44
|
/**
|
|
50
45
|
* Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).
|
|
51
46
|
*
|
|
@@ -53,10 +48,9 @@ export function isLowSurrogateHalf( character ) {
|
|
|
53
48
|
* @param {Number} offset Offset to check.
|
|
54
49
|
* @returns {Boolean}
|
|
55
50
|
*/
|
|
56
|
-
export function isInsideSurrogatePair(
|
|
57
|
-
|
|
51
|
+
export function isInsideSurrogatePair(string, offset) {
|
|
52
|
+
return isHighSurrogateHalf(string.charAt(offset - 1)) && isLowSurrogateHalf(string.charAt(offset));
|
|
58
53
|
}
|
|
59
|
-
|
|
60
54
|
/**
|
|
61
55
|
* Checks whether given offset in a string is between base character and combining mark or between two combining marks.
|
|
62
56
|
*
|
|
@@ -64,12 +58,10 @@ export function isInsideSurrogatePair( string, offset ) {
|
|
|
64
58
|
* @param {Number} offset Offset to check.
|
|
65
59
|
* @returns {Boolean}
|
|
66
60
|
*/
|
|
67
|
-
export function isInsideCombinedSymbol(
|
|
68
|
-
|
|
61
|
+
export function isInsideCombinedSymbol(string, offset) {
|
|
62
|
+
return isCombiningMark(string.charAt(offset));
|
|
69
63
|
}
|
|
70
|
-
|
|
71
64
|
const EMOJI_PATTERN = buildEmojiRegexp();
|
|
72
|
-
|
|
73
65
|
/**
|
|
74
66
|
* Checks whether given offset in a string is inside multi-character emoji sequence.
|
|
75
67
|
*
|
|
@@ -77,30 +69,23 @@ const EMOJI_PATTERN = buildEmojiRegexp();
|
|
|
77
69
|
* @param {Number} offset Offset to check.
|
|
78
70
|
* @returns {Boolean}
|
|
79
71
|
*/
|
|
80
|
-
export function isInsideEmojiSequence(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return Array.from( matches ).some( match => match.index < offset && offset < match.index + match[ 0 ].length );
|
|
72
|
+
export function isInsideEmojiSequence(string, offset) {
|
|
73
|
+
const matches = String(string).matchAll(EMOJI_PATTERN);
|
|
74
|
+
return Array.from(matches).some(match => match.index < offset && offset < match.index + match[0].length);
|
|
84
75
|
}
|
|
85
|
-
|
|
86
76
|
function buildEmojiRegexp() {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const flagSequence = /\p{Regional_Indicator}{2}/u.source;
|
|
102
|
-
const emoji = '(?:' + parts.map( part => part.source ).join( '|' ) + ')';
|
|
103
|
-
const sequence = `${ flagSequence }|${ emoji }(?:\u{200D}${ emoji })*`;
|
|
104
|
-
|
|
105
|
-
return new RegExp( sequence, 'ug' );
|
|
77
|
+
const parts = [
|
|
78
|
+
// Emoji Tag Sequence (ETS)
|
|
79
|
+
/\p{Emoji}[\u{E0020}-\u{E007E}]+\u{E007F}/u,
|
|
80
|
+
// Emoji Keycap Sequence
|
|
81
|
+
/\p{Emoji}\u{FE0F}?\u{20E3}/u,
|
|
82
|
+
// Emoji Presentation Sequence
|
|
83
|
+
/\p{Emoji}\u{FE0F}/u,
|
|
84
|
+
// Single-Character Emoji / Emoji Modifier Sequence
|
|
85
|
+
/(?=\p{General_Category=Other_Symbol})\p{Emoji}\p{Emoji_Modifier}*/u
|
|
86
|
+
];
|
|
87
|
+
const flagSequence = /\p{Regional_Indicator}{2}/u.source;
|
|
88
|
+
const emoji = '(?:' + parts.map(part => part.source).join('|') + ')';
|
|
89
|
+
const sequence = `${flagSequence}|${emoji}(?:\u{200D}${emoji})*`;
|
|
90
|
+
return new RegExp(sequence, 'ug');
|
|
106
91
|
}
|