X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=resources%2Fsrc%2Fjquery%2Fjquery.confirmable.js;h=70c32b92b43a5b207c90afbd50c0d2a072c5aa8f;hb=9ded67d0da1e75fa3a23e915b498ddf7fd3a348b;hp=028b4b9184e5bdf88ec89202fdc5e9228d856a2e;hpb=1de7117197761961736ea43b237599569eee93a2;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/src/jquery/jquery.confirmable.js b/resources/src/jquery/jquery.confirmable.js index 028b4b9184..70c32b92b4 100644 --- a/resources/src/jquery/jquery.confirmable.js +++ b/resources/src/jquery/jquery.confirmable.js @@ -36,6 +36,7 @@ * the first parameter and 'yes' or 'no' as the second. * @param {Function} [options.handler] Callback to fire when the action is confirmed (user clicks * the 'Yes' button). + * @param {string} [options.delegate] Optional selector used for jQuery event delegation * @param {string} [options.i18n] Text to use for interface elements. * @param {string} [options.i18n.space] Word separator to place between the three text messages. * @param {string} [options.i18n.confirm] Text to use for the confirmation question. @@ -49,117 +50,128 @@ $.fn.confirmable = function ( options ) { options = $.extend( true, {}, $.fn.confirmable.defaultOptions, options || {} ); - return this.on( options.events, function ( e ) { - var $element, $text, $buttonYes, $buttonNo, $wrapper, $interface, $elementClone, - interfaceWidth, elementWidth, rtl, positionOffscreen, positionRestore, sideMargin; + if ( options.delegate === null ) { + return this.on( options.events, function ( e ) { + $.fn.confirmable.handler( e, options ); + } ); + } - $element = $( this ); + return this.on( options.events, options.delegate, function ( e ) { + $.fn.confirmable.handler( e, options ); + } ); + }; - if ( $element.data( 'jquery-confirmable-button' ) ) { - // We're running on a clone of this element that represents the 'Yes' or 'No' button. - // (This should never happen for the 'No' case unless calling code does bad things.) - return; - } + $.fn.confirmable.handler = function ( event, options ) { + var $element, $text, $buttonYes, $buttonNo, $wrapper, $interface, $elementClone, + interfaceWidth, elementWidth, rtl, positionOffscreen, positionRestore, sideMargin; - // Only prevent native event handling. Stopping other JavaScript event handlers - // is impossible because they might have already run (we have no control over the order). - e.preventDefault(); + $element = $( event.target ); - rtl = $element.css( 'direction' ) === 'rtl'; - if ( rtl ) { - positionOffscreen = { position: 'absolute', right: '-9999px' }; - positionRestore = { position: '', right: '' }; - sideMargin = 'marginRight'; - } else { - positionOffscreen = { position: 'absolute', left: '-9999px' }; - positionRestore = { position: '', left: '' }; - sideMargin = 'marginLeft'; - } + if ( $element.data( 'jquery-confirmable-button' ) ) { + // We're running on a clone of this element that represents the 'Yes' or 'No' button. + // (This should never happen for the 'No' case unless calling code does bad things.) + return; + } - if ( $element.hasClass( 'jquery-confirmable-element' ) ) { - $wrapper = $element.closest( '.jquery-confirmable-wrapper' ); - $interface = $wrapper.find( '.jquery-confirmable-interface' ); - $text = $interface.find( '.jquery-confirmable-text' ); - $buttonYes = $interface.find( '.jquery-confirmable-button-yes' ); - $buttonNo = $interface.find( '.jquery-confirmable-button-no' ); + // Only prevent native event handling. Stopping other JavaScript event handlers + // is impossible because they might have already run (we have no control over the order). + event.preventDefault(); + + rtl = $element.css( 'direction' ) === 'rtl'; + if ( rtl ) { + positionOffscreen = { position: 'absolute', right: '-9999px' }; + positionRestore = { position: '', right: '' }; + sideMargin = 'marginRight'; + } else { + positionOffscreen = { position: 'absolute', left: '-9999px' }; + positionRestore = { position: '', left: '' }; + sideMargin = 'marginLeft'; + } - interfaceWidth = $interface.data( 'jquery-confirmable-width' ); - elementWidth = $element.data( 'jquery-confirmable-width' ); + // eslint-disable-next-line no-jquery/no-class-state + if ( $element.hasClass( 'jquery-confirmable-element' ) ) { + $wrapper = $element.closest( '.jquery-confirmable-wrapper' ); + $interface = $wrapper.find( '.jquery-confirmable-interface' ); + $text = $interface.find( '.jquery-confirmable-text' ); + $buttonYes = $interface.find( '.jquery-confirmable-button-yes' ); + $buttonNo = $interface.find( '.jquery-confirmable-button-no' ); + + interfaceWidth = $interface.data( 'jquery-confirmable-width' ); + elementWidth = $element.data( 'jquery-confirmable-width' ); + } else { + $elementClone = $element.clone( true ); + $element.addClass( 'jquery-confirmable-element' ); + + elementWidth = $element.width(); + $element.data( 'jquery-confirmable-width', elementWidth ); + + $wrapper = $( '' ) + .addClass( 'jquery-confirmable-wrapper' ); + $element.wrap( $wrapper ); + + // Build the mini-dialog + $text = $( '' ) + .addClass( 'jquery-confirmable-text' ) + .text( options.i18n.confirm ); + + // Clone original element along with event handlers to easily replicate its behavior. + // We could fiddle with .trigger() etc., but that is troublesome especially since + // Safari doesn't implement .click() on links and jQuery follows suit. + $buttonYes = $elementClone.clone( true ) + .addClass( 'jquery-confirmable-button jquery-confirmable-button-yes' ) + .data( 'jquery-confirmable-button', true ) + .text( options.i18n.yes ); + if ( options.handler ) { + $buttonYes.on( options.events, options.handler ); + } + if ( options.i18n.yesTitle ) { + $buttonYes.attr( 'title', options.i18n.yesTitle ); + } + $buttonYes = options.buttonCallback( $buttonYes, 'yes' ); + + // Clone it without any events and prevent default action to represent the 'No' button. + $buttonNo = $elementClone.clone( false ) + .addClass( 'jquery-confirmable-button jquery-confirmable-button-no' ) + .data( 'jquery-confirmable-button', true ) + .text( options.i18n.no ) + .on( options.events, function ( e ) { + $element.css( sideMargin, 0 ); + $interface.css( 'width', 0 ); + e.preventDefault(); + } ); + if ( options.i18n.noTitle ) { + $buttonNo.attr( 'title', options.i18n.noTitle ); } else { - $elementClone = $element.clone( true ); - $element.addClass( 'jquery-confirmable-element' ); - - elementWidth = $element.width(); - $element.data( 'jquery-confirmable-width', elementWidth ); - - $wrapper = $( '' ) - .addClass( 'jquery-confirmable-wrapper' ); - $element.wrap( $wrapper ); - - // Build the mini-dialog - $text = $( '' ) - .addClass( 'jquery-confirmable-text' ) - .text( options.i18n.confirm ); - - // Clone original element along with event handlers to easily replicate its behavior. - // We could fiddle with .trigger() etc., but that is troublesome especially since - // Safari doesn't implement .click() on links and jQuery follows suit. - $buttonYes = $elementClone.clone( true ) - .addClass( 'jquery-confirmable-button jquery-confirmable-button-yes' ) - .data( 'jquery-confirmable-button', true ) - .text( options.i18n.yes ); - if ( options.handler ) { - $buttonYes.on( options.events, options.handler ); - } - if ( options.i18n.yesTitle ) { - $buttonYes.attr( 'title', options.i18n.yesTitle ); - } - $buttonYes = options.buttonCallback( $buttonYes, 'yes' ); - - // Clone it without any events and prevent default action to represent the 'No' button. - $buttonNo = $elementClone.clone( false ) - .addClass( 'jquery-confirmable-button jquery-confirmable-button-no' ) - .data( 'jquery-confirmable-button', true ) - .text( options.i18n.no ) - .on( options.events, function ( e ) { - $element.css( sideMargin, 0 ); - $interface.css( 'width', 0 ); - e.preventDefault(); - } ); - if ( options.i18n.noTitle ) { - $buttonNo.attr( 'title', options.i18n.noTitle ); - } else { - $buttonNo.removeAttr( 'title' ); - } - $buttonNo = options.buttonCallback( $buttonNo, 'no' ); - - // Prevent memory leaks - $elementClone.remove(); - - $interface = $( '' ) - .addClass( 'jquery-confirmable-interface' ) - .append( $text, options.i18n.space, $buttonYes, options.i18n.space, $buttonNo ); - $interface = options.wrapperCallback( $interface ); - - // Render offscreen to measure real width - $interface.css( positionOffscreen ); - // Insert it in the correct place while we're at it - $element.after( $interface ); - interfaceWidth = $interface.width(); - $interface.data( 'jquery-confirmable-width', interfaceWidth ); - $interface.css( positionRestore ); - - // Hide to animate the transition later - $interface.css( 'width', 0 ); + $buttonNo.removeAttr( 'title' ); } + $buttonNo = options.buttonCallback( $buttonNo, 'no' ); + + // Prevent memory leaks + $elementClone.remove(); + + $interface = $( '' ) + .addClass( 'jquery-confirmable-interface' ) + .append( $text, options.i18n.space, $buttonYes, options.i18n.space, $buttonNo ); + $interface = options.wrapperCallback( $interface ); + + // Render offscreen to measure real width + $interface.css( positionOffscreen ); + // Insert it in the correct place while we're at it + $element.after( $interface ); + interfaceWidth = $interface.width(); + $interface.data( 'jquery-confirmable-width', interfaceWidth ); + $interface.css( positionRestore ); + + // Hide to animate the transition later + $interface.css( 'width', 0 ); + } - // Hide element, show interface. This triggers both transitions. - // In a timeout to trigger the 'width' transition. - setTimeout( function () { - $element.css( sideMargin, -elementWidth ); - $interface.css( 'width', interfaceWidth ); - }, 1 ); - } ); + // Hide element, show interface. This triggers both transitions. + // In a timeout to trigger the 'width' transition. + setTimeout( function () { + $element.css( sideMargin, -elementWidth ); + $interface.css( 'width', interfaceWidth ); + }, 1 ); }; /** @@ -171,6 +183,7 @@ wrapperCallback: identity, buttonCallback: identity, handler: null, + delegate: null, i18n: { space: ' ', confirm: 'Are you sure?',