@ckeditor/ckeditor5-utils 35.0.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 (59) hide show
  1. package/package.json +5 -5
  2. package/src/areconnectedthroughproperties.js +75 -0
  3. package/src/ckeditorerror.js +195 -0
  4. package/src/collection.js +619 -0
  5. package/src/comparearrays.js +45 -0
  6. package/src/config.js +216 -0
  7. package/src/count.js +22 -0
  8. package/src/diff.js +113 -0
  9. package/src/difftochanges.js +76 -0
  10. package/src/dom/createelement.js +41 -0
  11. package/src/dom/emittermixin.js +301 -0
  12. package/src/dom/getancestors.js +27 -0
  13. package/src/dom/getborderwidths.js +24 -0
  14. package/src/dom/getcommonancestor.js +25 -0
  15. package/src/dom/getdatafromelement.js +20 -0
  16. package/src/dom/getpositionedancestor.js +23 -0
  17. package/src/dom/global.js +23 -0
  18. package/src/dom/indexof.js +21 -0
  19. package/src/dom/insertat.js +17 -0
  20. package/src/dom/iscomment.js +17 -0
  21. package/src/dom/isnode.js +24 -0
  22. package/src/dom/isrange.js +16 -0
  23. package/src/dom/istext.js +16 -0
  24. package/src/dom/isvisible.js +23 -0
  25. package/src/dom/iswindow.js +25 -0
  26. package/src/dom/position.js +328 -0
  27. package/src/dom/rect.js +364 -0
  28. package/src/dom/remove.js +18 -0
  29. package/src/dom/resizeobserver.js +145 -0
  30. package/src/dom/scroll.js +270 -0
  31. package/src/dom/setdatainelement.js +20 -0
  32. package/src/dom/tounit.js +25 -0
  33. package/src/elementreplacer.js +43 -0
  34. package/src/emittermixin.js +471 -0
  35. package/src/env.js +168 -0
  36. package/src/eventinfo.js +26 -0
  37. package/src/fastdiff.js +229 -0
  38. package/src/first.js +20 -0
  39. package/src/focustracker.js +103 -0
  40. package/src/index.js +36 -0
  41. package/src/inserttopriorityarray.js +21 -0
  42. package/src/isiterable.js +16 -0
  43. package/src/keyboard.js +222 -0
  44. package/src/keystrokehandler.js +114 -0
  45. package/src/language.js +20 -0
  46. package/src/locale.js +79 -0
  47. package/src/mapsequal.js +27 -0
  48. package/src/mix.js +44 -0
  49. package/src/nth.js +28 -0
  50. package/src/objecttomap.js +25 -0
  51. package/src/observablemixin.js +605 -0
  52. package/src/priorities.js +32 -0
  53. package/src/spy.js +22 -0
  54. package/src/toarray.js +7 -0
  55. package/src/tomap.js +27 -0
  56. package/src/translation-service.js +180 -0
  57. package/src/uid.js +55 -0
  58. package/src/unicode.js +91 -0
  59. package/src/version.js +148 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/keystrokehandler
7
+ */
8
+ import DomEmitterMixin from './dom/emittermixin';
9
+ import { getCode, parseKeystroke } from './keyboard';
10
+ /**
11
+ * Keystroke handler allows registering callbacks for given keystrokes.
12
+ *
13
+ * The most frequent use of this class is through the {@link module:core/editor/editor~Editor#keystrokes `editor.keystrokes`}
14
+ * property. It allows listening to keystrokes executed in the editing view:
15
+ *
16
+ * editor.keystrokes.set( 'Ctrl+A', ( keyEvtData, cancel ) => {
17
+ * console.log( 'Ctrl+A has been pressed' );
18
+ * cancel();
19
+ * } );
20
+ *
21
+ * However, this utility class can be used in various part of the UI. For instance, a certain {@link module:ui/view~View}
22
+ * can use it like this:
23
+ *
24
+ * class MyView extends View {
25
+ * constructor() {
26
+ * this.keystrokes = new KeystrokeHandler();
27
+ *
28
+ * this.keystrokes.set( 'tab', handleTabKey );
29
+ * }
30
+ *
31
+ * render() {
32
+ * super.render();
33
+ *
34
+ * this.keystrokes.listenTo( this.element );
35
+ * }
36
+ * }
37
+ *
38
+ * That keystroke handler will listen to `keydown` events fired in this view's main element.
39
+ *
40
+ */
41
+ export default class KeystrokeHandler {
42
+ /**
43
+ * Creates an instance of the keystroke handler.
44
+ */
45
+ constructor() {
46
+ this._listener = Object.create(DomEmitterMixin);
47
+ }
48
+ /**
49
+ * Starts listening for `keydown` events from a given emitter.
50
+ *
51
+ * @param {module:utils/emittermixin~Emitter|HTMLElement|Window} emitter
52
+ */
53
+ listenTo(emitter) {
54
+ // The #_listener works here as a kind of dispatcher. It groups the events coming from the same
55
+ // keystroke so the listeners can be attached to them with different priorities.
56
+ //
57
+ // E.g. all the keystrokes with the `keyCode` of 42 coming from the `emitter` are propagated
58
+ // as a `_keydown:42` event by the `_listener`. If there's a callback created by the `set`
59
+ // method for this 42 keystroke, it listens to the `_listener#_keydown:42` event only and interacts
60
+ // only with other listeners of this particular event, thus making it possible to prioritize
61
+ // the listeners and safely cancel execution, when needed. Instead of duplicating the Emitter logic,
62
+ // the KeystrokeHandler re–uses it to do its job.
63
+ this._listener.listenTo(emitter, 'keydown', (evt, keyEvtData) => {
64
+ this._listener.fire('_keydown:' + getCode(keyEvtData), keyEvtData);
65
+ });
66
+ }
67
+ /**
68
+ * Registers a handler for the specified keystroke.
69
+ *
70
+ * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by
71
+ * the {@link module:utils/keyboard~parseKeystroke} function.
72
+ * @param {Function} callback A function called with the
73
+ * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and
74
+ * a helper funcion to call both `preventDefault()` and `stopPropagation()` on the underlying event.
75
+ * @param {Object} [options={}] Additional options.
76
+ * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke
77
+ * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority
78
+ * are called in the order they were added.
79
+ */
80
+ set(keystroke, callback, options = {}) {
81
+ const keyCode = parseKeystroke(keystroke);
82
+ const priority = options.priority;
83
+ // Execute the passed callback on KeystrokeHandler#_keydown.
84
+ // TODO: https://github.com/ckeditor/ckeditor5-utils/issues/144
85
+ this._listener.listenTo(this._listener, '_keydown:' + keyCode, (evt, keyEvtData) => {
86
+ callback(keyEvtData, () => {
87
+ // Stop the event in the DOM: no listener in the web page
88
+ // will be triggered by this event.
89
+ keyEvtData.preventDefault();
90
+ keyEvtData.stopPropagation();
91
+ // Stop the event in the KeystrokeHandler: no more callbacks
92
+ // will be executed for this keystroke.
93
+ evt.stop();
94
+ });
95
+ // Mark this keystroke as handled by the callback. See: #press.
96
+ evt.return = true;
97
+ }, { priority });
98
+ }
99
+ /**
100
+ * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.
101
+ *
102
+ * @param {module:engine/view/observer/keyobserver~KeyEventData} keyEvtData Key event data.
103
+ * @returns {Boolean} Whether the keystroke was handled.
104
+ */
105
+ press(keyEvtData) {
106
+ return !!this._listener.fire('_keydown:' + getCode(keyEvtData), keyEvtData);
107
+ }
108
+ /**
109
+ * Destroys the keystroke handler.
110
+ */
111
+ destroy() {
112
+ this._listener.stopListening();
113
+ }
114
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ const RTL_LANGUAGE_CODES = [
6
+ 'ar', 'ara',
7
+ 'fa', 'per', 'fas',
8
+ 'he', 'heb',
9
+ 'ku', 'kur',
10
+ 'ug', 'uig' // Uighur, Uyghur
11
+ ];
12
+ /**
13
+ * Helps determine whether a language text direction is LTR or RTL.
14
+ *
15
+ * @param {String} languageCode The ISO 639-1 or ISO 639-2 language code.
16
+ * @returns {module:utils/language~LanguageDirection}
17
+ */
18
+ export function getLanguageDirection(languageCode) {
19
+ return RTL_LANGUAGE_CODES.includes(languageCode) ? 'rtl' : 'ltr';
20
+ }
package/src/locale.js ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/locale
7
+ */
8
+ /* globals console */
9
+ import toArray from './toarray';
10
+ import { _translate } from './translation-service';
11
+ import { getLanguageDirection } from './language';
12
+ /**
13
+ * Represents the localization services.
14
+ */
15
+ export default class Locale {
16
+ /**
17
+ * Creates a new instance of the locale class. Learn more about
18
+ * {@glink features/ui-language configuring the language of the editor}.
19
+ *
20
+ * @param {Object} [options] Locale configuration.
21
+ * @param {String} [options.uiLanguage='en'] The editor UI language code in the
22
+ * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. See {@link #uiLanguage}.
23
+ * @param {String} [options.contentLanguage] The editor content language code in the
24
+ * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. If not specified, the same as `options.language`.
25
+ * See {@link #contentLanguage}.
26
+ */
27
+ constructor(options = {}) {
28
+ this.uiLanguage = options.uiLanguage || 'en';
29
+ this.contentLanguage = options.contentLanguage || this.uiLanguage;
30
+ this.uiLanguageDirection = getLanguageDirection(this.uiLanguage);
31
+ this.contentLanguageDirection = getLanguageDirection(this.contentLanguage);
32
+ this.t = (message, values) => this._t(message, values);
33
+ }
34
+ /**
35
+ * The editor UI language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.
36
+ *
37
+ * **Note**: This property was deprecated. Please use {@link #uiLanguage} and {@link #contentLanguage}
38
+ * properties instead.
39
+ *
40
+ * @deprecated
41
+ * @member {String}
42
+ */
43
+ get language() {
44
+ /**
45
+ * The {@link module:utils/locale~Locale#language `Locale#language`} property was deprecated and will
46
+ * be removed in the near future. Please use the {@link #uiLanguage} and {@link #contentLanguage} properties instead.
47
+ *
48
+ * @error locale-deprecated-language-property
49
+ */
50
+ console.warn('locale-deprecated-language-property: ' +
51
+ 'The Locale#language property has been deprecated and will be removed in the near future. ' +
52
+ 'Please use #uiLanguage and #contentLanguage properties instead.');
53
+ return this.uiLanguage;
54
+ }
55
+ /**
56
+ * An unbound version of the {@link #t} method.
57
+ *
58
+ * @private
59
+ * @param {String|module:utils/translation-service~Message} message
60
+ * @param {Number|String|Array.<Number|String>} [values]
61
+ * @returns {String}
62
+ */
63
+ _t(message, values = []) {
64
+ values = toArray(values);
65
+ if (typeof message === 'string') {
66
+ message = { string: message };
67
+ }
68
+ const hasPluralForm = !!message.plural;
69
+ const quantity = hasPluralForm ? values[0] : 1;
70
+ const translatedString = _translate(this.uiLanguage, message, quantity);
71
+ return interpolateString(translatedString, values);
72
+ }
73
+ }
74
+ // Fills the `%0, %1, ...` string placeholders with values.
75
+ function interpolateString(string, values) {
76
+ return string.replace(/%(\d+)/g, (match, index) => {
77
+ return (index < values.length) ? values[index] : match;
78
+ });
79
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/mapsequal
7
+ */
8
+ /**
9
+ * Checks whether given {Map}s are equal, that is has same size and same key-value pairs.
10
+ *
11
+ * @param {Map} mapA The first map to compare.
12
+ * @param {Map} mapB The second map to compare.
13
+ * @returns {Boolean} `true` if given maps are equal, `false` otherwise.
14
+ */
15
+ export default function mapsEqual(mapA, mapB) {
16
+ if (mapA.size != mapB.size) {
17
+ return false;
18
+ }
19
+ for (const attr of mapA.entries()) {
20
+ const valA = JSON.stringify(attr[1]);
21
+ const valB = JSON.stringify(mapB.get(attr[0]));
22
+ if (valA !== valB) {
23
+ return false;
24
+ }
25
+ }
26
+ return true;
27
+ }
package/src/mix.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/mix
7
+ */
8
+ /**
9
+ * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the
10
+ * prototype of first object (a constructor).
11
+ *
12
+ * class Editor {
13
+ * ...
14
+ * }
15
+ *
16
+ * const SomeMixin = {
17
+ * a() {
18
+ * return 'a';
19
+ * }
20
+ * };
21
+ *
22
+ * mix( Editor, SomeMixin, ... );
23
+ *
24
+ * new Editor().a(); // -> 'a'
25
+ *
26
+ * Note: Properties which already exist in the base class will not be overriden.
27
+ *
28
+ * @param {Function} [baseClass] Class which prototype will be extended.
29
+ * @param {Object} [...mixins] Objects from which to get properties.
30
+ */
31
+ export default function mix(baseClass, ...mixins) {
32
+ mixins.forEach(mixin => {
33
+ const propertyNames = Object.getOwnPropertyNames(mixin);
34
+ const propertySymbols = Object.getOwnPropertySymbols(mixin);
35
+ propertyNames.concat(propertySymbols).forEach(key => {
36
+ if (key in baseClass.prototype) {
37
+ return;
38
+ }
39
+ const sourceDescriptor = Object.getOwnPropertyDescriptor(mixin, key);
40
+ sourceDescriptor.enumerable = false;
41
+ Object.defineProperty(baseClass.prototype, key, sourceDescriptor);
42
+ });
43
+ });
44
+ }
package/src/nth.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/nth
7
+ */
8
+ /**
9
+ * Returns `nth` (starts from `0` of course) item of the given `iterable`.
10
+ *
11
+ * If the iterable is a generator, then it consumes **all its items**.
12
+ * If it's a normal iterator, then it consumes **all items up to the given index**.
13
+ * Refer to the [Iterators and Generators](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Iterators_and_Generators)
14
+ * guide to learn differences between these interfaces.
15
+ *
16
+ * @param {Number} index
17
+ * @param {Iterable.<*>} iterable
18
+ * @returns {*}
19
+ */
20
+ export default function nth(index, iterable) {
21
+ for (const item of iterable) {
22
+ if (index === 0) {
23
+ return item;
24
+ }
25
+ index -= 1;
26
+ }
27
+ return null;
28
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module utils/objecttomap
7
+ */
8
+ /**
9
+ * Transforms object to map.
10
+ *
11
+ * const map = objectToMap( { 'foo': 1, 'bar': 2 } );
12
+ * map.get( 'foo' ); // 1
13
+ *
14
+ * **Note**: For mixed data (`Object` or `Iterable`) there's a dedicated {@link module:utils/tomap~toMap} function.
15
+ *
16
+ * @param {Object|null} obj Object to transform.
17
+ * @returns {Map} Map created from object.
18
+ */
19
+ export default function objectToMap(obj) {
20
+ const map = new Map();
21
+ for (const key in obj) {
22
+ map.set(key, obj[key]);
23
+ }
24
+ return map;
25
+ }