/*!
- * OOjs UI v0.17.6
+ * OOjs UI v0.17.7
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-07-12T20:26:03Z
+ * Date: 2016-08-03T16:38:22Z
*/
( function ( OO ) {
* @param {jQuery.Event} e
*/
OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {
- var $options, checked,
+ var $options, lastClickedIndex, nowClickedIndex, i, direction, wasSelected, items,
$lastClicked = this.$lastClicked,
$nowClicked = $( e.target ).closest( '.oo-ui-checkboxMultioptionWidget' )
.not( '.oo-ui-widget-disabled' );
// Allow selecting multiple options at once by Shift-clicking them
if ( $lastClicked && $nowClicked.length && e.shiftKey ) {
$options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' );
- checked = $nowClicked.find( 'input' ).prop( 'checked' );
-
- $options
- .slice(
- Math.min( $options.index( $lastClicked ), $options.index( $nowClicked ) ),
- Math.max( $options.index( $lastClicked ), $options.index( $nowClicked ) ) + 1
- )
- .find( 'input' )
- .filter( function () {
- return !this.disabled;
- } )
- .prop( 'checked', checked )
- .trigger( 'change' );
+ lastClickedIndex = $options.index( $lastClicked );
+ nowClickedIndex = $options.index( $nowClicked );
+ // If it's the same item, either the user is being silly, or it's a fake event generated by the
+ // browser. In either case we don't need custom handling.
+ if ( nowClickedIndex !== lastClickedIndex ) {
+ items = this.items;
+ wasSelected = items[ nowClickedIndex ].isSelected();
+ direction = nowClickedIndex > lastClickedIndex ? 1 : -1;
+
+ // This depends on the DOM order of the items and the order of the .items array being the same.
+ for ( i = lastClickedIndex; i !== nowClickedIndex; i += direction ) {
+ if ( !items[ i ].isDisabled() ) {
+ items[ i ].setSelected( !wasSelected );
+ }
+ }
+ // For the now-clicked element, use immediate timeout to allow the browser to do its own
+ // handling first, then set our value. The order in which events happen is different for
+ // clicks on the <input> and on the <label> and there are additional fake clicks fired for
+ // non-click actions that change the checkboxes.
+ e.preventDefault();
+ setTimeout( function () {
+ if ( !items[ nowClickedIndex ].isDisabled() ) {
+ items[ nowClickedIndex ].setSelected( !wasSelected );
+ }
+ } );
+ }
}
if ( $nowClicked.length ) {