[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/skins/Vector/ -> collapsibleTabs.js (source)

   1  /**
   2   * Collapsible tabs jQuery Plugin
   3   */
   4  ( function ( $ ) {
   5      var rtl = $( 'html' ).attr( 'dir' ) === 'rtl';
   6      $.fn.collapsibleTabs = function ( options ) {
   7          // return if the function is called on an empty jquery object
   8          if ( !this.length ) {
   9              return this;
  10          }
  11          // Merge options into the defaults
  12          var settings = $.extend( {}, $.collapsibleTabs.defaults, options );
  13  
  14          this.each( function () {
  15              var $el = $( this );
  16              // add the element to our array of collapsible managers
  17              $.collapsibleTabs.instances = ( $.collapsibleTabs.instances.length === 0 ?
  18                  $el : $.collapsibleTabs.instances.add( $el ) );
  19              // attach the settings to the elements
  20              $el.data( 'collapsibleTabsSettings', settings );
  21              // attach data to our collapsible elements
  22              $el.children( settings.collapsible ).each( function () {
  23                  $.collapsibleTabs.addData( $( this ) );
  24              } );
  25          } );
  26  
  27          // if we haven't already bound our resize handler, bind it now
  28          if ( !$.collapsibleTabs.boundEvent ) {
  29              $( window ).on( 'resize', $.debounce( 500, function () {
  30                  $.collapsibleTabs.handleResize();
  31              } ) );
  32              $.collapsibleTabs.boundEvent = true;
  33          }
  34  
  35          // call our resize handler to setup the page
  36          $.collapsibleTabs.handleResize();
  37          return this;
  38      };
  39      $.collapsibleTabs = {
  40          instances: [],
  41          boundEvent: null,
  42          defaults: {
  43              expandedContainer: '#p-views ul',
  44              collapsedContainer: '#p-cactions ul',
  45              collapsible: 'li.collapsible',
  46              shifting: false,
  47              expandCondition: function ( eleWidth ) {
  48                  // If there are at least eleWidth + 1 pixels of free space, expand.
  49                  // We add 1 because .width() will truncate fractional values but .offset() will not.
  50                  return $.collapsibleTabs.calculateTabDistance() >= eleWidth + 1;
  51              },
  52              collapseCondition: function () {
  53                  // If there's an overlap, collapse.
  54                  return $.collapsibleTabs.calculateTabDistance() < 0;
  55              }
  56          },
  57          addData: function ( $collapsible ) {
  58              var settings = $collapsible.parent().data( 'collapsibleTabsSettings' );
  59              if ( settings ) {
  60                  $collapsible.data( 'collapsibleTabsSettings', {
  61                      expandedContainer: settings.expandedContainer,
  62                      collapsedContainer: settings.collapsedContainer,
  63                      expandedWidth: $collapsible.width(),
  64                      prevElement: $collapsible.prev()
  65                  } );
  66              }
  67          },
  68          getSettings: function ( $collapsible ) {
  69              var settings = $collapsible.data( 'collapsibleTabsSettings' );
  70              if ( !settings ) {
  71                  $.collapsibleTabs.addData( $collapsible );
  72                  settings = $collapsible.data( 'collapsibleTabsSettings' );
  73              }
  74              return settings;
  75          },
  76          handleResize: function () {
  77              $.collapsibleTabs.instances.each( function () {
  78                  var $el = $( this ),
  79                      data = $.collapsibleTabs.getSettings( $el );
  80  
  81                  if ( data.shifting ) {
  82                      return;
  83                  }
  84  
  85                  // if the two navigations are colliding
  86                  if ( $el.children( data.collapsible ).length > 0 && data.collapseCondition() ) {
  87  
  88                      $el.trigger( 'beforeTabCollapse' );
  89                      // move the element to the dropdown menu
  90                      $.collapsibleTabs.moveToCollapsed( $el.children( data.collapsible + ':last' ) );
  91                  }
  92  
  93                  // if there are still moveable items in the dropdown menu,
  94                  // and there is sufficient space to place them in the tab container
  95                  if ( $( data.collapsedContainer + ' ' + data.collapsible ).length > 0 &&
  96                          data.expandCondition( $.collapsibleTabs.getSettings( $( data.collapsedContainer ).children(
  97                                  data.collapsible + ':first' ) ).expandedWidth ) ) {
  98                      //move the element from the dropdown to the tab
  99                      $el.trigger( 'beforeTabExpand' );
 100                      $.collapsibleTabs
 101                          .moveToExpanded( data.collapsedContainer + ' ' + data.collapsible + ':first' );
 102                  }
 103              } );
 104          },
 105          moveToCollapsed: function ( ele ) {
 106              var outerData, expContainerSettings, target,
 107                  $moving = $( ele );
 108  
 109              outerData = $.collapsibleTabs.getSettings( $moving );
 110              if ( !outerData ) {
 111                  return;
 112              }
 113              expContainerSettings = $.collapsibleTabs.getSettings( $( outerData.expandedContainer ) );
 114              if ( !expContainerSettings ) {
 115                  return;
 116              }
 117              expContainerSettings.shifting = true;
 118  
 119              // Remove the element from where it's at and put it in the dropdown menu
 120              target = outerData.collapsedContainer;
 121              $moving.css( 'position', 'relative' )
 122                  .css( ( rtl ? 'left' : 'right' ), 0 )
 123                  .animate( { width: '1px' }, 'normal', function () {
 124                      var data, expContainerSettings;
 125                      $( this ).hide();
 126                      // add the placeholder
 127                      $( '<span class="placeholder" style="display: none;"></span>' ).insertAfter( this );
 128                      $( this ).detach().prependTo( target ).data( 'collapsibleTabsSettings', outerData );
 129                      $( this ).attr( 'style', 'display: list-item;' );
 130                      data = $.collapsibleTabs.getSettings( $( ele ) );
 131                      if ( data ) {
 132                          expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
 133                          if ( expContainerSettings ) {
 134                              expContainerSettings.shifting = false;
 135                              $.collapsibleTabs.handleResize();
 136                          }
 137                      }
 138                  } );
 139          },
 140          moveToExpanded: function ( ele ) {
 141              var data, expContainerSettings, $target, expandedWidth,
 142                  $moving = $( ele );
 143  
 144              data = $.collapsibleTabs.getSettings( $moving );
 145              if ( !data ) {
 146                  return;
 147              }
 148              expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
 149              if ( !expContainerSettings ) {
 150                  return;
 151              }
 152              expContainerSettings.shifting = true;
 153  
 154              // grab the next appearing placeholder so we can use it for replacing
 155              $target = $( data.expandedContainer ).find( 'span.placeholder:first' );
 156              expandedWidth = data.expandedWidth;
 157              $moving.css( 'position', 'relative' ).css( ( rtl ? 'right' : 'left' ), 0 ).css( 'width', '1px' );
 158              $target.replaceWith(
 159                  $moving
 160                  .detach()
 161                  .css( 'width', '1px' )
 162                  .data( 'collapsibleTabsSettings', data )
 163                  .animate( { width: expandedWidth + 'px' }, 'normal', function () {
 164                      $( this ).attr( 'style', 'display: block;' );
 165                      var data, expContainerSettings;
 166                      data = $.collapsibleTabs.getSettings( $( this ) );
 167                      if ( data ) {
 168                          expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
 169                          if ( expContainerSettings ) {
 170                              expContainerSettings.shifting = false;
 171                              $.collapsibleTabs.handleResize();
 172                          }
 173                      }
 174                  } )
 175              );
 176          },
 177          /**
 178           * Returns the amount of horizontal distance between the two tabs groups
 179           * (#left-navigation and #right-navigation), in pixels. If negative, this
 180           * means that the tabs overlap, and the value is the width of overlapping
 181           * parts.
 182           *
 183           * Used in default expandCondition and collapseCondition.
 184           *
 185           * @return {Numeric} distance/overlap in pixels
 186           */
 187          calculateTabDistance: function () {
 188              var $leftTab, $rightTab, leftEnd, rightStart;
 189  
 190              // In RTL, #right-navigation is actually on the left and vice versa.
 191              // Hooray for descriptive naming.
 192              if ( !rtl ) {
 193                  $leftTab = $( '#left-navigation' );
 194                  $rightTab = $( '#right-navigation' );
 195              } else {
 196                  $leftTab = $( '#right-navigation' );
 197                  $rightTab = $( '#left-navigation' );
 198              }
 199  
 200              leftEnd = $leftTab.offset().left + $leftTab.width();
 201              rightStart = $rightTab.offset().left;
 202  
 203              return rightStart - leftEnd;
 204          }
 205      };
 206  
 207  }( jQuery ) );


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1