1/*! 2 * Script for initializing globally-used functions and libs. 3 * 4 * @since 1.0.0 5 */ 6 7/* global jQuery, MakeFrontEnd */ 8 9var MakeFrontEnd = MakeFrontEnd || {}; 10 11(function($, MakeFrontEnd) { 12 'use strict'; 13 14 if ( ! MakeFrontEnd ) { return; } 15 16 /** 17 * MakeFrontEnd 18 * 19 * Starts with the following data properties added via script localization: 20 * - fitvids 21 */ 22 23 var Make = $.extend(MakeFrontEnd, { 24 /** 25 * Object for storing data. 26 * 27 * @since 1.0.0 28 */ 29 cache: {}, 30 31 /** 32 * Initialize the script. 33 * 34 * @since 1.0.0 35 */ 36 init: function() { 37 this.cacheElements(); 38 this.bindEvents(); 39 }, 40 41 /** 42 * Cache jQuery objects for later. 43 * 44 * @since 1.0.0 45 */ 46 cacheElements: function() { 47 this.cache = { 48 $window: $(window), 49 $document: $(document) 50 }; 51 }, 52 53 /** 54 * Set up event listeners. 55 * 56 * @since 1.0.0 57 */ 58 bindEvents: function() { 59 var self = this; 60 61 $(function() { 62 self.navigationInit(); 63 self.skipLinkFocusFix(); 64 self.navigationHoverFix(); 65 self.fitVidsInit( $('.ttfmake-embed-wrapper') ); 66 self.handleGalleryOverlayOnMobileDevices(); 67 } ); 68 69 // Infinite Scroll support 70 self.cache.$document.on('post-load', function() { 71 // FitVids 72 var $elements = $('.ttfmake-embed-wrapper:not(:has(".fluid-width-video-wrapper"))'); 73 self.fitVidsInit($elements); 74 }); 75 }, 76 77 /** 78 * Initialize the mobile menu functionality. 79 * 80 * @since 1.0.0 81 * 82 * @return void 83 */ 84 navigationInit: function() { 85 var container, button, menu, links, subMenus; 86 87 button = document.getElementsByClassName( 'menu-toggle' )[0]; 88 if ( 'undefined' === typeof button ) { 89 return; 90 } 91 92 container = button.parentElement; 93 if ( ! container ) { 94 return; 95 } 96 97 menu = container.getElementsByTagName( 'ul' )[0]; 98 99 // Hide menu toggle button if menu is empty and return early. 100 if ( 'undefined' === typeof menu ) { 101 button.style.display = 'none'; 102 return; 103 } 104 105 menu.setAttribute( 'aria-expanded', 'false' ); 106 if ( -1 === menu.className.indexOf( 'nav-menu' ) ) { 107 menu.className += ' nav-menu'; 108 } 109 110 button.onclick = function() { 111 if ( -1 !== container.className.indexOf( 'toggled' ) ) { 112 container.className = container.className.replace( ' toggled', '' ); 113 button.setAttribute( 'aria-expanded', 'false' ); 114 menu.setAttribute( 'aria-expanded', 'false' ); 115 } else { 116 container.className += ' toggled'; 117 button.setAttribute( 'aria-expanded', 'true' ); 118 menu.setAttribute( 'aria-expanded', 'true' ); 119 } 120 }; 121 122 // Get all the link elements within the menu. 123 links = menu.getElementsByTagName( 'a' ); 124 subMenus = menu.getElementsByTagName( 'ul' ); 125 126 var $links = $(links); 127 128 $links.on( 'focus',function() { 129 $(this).parents('li').addClass('focus'); 130 }).on( 'blur', function() { 131 $(this).parents('li').removeClass('focus'); 132 }); 133 134 // Set menu items with submenus to aria-haspopup="true". 135 for ( var i = 0, len = subMenus.length; i < len; i++ ) { 136 subMenus[i].parentNode.setAttribute( 'aria-haspopup', 'true' ); 137 } 138 }, 139 140 /** 141 * Fix tab destination after 'Skip to content' link has been clicked. 142 * 143 * @since 1.0.0 144 * 145 * @return void 146 */ 147 skipLinkFocusFix: function() { 148 var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, 149 is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, 150 is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; 151 152 if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) { 153 window.addEventListener( 'hashchange', function() { 154 var id = location.hash.substring( 1 ), 155 element; 156 157 if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { 158 return; 159 } 160 161 element = document.getElementById( id ); 162 163 if ( element ) { 164 if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { 165 element.tabIndex = -1; 166 } 167 168 element.trigger( 'focus' ); 169 } 170 }, false ); 171 } 172 }, 173 174 /** 175 * Bind a click event to nav menu items with sub menus. 176 * 177 * Fixes an issue with the sub menus not appearing correctly in some situations on iPads. 178 * 179 * @link http://blog.travelvictoria.com.au/2012/03/31/make-sure-your-websites-drop-down-menus-work-on-an-ipad/ 180 * 181 * @since 182 * 183 * @return void 184 */ 185 navigationHoverFix: function() { 186 this.cache.$dropdown = this.cache.$dropdown || $('li:has(ul)', '#site-navigation'); 187 this.cache.$dropdown.on('click', function() { 188 return true; 189 }); 190 }, 191 192 /** 193 * Initialize FitVids. 194 * 195 * @since 1.0.0 196 * 197 * @return void 198 */ 199 fitVidsInit: function($elements) { 200 // Make sure lib is loaded. 201 if (! $.fn.fitVids) { 202 return; 203 } 204 205 var self = this, 206 $container = $elements || $('.ttfmake-embed-wrapper'), 207 selectors = self.fitvids.selectors || '', 208 args = {}; 209 210 // Get custom selectors 211 if (selectors) { 212 args.customSelector = selectors; 213 } 214 215 // Run FitVids 216 $container.fitVids(args); 217 218 // Fix padding issue with Blip.tv. Note that this *must* happen after Fitvids runs. 219 // The selector finds the Blip.tv iFrame, then grabs the .fluid-width-video-wrapper div sibling. 220 $container.find('.fluid-width-video-wrapper:nth-child(2)').css({ 'paddingTop': 0 }); 221 }, 222 223 /** 224 * Handle gallery overlay show / hide on mobile devices "hover". 225 * 226 * @since 1.8.6 227 * 228 * @return void 229 */ 230 handleGalleryOverlayOnMobileDevices: function() { 231 $('.builder-section-gallery .builder-gallery-item').on('touchstart', function() { 232 var $this = $(this); 233 234 if ($this.find('.builder-gallery-content').length) { 235 $this.addClass('touchstart'); 236 } 237 }); 238 239 $('body:not(.builder-gallery-item)').on('touchstart', function() { 240 $('.builder-gallery-item').removeClass('touchstart'); 241 }); 242 } 243 }); 244 245 Make.init(); 246})(jQuery, MakeFrontEnd);
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.