1/** 2 * SCROLL TABS 3 * 4 * JQuery Plugin to manage scrollable tabs. See the 'defaultOptions' data structure for available options for configuration. The plugin is configured jointly via 5 * these Javascript options and CSS classes to style how it is displayed. Some of the CSS is set here in the javascript so that users will have minimal 6 * configuration to make the tabs themselves work, and should only have to do configuration on how they want it styled. 7 * 8 * Known Limitations: 9 * IE6 problems, it does not properly apply scrolling and therefore is always the 'full width.' Additionally, the multiple-class CSS styling does not work 10 * properly in IE6. We can work around this in the future by apply distinct class stylings that represent all the combinations. 11 * 12 * Version: 2.0 13 * Author: Josh Reed 14 */ 15(function($) { 16 $.fn.scrollTabs = function(opts){ 17 var initialize = function(state){ 18 opts = $.extend({}, $.fn.scrollTabs.defaultOptions, opts); 19 20 if($(this).prop('tagName').toLowerCase() === 'ul'){ 21 this.itemTag = 'li'; 22 } else { 23 this.itemTag = 'span'; 24 } 25 26 $(this).addClass('scroll_tabs_container'); 27 if($(this).css('position') === null || $(this).css('position') === 'static'){ 28 $(this).css('position','relative'); 29 } 30 31 $(this.itemTag, this).last().addClass('scroll_tab_last'); 32 $(this.itemTag, this).first().addClass('scroll_tab_first'); 33 34 $(this).html("<div class='scroll_tab_left_button'></div><div class='scroll_tab_inner'><span class='scroll_tab_left_finisher'> </span>"+$(this).html()+"<span class='scroll_tab_right_finisher'> </span></div><div class='scroll_tab_right_button'></div>"); 35 36 $('.scroll_tab_inner > span.scroll_tab_left_finisher', this).css({ 37 'display': 'none' 38 }); 39 40 $('.scroll_tab_inner > span.scroll_tab_right_finisher', this).css({ 41 'display': 'none' 42 }); 43 44 45 var _this = this; 46 47 $('.scroll_tab_inner', this).css({ 48 'margin': '0px', 49 'overflow': 'hidden', 50 'white-space': 'nowrap',
51 '-ms-text-overflow': 'clip', 52 'text-overflow': 'clip', 53 'font-size': '0px', 54 'position': 'absolute', 55 'top': '0px', 56 'left': opts.left_arrow_size + 'px', 57 'right': opts.right_arrow_size + 'px' 58 }); 59 60 // If mousewheel function not present, don't utilize it 61 if($.isFunction($.fn.mousewheel)){ 62 $('.scroll_tab_inner', this).mousewheel(function(event, delta){ 63 // Only do mousewheel scrolling if scrolling is necessary 64 if($('.scroll_tab_right_button', _this).css('display') !== 'none'){ 65 this.scrollLeft -= (delta * 30); 66 state.scrollPos = this.scrollLeft; 67 event.preventDefault(); 68 } 69 }); 70 } 71 72 // Set initial scroll position 73 $('.scroll_tab_inner', _this).animate({scrollLeft: state.scrollPos + 'px'}, 0); 74 75 $('.scroll_tab_left_button', this).css({ 76 'position': 'absolute', 77 'left': '0px', 78 'top': '0px', 79 'width': opts.left_arrow_size + 'px', 80 'cursor': 'pointer' 81 }); 82 83 $('.scroll_tab_right_button', this).css({ 84 'position': 'absolute', 85 'right': '0px', 86 'top': '0px', 87 'width': opts.right_arrow_size + 'px', 88 'cursor': 'pointer' 89 }); 90 91 $('.scroll_tab_inner > '+_this.itemTag, _this).css({ 92 'display': '-moz-inline-stack', 93 'display': 'inline-block', 94 'zoom':1, 95 '*display': 'inline', 96 '_height': '40px',
97 '-webkit-user-select': 'none', 98 '-khtml-user-select': 'none', 99 '-moz-user-select': 'none', 100 '-ms-user-select': 'none', 101 '-o-user-select': 'none', 102 'user-select': 'none' 103 }); 104 105 106 var size_checking = function(){ 107 var panel_width = $('.scroll_tab_inner', _this).outerWidth(); 108 109 if($('.scroll_tab_inner', _this)[0].scrollWidth > Math.ceil(panel_width)){ 110 $(_this).addClass('scroll_tab_active'); 111 $('.scroll_tab_right_button',_this).show(); 112 $('.scroll_tab_left_button',_this).show(); 113 $('.scroll_tab_inner',_this).css({left: opts.left_arrow_size + 'px', right: opts.right_arrow_size + 'px'}); 114 $('.scroll_tab_left_finisher',_this).css('display','none'); 115 $('.scroll_tab_right_finisher',_this).css('display','none'); 116 117 if($('.scroll_tab_inner', _this)[0].scrollWidth - panel_width == $('.scroll_tab_inner', _this).scrollLeft()){ 118 $('.scroll_tab_right_button', _this).addClass('scroll_arrow_disabled').addClass('scroll_tab_right_button_disabled'); 119 } else { 120 $('.scroll_tab_right_button', _this).removeClass('scroll_arrow_disabled').removeClass('scroll_tab_right_button_disabled'); 121 } 122 if ($('.scroll_tab_inner', _this).scrollLeft() == 0) { 123 $('.scroll_tab_left_button', _this).addClass('scroll_arrow_disabled').addClass('scroll_tab_left_button_disabled'); 124 } else { 125 $('.scroll_tab_left_button', _this).removeClass('scroll_arrow_disabled').removeClass('scroll_tab_left_button_disabled'); 126 } 127 } else { 128 $(_this).removeClass('scroll_tab_active'); 129 $('.scroll_tab_right_button',_this).hide(); 130 $('.scroll_tab_left_button',_this).hide(); 131 $('.scroll_tab_inner',_this).css({left: '0px', right: '0px'}); 132 133 if($('.scroll_tab_inner > '+_this.itemTag+':not(.scroll_tab_right_finisher):not(.scroll_tab_left_finisher):visible', _this).length > 0){ 134 $('.scroll_tab_left_finisher',_this).css('display','inline-block'); 135 $('.scroll_tab_right_finisher',_this).css('display','inline-block'); 136 } 137 } 138 }; 139 140 size_checking(); 141 142 state.delay_timer = setInterval(function(){ 143 size_checking(); 144 }, 500); 145 146 var press_and_hold_timeout; 147 148 $('.scroll_tab_right_button', this).mousedown(function(e){ 149 e.stopPropagation(); 150 var scrollRightFunc = function(){ 151 var left = $('.scroll_tab_inner', _this).scrollLeft(); 152 state.scrollPos = Math.min(left + opts.scroll_distance,$('.scroll_tab_inner', _this)[0].scrollWidth - $('.scroll_tab_inner', _this).outerWidth()); 153 $('.scroll_tab_inner', _this).animate({scrollLeft: (left + opts.scroll_distance) + 'px'}, opts.scroll_duration); 154 }; 155 scrollRightFunc(); 156 157 press_and_hold_timeout = setInterval(function(){ 158 scrollRightFunc(); 159 }, opts.scroll_duration); 160 }).bind("mouseup mouseleave", function(){ 161 clearInterval(press_and_hold_timeout); 162 }).mouseover(function(){ 163 $(this).addClass('scroll_arrow_over').addClass('scroll_tab_right_button_over'); 164 }).mouseout(function(){ 165 $(this).removeClass('scroll_arrow_over').removeClass('scroll_tab_right_button_over'); 166 }); 167 168 $('.scroll_tab_left_button', this).mousedown(function(e){ 169 e.stopPropagation(); 170 var scrollLeftFunc = function(){ 171 var left = $('.scroll_tab_inner', _this).scrollLeft(); 172 state.scrollPos = Math.max(left - opts.scroll_distance,0); 173 $('.scroll_tab_inner', _this).animate({scrollLeft: (left - opts.scroll_distance) + 'px'}, opts.scroll_duration); 174 }; 175 scrollLeftFunc(); 176 177 press_and_hold_timeout = setInterval(function(){ 178 scrollLeftFunc(); 179 }, opts.scroll_duration); 180 }).bind("mouseup mouseleave", function(){ 181 clearInterval(press_and_hold_timeout); 182 }).mouseover(function(){ 183 $(this).addClass('scroll_arrow_over').addClass('scroll_tab_left_button_over'); 184 }).mouseout(function(){ 185 $(this).removeClass('scroll_arrow_over').removeClass('scroll_tab_left_button_over'); 186 }); 187 188 $('.scroll_tab_inner > '+this.itemTag+(this.itemTag !== 'span' ? ', .scroll_tab_inner > span' : ''), this).mouseover(function(){ 189 $(this).addClass('scroll_tab_over'); 190 if($(this).hasClass('scroll_tab_left_finisher')){ 191 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).addClass('scroll_tab_over').addClass('scroll_tab_first_over'); 192 } 193 if($(this).hasClass('scroll_tab_right_finisher')){ 194 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).addClass('scroll_tab_over').addClass('scroll_tab_last_over'); 195 } 196 if($(this).hasClass('scroll_tab_first') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).hasClass('scroll_tab_first')){ 197 $('.scroll_tab_inner > span.scroll_tab_left_finisher', _this).addClass('scroll_tab_over').addClass('scroll_tab_left_finisher_over'); 198 } 199 if($(this).hasClass('scroll_tab_last') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).hasClass('scroll_tab_last')){ 200 $('.scroll_tab_inner > span.scroll_tab_right_finisher', _this).addClass('scroll_tab_over').addClass('scroll_tab_right_finisher_over'); 201 } 202 }).mouseout(function(){ 203 $(this).removeClass('scroll_tab_over'); 204 if($(this).hasClass('scroll_tab_left_finisher')){ 205 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).removeClass('scroll_tab_over').removeClass('scroll_tab_first_over'); 206 } 207 if($(this).hasClass('scroll_tab_right_finisher')){ 208 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).removeClass('scroll_tab_over').removeClass('scroll_tab_last_over'); 209 } 210 if($(this).hasClass('scroll_tab_first') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).hasClass('scroll_tab_first')){ 211 $('.scroll_tab_inner > span.scroll_tab_left_finisher', _this).removeClass('scroll_tab_over').removeClass('scroll_tab_left_finisher_over'); 212 } 213 if($(this).hasClass('scroll_tab_last') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).hasClass('scroll_tab_last')){ 214 $('.scroll_tab_inner > span.scroll_tab_right_finisher', _this).removeClass('scroll_tab_over').removeClass('scroll_tab_right_finisher_over'); 215 } 216 }).on('click',function(e){ 217 e.stopPropagation(); 218 $('.tab_selected',_this).removeClass('tab_selected scroll_tab_first_selected scroll_tab_last_selected scroll_tab_left_finisher_selected scroll_tab_right_finisher_selected'); 219 $(this).addClass('tab_selected'); 220 221 var context_obj = this; 222 if($(this).hasClass('scroll_tab_left_finisher')){ 223 context_obj = $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).addClass('tab_selected').addClass('scroll_tab_first_selected'); 224 } 225 if($(this).hasClass('scroll_tab_right_finisher')){ 226 context_obj = $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).addClass('tab_selected').addClass('scroll_tab_last_selected'); 227 } 228 if($(this).hasClass('scroll_tab_first') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).hasClass('scroll_tab_first')){ 229 $('.scroll_tab_inner > span.scroll_tab_left_finisher', _this).addClass('tab_selected').addClass('scroll_tab_left_finisher_selected'); 230 } 231 if($(this).hasClass('scroll_tab_last') || $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).hasClass('scroll_tab_last')){ 232 $('.scroll_tab_inner > span.scroll_tab_right_finisher', _this).addClass('tab_selected').addClass('scroll_tab_left_finisher_selected'); 233 } 234 235 // "Slide" it into view if not fully visible. 236 scroll_selected_into_view.call(_this, state); 237 238 opts.click_callback.call(context_obj,e); 239 }); 240 241 // Check to set the edges as selected if needed 242 if($('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_first', _this).hasClass('tab_selected')) 243 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_left_finisher', _this).addClass('tab_selected').addClass('scroll_tab_left_finisher_selected'); 244 if($('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_last', _this).hasClass('tab_selected')) 245 $('.scroll_tab_inner > '+_this.itemTag+'.scroll_tab_right_finisher', _this).addClass('tab_selected').addClass('scroll_tab_right_finisher_selected'); 246 }; 247 248 var scroll_selected_into_view = function(state){ 249 var _this = this; 250 251 var selected_item = $('.tab_selected:not(.scroll_tab_right_finisher, .scroll_tab_left_finisher)', _this); 252 253 var left = $('.scroll_tab_inner', _this).scrollLeft(); 254 var scroll_width = $('.scroll_tab_inner', _this).width(); 255 if(selected_item && typeof(selected_item) !== 'undefined' && selected_item.position() && typeof(selected_item.position()) !== 'undefined'){ 256 if(selected_item.position().left < 0){ 257 state.scrollPos = Math.max(left + selected_item.position().left + 1,0); 258 $('.scroll_tab_inner', _this).animate({scrollLeft: (left + selected_item.position().left + 1) + 'px'}, opts.scroll_duration); 259 } else if ((selected_item.position().left + selected_item.outerWidth()) > scroll_width){ 260 state.scrollPos = Math.min(left + ((selected_item.position().left + selected_item.outerWidth()) - scroll_width),$('.scroll_tab_inner', _this)[0].scrollWidth - $('.scroll_tab_inner', _this).outerWidth()); 261 $('.scroll_tab_inner', _this).animate({scrollLeft: (left + ((selected_item.position().left + selected_item.outerWidth()) - scroll_width)) + 'px'}, opts.scroll_duration); 262 } 263 } 264 }; 265 266 var ret = []; 267 268 this.each(function(){ 269 var backup = $(this).html(); 270 271 var state = {}; 272 state.scrollPos = 0; 273 initialize.call(this, state); 274 275 var context_obj = this; 276
277 ret.push({ 278 domObject: context_obj, 279 state: state, 280 addTab: function(html, position){ 281 if(typeof(position) === 'undefined'){ 282 position = $('.scroll_tab_inner > '+context_obj.itemTag, context_obj).length - (context_obj.itemTag === 'span' ? 2 : 0); 283 } 284 285 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_last', context_obj).removeClass('scroll_tab_last'); 286 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_first', context_obj).removeClass('scroll_tab_first'); 287 backup = ""; 288 var count = 0; 289 $('.scroll_tab_inner > '+context_obj.itemTag, context_obj).each(function(){ 290 if($(this).hasClass('scroll_tab_left_finisher') || $(this).hasClass('scroll_tab_right_finisher')) return true; 291 if(position == count){ 292 backup += html; 293 } 294 backup += $(this).clone().wrap('<div>').parent().html(); 295 count++; 296 }); 297 298 if(position >= count) 299 backup += html; 300 301 this.destroy(); 302 initialize.call(context_obj, state); 303 this.refreshFirstLast(); 304 }, 305 removeTabs: function(jquery_selector_str){ 306 $('.scroll_tab_left_finisher', context_obj).remove(); 307 $('.scroll_tab_right_finisher', context_obj).remove(); 308 309 $(jquery_selector_str, context_obj).remove(); 310 311 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_last', context_obj).removeClass('scroll_tab_last'); 312 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_first', context_obj).removeClass('scroll_tab_first'); 313 314 this.refreshState(); 315 }, 316 destroy: function(){ 317 clearInterval(state.delay_timer); 318 $(context_obj).html(backup); 319 $(context_obj).removeClass('scroll_tabs_container'); 320 }, 321 refreshState: function(){ 322 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_last', context_obj).removeClass('scroll_tab_last'); 323 $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_first', context_obj).removeClass('scroll_tab_first'); 324 backup = $('.scroll_tab_inner',context_obj).html(); 325 this.destroy(); 326 initialize.call(context_obj, state); 327 this.refreshFirstLast(); 328 }, 329 clearTabs: function(){ 330 backup = ""; 331 this.destroy(); 332 initialize.call(context_obj, state); 333 this.refreshFirstLast(); 334 }, 335 refreshFirstLast: function(){ 336 var old_last_item = $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_last', context_obj); 337 var old_first_item = $('.scroll_tab_inner > '+context_obj.itemTag+'.scroll_tab_first', context_obj); 338 339 old_last_item.removeClass('scroll_tab_last'); 340 old_first_item.removeClass('scroll_tab_first'); 341 342 if(old_last_item.hasClass('tab_selected')) 343 $('.scroll_tab_inner > span.scroll_tab_right_finisher', context_obj).removeClass('tab_selected scroll_tab_right_finisher_selected'); 344 if(old_first_item.hasClass('tab_selected')) 345 $('.scroll_tab_inner > span.scroll_tab_left_finisher', context_obj).removeClass('tab_selected scroll_tab_left_finisher_selected'); 346 347 if($('.scroll_tab_inner > '+context_obj.itemTag+':not(.scroll_tab_right_finisher):not(.scroll_tab_left_finisher):visible', context_obj).length > 0){ 348 var new_last_item = $('.scroll_tab_inner > '+context_obj.itemTag+':not(.scroll_tab_right_finisher):visible', context_obj).last(); 349 var new_first_item = $('.scroll_tab_inner > '+context_obj.itemTag+':not(.scroll_tab_left_finisher):visible', context_obj).first(); 350 351 new_last_item.addClass('scroll_tab_last'); 352 new_first_item.addClass('scroll_tab_first'); 353 354 if(new_last_item.hasClass('tab_selected')) 355 $('.scroll_tab_inner > span.scroll_tab_right_finisher', context_obj).addClass('tab_selected').addClass('scroll_tab_right_finisher_selected'); 356 if(new_first_item.hasClass('tab_selected')) 357 $('.scroll_tab_inner > span.scroll_tab_left_finisher', context_obj).addClass('tab_selected').addClass('scroll_tab_right_finisher_selected'); 358 } else { 359 $('.scroll_tab_inner > span.scroll_tab_right_finisher', context_obj).hide(); 360 $('.scroll_tab_inner > span.scroll_tab_left_finisher', context_obj).hide(); 361 } 362 }, 363 hideTabs: function(domObj){ 364 $(domObj, context_obj).css('display','none'); 365 this.refreshFirstLast(); 366 }, 367 showTabs: function(domObj){ 368 $(domObj, context_obj).css({ 369 'display': '-moz-inline-stack', 370 'display': 'inline-block', 371 '*display': 'inline' 372 }); 373 this.refreshFirstLast(); 374 }, 375 scrollSelectedIntoView:function(){ 376 scroll_selected_into_view.call(context_obj, state); 377 } 378 }); 379 }); 380 381 if(this.length == 1){ 382 return ret[0]; 383 } else { 384 return ret; 385 } 386 }; 387 388 $.fn.scrollTabs.defaultOptions = { 389 scroll_distance: 300, 390 scroll_duration: 300, 391 left_arrow_size: 26, 392 right_arrow_size: 26, 393 click_callback: function(e){ 394 var val = $(this).attr('rel'); 395 if(val){ 396 window.location.href = val; 397 } 398 } 399 }; 400})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.