1/* ---------------- 2Tabby.js 1.4.0 3 4based on ResponsiveTabs.js 1.10 5by Pete Love 6------------------- */ 7 8var RESPONSIVEUI = {}; 9 10(function($) { 11 12 RESPONSIVEUI.responsiveTabs = function () { 13 var $tabSets = $('.responsive-tabs'); 14 15 if (!$tabSets.hasClass('responsive-tabs--enabled')) { // if we haven't already called this function and enabled tabs 16 $tabSets.addClass('responsive-tabs--enabled'); 17 18 //loop through all sets of tabs on the page 19 var tablistcount = 1; 20 21 $tabSets.each(function() { 22 23 var $tabs = $(this); 24 25 // add tab heading and tab panel classes 26 $tabs.children(':header, p').addClass('responsive-tabs__heading'); 27 $tabs.children('div').addClass('responsive-tabs__panel'); 28 29 // determine if markup already identifies the active tab panel for this set of tabs 30 // if not then set first heading and tab to be the active one 31 var $activePanel = $tabs.find('.responsive-tabs__panel--active'); 32 if(!$activePanel.length) { 33 $activePanel = $tabs.find('.responsive-tabs__panel').first().addClass('responsive-tabs__panel--active'); 34 } 35 36 /* Add active class to the active header of the panel (FOR MOBILE) */ 37 $activeHeader = $activePanel.prev(); 38 if($activeHeader !== null) { 39 $activeHeader.addClass("responsive-tabs__heading--active"); 40 } 41 42 $tabs.find('.responsive-tabs__panel').not('.responsive-tabs__panel--active').hide().attr('aria-hidden','true'); //hide all except active panel 43 $activePanel.attr('aria-hidden', 'false'); 44 /* make active tab panel hidden for mobile * 45 $activePanel.addClass('responsive-tabs__panel--closed-accordion-only');*/ 46 47 // wrap tabs in container - to be dynamically resized to help prevent page jump 48 var $tabsWrapper = $('<div/>', {'class': 'responsive-tabs-wrapper' }); 49 $tabs.wrap($tabsWrapper); 50 51 var highestHeight = 0; 52 53 // determine height of tallest tab panel. Used later to prevent page jump when tabs are clicked 54 $tabs.find('.responsive-tabs__panel').each(function() { 55 var tabHeight = $(this).height(); 56 if (tabHeight > highestHeight) { 57 highestHeight = tabHeight; 58 } 59 }); 60 61 //create the tab list 62 var $tabList = $('<ul/>', { 'class': 'responsive-tabs__list', 'role': 'tablist' }); 63 64 //loop through each heading in set 65 var tabcount = 1; 66 $tabs.find('.responsive-tabs__heading').each(function() { 67 68 var $tabHeading = $(this); 69 var $tabPanel = $(this).next(); 70 71 $tabHeading.attr('tabindex', 0); 72 73 // CREATE TAB ITEMS (VISIBLE ON DESKTOP) 74 //create tab list item from heading 75 //associate tab list item with tab panel 76 var $tabListItem = $('<li/>', { 77 'class': 'responsive-tabs__list__item', 78 html: $tabHeading.html(), 79 id: 'tablist' + tablistcount + '-tab' + tabcount, 80 'aria-controls': 'tablist' + tablistcount +'-panel' + tabcount, 81 'role': 'tab', 82 tabindex: 0, 83 keydown: function (objEvent) { 84 if (objEvent.keyCode === 13) { // if user presses 'enter' 85 $tabListItem.click(); 86 } 87 }, 88 click: function() { 89 90 //Show associated panel 91 92 //set height of tab container to highest panel height to avoid page jump 93 $tabsWrapper.css('height', highestHeight); 94 95 // remove hidden mobile class from any other panel as we'll want that panel to be open at mobile size 96 $tabs.find('.responsive-tabs__panel--closed-accordion-only').removeClass('responsive-tabs__panel--closed-accordion-only'); 97 98 // close current panel and remove active state from its (hidden on desktop) heading 99 $tabs.find('.responsive-tabs__panel--active').toggle().removeClass('responsive-tabs__panel--active').attr('aria-hidden','true').prev().removeClass('responsive-tabs__heading--active'); 100 101 //make this tab panel active 102 $tabPanel.toggle().addClass('responsive-tabs__panel--active').attr('aria-hidden','false'); 103 104 //make the hidden heading active 105 $tabHeading.addClass('responsive-tabs__heading--active'); 106 107 //remove active state from currently active tab list item 108 $tabList.find('.responsive-tabs__list__item--active').removeClass('responsive-tabs__list__item--active'); 109 110 //make this tab active 111 $tabListItem.addClass('responsive-tabs__list__item--active'); 112 113 //reset height of tab panels to auto 114 $tabsWrapper.css('height', 'auto'); 115 116 } 117 }); 118 119 //associate tab panel with tab list item 120 $tabPanel.attr({ 121 'role': 'tabpanel', 122 'aria-labelledby': $tabListItem.attr('id'), 123 id: 'tablist' + tablistcount + '-panel' + tabcount 124 }); 125 126 // if this is the active panel then make it the active tab item 127 if($tabPanel.hasClass('responsive-tabs__panel--active')) { 128 $tabListItem.addClass('responsive-tabs__list__item--active'); 129 } 130 131 // add tab item 132 $tabList.append($tabListItem); 133 134 135 // TAB HEADINGS (VISIBLE ON MOBILE) 136 // if user presses 'enter' on tab heading trigger the click event 137 $tabHeading.keydown(function(objEvent) { 138 if (objEvent.keyCode === 13) { 139 $tabHeading.click(); 140 } 141 }); 142 143 //toggle tab panel if click heading (on mobile) 144 $tabHeading.click(function() { 145 146 // remove any hidden mobile class 147 $tabs.find('.responsive-tabs__panel--closed-accordion-only').removeClass('responsive-tabs__panel--closed-accordion-only'); 148 149 // if this isn't currently active 150 if (!$tabHeading.hasClass('responsive-tabs__heading--active')){ 151 152 var oldActivePos, 153 $activeHeading = $tabs.find('.responsive-tabs__heading--active'); 154 155 // if there is an active heading, get its position 156 if($activeHeading.length) { 157 oldActivePos = $activeHeading.offset().top; 158 } 159 160 // close currently active panel and remove active state from any hidden heading 161 $tabs.find('.responsive-tabs__panel--active').slideToggle().removeClass('responsive-tabs__panel--active').prev().removeClass('responsive-tabs__heading--active'); 162 163 //close all tabs 164 $tabs.find('.responsive-tabs__panel').hide().attr('aria-hidden','true'); 165 166 //open this panel 167 $tabPanel.slideToggle().addClass('responsive-tabs__panel--active').attr('aria-hidden','false'); 168 169 // make this heading active 170 $tabHeading.addClass('responsive-tabs__heading--active'); 171 172 var $currentActive = $tabs.find('.responsive-tabs__list__item--active'); 173 174 //set the active tab list item (for desktop) 175 $currentActive.removeClass('responsive-tabs__list__item--active'); 176 var panelId = $tabPanel.attr('id'); 177 var tabId = panelId.replace('panel','tab'); 178 $('#' + tabId).addClass('responsive-tabs__list__item--active'); 179 180 //scroll to active heading only if it is below previous one 181 var tabsPos = $tabs.offset().top; 182 var newActivePos = ($tabHeading.offset().top) - 15; 183 if(oldActivePos < newActivePos) { 184 $('html, body').animate({ scrollTop: tabsPos }, 0).animate({ scrollTop: newActivePos }, 550); 185 } 186 187 } 188 189 // if this tab panel is already active 190 else { 191 192 // hide panel but give it special responsive-tabs__panel--closed-accordion-only class so that it can be visible at desktop size 193 $tabPanel.removeClass('responsive-tabs__panel--active').slideToggle(function () { $(this).addClass('responsive-tabs__panel--closed-accordion-only'); }); 194 195 //remove active heading class 196 $tabHeading.removeClass('responsive-tabs__heading--active'); 197 198 //don't alter classes on tabs as we want it active if put back to desktop size 199 } 200 201 }); 202 203 tabcount ++; 204 }); 205 206 // add finished tab list to its container 207 $tabs.prepend($tabList); 208 209 210 // next set of tabs on page 211 tablistcount ++; 212 }); 213 } 214 }; 215 216 // Additional helper function to ensure embedded tab content will be visible when the tab is opened 217 $("body").on("click", ".responsive-tabs__list__item, .responsive-tabs__heading, .tabbylink", function() { 218 if (typeof(Event) === "function") { 219 window.dispatchEvent(new Event("resize")); 220 } else { 221 var evt = window.document.createEvent("UIEvents"); 222 evt.initUIEvent("resize", true, false, window, 0); 223 window.dispatchEvent(evt); 224 } 225 }); 226 227})(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.