@ckeditor/ckeditor5-utils 29.1.0 → 31.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/package.json +5 -7
- package/src/ckeditorerror.js +39 -5
- package/src/collection.js +1 -1
- package/src/dom/emittermixin.js +117 -51
- package/src/dom/position.js +292 -189
- package/src/env.js +37 -0
- package/src/keyboard.js +6 -0
- package/src/translation-service.js +1 -1
- package/src/version.js +1 -1
- package/CHANGELOG.md +0 -324
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "31.1.0",
|
|
4
4
|
"description": "Miscellaneous utilities used by CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -14,12 +14,10 @@
|
|
|
14
14
|
"lodash-es": "^4.17.15"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@ckeditor/ckeditor5-build-classic": "^
|
|
18
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
|
19
|
-
"@ckeditor/ckeditor5-core": "^
|
|
20
|
-
"@ckeditor/ckeditor5-engine": "^
|
|
21
|
-
"assertion-error": "^1.1.0",
|
|
22
|
-
"js-beautify": "^1.11.0"
|
|
17
|
+
"@ckeditor/ckeditor5-build-classic": "^31.1.0",
|
|
18
|
+
"@ckeditor/ckeditor5-editor-classic": "^31.1.0",
|
|
19
|
+
"@ckeditor/ckeditor5-core": "^31.1.0",
|
|
20
|
+
"@ckeditor/ckeditor5-engine": "^31.1.0"
|
|
23
21
|
},
|
|
24
22
|
"engines": {
|
|
25
23
|
"node": ">=12.0.0",
|
package/src/ckeditorerror.js
CHANGED
|
@@ -59,9 +59,7 @@ export default class CKEditorError extends Error {
|
|
|
59
59
|
* data object will also be later available under the {@link #data} property.
|
|
60
60
|
*/
|
|
61
61
|
constructor( errorName, context, data ) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
super( message );
|
|
62
|
+
super( getErrorMessage( errorName, data ) );
|
|
65
63
|
|
|
66
64
|
/**
|
|
67
65
|
* @type {String}
|
|
@@ -85,6 +83,7 @@ export default class CKEditorError extends Error {
|
|
|
85
83
|
|
|
86
84
|
/**
|
|
87
85
|
* Checks if the error is of the `CKEditorError` type.
|
|
86
|
+
* @returns {Boolean}
|
|
88
87
|
*/
|
|
89
88
|
is( type ) {
|
|
90
89
|
return type === 'CKEditorError';
|
|
@@ -142,7 +141,6 @@ export default class CKEditorError extends Error {
|
|
|
142
141
|
*
|
|
143
142
|
* @param {String} errorName The error name to be logged.
|
|
144
143
|
* @param {Object} [data] Additional data to be logged.
|
|
145
|
-
* @returns {String}
|
|
146
144
|
*/
|
|
147
145
|
export function logWarning( errorName, data ) {
|
|
148
146
|
console.warn( ...formatConsoleArguments( errorName, data ) );
|
|
@@ -167,16 +165,52 @@ export function logWarning( errorName, data ) {
|
|
|
167
165
|
*
|
|
168
166
|
* @param {String} errorName The error name to be logged.
|
|
169
167
|
* @param {Object} [data] Additional data to be logged.
|
|
170
|
-
* @returns {String}
|
|
171
168
|
*/
|
|
172
169
|
export function logError( errorName, data ) {
|
|
173
170
|
console.error( ...formatConsoleArguments( errorName, data ) );
|
|
174
171
|
}
|
|
175
172
|
|
|
173
|
+
// Returns formatted link to documentation message.
|
|
174
|
+
//
|
|
175
|
+
// @private
|
|
176
|
+
// @param {String} errorName
|
|
177
|
+
// @returns {string}
|
|
176
178
|
function getLinkToDocumentationMessage( errorName ) {
|
|
177
179
|
return `\nRead more: ${ DOCUMENTATION_URL }#error-${ errorName }`;
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
// Returns formatted error message.
|
|
183
|
+
//
|
|
184
|
+
// @private
|
|
185
|
+
// @param {String} errorName
|
|
186
|
+
// @param {Object} [data]
|
|
187
|
+
// @returns {string}
|
|
188
|
+
function getErrorMessage( errorName, data ) {
|
|
189
|
+
const processedObjects = new WeakSet();
|
|
190
|
+
const circularReferencesReplacer = ( key, value ) => {
|
|
191
|
+
if ( typeof value === 'object' && value !== null ) {
|
|
192
|
+
if ( processedObjects.has( value ) ) {
|
|
193
|
+
return `[object ${ value.constructor.name }]`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
processedObjects.add( value );
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return value;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const stringifiedData = data ? ` ${ JSON.stringify( data, circularReferencesReplacer ) }` : '';
|
|
203
|
+
const documentationLink = getLinkToDocumentationMessage( errorName );
|
|
204
|
+
|
|
205
|
+
return errorName + stringifiedData + documentationLink;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Returns formatted console error arguments.
|
|
209
|
+
//
|
|
210
|
+
// @private
|
|
211
|
+
// @param {String} errorName
|
|
212
|
+
// @param {Object} [data]
|
|
213
|
+
// @returns {Array}
|
|
180
214
|
function formatConsoleArguments( errorName, data ) {
|
|
181
215
|
const documentationMessage = getLinkToDocumentationMessage( errorName );
|
|
182
216
|
|
package/src/collection.js
CHANGED
|
@@ -56,7 +56,7 @@ export default class Collection {
|
|
|
56
56
|
* console.log( collection.get( 'George' ) ); // -> { name: 'George' }
|
|
57
57
|
* console.log( collection.get( 'John' ) ); // -> { name: 'John' }
|
|
58
58
|
*
|
|
59
|
-
* @param {Iterable.<Object>|Object} initialItemsOrOptions The initial items of the collection or
|
|
59
|
+
* @param {Iterable.<Object>|Object} [initialItemsOrOptions] The initial items of the collection or
|
|
60
60
|
* the options object.
|
|
61
61
|
* @param {Object} [options={}] The options object, when the first argument is an array of initial items.
|
|
62
62
|
* @param {String} [options.idProperty='id'] The name of the property which is used to identify an item.
|
package/src/dom/emittermixin.js
CHANGED
|
@@ -52,19 +52,21 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
|
|
|
52
52
|
* @param {Boolean} [options.usePassive=false] Indicates that the function specified by listener will never call preventDefault()
|
|
53
53
|
* and prevents blocking browser's main thread by this event handler.
|
|
54
54
|
*/
|
|
55
|
-
listenTo( emitter,
|
|
56
|
-
// Check if emitter is an instance of DOM Node. If so,
|
|
57
|
-
// corresponding ProxyEmitter (or create one if not existing).
|
|
55
|
+
listenTo( emitter, event, callback, options = {} ) {
|
|
56
|
+
// Check if emitter is an instance of DOM Node. If so, use corresponding ProxyEmitter (or create one if not existing).
|
|
58
57
|
if ( isNode( emitter ) || isWindow( emitter ) ) {
|
|
59
|
-
const
|
|
58
|
+
const proxyOptions = {
|
|
59
|
+
capture: !!options.useCapture,
|
|
60
|
+
passive: !!options.usePassive
|
|
61
|
+
};
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
const proxyEmitter = this._getProxyEmitter( emitter, proxyOptions ) || new ProxyEmitter( emitter, proxyOptions );
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
this.listenTo( proxyEmitter, event, callback, options );
|
|
66
|
+
} else {
|
|
67
|
+
// Execute parent class method with Emitter (or ProxyEmitter) instance.
|
|
68
|
+
EmitterMixin.listenTo.call( this, emitter, event, callback, options );
|
|
64
69
|
}
|
|
65
|
-
|
|
66
|
-
// Execute parent class method with Emitter (or ProxyEmitter) instance.
|
|
67
|
-
EmitterMixin.listenTo.call( this, emitter, ...rest );
|
|
68
70
|
},
|
|
69
71
|
|
|
70
72
|
/**
|
|
@@ -83,35 +85,49 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
|
|
|
83
85
|
* `event`.
|
|
84
86
|
*/
|
|
85
87
|
stopListening( emitter, event, callback ) {
|
|
86
|
-
// Check if emitter is an instance of DOM Node. If so,
|
|
88
|
+
// Check if the emitter is an instance of DOM Node. If so, forward the call to the corresponding ProxyEmitters.
|
|
87
89
|
if ( isNode( emitter ) || isWindow( emitter ) ) {
|
|
88
|
-
const
|
|
90
|
+
const proxyEmitters = this._getAllProxyEmitters( emitter );
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return;
|
|
92
|
+
for ( const proxy of proxyEmitters ) {
|
|
93
|
+
this.stopListening( proxy, event, callback );
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
} else {
|
|
96
|
+
// Execute parent class method with Emitter (or ProxyEmitter) instance.
|
|
97
|
+
EmitterMixin.stopListening.call( this, emitter, event, callback );
|
|
96
98
|
}
|
|
99
|
+
},
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves ProxyEmitter instance for given DOM Node residing in this Host and given options.
|
|
103
|
+
*
|
|
104
|
+
* @private
|
|
105
|
+
* @param {Node} node DOM Node of the ProxyEmitter.
|
|
106
|
+
* @param {Object} [options] Additional options.
|
|
107
|
+
* @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered
|
|
108
|
+
* listener before being dispatched to any EventTarget beneath it in the DOM tree.
|
|
109
|
+
* @param {Boolean} [options.usePassive=false] Indicates that the function specified by listener will never call preventDefault()
|
|
110
|
+
* and prevents blocking browser's main thread by this event handler.
|
|
111
|
+
* @returns {module:utils/dom/emittermixin~ProxyEmitter|null} ProxyEmitter instance bound to the DOM Node.
|
|
112
|
+
*/
|
|
113
|
+
_getProxyEmitter( node, options ) {
|
|
114
|
+
return _getEmitterListenedTo( this, getProxyEmitterId( node, options ) );
|
|
104
115
|
},
|
|
105
116
|
|
|
106
117
|
/**
|
|
107
|
-
* Retrieves ProxyEmitter
|
|
118
|
+
* Retrieves all the ProxyEmitter instances for given DOM Node residing in this Host.
|
|
108
119
|
*
|
|
109
120
|
* @private
|
|
110
121
|
* @param {Node} node DOM Node of the ProxyEmitter.
|
|
111
|
-
* @returns {module:utils/dom/emittermixin~ProxyEmitter}
|
|
122
|
+
* @returns {Array.<module:utils/dom/emittermixin~ProxyEmitter>}
|
|
112
123
|
*/
|
|
113
|
-
|
|
114
|
-
return
|
|
124
|
+
_getAllProxyEmitters( node ) {
|
|
125
|
+
return [
|
|
126
|
+
{ capture: false, passive: false },
|
|
127
|
+
{ capture: false, passive: true },
|
|
128
|
+
{ capture: true, passive: false },
|
|
129
|
+
{ capture: true, passive: true }
|
|
130
|
+
].map( options => this._getProxyEmitter( node, options ) ).filter( proxy => !!proxy );
|
|
115
131
|
}
|
|
116
132
|
} );
|
|
117
133
|
|
|
@@ -120,6 +136,8 @@ export default DomEmitterMixin;
|
|
|
120
136
|
/**
|
|
121
137
|
* Creates a ProxyEmitter instance. Such an instance is a bridge between a DOM Node firing events
|
|
122
138
|
* and any Host listening to them. It is backwards compatible with {@link module:utils/emittermixin~EmitterMixin#on}.
|
|
139
|
+
* There is a separate instance for each combination of modes (useCapture & usePassive). The mode is concatenated with
|
|
140
|
+
* UID stored in HTMLElement to give each instance unique identifier.
|
|
123
141
|
*
|
|
124
142
|
* listenTo( click, ... )
|
|
125
143
|
* +-----------------------------------------+
|
|
@@ -128,14 +146,14 @@ export default DomEmitterMixin;
|
|
|
128
146
|
* | Host | | +---------------------------------------------+
|
|
129
147
|
* +----------------------------+ | | removeEventListener( click, ... ) |
|
|
130
148
|
* | _listeningTo: { | +----------v-------------+ |
|
|
131
|
-
* | UID: {
|
|
149
|
+
* | UID+mode: { | | ProxyEmitter | |
|
|
132
150
|
* | emitter: ProxyEmitter, | +------------------------+ +------------v----------+
|
|
133
151
|
* | callbacks: { | | events: { | | Node (HTMLElement) |
|
|
134
152
|
* | click: [ callbacks ] | | click: [ callbacks ] | +-----------------------+
|
|
135
153
|
* | } | | }, | | data-ck-expando: UID |
|
|
136
154
|
* | } | | _domNode: Node, | +-----------------------+
|
|
137
155
|
* | } | | _domListeners: {}, | |
|
|
138
|
-
* | +------------------------+ | | _emitterId: UID
|
|
156
|
+
* | +------------------------+ | | _emitterId: UID+mode | |
|
|
139
157
|
* | | DomEmitterMixin | | +--------------^---------+ |
|
|
140
158
|
* | +------------------------+ | | | |
|
|
141
159
|
* +--------------^-------------+ | +---------------------------------------------+
|
|
@@ -150,14 +168,21 @@ export default DomEmitterMixin;
|
|
|
150
168
|
class ProxyEmitter {
|
|
151
169
|
/**
|
|
152
170
|
* @param {Node} node DOM Node that fires events.
|
|
153
|
-
* @
|
|
171
|
+
* @param {Object} [options] Additional options.
|
|
172
|
+
* @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered
|
|
173
|
+
* listener before being dispatched to any EventTarget beneath it in the DOM tree.
|
|
174
|
+
* @param {Boolean} [options.usePassive=false] Indicates that the function specified by listener will never call preventDefault()
|
|
175
|
+
* and prevents blocking browser's main thread by this event handler.
|
|
154
176
|
*/
|
|
155
|
-
constructor( node ) {
|
|
177
|
+
constructor( node, options ) {
|
|
156
178
|
// Set emitter ID to match DOM Node "expando" property.
|
|
157
|
-
_setEmitterId( this,
|
|
179
|
+
_setEmitterId( this, getProxyEmitterId( node, options ) );
|
|
158
180
|
|
|
159
181
|
// Remember the DOM Node this ProxyEmitter is bound to.
|
|
160
182
|
this._domNode = node;
|
|
183
|
+
|
|
184
|
+
// And given options.
|
|
185
|
+
this._options = options;
|
|
161
186
|
}
|
|
162
187
|
}
|
|
163
188
|
|
|
@@ -175,31 +200,23 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
|
|
|
175
200
|
* It attaches a native DOM listener to the DOM Node. When fired,
|
|
176
201
|
* a corresponding Emitter event will also fire with DOM Event object as an argument.
|
|
177
202
|
*
|
|
203
|
+
* **Note**: This is automatically called by the
|
|
204
|
+
* {@link module:utils/emittermixin~EmitterMixin#listenTo `EmitterMixin#listenTo()`}.
|
|
205
|
+
*
|
|
178
206
|
* @method module:utils/dom/emittermixin~ProxyEmitter#attach
|
|
179
207
|
* @param {String} event The name of the event.
|
|
180
|
-
* @param {Function} callback The function to be called on event.
|
|
181
|
-
* @param {Object} [options={}] Additional options.
|
|
182
|
-
* @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered
|
|
183
|
-
* listener before being dispatched to any EventTarget beneath it in the DOM tree.
|
|
184
|
-
* @param {Boolean} [options.usePassive=false] Indicates that the function specified by listener will never call preventDefault()
|
|
185
|
-
* and prevents blocking browser's main thread by this event handler.
|
|
186
208
|
*/
|
|
187
|
-
attach( event
|
|
209
|
+
attach( event ) {
|
|
188
210
|
// If the DOM Listener for given event already exist it is pointless
|
|
189
211
|
// to attach another one.
|
|
190
212
|
if ( this._domListeners && this._domListeners[ event ] ) {
|
|
191
213
|
return;
|
|
192
214
|
}
|
|
193
215
|
|
|
194
|
-
const
|
|
195
|
-
capture: !!options.useCapture,
|
|
196
|
-
passive: !!options.usePassive
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const domListener = this._createDomListener( event, listenerOptions );
|
|
216
|
+
const domListener = this._createDomListener( event );
|
|
200
217
|
|
|
201
218
|
// Attach the native DOM listener to DOM Node.
|
|
202
|
-
this._domNode.addEventListener( event, domListener,
|
|
219
|
+
this._domNode.addEventListener( event, domListener, this._options );
|
|
203
220
|
|
|
204
221
|
if ( !this._domListeners ) {
|
|
205
222
|
this._domListeners = {};
|
|
@@ -213,6 +230,9 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
|
|
|
213
230
|
/**
|
|
214
231
|
* Stops executing the callback on the given event.
|
|
215
232
|
*
|
|
233
|
+
* **Note**: This is automatically called by the
|
|
234
|
+
* {@link module:utils/emittermixin~EmitterMixin#stopListening `EmitterMixin#stopListening()`}.
|
|
235
|
+
*
|
|
216
236
|
* @method module:utils/dom/emittermixin~ProxyEmitter#detach
|
|
217
237
|
* @param {String} event The name of the event.
|
|
218
238
|
*/
|
|
@@ -228,6 +248,36 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
|
|
|
228
248
|
}
|
|
229
249
|
},
|
|
230
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Adds callback to emitter for given event.
|
|
253
|
+
*
|
|
254
|
+
* @protected
|
|
255
|
+
* @method module:utils/dom/emittermixin~ProxyEmitter#_addEventListener
|
|
256
|
+
* @param {String} event The name of the event.
|
|
257
|
+
* @param {Function} callback The function to be called on event.
|
|
258
|
+
* @param {Object} [options={}] Additional options.
|
|
259
|
+
* @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher
|
|
260
|
+
* the priority value the sooner the callback will be fired. Events having the same priority are called in the
|
|
261
|
+
* order they were added.
|
|
262
|
+
*/
|
|
263
|
+
_addEventListener( event, callback, options ) {
|
|
264
|
+
this.attach( event );
|
|
265
|
+
EmitterMixin._addEventListener.call( this, event, callback, options );
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Removes callback from emitter for given event.
|
|
270
|
+
*
|
|
271
|
+
* @protected
|
|
272
|
+
* @method module:utils/dom/emittermixin~ProxyEmitter#_removeEventListener
|
|
273
|
+
* @param {String} event The name of the event.
|
|
274
|
+
* @param {Function} callback The function to stop being called.
|
|
275
|
+
*/
|
|
276
|
+
_removeEventListener( event, callback ) {
|
|
277
|
+
EmitterMixin._removeEventListener.call( this, event, callback );
|
|
278
|
+
this.detach( event );
|
|
279
|
+
},
|
|
280
|
+
|
|
231
281
|
/**
|
|
232
282
|
* Creates a native DOM listener callback. When the native DOM event
|
|
233
283
|
* is fired it will fire corresponding event on this ProxyEmitter.
|
|
@@ -236,13 +286,9 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
|
|
|
236
286
|
* @private
|
|
237
287
|
* @method module:utils/dom/emittermixin~ProxyEmitter#_createDomListener
|
|
238
288
|
* @param {String} event The name of the event.
|
|
239
|
-
* @param {Object} [options] Additional options.
|
|
240
|
-
* @param {Boolean} [options.capture=false] Indicates whether the listener was created for capturing event.
|
|
241
|
-
* @param {Boolean} [options.passive=false] Indicates that the function specified by listener will never call preventDefault()
|
|
242
|
-
* and prevents blocking browser's main thread by this event handler.
|
|
243
289
|
* @returns {Function} The DOM listener callback.
|
|
244
290
|
*/
|
|
245
|
-
_createDomListener( event
|
|
291
|
+
_createDomListener( event ) {
|
|
246
292
|
const domListener = domEvt => {
|
|
247
293
|
this.fire( event, domEvt );
|
|
248
294
|
};
|
|
@@ -251,7 +297,7 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
|
|
|
251
297
|
// detach it from the DOM Node, when it is no longer necessary.
|
|
252
298
|
// See: {@link detach}.
|
|
253
299
|
domListener.removeListener = () => {
|
|
254
|
-
this._domNode.removeEventListener( event, domListener,
|
|
300
|
+
this._domNode.removeEventListener( event, domListener, this._options );
|
|
255
301
|
delete this._domListeners[ event ];
|
|
256
302
|
};
|
|
257
303
|
|
|
@@ -268,6 +314,26 @@ function getNodeUID( node ) {
|
|
|
268
314
|
return node[ 'data-ck-expando' ] || ( node[ 'data-ck-expando' ] = uid() );
|
|
269
315
|
}
|
|
270
316
|
|
|
317
|
+
// Gets id of the ProxyEmitter for the given node.
|
|
318
|
+
//
|
|
319
|
+
// Combines DOM Node identifier and additional options.
|
|
320
|
+
//
|
|
321
|
+
// @private
|
|
322
|
+
// @param {Node} node
|
|
323
|
+
// @param {Object} options Additional options.
|
|
324
|
+
// @returns {String} ProxyEmitter id.
|
|
325
|
+
function getProxyEmitterId( node, options ) {
|
|
326
|
+
let id = getNodeUID( node );
|
|
327
|
+
|
|
328
|
+
for ( const option of Object.keys( options ).sort() ) {
|
|
329
|
+
if ( options[ option ] ) {
|
|
330
|
+
id += '-' + option;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return id;
|
|
335
|
+
}
|
|
336
|
+
|
|
271
337
|
/**
|
|
272
338
|
* Interface representing classes which mix in {@link module:utils/dom/emittermixin~EmitterMixin}.
|
|
273
339
|
*
|