@ckeditor/ckeditor5-utils 35.0.1 → 35.2.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.
@@ -2,11 +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
- /* eslint-disable @typescript-eslint/unified-signatures */
5
+ /* eslint-disable @typescript-eslint/unified-signatures, new-cap */
6
6
  /**
7
7
  * @module utils/observablemixin
8
8
  */
9
- import EmitterMixin from './emittermixin';
9
+ import { Emitter } from './emittermixin';
10
10
  import CKEditorError from './ckeditorerror';
11
11
  import { isObject } from 'lodash-es';
12
12
  const observablePropertiesSymbol = Symbol('observableProperties');
@@ -27,217 +27,216 @@ const decoratedOriginal = Symbol('decoratedOriginal');
27
27
  * @mixes module:utils/emittermixin~EmitterMixin
28
28
  * @implements module:utils/observablemixin~Observable
29
29
  */
30
- const ObservableMixin = {
31
- /**
32
- * @inheritDoc
33
- */
34
- set(name, value) {
35
- // If the first parameter is an Object, iterate over its properties.
36
- if (isObject(name)) {
37
- Object.keys(name).forEach(property => {
38
- this.set(property, name[property]);
39
- }, this);
40
- return;
41
- }
42
- initObservable(this);
43
- const properties = this[observablePropertiesSymbol];
44
- if ((name in this) && !properties.has(name)) {
45
- /**
46
- * Cannot override an existing property.
47
- *
48
- * This error is thrown when trying to {@link ~Observable#set set} a property with
49
- * a name of an already existing property. For example:
50
- *
51
- * let observable = new Model();
52
- * observable.property = 1;
53
- * observable.set( 'property', 2 ); // throws
54
- *
55
- * observable.set( 'property', 1 );
56
- * observable.set( 'property', 2 ); // ok, because this is an existing property.
57
- *
58
- * @error observable-set-cannot-override
59
- */
60
- throw new CKEditorError('observable-set-cannot-override', this);
61
- }
62
- Object.defineProperty(this, name, {
63
- enumerable: true,
64
- configurable: true,
65
- get() {
66
- return properties.get(name);
67
- },
68
- set(value) {
69
- const oldValue = properties.get(name);
70
- // Fire `set` event before the new value will be set to make it possible
71
- // to override observable property without affecting `change` event.
72
- // See https://github.com/ckeditor/ckeditor5-utils/issues/171.
73
- let newValue = this.fire('set:' + name, name, value, oldValue);
74
- if (newValue === undefined) {
75
- newValue = value;
76
- }
77
- // Allow undefined as an initial value like A.define( 'x', undefined ) (#132).
78
- // Note: When properties map has no such own property, then its value is undefined.
79
- if (oldValue !== newValue || !properties.has(name)) {
80
- properties.set(name, newValue);
81
- this.fire('change:' + name, name, newValue, oldValue);
82
- }
30
+ export default function ObservableMixin(base) {
31
+ class Mixin extends base {
32
+ set(name, value) {
33
+ // If the first parameter is an Object, iterate over its properties.
34
+ if (isObject(name)) {
35
+ Object.keys(name).forEach(property => {
36
+ this.set(property, name[property]);
37
+ }, this);
38
+ return;
83
39
  }
84
- });
85
- this[name] = value;
86
- },
87
- /**
88
- * @inheritDoc
89
- */
90
- bind(...bindProperties) {
91
- if (!bindProperties.length || !isStringArray(bindProperties)) {
92
- /**
93
- * All properties must be strings.
94
- *
95
- * @error observable-bind-wrong-properties
96
- */
97
- throw new CKEditorError('observable-bind-wrong-properties', this);
98
- }
99
- if ((new Set(bindProperties)).size !== bindProperties.length) {
100
- /**
101
- * Properties must be unique.
102
- *
103
- * @error observable-bind-duplicate-properties
104
- */
105
- throw new CKEditorError('observable-bind-duplicate-properties', this);
106
- }
107
- initObservable(this);
108
- const boundProperties = this[boundPropertiesSymbol];
109
- bindProperties.forEach(propertyName => {
110
- if (boundProperties.has(propertyName)) {
40
+ initObservable(this);
41
+ const properties = this[observablePropertiesSymbol];
42
+ if ((name in this) && !properties.has(name)) {
111
43
  /**
112
- * Cannot bind the same property more than once.
44
+ * Cannot override an existing property.
45
+ *
46
+ * This error is thrown when trying to {@link ~Observable#set set} a property with
47
+ * a name of an already existing property. For example:
48
+ *
49
+ * let observable = new Model();
50
+ * observable.property = 1;
51
+ * observable.set( 'property', 2 ); // throws
52
+ *
53
+ * observable.set( 'property', 1 );
54
+ * observable.set( 'property', 2 ); // ok, because this is an existing property.
113
55
  *
114
- * @error observable-bind-rebind
56
+ * @error observable-set-cannot-override
115
57
  */
116
- throw new CKEditorError('observable-bind-rebind', this);
58
+ throw new CKEditorError('observable-set-cannot-override', this);
117
59
  }
118
- });
119
- const bindings = new Map();
120
- // @typedef {Object} Binding
121
- // @property {Array} property Property which is bound.
122
- // @property {Array} to Array of observable–property components of the binding (`{ observable: ..., property: .. }`).
123
- // @property {Array} callback A function which processes `to` components.
124
- bindProperties.forEach(a => {
125
- const binding = { property: a, to: [] };
126
- boundProperties.set(a, binding);
127
- bindings.set(a, binding);
128
- });
129
- // @typedef {Object} BindChain
130
- // @property {Function} to See {@link ~ObservableMixin#_bindTo}.
131
- // @property {Function} toMany See {@link ~ObservableMixin#_bindToMany}.
132
- // @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.
133
- // @property {Array} _bindProperties Array of `_observable` properties to be bound.
134
- // @property {Array} _to Array of `to()` observable–properties (`{ observable: toObservable, properties: ...toProperties }`).
135
- // @property {Map} _bindings Stores bindings to be kept in
136
- // {@link ~ObservableMixin#_boundProperties}/{@link ~ObservableMixin#_boundObservables}
137
- // initiated in this binding chain.
138
- return {
139
- to: bindTo,
140
- toMany: bindToMany,
141
- _observable: this,
142
- _bindProperties: bindProperties,
143
- _to: [],
144
- _bindings: bindings
145
- };
146
- },
147
- /**
148
- * @inheritDoc
149
- */
150
- unbind(...unbindProperties) {
151
- // Nothing to do here if not inited yet.
152
- if (!(this[observablePropertiesSymbol])) {
153
- return;
60
+ Object.defineProperty(this, name, {
61
+ enumerable: true,
62
+ configurable: true,
63
+ get() {
64
+ return properties.get(name);
65
+ },
66
+ set(value) {
67
+ const oldValue = properties.get(name);
68
+ // Fire `set` event before the new value will be set to make it possible
69
+ // to override observable property without affecting `change` event.
70
+ // See https://github.com/ckeditor/ckeditor5-utils/issues/171.
71
+ let newValue = this.fire(`set:${name}`, name, value, oldValue);
72
+ if (newValue === undefined) {
73
+ newValue = value;
74
+ }
75
+ // Allow undefined as an initial value like A.define( 'x', undefined ) (#132).
76
+ // Note: When properties map has no such own property, then its value is undefined.
77
+ if (oldValue !== newValue || !properties.has(name)) {
78
+ properties.set(name, newValue);
79
+ this.fire(`change:${name}`, name, newValue, oldValue);
80
+ }
81
+ }
82
+ });
83
+ this[name] = value;
154
84
  }
155
- const boundProperties = this[boundPropertiesSymbol];
156
- const boundObservables = this[boundObservablesSymbol];
157
- if (unbindProperties.length) {
158
- if (!isStringArray(unbindProperties)) {
85
+ bind(...bindProperties) {
86
+ if (!bindProperties.length || !isStringArray(bindProperties)) {
87
+ /**
88
+ * All properties must be strings.
89
+ *
90
+ * @error observable-bind-wrong-properties
91
+ */
92
+ throw new CKEditorError('observable-bind-wrong-properties', this);
93
+ }
94
+ if ((new Set(bindProperties)).size !== bindProperties.length) {
159
95
  /**
160
- * Properties must be strings.
96
+ * Properties must be unique.
161
97
  *
162
- * @error observable-unbind-wrong-properties
98
+ * @error observable-bind-duplicate-properties
163
99
  */
164
- throw new CKEditorError('observable-unbind-wrong-properties', this);
100
+ throw new CKEditorError('observable-bind-duplicate-properties', this);
165
101
  }
166
- unbindProperties.forEach(propertyName => {
167
- const binding = boundProperties.get(propertyName);
168
- // Nothing to do if the binding is not defined
169
- if (!binding) {
170
- return;
102
+ initObservable(this);
103
+ const boundProperties = this[boundPropertiesSymbol];
104
+ bindProperties.forEach(propertyName => {
105
+ if (boundProperties.has(propertyName)) {
106
+ /**
107
+ * Cannot bind the same property more than once.
108
+ *
109
+ * @error observable-bind-rebind
110
+ */
111
+ throw new CKEditorError('observable-bind-rebind', this);
171
112
  }
172
- binding.to.forEach(([toObservable, toProperty]) => {
173
- const toProperties = boundObservables.get(toObservable);
174
- const toPropertyBindings = toProperties[toProperty];
175
- toPropertyBindings.delete(binding);
176
- if (!toPropertyBindings.size) {
177
- delete toProperties[toProperty];
178
- }
179
- if (!Object.keys(toProperties).length) {
180
- boundObservables.delete(toObservable);
181
- this.stopListening(toObservable, 'change');
182
- }
183
- });
184
- boundProperties.delete(propertyName);
185
113
  });
186
- }
187
- else {
188
- boundObservables.forEach((bindings, boundObservable) => {
189
- this.stopListening(boundObservable, 'change');
114
+ const bindings = new Map();
115
+ // @typedef {Object} Binding
116
+ // @property {Array} property Property which is bound.
117
+ // @property {Array} to Array of observable–property components of the binding (`{ observable: ..., property: .. }`).
118
+ // @property {Array} callback A function which processes `to` components.
119
+ bindProperties.forEach(a => {
120
+ const binding = { property: a, to: [] };
121
+ boundProperties.set(a, binding);
122
+ bindings.set(a, binding);
190
123
  });
191
- boundObservables.clear();
192
- boundProperties.clear();
124
+ // @typedef {Object} BindChain
125
+ // @property {Function} to See {@link ~ObservableMixin#_bindTo}.
126
+ // @property {Function} toMany See {@link ~ObservableMixin#_bindToMany}.
127
+ // @property {module:utils/observablemixin~Observable} _observable The observable which initializes the binding.
128
+ // @property {Array} _bindProperties Array of `_observable` properties to be bound.
129
+ // @property {Array} _to Array of `to()` observable–properties (`{ observable: toObservable, properties: ...toProperties }`).
130
+ // @property {Map} _bindings Stores bindings to be kept in
131
+ // {@link ~ObservableMixin#_boundProperties}/{@link ~ObservableMixin#_boundObservables}
132
+ // initiated in this binding chain.
133
+ return {
134
+ to: bindTo,
135
+ toMany: bindToMany,
136
+ _observable: this,
137
+ _bindProperties: bindProperties,
138
+ _to: [],
139
+ _bindings: bindings
140
+ };
193
141
  }
194
- },
195
- /**
196
- * @inheritDoc
197
- */
198
- decorate(methodName) {
199
- initObservable(this);
200
- const originalMethod = this[methodName];
201
- if (!originalMethod) {
202
- /**
203
- * Cannot decorate an undefined method.
204
- *
205
- * @error observablemixin-cannot-decorate-undefined
206
- * @param {Object} object The object which method should be decorated.
207
- * @param {String} methodName Name of the method which does not exist.
208
- */
209
- throw new CKEditorError('observablemixin-cannot-decorate-undefined', this, { object: this, methodName });
142
+ unbind(...unbindProperties) {
143
+ // Nothing to do here if not inited yet.
144
+ if (!(this[observablePropertiesSymbol])) {
145
+ return;
146
+ }
147
+ const boundProperties = this[boundPropertiesSymbol];
148
+ const boundObservables = this[boundObservablesSymbol];
149
+ if (unbindProperties.length) {
150
+ if (!isStringArray(unbindProperties)) {
151
+ /**
152
+ * Properties must be strings.
153
+ *
154
+ * @error observable-unbind-wrong-properties
155
+ */
156
+ throw new CKEditorError('observable-unbind-wrong-properties', this);
157
+ }
158
+ unbindProperties.forEach(propertyName => {
159
+ const binding = boundProperties.get(propertyName);
160
+ // Nothing to do if the binding is not defined
161
+ if (!binding) {
162
+ return;
163
+ }
164
+ binding.to.forEach(([toObservable, toProperty]) => {
165
+ const toProperties = boundObservables.get(toObservable);
166
+ const toPropertyBindings = toProperties[toProperty];
167
+ toPropertyBindings.delete(binding);
168
+ if (!toPropertyBindings.size) {
169
+ delete toProperties[toProperty];
170
+ }
171
+ if (!Object.keys(toProperties).length) {
172
+ boundObservables.delete(toObservable);
173
+ this.stopListening(toObservable, 'change');
174
+ }
175
+ });
176
+ boundProperties.delete(propertyName);
177
+ });
178
+ }
179
+ else {
180
+ boundObservables.forEach((bindings, boundObservable) => {
181
+ this.stopListening(boundObservable, 'change');
182
+ });
183
+ boundObservables.clear();
184
+ boundProperties.clear();
185
+ }
210
186
  }
211
- this.on(methodName, (evt, args) => {
212
- evt.return = originalMethod.apply(this, args);
213
- });
214
- this[methodName] = function (...args) {
215
- return this.fire(methodName, args);
216
- };
217
- this[methodName][decoratedOriginal] = originalMethod;
218
- if (!this[decoratedMethods]) {
219
- this[decoratedMethods] = [];
187
+ decorate(methodName) {
188
+ initObservable(this);
189
+ const originalMethod = this[methodName];
190
+ if (!originalMethod) {
191
+ /**
192
+ * Cannot decorate an undefined method.
193
+ *
194
+ * @error observablemixin-cannot-decorate-undefined
195
+ * @param {Object} object The object which method should be decorated.
196
+ * @param {String} methodName Name of the method which does not exist.
197
+ */
198
+ throw new CKEditorError('observablemixin-cannot-decorate-undefined', this, { object: this, methodName });
199
+ }
200
+ this.on(methodName, (evt, args) => {
201
+ evt.return = originalMethod.apply(this, args);
202
+ });
203
+ this[methodName] = function (...args) {
204
+ return this.fire(methodName, args);
205
+ };
206
+ this[methodName][decoratedOriginal] = originalMethod;
207
+ if (!this[decoratedMethods]) {
208
+ this[decoratedMethods] = [];
209
+ }
210
+ this[decoratedMethods].push(methodName);
220
211
  }
221
- this[decoratedMethods].push(methodName);
222
- },
223
- ...EmitterMixin
224
- };
225
- // Override the EmitterMixin stopListening method to be able to clean (and restore) decorated methods.
226
- // This is needed in case of:
227
- // 1. Have x.foo() decorated.
228
- // 2. Call x.stopListening()
229
- // 3. Call x.foo(). Problem: nothing happens (the original foo() method is not executed)
230
- ObservableMixin.stopListening = function (emitter, event, callback) {
231
- // Removing all listeners so let's clean the decorated methods to the original state.
232
- if (!emitter && this[decoratedMethods]) {
233
- for (const methodName of this[decoratedMethods]) {
234
- this[methodName] = this[methodName][decoratedOriginal];
212
+ // Override the EmitterMixin stopListening method to be able to clean (and restore) decorated methods.
213
+ // This is needed in case of:
214
+ // 1. Have x.foo() decorated.
215
+ // 2. Call x.stopListening()
216
+ // 3. Call x.foo(). Problem: nothing happens (the original foo() method is not executed)
217
+ stopListening(emitter, event, callback) {
218
+ // Removing all listeners so let's clean the decorated methods to the original state.
219
+ if (!emitter && this[decoratedMethods]) {
220
+ for (const methodName of this[decoratedMethods]) {
221
+ this[methodName] = this[methodName][decoratedOriginal];
222
+ }
223
+ delete this[decoratedMethods];
224
+ }
225
+ Emitter.prototype.stopListening.call(this, emitter, event, callback);
235
226
  }
236
- delete this[decoratedMethods];
237
227
  }
238
- EmitterMixin.stopListening.call(this, emitter, event, callback);
239
- };
240
- export default ObservableMixin;
228
+ return Mixin;
229
+ }
230
+ export const Observable = ObservableMixin(Emitter);
231
+ // Backward compatibility with `mix`
232
+ ([
233
+ 'set', 'bind', 'unbind', 'decorate',
234
+ 'on', 'once', 'off', 'listenTo',
235
+ 'stopListening', 'fire', 'delegate', 'stopDelegating',
236
+ '_addEventListener', '_removeEventListener'
237
+ ]).forEach(key => {
238
+ ObservableMixin[key] = Observable.prototype[key];
239
+ });
241
240
  // Init symbol properties needed for the observable mechanism to work.
242
241
  //
243
242
  // @private
@@ -0,0 +1,39 @@
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/splicearray
7
+ */
8
+ const BIG_CHUNK_SIZE = 10000;
9
+ /**
10
+ * Splices one array into another. To be used instead of `Array.prototype.splice` as the latter may
11
+ * throw "Maximum call stack size exceeded" when passed huge number of items to insert.
12
+ *
13
+ * Note: in contrary to Array.splice, this function does not modify the original `target`.
14
+ *
15
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 0, 0 ); // [ 3, 4, 1, 2 ]
16
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 1 ); // [ 1, 3, 4 ]
17
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 0 ); // [ 1, 3, 4, 2 ]
18
+ * spliceArray( [ 1, 2 ], [ 3, 4 ], 2, 0 ); // [ 1, 2, 3, 4 ]
19
+ * spliceArray( [ 1, 2 ], [], 0, 1 ); // [ 2 ]
20
+ *
21
+ * @private
22
+ * @param {Array} target Array to be spliced.
23
+ * @param {Array} source Array of elements to be inserted to target.
24
+ * @param {Number} start Index at which nodes should be inserted/removed.
25
+ * @param {Number} count Number of items.
26
+ *
27
+ * @returns {Array} New spliced array.
28
+ */
29
+ export default function spliceArray(target, source, start, count) {
30
+ // In case of performance problems, see: https://github.com/ckeditor/ckeditor5/pull/12429/files#r965850568
31
+ if (Math.max(source.length, target.length) > BIG_CHUNK_SIZE) {
32
+ return target.slice(0, start).concat(source).concat(target.slice(start + count, target.length));
33
+ }
34
+ else {
35
+ const newTarget = Array.from(target);
36
+ newTarget.splice(start, count, ...source);
37
+ return newTarget;
38
+ }
39
+ }
@@ -2,15 +2,15 @@
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
- /* globals window */
6
5
  /* eslint-disable no-var */
7
6
  /**
8
7
  * @module utils/translation-service
9
8
  */
10
9
  import CKEditorError from './ckeditorerror';
10
+ import global from './dom/global';
11
11
  /* istanbul ignore else */
12
- if (!window.CKEDITOR_TRANSLATIONS) {
13
- window.CKEDITOR_TRANSLATIONS = {};
12
+ if (!global.window.CKEDITOR_TRANSLATIONS) {
13
+ global.window.CKEDITOR_TRANSLATIONS = {};
14
14
  }
15
15
  /**
16
16
  * Adds translations to existing ones or overrides the existing translations. These translations will later
@@ -64,15 +64,15 @@ if (!window.CKEDITOR_TRANSLATIONS) {
64
64
  * the one below:
65
65
  *
66
66
  * function addTranslations( language, translations, getPluralForm ) {
67
- * if ( !window.CKEDITOR_TRANSLATIONS ) {
68
- * window.CKEDITOR_TRANSLATIONS = {};
67
+ * if ( !global.window.CKEDITOR_TRANSLATIONS ) {
68
+ * global.window.CKEDITOR_TRANSLATIONS = {};
69
69
  * }
70
70
 
71
- * if ( !window.CKEDITOR_TRANSLATIONS[ language ] ) {
72
- * window.CKEDITOR_TRANSLATIONS[ language ] = {};
71
+ * if ( !global.window.CKEDITOR_TRANSLATIONS[ language ] ) {
72
+ * global.window.CKEDITOR_TRANSLATIONS[ language ] = {};
73
73
  * }
74
74
  *
75
- * const languageTranslations = window.CKEDITOR_TRANSLATIONS[ language ];
75
+ * const languageTranslations = global.window.CKEDITOR_TRANSLATIONS[ language ];
76
76
  *
77
77
  * languageTranslations.dictionary = languageTranslations.dictionary || {};
78
78
  * languageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;
@@ -88,10 +88,10 @@ if (!window.CKEDITOR_TRANSLATIONS) {
88
88
  * @param {Function} [getPluralForm] A function that returns the plural form index (a number).
89
89
  */
90
90
  export function add(language, translations, getPluralForm) {
91
- if (!window.CKEDITOR_TRANSLATIONS[language]) {
92
- window.CKEDITOR_TRANSLATIONS[language] = {};
91
+ if (!global.window.CKEDITOR_TRANSLATIONS[language]) {
92
+ global.window.CKEDITOR_TRANSLATIONS[language] = {};
93
93
  }
94
- const languageTranslations = window.CKEDITOR_TRANSLATIONS[language];
94
+ const languageTranslations = global.window.CKEDITOR_TRANSLATIONS[language];
95
95
  languageTranslations.dictionary = languageTranslations.dictionary || {};
96
96
  languageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;
97
97
  Object.assign(languageTranslations.dictionary, translations);
@@ -142,7 +142,7 @@ export function _translate(language, message, quantity = 1) {
142
142
  if (numberOfLanguages === 1) {
143
143
  // Override the language to the only supported one.
144
144
  // This can't be done in the `Locale` class, because the translations comes after the `Locale` class initialization.
145
- language = Object.keys(window.CKEDITOR_TRANSLATIONS)[0];
145
+ language = Object.keys(global.window.CKEDITOR_TRANSLATIONS)[0];
146
146
  }
147
147
  const messageId = message.id || message.string;
148
148
  if (numberOfLanguages === 0 || !hasTranslation(language, messageId)) {
@@ -152,8 +152,8 @@ export function _translate(language, message, quantity = 1) {
152
152
  }
153
153
  return message.string;
154
154
  }
155
- const dictionary = window.CKEDITOR_TRANSLATIONS[language].dictionary;
156
- const getPluralForm = window.CKEDITOR_TRANSLATIONS[language].getPluralForm || (n => n === 1 ? 0 : 1);
155
+ const dictionary = global.window.CKEDITOR_TRANSLATIONS[language].dictionary;
156
+ const getPluralForm = global.window.CKEDITOR_TRANSLATIONS[language].getPluralForm || (n => n === 1 ? 0 : 1);
157
157
  const translation = dictionary[messageId];
158
158
  if (typeof translation === 'string') {
159
159
  return translation;
@@ -168,13 +168,13 @@ export function _translate(language, message, quantity = 1) {
168
168
  * @protected
169
169
  */
170
170
  export function _clear() {
171
- window.CKEDITOR_TRANSLATIONS = {};
171
+ global.window.CKEDITOR_TRANSLATIONS = {};
172
172
  }
173
173
  // Checks whether the dictionary exists and translation in that dictionary exists.
174
174
  function hasTranslation(language, messageId) {
175
- return (!!window.CKEDITOR_TRANSLATIONS[language] &&
176
- !!window.CKEDITOR_TRANSLATIONS[language].dictionary[messageId]);
175
+ return (!!global.window.CKEDITOR_TRANSLATIONS[language] &&
176
+ !!global.window.CKEDITOR_TRANSLATIONS[language].dictionary[messageId]);
177
177
  }
178
178
  function getNumberOfLanguages() {
179
- return Object.keys(window.CKEDITOR_TRANSLATIONS).length;
179
+ return Object.keys(global.window.CKEDITOR_TRANSLATIONS).length;
180
180
  }
package/src/version.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  /* globals window, global */
9
9
  import CKEditorError from './ckeditorerror';
10
- const version = '35.0.1';
10
+ const version = '35.2.0';
11
11
  export default version;
12
12
  /* istanbul ignore next */
13
13
  const windowOrGlobal = typeof window === 'object' ? window : global;