]>
git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blob - sources/core/event.js
89444b5e2e054886732c3221ab0c87e920dc1f7a
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
7 * @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
8 * base for classes and objects that require event handling features.
11 if ( !CKEDITOR
.event
) {
13 * Creates an event class instance. This constructor is rarely used, being
14 * the {@link #implementOn} function used in class prototypes directly
17 * This is a base class for classes and objects that require event
20 * Do not confuse this class with {@link CKEDITOR.dom.event} which is
21 * instead used for DOM events. The CKEDITOR.event class implements the
22 * internal event system used by the CKEditor to fire API related events.
25 * @constructor Creates an event class instance.
27 CKEDITOR
.event = function() {};
30 * Implements the {@link CKEDITOR.event} features in an object.
32 * var myObject = { message: 'Example' };
33 * CKEDITOR.event.implementOn( myObject );
35 * myObject.on( 'testEvent', function() {
36 * alert( this.message );
38 * myObject.fire( 'testEvent' ); // 'Example'
41 * @param {Object} targetObject The object into which implement the features.
43 CKEDITOR
.event
.implementOn = function( targetObject
) {
44 var eventProto
= CKEDITOR
.event
.prototype;
46 for ( var prop
in eventProto
) {
47 if ( targetObject
[ prop
] == null )
48 targetObject
[ prop
] = eventProto
[ prop
];
52 CKEDITOR
.event
.prototype = ( function() {
53 // Returns the private events object for a given object.
54 var getPrivate = function( obj
) {
55 var _
= ( obj
.getPrivate
&& obj
.getPrivate() ) || obj
._
|| ( obj
._
= {} );
56 return _
.events
|| ( _
.events
= {} );
59 var eventEntry = function( eventName
) {
60 this.name
= eventName
;
64 eventEntry
.prototype = {
65 // Get the listener index for a specified function.
66 // Returns -1 if not found.
67 getListenerIndex: function( listenerFunction
) {
68 for ( var i
= 0, listeners
= this.listeners
; i
< listeners
.length
; i
++ ) {
69 if ( listeners
[ i
].fn
== listenerFunction
)
76 // Retrieve the event entry on the event host (create it if needed).
77 function getEntry( name
) {
78 // Get the event entry (create it if needed).
79 var events
= getPrivate( this );
80 return events
[ name
] || ( events
[ name
] = new eventEntry( name
) );
85 * Predefine some intrinsic properties on a specific event name.
87 * @param {String} name The event name
89 * @param [meta.errorProof=false] Whether the event firing should catch error thrown from a per listener call.
91 define: function( name
, meta
) {
92 var entry
= getEntry
.call( this, name
);
93 CKEDITOR
.tools
.extend( entry
, meta
, true );
97 * Registers a listener to a specific event in the current object.
99 * someObject.on( 'someEvent', function() {
100 * alert( this == someObject ); // true
103 * someObject.on( 'someEvent', function() {
104 * alert( this == anotherObject ); // true
105 * }, anotherObject );
107 * someObject.on( 'someEvent', function( event ) {
108 * alert( event.listenerData ); // 'Example'
109 * }, null, 'Example' );
111 * someObject.on( 'someEvent', function() { ... } ); // 2nd called
112 * someObject.on( 'someEvent', function() { ... }, null, null, 100 ); // 3rd called
113 * someObject.on( 'someEvent', function() { ... }, null, null, 1 ); // 1st called
115 * @param {String} eventName The event name to which listen.
116 * @param {Function} listenerFunction The function listening to the
117 * event. A single {@link CKEDITOR.eventInfo} object instanced
118 * is passed to this function containing all the event data.
119 * @param {Object} [scopeObj] The object used to scope the listener
120 * call (the `this` object). If omitted, the current object is used.
121 * @param {Object} [listenerData] Data to be sent as the
122 * {@link CKEDITOR.eventInfo#listenerData} when calling the
124 * @param {Number} [priority=10] The listener priority. Lower priority
125 * listeners are called first. Listeners with the same priority
126 * value are called in registration order.
127 * @returns {Object} An object containing the `removeListener`
128 * function, which can be used to remove the listener at any time.
130 on: function( eventName
, listenerFunction
, scopeObj
, listenerData
, priority
) {
131 // Create the function to be fired for this listener.
132 function listenerFirer( editor
, publisherData
, stopFn
, cancelFn
) {
138 listenerData: listenerData
,
141 removeListener: removeListener
144 var ret
= listenerFunction
.call( scopeObj
, ev
);
146 return ret
=== false ? false : ev
.data
;
149 function removeListener() {
150 me
.removeListener( eventName
, listenerFunction
);
153 var event
= getEntry
.call( this, eventName
);
155 if ( event
.getListenerIndex( listenerFunction
) < 0 ) {
156 // Get the listeners.
157 var listeners
= event
.listeners
;
163 // Default the priority, if needed.
164 if ( isNaN( priority
) )
169 listenerFirer
.fn
= listenerFunction
;
170 listenerFirer
.priority
= priority
;
172 // Search for the right position for this new listener, based on its
174 for ( var i
= listeners
.length
- 1; i
>= 0; i
-- ) {
175 // Find the item which should be before the new one.
176 if ( listeners
[ i
].priority
<= priority
) {
177 // Insert the listener in the array.
178 listeners
.splice( i
+ 1, 0, listenerFirer
);
179 return { removeListener: removeListener
};
183 // If no position has been found (or zero length), put it in
184 // the front of list.
185 listeners
.unshift( listenerFirer
);
188 return { removeListener: removeListener
};
192 * Similiar with {@link #on} but the listener will be called only once upon the next event firing.
194 * @see CKEDITOR.event#on
197 var args
= Array
.prototype.slice
.call( arguments
),
200 args
[ 1 ] = function( evt
) {
201 evt
.removeListener();
202 return fn
.apply( this, arguments
);
205 return this.on
.apply( this, args
);
210 * @property {Boolean} useCapture
215 * Register event handler under the capturing stage on supported target.
217 capture: function() {
218 CKEDITOR
.event
.useCapture
= 1;
219 var retval
= this.on
.apply( this, arguments
);
220 CKEDITOR
.event
.useCapture
= 0;
225 * Fires an specific event in the object. All registered listeners are
226 * called at this point.
228 * someObject.on( 'someEvent', function() { ... } );
229 * someObject.on( 'someEvent', function() { ... } );
230 * someObject.fire( 'someEvent' ); // Both listeners are called.
232 * someObject.on( 'someEvent', function( event ) {
233 * alert( event.data ); // 'Example'
235 * someObject.fire( 'someEvent', 'Example' );
238 * @param {String} eventName The event name to fire.
239 * @param {Object} [data] Data to be sent as the
240 * {@link CKEDITOR.eventInfo#data} when calling the listeners.
241 * @param {CKEDITOR.editor} [editor] The editor instance to send as the
242 * {@link CKEDITOR.eventInfo#editor} when calling the listener.
243 * @returns {Boolean/Object} A boolean indicating that the event is to be
244 * canceled, or data returned by one of the listeners.
247 // Create the function that marks the event as stopped.
249 var stopEvent = function() {
253 // Create the function that marks the event as canceled.
255 var cancelEvent = function() {
259 return function( eventName
, data
, editor
) {
260 // Get the event entry.
261 var event
= getPrivate( this )[ eventName
];
263 // Save the previous stopped and cancelled states. We may
264 // be nesting fire() calls.
265 var previousStopped
= stopped
,
266 previousCancelled
= canceled
;
268 // Reset the stopped and canceled flags.
269 stopped
= canceled
= 0;
272 var listeners
= event
.listeners
;
274 if ( listeners
.length
) {
275 // As some listeners may remove themselves from the
276 // event, the original array length is dinamic. So,
277 // let's make a copy of all listeners, so we are
278 // sure we'll call all of them.
279 listeners
= listeners
.slice( 0 );
282 // Loop through all listeners.
283 for ( var i
= 0; i
< listeners
.length
; i
++ ) {
284 // Call the listener, passing the event data.
285 if ( event
.errorProof
) {
287 retData
= listeners
[ i
].call( this, editor
, data
, stopEvent
, cancelEvent
);
290 retData
= listeners
[ i
].call( this, editor
, data
, stopEvent
, cancelEvent
);
293 if ( retData
=== false )
295 else if ( typeof retData
!= 'undefined' )
298 // No further calls is stopped or canceled.
299 if ( stopped
|| canceled
)
305 var ret
= canceled
? false : ( typeof data
== 'undefined' ? true : data
);
307 // Restore the previous stopped and canceled states.
308 stopped
= previousStopped
;
309 canceled
= previousCancelled
;
316 * Fires an specific event in the object, releasing all listeners
317 * registered to that event. The same listeners are not called again on
318 * successive calls of it or of {@link #fire}.
320 * someObject.on( 'someEvent', function() { ... } );
321 * someObject.fire( 'someEvent' ); // Above listener called.
322 * someObject.fireOnce( 'someEvent' ); // Above listener called.
323 * someObject.fire( 'someEvent' ); // No listeners called.
325 * @param {String} eventName The event name to fire.
326 * @param {Object} [data] Data to be sent as the
327 * {@link CKEDITOR.eventInfo#data} when calling the listeners.
328 * @param {CKEDITOR.editor} [editor] The editor instance to send as the
329 * {@link CKEDITOR.eventInfo#editor} when calling the listener.
330 * @returns {Boolean/Object} A booloan indicating that the event is to be
331 * canceled, or data returned by one of the listeners.
333 fireOnce: function( eventName
, data
, editor
) {
334 var ret
= this.fire( eventName
, data
, editor
);
335 delete getPrivate( this )[ eventName
];
340 * Unregisters a listener function from being called at the specified
341 * event. No errors are thrown if the listener has not been registered previously.
343 * var myListener = function() { ... };
344 * someObject.on( 'someEvent', myListener );
345 * someObject.fire( 'someEvent' ); // myListener called.
346 * someObject.removeListener( 'someEvent', myListener );
347 * someObject.fire( 'someEvent' ); // myListener not called.
349 * @param {String} eventName The event name.
350 * @param {Function} listenerFunction The listener function to unregister.
352 removeListener: function( eventName
, listenerFunction
) {
353 // Get the event entry.
354 var event
= getPrivate( this )[ eventName
];
357 var index
= event
.getListenerIndex( listenerFunction
);
359 event
.listeners
.splice( index
, 1 );
364 * Remove all existing listeners on this object, for cleanup purpose.
366 removeAllListeners: function() {
367 var events
= getPrivate( this );
368 for ( var i
in events
)
373 * Checks if there is any listener registered to a given event.
375 * var myListener = function() { ... };
376 * someObject.on( 'someEvent', myListener );
377 * alert( someObject.hasListeners( 'someEvent' ) ); // true
378 * alert( someObject.hasListeners( 'noEvent' ) ); // false
380 * @param {String} eventName The event name.
383 hasListeners: function( eventName
) {
384 var event
= getPrivate( this )[ eventName
];
385 return ( event
&& event
.listeners
.length
> 0 );