[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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 ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |