@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.
- package/CHANGELOG.md +1 -1
- package/package.json +5 -5
- package/src/collection.js +3 -5
- package/src/dom/emittermixin.js +75 -96
- package/src/dom/global.js +15 -1
- package/src/dom/rect.js +4 -5
- package/src/emittermixin.js +204 -222
- package/src/env.js +16 -1
- package/src/focustracker.js +4 -6
- package/src/keystrokehandler.js +1 -1
- package/src/mix.js +4 -0
- package/src/observablemixin.js +194 -195
- package/src/splicearray.js +39 -0
- package/src/translation-service.js +18 -18
- package/src/version.js +1 -1
package/src/observablemixin.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
|
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-
|
|
56
|
+
* @error observable-set-cannot-override
|
|
115
57
|
*/
|
|
116
|
-
throw new CKEditorError('observable-
|
|
58
|
+
throw new CKEditorError('observable-set-cannot-override', this);
|
|
117
59
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
|
96
|
+
* Properties must be unique.
|
|
161
97
|
*
|
|
162
|
-
* @error observable-
|
|
98
|
+
* @error observable-bind-duplicate-properties
|
|
163
99
|
*/
|
|
164
|
-
throw new CKEditorError('observable-
|
|
100
|
+
throw new CKEditorError('observable-bind-duplicate-properties', this);
|
|
165
101
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (
|
|
170
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this
|
|
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
|
-
|
|
239
|
-
}
|
|
240
|
-
export
|
|
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
|
|
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;
|