Problem was per CR comment https://www.mediawiki.org/wiki/Special:Code/MediaWiki/104671#c26836 -- parameter count check changed in upstream jquery.bind(), causing the way we passed params to break if the optional 'data' parameter was left out. Added QUnit test cases for jquery.delayedBind() with and without the optional 'data' parameter. Undoes r104671 since the issue it was working around is fixed.
73 lines
No EOL
2.3 KiB
JavaScript
73 lines
No EOL
2.3 KiB
JavaScript
(function( $ ) {
|
|
/**
|
|
* Function that escapes spaces in event names. This is needed because
|
|
* "_delayedBind-foo bar-1000" refers to two events
|
|
*/
|
|
function encodeEvent( event ) {
|
|
return event.replace( /-/g, '--' ).replace( / /g, '-' );
|
|
}
|
|
|
|
$.fn.extend( {
|
|
/**
|
|
* Bind a callback to an event in a delayed fashion.
|
|
* In detail, this means that the callback will be called a certain
|
|
* time after the event fires, but the timer is reset every time
|
|
* the event fires.
|
|
* @param timeout Number of milliseconds to wait
|
|
* @param event Name of the event (string)
|
|
* @param data Data to pass to the event handler (optional)
|
|
* @param callback Function to call
|
|
*/
|
|
delayedBind: function( timeout, event, data, callback ) {
|
|
if ( arguments.length == 3 ) {
|
|
// Shift optional parameter down
|
|
callback = data;
|
|
data = undefined;
|
|
}
|
|
var encEvent = encodeEvent( event );
|
|
return this.each( function() {
|
|
var that = this;
|
|
// Bind the top half
|
|
// Do this only once for every (event, timeout) pair
|
|
if ( !( $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout ) ) ) {
|
|
$(this).data( '_delayedBindBound-' + encEvent + '-' + timeout, true );
|
|
$(this).bind( event, function() {
|
|
var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
|
|
// Cancel the running timer
|
|
if ( typeof timerID != 'undefined' )
|
|
clearTimeout( timerID );
|
|
timerID = setTimeout( function() {
|
|
$(that).trigger( '_delayedBind-' + encEvent + '-' + timeout );
|
|
}, timeout );
|
|
$(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout, timerID );
|
|
} );
|
|
}
|
|
|
|
// Bottom half
|
|
$(this).bind( '_delayedBind-' + encEvent + '-' + timeout, data, callback );
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Cancel the timers for delayed events on the selected elements.
|
|
*/
|
|
delayedBindCancel: function( timeout, event ) {
|
|
var encEvent = encodeEvent( event );
|
|
return this.each( function() {
|
|
var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
|
|
if ( typeof timerID != 'undefined' )
|
|
clearTimeout( timerID );
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Unbind an event bound with delayedBind()
|
|
*/
|
|
delayedBindUnbind: function( timeout, event, callback ) {
|
|
var encEvent = encodeEvent( event );
|
|
return this.each( function() {
|
|
$(this).unbind( '_delayedBind-' + encEvent + '-' + timeout, callback );
|
|
} );
|
|
}
|
|
} );
|
|
} )( jQuery ); |