@ckeditor/ckeditor5-utils 31.0.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/dom/emittermixin.js +117 -51
- package/src/env.js +37 -0
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-utils",
|
|
3
|
-
"version": "31.
|
|
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": "^31.
|
|
18
|
-
"@ckeditor/ckeditor5-editor-classic": "^31.
|
|
19
|
-
"@ckeditor/ckeditor5-core": "^31.
|
|
20
|
-
"@ckeditor/ckeditor5-engine": "^31.
|
|
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/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
|
*
|
package/src/env.js
CHANGED
|
@@ -25,6 +25,14 @@ const env = {
|
|
|
25
25
|
*/
|
|
26
26
|
isMac: isMac( userAgent ),
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Indicates that the application is running on Windows.
|
|
30
|
+
*
|
|
31
|
+
* @static
|
|
32
|
+
* @type {Boolean}
|
|
33
|
+
*/
|
|
34
|
+
isWindows: isWindows( userAgent ),
|
|
35
|
+
|
|
28
36
|
/**
|
|
29
37
|
* Indicates that the application is running in Firefox (Gecko).
|
|
30
38
|
*
|
|
@@ -41,6 +49,14 @@ const env = {
|
|
|
41
49
|
*/
|
|
42
50
|
isSafari: isSafari( userAgent ),
|
|
43
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Indicates the the application is running in iOS.
|
|
54
|
+
*
|
|
55
|
+
* @static
|
|
56
|
+
* @type {Boolean}
|
|
57
|
+
*/
|
|
58
|
+
isiOS: isiOS( userAgent ),
|
|
59
|
+
|
|
44
60
|
/**
|
|
45
61
|
* Indicates that the application is running on Android mobile device.
|
|
46
62
|
*
|
|
@@ -87,6 +103,16 @@ export function isMac( userAgent ) {
|
|
|
87
103
|
return userAgent.indexOf( 'macintosh' ) > -1;
|
|
88
104
|
}
|
|
89
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Checks if User Agent represented by the string is running on Windows.
|
|
108
|
+
*
|
|
109
|
+
* @param {String} userAgent **Lowercase** `navigator.userAgent` string.
|
|
110
|
+
* @returns {Boolean} Whether User Agent is running on Windows or not.
|
|
111
|
+
*/
|
|
112
|
+
export function isWindows( userAgent ) {
|
|
113
|
+
return userAgent.indexOf( 'windows' ) > -1;
|
|
114
|
+
}
|
|
115
|
+
|
|
90
116
|
/**
|
|
91
117
|
* Checks if User Agent represented by the string is Firefox (Gecko).
|
|
92
118
|
*
|
|
@@ -107,6 +133,17 @@ export function isSafari( userAgent ) {
|
|
|
107
133
|
return userAgent.indexOf( ' applewebkit/' ) > -1 && userAgent.indexOf( 'chrome' ) === -1;
|
|
108
134
|
}
|
|
109
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Checks if User Agent represented by the string is running in iOS.
|
|
138
|
+
*
|
|
139
|
+
* @param {String} userAgent **Lowercase** `navigator.userAgent` string.
|
|
140
|
+
* @returns {Boolean} Whether User Agent is running in iOS or not.
|
|
141
|
+
*/
|
|
142
|
+
export function isiOS( userAgent ) {
|
|
143
|
+
// "Request mobile site" || "Request desktop site".
|
|
144
|
+
return !!userAgent.match( /iphone|ipad/i ) || ( isMac( userAgent ) && navigator.maxTouchPoints > 0 );
|
|
145
|
+
}
|
|
146
|
+
|
|
110
147
|
/**
|
|
111
148
|
* Checks if User Agent represented by the string is Android mobile device.
|
|
112
149
|
*
|