PageSourceSearch

https://bushandbeyond.nz/wp-content/uploads/ac_assets/uc_content_t…jquery.responsiveContentTabs.js?ver=1.5.141

js bushandbeyond.nz collected 2026-10-10 00:33:39 UTC 29,723 bytes, 883 lines download raw bytes

1;(function ( $, window, undefined ) {
2  
3  /** Default settings */
4  var defaults = {
5    active: null,
6    event: 'click',
7    disabled: [],
8    collapsible: 'accordion',
9    startCollapsed: 'none',
10    rotate: false,
11    setHash: false,
12    animation: 'default',
13    animationQueue: false,
14    duration: 500,
15    fluidHeight: true,
16    scrollToAccordion: true,
17    scrollToAccordionOnLoad: false,
18    scrollToAccordionOffset: 0,
19    accordionTabElement: '<div></div>',
20    accordionAnchorHTML: '',
21    closeCurrent: true,
22    breakpoint: 767,
23    click: function(){},
24    activate: function(){},
25    deactivate: function(){},
26    load: function(){},
27    activateState: function(){},
28    classes: {
29      stateDefault: 'r-tabs-state-default',
30      stateActive: 'r-tabs-state-active',
31      stateDisabled: 'r-tabs-state-disabled',
32      stateExcluded: 'r-tabs-state-excluded',
33      container: 'r-tabs',
34      ul: 'r-tabs-nav',
35      tab: 'r-tabs-tab',
36      anchor: 'r-tabs-anchor',
37      panel: 'r-tabs-panel',
38      accordionTitle: 'r-tabs-accordion-title',
39      elements: '.ue-element',
40      activeElements: '.ue-element.active',
41      containerPanel: '.tab-container'
42    }
43  };
44  
45  /**
46  * Responsive Tabs
47  * @constructor
48  * @param {object} element - The HTML element the validator should be bound to
49  * @param {object} options - An option map
50  */
51  function ResponsiveContentTabs(element, options) {
52    this.element = element; // Selected DOM element
53    this.$element = $(element); // Selected jQuery element
54    
55    this.tabs = []; // Create tabs array
56    this.state = ''; // Define the plugin state (tabs/accordion)
57    this.rotateInterval = 0; // Define rotate interval
58    this.$queue = $({});
59    
60    // Extend the defaults with the passed options
61    this.options = $.extend( {}, defaults, options);
62    
63    this.init();
64  }
65  
66  
67  /**
68  * This function initializes the tab plugin
69  */
70  ResponsiveContentTabs.prototype.init = function () {
71    var _this = this;
72    
73    // Load all the elements
74    this.tabs = this._loadElements();
75    this._loadClasses();
76    this._loadEvents();
77    
78    // Window resize bind to check state
79    $(window).on('resize', function(e) {
80      _this._setState(e);
81      if(_this.options.fluidHeight !== true) {
82        _this._equaliseHeights();
83      }
84    });
85    
86    // Hashchange event
87    $(window).on('hashchange', function(e) {
88      var tabRef = _this._getTabRefBySelector(window.location.hash);
89      var oTab = _this._getTab(tabRef);
90      
91      // Check if a tab is found that matches the hash
92      if(tabRef >= 0 && !oTab._ignoreHashChange && !oTab.disabled) {
93
94        //close other tabs
95
96
97        // If so, open the tab and auto close the current one
98        _this._openTab(e, _this._getTab(tabRef), true);
99
100      }
101
102
103    });
104    
105    // Start rotate event if rotate option is defined
106    if(this.options.rotate !== false) {
107      this.startRotation();
108    }
109    
110    // Set fluid height
111    if(this.options.fluidHeight !== true) {
112      _this._equaliseHeights();
113    }
114    
115    // --------------------
116    // Define plugin events
117    //
118    
119    // Activate: this event is called when a tab is selected
120    this.$element.bind('tabs-click', function(e, oTab) {
121      _this.options.click.call(this, e, oTab);
122    });
123    
124    // Activate: this event is called when a tab is selected
125    this.$element.bind('tabs-activate', function(e, oTab) {
126      _this.options.activate.call(this, e, oTab);
127    });
128    // Deactivate: this event is called when a tab is closed
129    this.$element.bind('tabs-deactivate', function(e, oTab) {
130      _this.options.deactivate.call(this, e, oTab);
131    });
132    // Activate State: this event is called when the plugin switches states
133    this.$element.bind('tabs-activate-state', function(e, state) {
134      _this.options.activateState.call(this, e, state);
135    });
136    
137    // Load: this event is called when the plugin has been loaded
138    this.$element.bind('tabs-load', function(e) {
139      var startTab;
140      
141      _this._setState(e); // Set state
142      
143      var isDesktopBeakpoint = window.matchMedia("(min-width: " + _this.options.breakpoint + "px)");
144      
145      function openFirstItem(){
146        
147        startTab = _this._getStartTab();
148        
149        // Open the initial tab
150        _this._openTab(e, startTab); // Open first tab
151        
152        // Call the callback function
153        _this.options.load.call(this, e, startTab); // Call the load callback
154      }
155      
156      // Check if the panel should be collapsed on load
157      if(_this.options.startCollapsed == 'none' && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion'))
158      openFirstItem();
159      
160      // Check if the panel should be collapsed on load
161      if(_this.options.startCollapsed == 'mobile' && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion')) {
162        
163        if(isDesktopBeakpoint.matches == true)
164        openFirstItem();
165        
166      }
167      
168      if(window.location.hash && _this.options.startCollapsed != 'none' && _this.options.setHash == true){
169     
170        var tabRef = _this._getTabRefBySelector(window.location.hash);
171        startTab = _this._getTab(tabRef);
172    
173        if(tabRef >= 0 && !startTab.disabled)
174        openFirstItem();
175      }
176      
177    });
178    // Trigger loaded event
179    this.$element.trigger('tabs-load');
180  };
181  
182  //
183  // PRIVATE FUNCTIONS
184  //
185  
186  /**
187  * This function loads the tab elements and stores them in an array
188  * @returns {Array} Array of tab elements
189  */
190  ResponsiveContentTabs.prototype._loadElements = function() {
191    var _this = this;
192    var $ul = this.$element.children('ul:first');
193    var tabs = [];
194    var id = 0;
195    
196    // Add the classes to the basic html elements
197    this.$element.addClass(_this.options.classes.container); // Tab container
198    $ul.addClass(_this.options.classes.ul); // List container
199    
200    // Get tab buttons and store their data in an array
201    $('li', $ul).each(function() {
202      var $tab = $(this);
203      var isExcluded = $tab.hasClass(_this.options.classes.stateExcluded);
204      var $anchor, $panel, $accordionTab, $accordionAnchor, panelSelector;
205      
206      // Check if the tab should be excluded
207      if(!isExcluded) {
208        
209        $anchor = $('a', $tab);
210        panelSelector = $anchor.attr('data-content-id');
211        panelSelectorId = $anchor.attr('id');
212        $panel = $("#"+panelSelector);
213        $accordionTab = $(_this.options.accordionTabElement).insertBefore($panel);
214        $accordionAnchor = $('<a></a>').attr('href', panelSelector).attr("rel", "nofollow").html("<div class='uc-tabs-accordion-title'>" +$anchor.html()+"</div>").appendTo($accordionTab);
215        
216        if(_this.options.accordionAnchorHTML)
217        $accordionAnchor.append(_this.options.accordionAnchorHTML);				
218        
219        var oTab = {
220          _ignoreHashChange: false,
221          id: id,
222          disabled: ($.inArray(id, _this.options.disabled) !== -1),
223          tab: $(this),
224          anchor: $('a', $tab),
225          panel: $panel,
226          selector: panelSelectorId,
227          accordionTab: $accordionTab,
228          accordionAnchor: $accordionAnchor,
229          active: false
230        };
231        
232        // 1up the ID
233        id++;
234        // Add to tab array
235        tabs.push(oTab);
236      }
237    });
238    return tabs;
239  };
240  
241  
242  /**
243  * This function adds classes to the tab elements based on the options
244  */
245  ResponsiveContentTabs.prototype._loadClasses = function() {
246    for (var i=0; i<this.tabs.length; i++) {
247      this.tabs[i].tab.addClass(this.options.classes.stateDefault).addClass(this.options.classes.tab);
248      this.tabs[i].anchor.addClass(this.options.classes.anchor);
249      this.tabs[i].panel.addClass(this.options.classes.stateDefault).addClass(this.options.classes.panel);
250      this.tabs[i].accordionTab.addClass(this.options.classes.accordionTitle);
251      this.tabs[i].accordionAnchor.addClass(this.options.classes.anchor);
252      if(this.tabs[i].disabled) {
253        this.tabs[i].tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
254        this.tabs[i].accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
255      }
256    }
257  };
258  
259  /**
260  * This function adds events to the tab elements
261  */
262  ResponsiveContentTabs.prototype._loadEvents = function() {
263    var _this = this;
264    
265    // Define activate event on a tab element
266    var fActivate = function(e) {
267      var current = _this._getCurrentTab(); // Fetch current tab
268      var activatedTab = e.data.tab;
269      e.preventDefault();
270    
271      // Trigger click event for whenever a tab is clicked/touched even if the tab is disabled
272      activatedTab.tab.trigger('tabs-click', activatedTab);
273      
274      // Make sure this tab isn't disabled
275      if(!activatedTab.disabled) {
276        
277        // Check if hash has to be set in the URL location
278        if(_this.options.setHash) {
279          // Set the hash using the history api if available to tackle Chromes repaint bug on hash change
280          if(history.pushState) {
281            history.pushState(null, null, window.location.origin + window.location.pathname + window.location.search + activatedTab.selector);
282          } else {
283            // Otherwise fallback to the hash update for sites that don't support the history api
284            window.location.hash = activatedTab.selector;
285          }
286        }
287        
288        e.data.tab._ignoreHashChange = true;
289     
290        // Check if the activated tab isnt the current one or if its collapsible. If not, do nothing
291        if(current !== activatedTab || _this._isCollapisble()) {
292          // The activated tab is either another tab of the current one. If it's the current tab it is collapsible
293          // Either way, the current tab can be closed          
294        
295          if(current == activatedTab && _this.options.closeCurrent == true){
296            _this._closeTab(e, current);
297          }
298         
299          if(current != activatedTab || _this.getState() === 'accordion'){
300            _this._closeTab(e, current);
301          }
302
303          // Check if the activated tab isnt the current one or if it isnt collapsible
304          if(current !== activatedTab || !_this._isCollapisble()) {
305            _this._openTab(e, activatedTab, false, true);
306          }
307        }
308      }
309    };
310    
311    // Loop tabs
312    for (var i=0; i<this.tabs.length; i++) {
313      // Add activate function to the tab and accordion selection element
314      this.tabs[i].anchor.on(_this.options.event, {tab: _this.tabs[i]}, fActivate);
315      this.tabs[i].accordionAnchor.on(_this.options.event, {tab: _this.tabs[i]}, fActivate);
316      
317      this.tabs[i].anchor.on("ucclick", {tab: _this.tabs[i]}, fActivate);
318      this.tabs[i].accordionAnchor.on("ucclick", {tab: _this.tabs[i]}, fActivate);
319      
320    }
321  };
322  
323  /**
324  * This function gets the tab that should be opened at start
325  * @returns {Object} Tab object
326  */
327  ResponsiveContentTabs.prototype._getStartTab = function() {
328    var tabRef = this._getTabRefBySelector(window.location.hash);
329    var startTab;
330    
331    // Check if the page has a hash set that is linked to a tab
332    if(tabRef >= 0 && !this._getTab(tabRef).disabled) {
333      // If so, set the current tab to the linked tab
334      startTab = this._getTab(tabRef);
335    } else if(this.options.active > 0 && !this._getTab(this.options.active).disabled) {
336      startTab = this._getTab(this.options.active);
337    } else {
338      // If not, just get the first one
339      startTab = this._getTab(0);
340    }
341    
342    return startTab;
343  };
344  
345  /**
346  * This function sets the current state of the plugin
347  * @param {Event} e - The event that triggers the state change
348  */
349  ResponsiveContentTabs.prototype._setState = function(e) {
350    var $ul = $('ul:first', this.$element);
351    var oldState = this.state;
352    var startCollapsedIsState = (typeof this.options.startCollapsed === 'string');
353    var startTab;
354    
355    // The state is based on the visibility of the tabs list
356    if($ul.is(':visible')){
357      // Tab list is visible, so the state is 'tabs'
358      this.state = 'tabs';
359    } else {
360      // Tab list is invisible, so the state is 'accordion'
361      
362      this.state = 'accordion';
363    }
364    
365    // If the new state is different from the old state
366    if(this.state !== oldState) {
367      // If so, the state activate trigger must be called
368      this.$element.trigger('tabs-activate-state', {oldState: oldState, newState: this.state});
369      
370      // Check if the state switch should open a tab
371      if(oldState && startCollapsedIsState && this.options.startCollapsed !== this.state && this._getCurrentTab() === undefined) {
372        // Get initial tab
373        startTab = this._getStartTab(e);
374        // Open the initial tab
375        this._openTab(e, startTab); // Open first tab
376      }
377    }
378  };
379  
380  /**
381  * This function opens a tab
382  * @param {Event} e - The event that triggers the tab opening
383  * @param {Object} oTab - The tab object that should be opened
384  * @param {Boolean} closeCurrent - Defines if the current tab should be closed
385  * @param {Boolean} stopRotation - Defines if the tab rotation loop should be stopped
386  */
387  ResponsiveContentTabs.prototype._openTab = function(e, oTab, closeCurrent, stopRotation) {
388      
389    //protection from synced parent invisible elementor container    
390    var objHiddenParentDesktop = jQuery(oTab.accordionTab).parents('.elementor-hidden-desktop');
391    var objHiddenParentTablet = jQuery(oTab.accordionTab).parents('.elementor-hidden-tablet');
392    var objHiddenParentMobile = jQuery(oTab.accordionTab).parents('.elementor-hidden-mobile');
393
394    if(objHiddenParentDesktop.length >= 1 && objHiddenParentDesktop.is(':visible') == false)
395    return(false);
396
397    if(objHiddenParentTablet.length >= 1 && objHiddenParentTablet.is(':visible') == false)
398    return(false);
399
400    if(objHiddenParentTablet.length >= 1 &&objHiddenParentMobile.is(':visible') == false)
401    return(false);  
402      
403    var _this = this;
404    var scrollOffset;
405    
406    // Check if the current tab has to be closed
407
408    if(_this.options.closeCurrent == true) {
409      this._closeTab(e, this._getCurrentTab());
410    }
411    
412    // Check if the rotation has to be stopped when activated
413    if(stopRotation && this.rotateInterval > 0) {
414      this.stopRotation();
415    }
416
417    if(oTab == undefined)
418    return(false)
419    
420    // Set this tab to active
421    oTab.active = true;
422    // Set active classes to the tab button and accordion tab button
423    
424    if(_this.getState() === 'tabs'){
425      oTab.tab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);     
426    }
427    
428    if(_this.getState() === 'accordion'){
429      oTab.accordionTab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);    
430    }
431    
432    // Run panel transiton
433    _this._doTransition(oTab.panel, _this.options.animation, 'open', function() {
434      var scrollOnLoad = (e.type !== 'tabs-load' || _this.options.scrollToAccordionOnLoad);
435      
436      // When finished, set active class to the panel
437      oTab.panel.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);
438      
439      // And if enabled and state is accordion, scroll to the accordion tab
440      if(_this.getState() === 'accordion' && _this.options.scrollToAccordion && (!_this._isInView(oTab.accordionTab) || _this.options.animation !== 'default') && scrollOnLoad) {
441        
442        // Add offset element's height to scroll position
443        scrollOffset = oTab.accordionTab.offset().top - _this.options.scrollToAccordionOffset;
444        
445        // Check if the animation option is enabled, and if the duration isn't 0
446        if(_this.options.animation !== 'default' && _this.options.duration > 0) {
447          // If so, set scrollTop with animate and use the 'animation' duration
448          $('html, body').animate({
449            scrollTop: scrollOffset
450          }, _this.options.duration);
451        } else {
452          //  If not, just set scrollTop
453          $('html, body').scrollTop(scrollOffset);
454        }
455      }
456    });
457    
458    this.$element.trigger('tabs-activate', oTab);
459    
460    // show/hide elements by id
461    
462    var elements = defaults.classes.elements;
463    
464    if(jQuery(elements).length < 0){
465      return true
466    }
467    
468    var objTabs = this.$element;
469    var container = defaults.classes.containerPanel;
470    var parentElement = jQuery(elements).parents(container);
471    var elementParentIndex;
472    var elementParentArray = [];
473    
474    parentElement.each(function(){
475      elementParentIndex = Math.floor(jQuery(this).index() / 2);
476      elementParentArray.push(elementParentIndex);
477    });
478    
479    // hide container when tab with elements to show is clicked
480    
481    function hideContainer(){
482      jQuery(elements).parents(container).hide();
483    }
484    
485    if(elementParentIndex == 0){
486      hideContainer();
487    }
488    
489    var elementsId;
490    var currentTabIndex = jQuery(oTab.tab[0]).index();
491    
492    // hide all elements
493    
494    jQuery(elements).each(function(){
495      
496      elementsId = jQuery(this).data('id');
497      var elementsIdArray = elementsId.split(',');
498      
499      elementsIdArray.forEach(function(value){
500        var element = jQuery("#" + value);
501        element.hide();
502        
503        // show elements if in editor and debug mode is true
504        
505        var dataDebug = _this.$element.data("debug");
506        var dataEditor = _this.$element.data("editor");
507        
508        if(dataEditor == "yes" && dataDebug == true){
509          element.show();
510          element.css({"border": "3px solid red"});
511        }else{
512          element.css({"border": "none"});
513        }
514      });
515    });
516    
517    // find active elements     
518    objTabs.find(container).find(elements).removeClass('active');
519    objTabs.find(container).eq(currentTabIndex).find(elements).addClass('active');
520    
521    var activeElements = jQuery(defaults.classes.activeElements);
522    
523    // show active elements
524    
525    jQuery(activeElements).each(function(){
526      
527      elementsId = jQuery(this).data('id');
528      var elementsIdArray = elementsId.split(',');
529      
530      elementsIdArray.forEach(function(value){
531        var element = jQuery("#" + value);
532        
533        elementParentArray.forEach(function(index, value){
534          
535          if(currentTabIndex == index){
536            element.show();
537            hideContainer();
538          }
539        });
540      });
541    });
542  };
543  
544  /**
545  * This function closes a tab
546  * @param {Event} e - The event that is triggered when a tab is closed
547  * @param {Object} oTab - The tab object that should be closed
548  */
549  ResponsiveContentTabs.prototype._closeTab = function(e, oTab) {
550    var _this = this;
551    var doQueueOnState = typeof _this.options.animationQueue === 'string';
552    var doQueue;
553    
554    if(oTab !== undefined) {
555      if(doQueueOnState && _this.getState() === _this.options.animationQueue) {
556        doQueue = true;
557      } else if(doQueueOnState) {
558        doQueue = false;
559      } else {
560        doQueue = _this.options.animationQueue;
561      }
562      
563      // Deactivate tab
564      oTab.active = false;
565      // Set default class to the tab button
566      if(_this.getState() === 'tabs'){
567        oTab.tab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);    
568      }
569      
570      if(_this.getState() === 'accordion'){
571        oTab.accordionTab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);    
572      }
573      
574      // Run panel transition
575      _this._doTransition(oTab.panel, _this.options.animation, 'close', function() {
576        // Set default class to the accordion tab button and tab panel
577        oTab.accordionTab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);
578        oTab.panel.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);
579      }, !doQueue);
580      
581      this.$element.trigger('tabs-deactivate', oTab);
582    }
583  };
584  
585  /**
586  * This function runs an effect on a panel
587  * @param {Element} panel - The HTML element of the tab panel
588  * @param {String} method - The transition method reference
589  * @param {String} state - The state (open/closed) that the panel should transition to
590  * @param {Function} callback - The callback function that is called after the transition
591  * @param {Boolean} dequeue - Defines if the event queue should be dequeued after the transition
592  */
593  ResponsiveContentTabs.prototype._doTransition = function(panel, method, state, callback, dequeue) {
594    var effect;
595    var _this = this;
596    
597    // Get effect based on method
598    switch(method) {
599      case 'slide':
600      effect = (state === 'open') ? 'slideDown' : 'slideUp';
601      break;
602      case 'fade':
603      effect = (state === 'open') ? 'fadeIn' : 'fadeOut';
604      break;
605      default:
606      effect = (state === 'open') ? 'show' : 'hide';
607      // When default is used, set the duration to 0
608      _this.options.duration = 0;
609      break;
610    }
611    
612    // Add the transition to a custom queue
613    this.$queue.queue('responsive-tabs',function(next){
614      // Run the transition on the panel
615      panel[effect]({
616        duration: _this.options.duration,
617        complete: function() {
618          // Call the callback function
619          callback.call(panel, method, state);
620          // Run the next function in the queue
621          next();
622        }
623      });
624    });
625    
626    // When the panel is openend, dequeue everything so the animation starts
627    if(state === 'open' || dequeue) {
628      this.$queue.dequeue('responsive-tabs');
629    }
630    
631  };
632  
633  /**
634  * This function returns the collapsibility of the tab in this state
635  * @returns {Boolean} The collapsibility of the tab
636  */
637  ResponsiveContentTabs.prototype._isCollapisble = function() {
638    return (typeof this.options.collapsible === 'boolean' && this.options.collapsible) || (typeof this.options.collapsible === 'string' && this.options.collapsible === this.getState());
639  };
640  
641  /**
642  * This function returns a tab by numeric reference
643  * @param {Integer} numRef - Numeric tab reference
644  * @returns {Object} Tab object
645  */
646  ResponsiveContentTabs.prototype._getTab = function(numRef) {
647    return this.tabs[numRef];
648  };
649  
650  /**
651  * This function returns the numeric tab reference based on a hash selector
652  * @param {String} selector - Hash selector
653  * @returns {Integer} Numeric tab reference
654  */
655  ResponsiveContentTabs.prototype._getTabRefBySelector = function(selector) {
656    // Loop all tabs
657    
658    for (var i=0; i<this.tabs.length; i++) {
659      // Check if the hash selector is equal to the tab selector
660      if(this.tabs[i].selector === selector) {
661        return i;
662      }
663    }
664    // If none is found return a negative index
665    return -1;
666  };
667  
668  /**
669  * This function returns the current tab element
670  * @returns {Object} Current tab element
671  */
672  ResponsiveContentTabs.prototype._getCurrentTab = function() {
673    return this._getTab(this._getCurrentTabRef());
674  };
675  
676  /**
677  * This function returns the next tab's numeric reference
678  * @param {Integer} currentTabRef - Current numeric tab reference
679  * @returns {Integer} Numeric tab reference
680  */
681  ResponsiveContentTabs.prototype._getNextTabRef = function(currentTabRef) {
682    var tabRef = (currentTabRef || this._getCurrentTabRef());
683    var nextTabRef = (tabRef === this.tabs.length - 1) ? 0 : tabRef + 1;
684    return (this._getTab(nextTabRef).disabled) ? this._getNextTabRef(nextTabRef) : nextTabRef;
685  };
686  
687  /**
688  * This function returns the previous tab's numeric reference
689  * @returns {Integer} Numeric tab reference
690  */
691  ResponsiveContentTabs.prototype._getPreviousTabRef = function() {
692    return (this._getCurrentTabRef() === 0) ? this.tabs.length - 1 : this._getCurrentTabRef() - 1;
693  };
694  
695  /**
696  * This function returns the current tab's numeric reference
697  * @returns {Integer} Numeric tab reference
698  */
699  ResponsiveContentTabs.prototype._getCurrentTabRef = function() {
700    // Loop all tabs
701    for (var i=0; i<this.tabs.length; i++) {
702      // If this tab is active, return it
703      if(this.tabs[i].active) {
704        return i;
705      }
706    }
707    // No tabs have been found, return negative index
708    return -1;
709  };
710  
711  /**
712  * This function gets the tallest tab and applied the height to all tabs
713  */
714  ResponsiveContentTabs.prototype._equaliseHeights = function() {
715    var maxHeight = 0;
716    
717    $.each($.map(this.tabs, function(tab) {
718      maxHeight = Math.max(maxHeight, tab.panel.css('minHeight', '').height());
719      return tab.panel;
720    }), function() {
721      this.css('minHeight', maxHeight);
722    });
723  };
724  
725  //
726  // HELPER FUNCTIONS
727  //
728  
729  ResponsiveContentTabs.prototype._isInView = function($element) {
730    var docViewTop = $(window).scrollTop(),
731    docViewBottom = docViewTop + $(window).height(),
732    elemTop = $element.offset().top,
733    elemBottom = elemTop + $element.height();
734    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
735  };
736  
737  //
738  // PUBLIC FUNCTIONS
739  //
740  
741  /**
742  * This function activates a tab
743  * @param {Integer} tabRef - Numeric tab reference
744  * @param {Boolean} stopRotation - Defines if the tab rotation should stop after activation
745  */
746  ResponsiveContentTabs.prototype.activate = function(tabRef, stopRotation) {
747    var e = jQuery.Event('tabs-activate');
748    var oTab = this._getTab(tabRef);
749    
750    if(!oTab.disabled) {
751      this._openTab(e, oTab, true, stopRotation || true);
752    }
753  };
754  
755  /**
756  * This function deactivates a tab
757  * @param {Integer} tabRef - Numeric tab reference
758  */
759  ResponsiveContentTabs.prototype.deactivate = function(tabRef) {
760    var e = jQuery.Event('tabs-dectivate');
761    var oTab = this._getTab(tabRef);
762    if(!oTab.disabled) {
763      this._closeTab(e, oTab);
764    }
765  };
766  
767  /**
768  * This function enables a tab
769  * @param {Integer} tabRef - Numeric tab reference
770  */
771  ResponsiveContentTabs.prototype.enable = function(tabRef) {
772    var oTab = this._getTab(tabRef);
773    if(oTab){
774      oTab.disabled = false;
775      oTab.tab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled);
776      oTab.accordionTab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled);
777    }
778  };
779  
780  /**
781  * This function disable a tab
782  * @param {Integer} tabRef - Numeric tab reference
783  */
784  ResponsiveContentTabs.prototype.disable = function(tabRef) {
785    var oTab = this._getTab(tabRef);
786    if(oTab){
787      oTab.disabled = true;
788      oTab.tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
789      oTab.accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
790    }
791  };
792  
793  /**
794  * This function gets the current state of the plugin
795  * @returns {String} State of the plugin
796  */
797  ResponsiveContentTabs.prototype.getState = function() {
798    return this.state;
799  };
800  
801  /**
802  * This function starts the rotation of the tabs
803  * @param {Integer} speed - The speed of the rotation
804  */
805  ResponsiveContentTabs.prototype.startRotation = function(speed) {
806    var _this = this;
807    // Make sure not all tabs are disabled
808    if(this.tabs.length > this.options.disabled.length) {
809      this.rotateInterval = setInterval(function(){
810        var e = jQuery.Event('rotate');
811        _this._openTab(e, _this._getTab(_this._getNextTabRef()), true);
812      }, speed || (($.isNumeric(_this.options.rotate)) ? _this.options.rotate : 4000) );
813    } else {
814      throw new Error("Rotation is not possible if all tabs are disabled");
815    }
816  };
817  
818  /**
819  * This function stops the rotation of the tabs
820  */
821  ResponsiveContentTabs.prototype.stopRotation = function() {
822    window.clearInterval(this.rotateInterval);
823    this.rotateInterval = 0;
824  };
825  
826  /**
827  * This function can be used to get/set options
828  * @return {any} Option value
829  */
830  ResponsiveContentTabs.prototype.option = function(key, value) {
831    if(value) {
832      this.options[key] = value;
833    }
834    return this.options[key];
835  };
836  
837  /** jQuery wrapper */
838  $.fn.responsiveContentTabs = function ( event, options ) {
839    var args = arguments;
840    var instance;
841    
842    if(event == 'init'){
843      
844      if (options === undefined || typeof options === 'object') {
845        return this.each(function () {
846          if (!$.data(this, 'responsivecontenttabs')) {
847            $.data(this, 'responsivecontenttabs', new ResponsiveContentTabs( this, options ));
848          }
849        });
850      } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
851        instance = $.data(this[0], 'responsivecontenttabs');
852        
853        // Allow instances to be destroyed via the 'destroy' method
854        if (options === 'destroy') {
855          // TODO: destroy instance classes, etc
856          $.data(this, 'responsivecontenttabs', null);
857        }        
858        
859        if (instance instanceof ResponsiveContentTabs && typeof instance[options] === 'function') {
860          return instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
861        } else {
862          return this;
863        }
864      }
865      
866    }
867    
868    if(event == 'reinit'){
869      
870      if (options === undefined || typeof options === 'object') {
871        
872        if (!$.data(this, 'responsivecontenttabs')) {
873          $.data(this, 'responsivecontenttabs', new ResponsiveContentTabs( this, options ));
874        }
875        
876      }
877      
878    }
879    
880    
881  };
882  
883}(jQuery, window));

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.