wiki.techinc.nl/resources/jquery/jquery.collapsibleTabs.js
Brion Vibber b36d8ace6d Followup r104671: fix regression in jquery.delayedBind() due to change in param processing for jquery's bind()
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.
2011-12-02 21:47:46 +00:00

117 lines
4.3 KiB
JavaScript

/*
* Collapsible tabs jQuery Plugin
*/
( function( $ ) {
$.fn.collapsibleTabs = function( options ) {
// return if the function is called on an empty jquery object
if( !this.length ) return this;
//merge options into the defaults
var $settings = $.extend( {}, $.collapsibleTabs.defaults, options );
this.each( function() {
var $this = $( this );
// add the element to our array of collapsible managers
$.collapsibleTabs.instances = ( $.collapsibleTabs.instances.length == 0 ?
$this : $.collapsibleTabs.instances.add( $this ) );
// attach the settings to the elements
$this.data( 'collapsibleTabsSettings', $settings );
// attach data to our collapsible elements
$this.children( $settings.collapsible ).each( function() {
$.collapsibleTabs.addData( $( this ) );
} );
} );
// if we haven't already bound our resize hanlder, bind it now
if( !$.collapsibleTabs.boundEvent ) {
$( window )
.delayedBind( '500', 'resize', function( ) { $.collapsibleTabs.handleResize(); } );
}
// call our resize handler to setup the page
$.collapsibleTabs.handleResize();
return this;
};
$.collapsibleTabs = {
instances: [],
boundEvent: null,
defaults: {
expandedContainer: '#p-views ul',
collapsedContainer: '#p-cactions ul',
collapsible: 'li.collapsible',
shifting: false,
expandCondition: function( eleWidth ) {
return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() )
< ( $( '#right-navigation' ).position().left - eleWidth );
},
collapseCondition: function() {
return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() )
> $( '#right-navigation' ).position().left;
}
},
addData: function( $collapsible ) {
var $settings = $collapsible.parent().data( 'collapsibleTabsSettings' );
if ( $settings != null ) {
$collapsible.data( 'collapsibleTabsSettings', {
'expandedContainer': $settings.expandedContainer,
'collapsedContainer': $settings.collapsedContainer,
'expandedWidth': $collapsible.width(),
'prevElement': $collapsible.prev()
} );
}
},
getSettings: function( $collapsible ) {
var $settings = $collapsible.data( 'collapsibleTabsSettings' );
if ( typeof $settings == 'undefined' ) {
$.collapsibleTabs.addData( $collapsible );
$settings = $collapsible.data( 'collapsibleTabsSettings' );
}
return $settings;
},
handleResize: function( e ){
$.collapsibleTabs.instances.each( function() {
var $this = $( this ), data = $.collapsibleTabs.getSettings( $this );
if( data.shifting ) return;
// if the two navigations are colliding
if( $this.children( data.collapsible ).length > 0 && data.collapseCondition() ) {
$this.trigger( "beforeTabCollapse" );
// move the element to the dropdown menu
$.collapsibleTabs.moveToCollapsed( $this.children( data.collapsible + ':last' ) );
}
// if there are still moveable items in the dropdown menu,
// and there is sufficient space to place them in the tab container
if( $( data.collapsedContainer + ' ' + data.collapsible ).length > 0
&& data.expandCondition( $.collapsibleTabs.getSettings( $( data.collapsedContainer ).children(
data.collapsible+":first" ) ).expandedWidth ) ) {
//move the element from the dropdown to the tab
$this.trigger( "beforeTabExpand" );
$.collapsibleTabs
.moveToExpanded( data.collapsedContainer + " " + data.collapsible + ':first' );
}
});
},
moveToCollapsed: function( ele ) {
var $moving = $( ele );
var data = $.collapsibleTabs.getSettings( $moving );
var dataExp = $.collapsibleTabs.getSettings( data.expandedContainer );
dataExp.shifting = true;
$moving
.detach()
.prependTo( data.collapsedContainer )
.data( 'collapsibleTabsSettings', data );
dataExp.shifting = false;
$.collapsibleTabs.handleResize();
},
moveToExpanded: function( ele ) {
var $moving = $( ele );
var data = $.collapsibleTabs.getSettings( $moving );
var dataExp = $.collapsibleTabs.getSettings( data.expandedContainer );
dataExp.shifting = true;
// remove this element from where it's at and put it in the dropdown menu
$moving.detach().insertAfter( data.prevElement ).data( 'collapsibleTabsSettings', data );
dataExp.shifting = false;
$.collapsibleTabs.handleResize();
}
};
} )( jQuery );