| Current File : /home/jvzmxxx/wiki1/extensions/Wikibase/view/resources/jquery/jquery.util.EventSingletonManager.js |
/**
* @license GPL-2.0+
* @author H. Snater < mediawiki@snater.com >
*/
( function( $ ) {
'use strict';
$.util = $.util || {};
/**
* Manages attaching an event handler to a target only once for a set of source objects.
* Since an event is attached only once, the initial event handler (for the combination of target/
* event name/event namespace) may not be overwritten later on.
*
* @constructor
*/
var SELF = $.util.EventSingletonManager = function UtilEventSingletonManager() {
this._registry = [];
};
$.extend( SELF.prototype, {
/**
* @type {Object[]}
*/
_registry: [],
/**
* Attaches an event handler to a target element unless it is not attached already. The event
* binding is registered for a source element.
*
* @param {*} source
* @param {HTMLElement|Object} target
* @param {string} event
* @param {Function} handler
* Will receive the following arguments when the event is triggered:
* - {jQuery.Event} Object representing the actual event triggered on the target.
* - {*} source
* @param {Object} [options]
* - {number} [throttle] Throttle delay
* Default: undefined (no throttling)
* - {number} [debounce] Debounce delay
* Default: undefined (no debouncing)
*/
register: function( source, target, event, handler, options ) {
var namespacedEvents = event.split( ' ' );
options = options || {};
for ( var i = 0; i < namespacedEvents.length; i++ ) {
var registration = this._getRegistration( target, namespacedEvents[i] );
if ( registration ) {
registration.sources.push( source );
} else {
this._attach( source, target, namespacedEvents[i], handler, options );
}
}
},
/**
* Unregisters one or multiple events attached to a target element and registered for a specific
* source.
*
* @param {*} source
* @param {HTMLElement|Object} target
* @param {string} event
* Instead of white-space separated list of event names, a single namespace may be passed
* to remove all events attached to target and registered on source.
*/
unregister: function( source, target, event ) {
var registrations = [],
i;
if ( event.indexOf( '.' ) === 0 ) {
registrations = this._getRegistrations( target, event.split( '.' )[1] );
} else {
var events = event.split( ' ' );
for ( i = 0; i < events.length; i++ ) {
var registration = this._getRegistration( target, events[i] );
if ( registration ) {
registrations.push( registration );
}
}
}
for ( i = 0; i < registrations.length; i++ ) {
var index = $.inArray( source, registrations[i].sources );
if ( index !== -1 ) {
registrations[i].sources.splice( index, 1 );
}
if ( !registrations[i].sources.length ) {
this._detach( registrations[i] );
}
}
},
/**
* @param {HTMLElement|Object} target
* @param {string} event
* @return {Object}
*/
_getRegistration: function( target, event ) {
var eventSegments = event.split( '.' );
for ( var i = 0; i < this._registry.length; i++ ) {
if ( this._registry[i].target === target
&& this._registry[i].event === eventSegments[0]
&& this._registry[i].namespace === eventSegments[1]
) {
return this._registry[i];
}
}
},
/**
* @param {HTMLElement|Object} target
* @param {string} namespace
* @return {Object[]}
*/
_getRegistrations: function( target, namespace ) {
var registered = [];
for ( var i = 0; i < this._registry.length; i++ ) {
if ( this._registry[i].target === target && this._registry[i].namespace === namespace ) {
registered.push( this._registry[i] );
}
}
return registered;
},
/**
* @param {*} source
* @param {HTMLElement|Object} target
* @param {string} event
* @param {Function} handler
* @param {Object} options
*/
_attach: function( source, target, event, handler, options ) {
var self = this,
eventSegments = event.split( '.' ),
actualHandler = function( actualEvent ) {
self._triggerHandler( target, event, actualEvent );
},
alteredHandler;
if ( options.throttle ) {
alteredHandler = $.throttle( options.throttle, actualHandler );
} else if ( options.debounce ) {
alteredHandler = $.debounce( options.debounce, actualHandler );
}
$( target ).on( event, alteredHandler || actualHandler );
this._registry.push( {
sources: [source],
target: target,
event: eventSegments[0],
namespace: eventSegments[1],
handler: handler
} );
},
/**
* @param {Object} registration
*/
_detach: function( registration ) {
var namespaced = registration.event;
if ( registration.namespace ) {
namespaced += '.' + registration.namespace;
}
$( registration.target ).off( namespaced );
for ( var i = 0; i < this._registry.length; i++ ) {
if ( this._registry[i].target === registration.target
&& this._registry[i].event === registration.event
&& this._registry[i].namespace === registration.namespace
) {
this._registry.splice( i, 1 );
}
}
},
/**
* @param {HTMLElement|Object} target
* @param {string} event
* @param {jQuery.Event} actualEvent
*/
_triggerHandler: function( target, event, actualEvent ) {
var registration = this._getRegistration( target, event );
if ( registration ) {
for ( var i = 0; i < registration.sources.length; i++ ) {
registration.handler( actualEvent, registration.sources[i] );
}
}
}
} );
} )( jQuery );