jquery.makeCollapsible: add a few explicit options to the jQuery plugin
authorMatmaRex <matma.rex@gmail.com>
Fri, 15 Mar 2013 10:25:03 +0000 (11:25 +0100)
committerMatmaRex <matma.rex@gmail.com>
Sat, 16 Mar 2013 00:05:41 +0000 (01:05 +0100)
Add a few options to the jQuery plugin to allow for explicit passing
of various options in addition to the conventions used now (via data-
attributes or magic id/class combinations).

Change-Id: Ic498e7a3b2d2e964bda8d31a70f71cda08560cec

resources/jquery/jquery.makeCollapsible.js

index def1dc4..def2c60 100644 (file)
@@ -15,6 +15,8 @@
  * @license GPL2 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
  */
 ( function ( $, mw ) {
+       var lpx = 'jquery.makeCollapsible> ';
+
        /**
         * @param {jQuery} $collapsible
         * @param {string} action The action this function will take ('expand' or 'collapse').
                togglingHandler( $that, $collapsible, e, options );
        }
 
-       $.fn.makeCollapsible = function () {
+       /**
+        * Make any element collapsible.
+        *
+        * Supported options:
+        * - collapseText: text to be used for the toggler when clicking it would
+        *   collapse the element. Default: the 'data-collapsetext' attribute of
+        *   the collapsible element or the content of 'collapsible-collapse'
+        *   message.
+        * - expandText: text to be used for the toggler when clicking it would
+        *   expand the element. Default: the 'data-expandtext' attribute of
+        *   the collapsible element or the content of 'collapsible-expand'
+        *   message.
+        * - collapsed: boolean, whether to collapse immediately. By default
+        *   collapse only if the elements has the 'mw-collapsible' class.
+        * - $customTogglers: jQuerified list of elements to be used as togglers
+        *   for this collapsible element. By default, if the collapsible element
+        *   has an id attribute like 'mw-customcollapsible-XXX', elements with a
+        *   *class* of 'mw-customtoggle-XXX' are made togglers for it.
+        */
+       $.fn.makeCollapsible = function ( options ) {
                return this.each(function () {
-                       // Define reused variables and functions
-                       var lpx = 'jquery.makeCollapsible> ',
-                               collapsible = this,
-                               // Ensure class "mw-collapsible" is present in case .makeCollapsible()
-                               // is called on element(s) that don't have it yet.
-                               $collapsible = $(collapsible).addClass( 'mw-collapsible' ),
-                               collapsetext = $collapsible.attr( 'data-collapsetext' ),
-                               expandtext = $collapsible.attr( 'data-expandtext' ),
-                               $toggle,
-                               $toggleLink,
-                               $firstItem,
-                               collapsibleId,
-                               $customTogglers,
-                               firstval;
+                       var $collapsible, collapsetext, expandtext, $toggle, $toggleLink, $firstItem, collapsibleId,
+                               $customTogglers, firstval;
+
+                       // Ensure class "mw-collapsible" is present in case .makeCollapsible()
+                       // is called on element(s) that don't have it yet.
+                       $collapsible = $(this).addClass( 'mw-collapsible' );
 
                        // Return if it has been enabled already.
                        if ( $collapsible.data( 'mw-made-collapsible' ) ) {
                                $collapsible.data( 'mw-made-collapsible', true );
                        }
 
-                       // Use custom text or default ?
-                       if ( !collapsetext ) {
-                               collapsetext = mw.msg( 'collapsible-collapse' );
-                       }
-                       if ( !expandtext ) {
-                               expandtext = mw.msg( 'collapsible-expand' );
-                       }
+                       // Use custom text or default?
+                       collapsetext = options.collapsetext || $collapsible.attr( 'data-collapsetext' ) || mw.msg( 'collapsible-collapse' );
+                       expandtext = options.expandText || $collapsible.attr( 'data-expandtext' ) || mw.msg( 'collapsible-expand' );
 
                        // Create toggle link with a space around the brackets (&nbsp;[text]&nbsp;)
                        $toggleLink =
                                                .parent()
                                                .prepend( '&nbsp;[' )
                                                .append( ']&nbsp;' )
-                                               .on( 'click.mw-collapse', function ( e, options ) {
-                                                       options = $.extend( { toggleText: { collapseText: collapsetext, expandText: expandtext } }, options );
-                                                       toggleLinkDefault( $(this), e, options );
+                                               .on( 'click.mw-collapse', function ( e, opts ) {
+                                                       opts = $.extend( { toggleText: { collapseText: collapsetext, expandText: expandtext } }, options, opts );
+                                                       toggleLinkDefault( $(this), e, opts );
                                                } );
 
                        // 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 ( ( $collapsible.attr( 'id' ) || '' ).indexOf( 'mw-customcollapsible-' ) === 0 ) {
-                               collapsibleId = $collapsible.attr( 'id' );
-                               $customTogglers = $( '.' + collapsibleId.replace( 'mw-customcollapsible', 'mw-customtoggle' ) );
-                               mw.log( lpx + 'Found custom collapsible: #' + collapsibleId );
-
-                               // Double check that there is actually a customtoggle link
-                               if ( $customTogglers.length ) {
-                                       $customTogglers.on( 'click.mw-collapse', function ( e, options ) {
-                                               toggleLinkCustom( $(this), e, options, $collapsible );
-                                       } );
-                               } else {
-                                       mw.log( lpx + '#' + collapsibleId + ': Missing toggler!' );
+                       if ( options.$customTogglers ) {
+                               $customTogglers = $( options.$customTogglers );
+                       } else {
+                               collapsibleId = $collapsible.attr( 'id' ) || '';
+                               if ( collapsibleId.indexOf( 'mw-customcollapsible-' ) === 0 ) {
+                                       mw.log( lpx + 'Found custom collapsible: #' + collapsibleId );
+                                       $customTogglers = $( '.' + collapsibleId.replace( 'mw-customcollapsible', 'mw-customtoggle' ) );
+
+                                       // Double check that there is actually a customtoggle link
+                                       if ( !$customTogglers.length ) {
+                                               mw.log( lpx + '#' + collapsibleId + ': Missing toggler!' );
+                                       }
                                }
+                       }
+
+                       // Bind the custom togglers
+                       if ( $customTogglers && $customTogglers.length ) {
+                               $customTogglers.on( 'click.mw-collapse', function ( e, opts ) {
+                                       opts = $.extend( {}, options, opts );
+                                       toggleLinkCustom( $(this), e, opts, $collapsible );
+                               } );
 
                                // Initial state
-                               if ( $collapsible.hasClass( 'mw-collapsed' ) ) {
+                               if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
                                        // Remove here so that the toggler goes in the right direction,
                                        // It re-adds the class.
                                        $collapsible.removeClass( 'mw-collapsed' );
-                                       toggleLinkCustom( $customTogglers, null, { instantHide: true }, $collapsible );
+                                       toggleLinkCustom( $customTogglers, null, $.extend( { instantHide: true }, options ), $collapsible );
                                }
 
                        // If this is not a custom case, do the default:
-                       // Wrap the contents add the toggle link
+                       // Wrap the contents and add the toggle link
                        } else {
                                // Elements are treated differently
                                if ( $collapsible.is( 'table' ) ) {
                                        if ( !$toggle.length ) {
                                                $firstItem.eq(-1).prepend( $toggleLink );
                                        } else {
-                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, options ) {
-                                                       toggleLinkPremade( $toggle, e, options );
+                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, opts ) {
+                                                       opts = $.extend( {}, options, opts );
+                                                       toggleLinkPremade( $toggle, e, opts );
                                                } );
                                        }
 
                                                }
                                                $collapsible.prepend( $toggleLink.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent() );
                                        } else {
-                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, options ) {
-                                                       toggleLinkPremade( $toggle, e, options );
+                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, opts ) {
+                                                       opts = $.extend( {}, options, opts );
+                                                       toggleLinkPremade( $toggle, e, opts );
                                                } );
                                        }
 
                                        if ( !$toggle.length ) {
                                                $collapsible.prepend( $toggleLink );
                                        } else {
-                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, options ) {
-                                                       toggleLinkPremade( $toggle, e, options );
+                                               $toggleLink = $toggle.off( 'click.mw-collapse' ).on( 'click.mw-collapse', function ( e, opts ) {
+                                                       opts = $.extend( {}, options, opts );
+                                                       toggleLinkPremade( $toggle, e, opts );
                                                } );
                                        }
                                }
 
                        // Initial state (only for those that are not custom,
                        // because the initial state of those has been taken care of already).
-                       if ( $collapsible.hasClass( 'mw-collapsed' ) && ( $collapsible.attr( 'id' ) || '').indexOf( 'mw-customcollapsible-' ) !== 0 ) {
+                       if (
+                               ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) &&
+                               ( !$customTogglers || !$customTogglers.length )
+                       ) {
                                $collapsible.removeClass( 'mw-collapsed' );
                                // The collapsible element could have multiple togglers
                                // To toggle the initial state only click one of them (ie. the first one, eq(0) )