MediaWiki:Gadget-newCollapsible.js

De Wikidébats
Aller à : navigation, rechercher

Note : après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : Maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ou Ctrl-R (⌘-R sur un Mac) ;
  • Google Chrome : Appuyez sur Ctrl-Maj-R (⌘-Shift-R sur un Mac) ;
  • Internet Explorer : Maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ;
  • Opera : Allez dans Menu → Settings (Opera → Préférences sur un Mac) et ensuite à Confidentialité & sécurité → Effacer les données d'exploration → Images et fichiers en cache.
/**
 * fork de jQuery makeCollapsible 
 * 
 * script initial : http://www.mediawiki.org/wiki/RL/DM#jQuery.makeCollapsible
 * auteur initial : Krinkle <[email protected]>
 *
 * modifications : http://fr.wikipedia.org/wiki/Utilisateur:Lgd
 *
 * Dual license:
 * @license CC-BY 3.0 <http://creativecommons.org/licenses/by/3.0>
 * @license GPL2 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
 */

function newCollapsible( $content ) {

	return $content.find('.fr-collapsible').each(function() {
		// Define reused variables and functions
		var	$that = $(this),
			that = this,
			collapsetext = $(this).attr( 'data-collapsetext' ),
			expandtext = $(this).attr( 'data-expandtext' ),
			toggleElement = function( $collapsible, action, $defaultToggle, instantHide ) {
				// Validate parameters
				if ( !$collapsible.jquery ) { // $collapsible must be an instance of jQuery
					return;
				}
				if ( action != 'expand' && action != 'collapse' ) {
					// action must be string with 'expand' or 'collapse'
					return;
				}
				if ( typeof $defaultToggle == 'undefined' ) {
					$defaultToggle = null;
				}
				if ( $defaultToggle !== null && !($defaultToggle instanceof $) ) {
					// is optional (may be undefined), but if defined it must be an instance of jQuery.
					// If it's not, abort right away.
					// After this $defaultToggle is either null or a valid jQuery instance.
					return;
				}

				var $containers = null;

				if ( action == 'collapse' ) {

					// Collapse the element
					if ( $collapsible.is( 'table' ) &&  $collapsible.find('caption').length ) { // only table with caption
						// Hide all table rows of this table
						// Slide doens't work with tables, but fade does as of jQuery 1.1.3
						// http://stackoverflow.com/questions/467336#920480
						$containers = $collapsible.find( '>tbody>tr, >thead>tr' );
						if ( $defaultToggle ) {
							$containers.stop(true, true).fadeOut();
						} else {
							if ( instantHide ) {
								$containers.hide();
							} else {
								$containers.stop( true, true ).fadeOut();
							}
						}

					} else if ( !$collapsible.is( 'ul' ) && !$collapsible.is( 'ol' )  && !$that.is( 'table' ) ) { // <div>, <p> etc. but not ul ol and tables without caption
						var $collapsibleContent = $collapsible.find( '> .fr-collapsible-content' );

						// If a collapsible-content is defined, collapse it
						if ( $collapsibleContent.length ) {
							if ( instantHide ) {
								$collapsibleContent.hide();
							} else {
								$collapsibleContent.slideUp();
							}

						// Otherwise assume this is a customcollapse with a remote toggle
						// .. and there is no collapsible-content because the entire element should be toggled
						} else {
							if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
								$collapsible.fadeOut();
							} else {
								$collapsible.slideUp();
							}
						}
					}

				} else {

					// Expand the element
					if ( $collapsible.is( 'table' ) &&  $collapsible.find('caption').length ) {
						$containers = $collapsible.find( '>tbody>tr, >thead>tr' );
						if ( $defaultToggle ) {
							$containers.stop(true, true).fadeIn();
						} else {
							$containers.stop(true, true).fadeIn();
						}

					} else if ( !$collapsible.is( 'ul' ) && !$collapsible.is( 'ol' )  && !$that.is( 'table' ) ) { // <div>, <p> etc.but not ul ol and not tables without caption
						var $collapsibleContent = $collapsible.find( '> .fr-collapsible-content' );

						// If a collapsible-content is defined, collapse it
						if ( $collapsibleContent.length ) {
							$collapsibleContent.slideDown();

						// Otherwise assume this is a customcollapse with a remote toggle
						// .. and there is no collapsible-content because the entire element should be toggled
						} else {
							if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
								$collapsible.fadeIn();
							} else {
								$collapsible.slideDown();
							}
						}
					}
				}
			},
			// Toggles collapsible and togglelink class and updates text label
			toggleLinkDefault = function( that, e ) {
				var	$that = $(that),
					$collapsible = $that.closest( '.fr-collapsible.fr-made-collapsible' ).toggleClass( 'fr-collapsed' );
				e.preventDefault();
				e.stopPropagation();

				// It's expanded right now
				if ( !$that.hasClass( 'fr-collapsible-toggle-collapsed' ) ) {
					// Change link to "Show"
					$that.removeClass( 'fr-collapsible-toggle-expanded' ).addClass( 'fr-collapsible-toggle-collapsed' );
					if ( $that.find( '> a' ).length ) {
						$that.find( '> a' ).text( expandtext );
					} else {
						$that.text( expandtext );
					}
					// Collapse element
					toggleElement( $collapsible, 'collapse', $that );

				// It's collapsed right now
				} else {
					// Change link to "Hide"
					$that.removeClass( 'fr-collapsible-toggle-collapsed' ).addClass( 'fr-collapsible-toggle-expanded' );
					if ( $that.find( '> a' ).length ) {
						$that.find( '> a' ).text( collapsetext );
					} else {
						$that.text( collapsetext );
					}
					// Expand element
					toggleElement( $collapsible, 'expand', $that );
				}
				return;
			},
			// Toggles collapsible and togglelink class
			toggleLinkPremade = function( $that, e ) {
				var	$collapsible = $that.eq(0).closest( '.fr-collapsible.fr-made-collapsible' ).toggleClass( 'fr-collapsed' );
				if ( $(e.target).is('a') ) {
					return true;
				}
				e.preventDefault();
				e.stopPropagation();

				// It's expanded right now
				if ( !$that.hasClass( 'fr-collapsible-toggle-collapsed' ) ) {
					// Change toggle to collapsed
					$that.removeClass( 'fr-collapsible-toggle-expanded' ).addClass( 'fr-collapsible-toggle-collapsed' );
					// Collapse element
					toggleElement( $collapsible, 'collapse', $that );

				// It's collapsed right now
				} else {
					// Change toggle to expanded
					$that.removeClass( 'fr-collapsible-toggle-collapsed' ).addClass( 'fr-collapsible-toggle-expanded' );
					// Expand element
					toggleElement( $collapsible, 'expand', $that );
				}
				return;
			},
			// Toggles customcollapsible
			toggleLinkCustom = function( $that, e, $collapsible ) {
				// For the initial state call of customtogglers there is no event passed
				if (e) {
					e.preventDefault();
				e.stopPropagation();
				}
				// Get current state and toggle to the opposite
				var action = $collapsible.hasClass( 'fr-collapsed' ) ? 'expand' : 'collapse';
				$collapsible.toggleClass( 'fr-collapsed' );
				toggleElement( $collapsible, action, $that );

			};

		// Use custom text or default ?
		if( !collapsetext ) {
			//collapsetext = mw.message( 'collapsible-collapse' );
			collapsetext = 'masquer';
		}
		if ( !expandtext ) {
			//expandtext = mw.message( 'collapsible-expand' );
			expandtext = 'afficher';
		}

		// Create toggle link with a space around the brackets (&nbsp;[text]&nbsp;)
		var $toggleLink =
			$( '<a href="#"></a>' )
				.text( collapsetext )
				.wrap( '<span class="fr-collapsible-toggle"></span>' )
				.parent()
				.bind( 'click.fr-collapse', function(e) {
					toggleLinkDefault( this, e );
				} );

		// Return if it has been enabled already.
		if ( $that.hasClass( 'fr-made-collapsible' ) ) {
			return;
		} else {
			$that.addClass( 'fr-made-collapsible' );
		}

		// Check if this element has a custom position for the toggle link
		// (ie. outside the container or deeper inside the tree)
		// Then: Locate the custom toggle link(s) and bind them
		if ( ( $that.attr( 'id' ) || '' ).indexOf( 'fr-customcollapsible-' ) === 0 ) {

			var thatId = $that.attr( 'id' ),
				$customTogglers = $content.find( '.' + thatId.replace( 'fr-customcollapsible', 'fr-customtoggle' ) );

			// Double check that there is actually a customtoggle link
			if ( $customTogglers.length ) {
				$customTogglers.bind( 'click.fr-collapse', function( e ) {
					toggleLinkCustom( $(this), e, $that );
				} );
			}

			// Initial state
			if ( $that.hasClass( 'fr-collapsed' ) ) {
				$that.removeClass( 'fr-collapsed' );
				toggleLinkCustom( $customTogglers, null, $that );
			}

		// If this is not a custom case, do the default:
		// Wrap the contents add the toggle link
		} else {

			// Elements are treated differently
			if ( $that.is( 'table' )  &&  $that.find('caption').length ) { // only table with caption
				// The toggle-link will be in the caption
				var	$caption = $that.find( 'caption' ),
					$toggle = $caption.find( '> .fr-collapsible-toggle' );

				// If theres no toggle link, add it to the caption
				if ( !$toggle.length ) {
					$caption.eq(-1).prepend( $toggleLink );
				} else {
					$toggleLink = $toggle.unbind( 'click.fr-collapse' ).bind( 'click.fr-collapse', function( e ) {
						toggleLinkPremade( $toggle, e );
					} );
				}

			} else if ( !$that.is( 'ul' ) && !$that.is( 'ol' )  && !$that.is( 'table' ) ) { // <div>, <p> etc.but not ol ul and not tables without caption

				// The toggle-link will be the first child of the element
				var $toggle = $that.find( '> .fr-collapsible-toggle' );

				// If a direct child .content-wrapper does not exists, create it
				if ( !$that.find( '> .fr-collapsible-content' ).length ) {
					$that.wrapInner( '<div class="fr-collapsible-content"></div>' );
				}

				// If theres no toggle link, add it
				if ( !$toggle.length ) {
					$that.prepend( $toggleLink );
				} else {
					$toggleLink = $toggle.unbind( 'click.fr-collapse' ).bind( 'click.fr-collapse', function( e ) {
						toggleLinkPremade( $toggle, e );
					} );
				}
			}
		}

		// Initial state (only for those that are not custom)
		if ( $that.hasClass( 'fr-collapsed' ) && ( $that.attr( 'id' ) || '').indexOf( 'fr-customcollapsible-' ) !== 0 ) {
			$that.removeClass( 'fr-collapsed' );
			// The collapsible element could have multiple togglers
			// To toggle the initial state only click one of them (ie. the first one, eq(0) )
			// Else it would go like: hide,show,hide,show for each toggle link.
			toggleElement( $that, 'collapse', $toggleLink.eq(0), /* instantHide = */ true );
			$toggleLink.eq(0).click();
		}
	} );
};

function newCollapsibleKeyboard($content) {
	$content.find('.fr-collapsible-toggle, .fr-collapsible-toggle-keyboard').attr('tabindex',0).keypress(function(event){
		if ( event.which == 13 ) {
			$(this).click()
		}
	});
};

function newCollapsibleGroup($content) {
	$content.find('.fr-collapsible-group').each(function(){
		var $that = $(this);
		var text = 'Tout ouvrir';
		var $tooglelink = $('<a class="fr-collapsible-toggle fr-collapsible-toggle-collapsed fr-collapsible-group-toogle-all" href="#">Tout ouvrir</a>');
		$that.find('.fr-collapsible-group-toogle:first').append($tooglelink).click(function(event){
			if(text == 'Tout ouvrir') {
				text = 'Tout fermer';
				$that.find('.fr-collapsible-toggle-collapsed:not(".fr-collapsible-group-toogle-all")').click();
			} else {
				text = 'Tout ouvrir';
				$that.find('.fr-collapsible-toggle-expanded:not(".fr-collapsible-group-toogle-all")').click();
			}
			$tooglelink.text(text);
			return false;
		});
	});
};

mw.hook( 'wikipage.content' ).add( [
	newCollapsible,
	newCollapsibleKeyboard,
	newCollapsibleGroup
] );