[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 /** 2 * jQuery confirmable plugin 3 * 4 * Released under the MIT License. 5 * 6 * @author Bartosz Dziewoński 7 * 8 * @class jQuery.plugin.confirmable 9 */ 10 ( function ( $ ) { 11 var identity = function ( data ) { 12 return data; 13 }; 14 15 /** 16 * Enable inline confirmation for given clickable element (like `<a />` or `<button />`). 17 * 18 * An additional inline confirmation step being shown before the default action is carried out on 19 * click. 20 * 21 * Calling `.confirmable( { handler: function () { … } } )` will fire the handler only after the 22 * confirmation step. 23 * 24 * The element will have the `jquery-confirmable-element` class added to it when it's clicked for 25 * the first time, which has `white-space: nowrap;` and `display: inline-block;` defined in CSS. 26 * If the computed values for the element are different when you make it confirmable, you might 27 * encounter unexpected behavior. 28 * 29 * @param {Object} [options] 30 * @param {string} [options.events='click'] Events to hook to. 31 * @param {Function} [options.wrapperCallback] Callback to fire when preparing confirmable 32 * interface. Receives the interface jQuery object as the only parameter. 33 * @param {Function} [options.buttonCallback] Callback to fire when preparing confirmable buttons. 34 * It is fired separately for the 'Yes' and 'No' button. Receives the button jQuery object as 35 * the first parameter and 'yes' or 'no' as the second. 36 * @param {Function} [options.handler] Callback to fire when the action is confirmed (user clicks 37 * the 'Yes' button). 38 * @param {string} [options.i18n] Text to use for interface elements. 39 * @param {string} [options.i18n.space] Word separator to place between the three text messages. 40 * @param {string} [options.i18n.confirm] Text to use for the confirmation question. 41 * @param {string} [options.i18n.yes] Text to use for the 'Yes' button. 42 * @param {string} [options.i18n.no] Text to use for the 'No' button. 43 * 44 * @chainable 45 */ 46 $.fn.confirmable = function ( options ) { 47 options = $.extend( true, {}, $.fn.confirmable.defaultOptions, options || {} ); 48 49 return this.on( options.events, function ( e ) { 50 var $element, $text, $buttonYes, $buttonNo, $wrapper, $interface, $elementClone, 51 interfaceWidth, elementWidth, rtl, positionOffscreen, positionRestore, sideMargin; 52 53 $element = $( this ); 54 55 if ( $element.data( 'jquery-confirmable-button' ) ) { 56 // We're running on a clone of this element that represents the 'Yes' or 'No' button. 57 // (This should never happen for the 'No' case unless calling code does bad things.) 58 return; 59 } 60 61 // Only prevent native event handling. Stopping other JavaScript event handlers 62 // is impossible because they might have already run (we have no control over the order). 63 e.preventDefault(); 64 65 rtl = $element.css( 'direction' ) === 'rtl'; 66 if ( rtl ) { 67 positionOffscreen = { position: 'absolute', right: '-9999px' }; 68 positionRestore = { position: '', right: '' }; 69 sideMargin = 'marginRight'; 70 } else { 71 positionOffscreen = { position: 'absolute', left: '-9999px' }; 72 positionRestore = { position: '', left: '' }; 73 sideMargin = 'marginLeft'; 74 } 75 76 if ( $element.hasClass( 'jquery-confirmable-element' ) ) { 77 $wrapper = $element.closest( '.jquery-confirmable-wrapper' ); 78 $interface = $wrapper.find( '.jquery-confirmable-interface' ); 79 $text = $interface.find( '.jquery-confirmable-text' ); 80 $buttonYes = $interface.find( '.jquery-confirmable-button-yes' ); 81 $buttonNo = $interface.find( '.jquery-confirmable-button-no' ); 82 83 interfaceWidth = $interface.data( 'jquery-confirmable-width' ); 84 elementWidth = $element.data( 'jquery-confirmable-width' ); 85 } else { 86 $elementClone = $element.clone( true ); 87 $element.addClass( 'jquery-confirmable-element' ); 88 89 elementWidth = $element.width(); 90 $element.data( 'jquery-confirmable-width', elementWidth ); 91 92 $wrapper = $( '<span>' ) 93 .addClass( 'jquery-confirmable-wrapper' ); 94 $element.wrap( $wrapper ); 95 96 // Build the mini-dialog 97 $text = $( '<span>' ) 98 .addClass( 'jquery-confirmable-text' ) 99 .text( options.i18n.confirm ); 100 101 // Clone original element along with event handlers to easily replicate its behavior. 102 // We could fiddle with .trigger() etc., but that is troublesome especially since 103 // Safari doesn't implement .click() on <a> links and jQuery follows suit. 104 $buttonYes = $elementClone.clone( true ) 105 .addClass( 'jquery-confirmable-button jquery-confirmable-button-yes' ) 106 .data( 'jquery-confirmable-button', true ) 107 .text( options.i18n.yes ); 108 if ( options.handler ) { 109 $buttonYes.on( options.events, options.handler ); 110 } 111 $buttonYes = options.buttonCallback( $buttonYes, 'yes' ); 112 113 // Clone it without any events and prevent default action to represent the 'No' button. 114 $buttonNo = $elementClone.clone( false ) 115 .addClass( 'jquery-confirmable-button jquery-confirmable-button-no' ) 116 .data( 'jquery-confirmable-button', true ) 117 .text( options.i18n.no ) 118 .on( options.events, function ( e ) { 119 $element.css( sideMargin, 0 ); 120 $interface.css( 'width', 0 ); 121 e.preventDefault(); 122 } ); 123 $buttonNo = options.buttonCallback( $buttonNo, 'no' ); 124 125 // Prevent memory leaks 126 $elementClone.remove(); 127 128 $interface = $( '<span>' ) 129 .addClass( 'jquery-confirmable-interface' ) 130 .append( $text, options.i18n.space, $buttonYes, options.i18n.space, $buttonNo ); 131 $interface = options.wrapperCallback( $interface ); 132 133 // Render offscreen to measure real width 134 $interface.css( positionOffscreen ); 135 // Insert it in the correct place while we're at it 136 $element.after( $interface ); 137 interfaceWidth = $interface.width(); 138 $interface.data( 'jquery-confirmable-width', interfaceWidth ); 139 $interface.css( positionRestore ); 140 141 // Hide to animate the transition later 142 $interface.css( 'width', 0 ); 143 } 144 145 // Hide element, show interface. This triggers both transitions. 146 // In a timeout to trigger the 'width' transition. 147 setTimeout( function () { 148 $element.css( sideMargin, -elementWidth ); 149 $interface.css( 'width', interfaceWidth ); 150 }, 1 ); 151 } ); 152 }; 153 154 /** 155 * Default options. Overridable primarily for internationalisation handling. 156 * @property {Object} defaultOptions 157 */ 158 $.fn.confirmable.defaultOptions = { 159 events: 'click', 160 wrapperCallback: identity, 161 buttonCallback: identity, 162 handler: null, 163 i18n: { 164 space: ' ', 165 confirm: 'Are you sure?', 166 yes: 'Yes', 167 no: 'No' 168 } 169 }; 170 }( jQuery ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |