1(function ($) { // Mobile Menu 2 var buildMenu = true; 3 4 // todo: when more regression time is available, consider changing this initializer to use asi_getSmallestViewportWidth() 5 window.asi_screenWidth = !window.jQuery ? (window.screen.width || window.innerWidth) : $(window).width(); 6 window.asi_resizeHandlerLock = false; 7 8 function consolidateMenus() { 9 if ($('#mobile-menu').length) { 10 return false; 11 } 12 13 function mobileToggle(toggleText) { 14 return $('<a class="toggle-nav" href="#"><div class="mobile-menu-icon"><span></span></div> ' + (toggleText ? toggleText : 'Menu') + '</a>'); 15 } 16 17 var $nav = $('<nav id="mobile-menu" class="mobile-menu"></nav>'); 18 var $ul = $('<ul />'); 19 var $endUserList = $('.EndUserStatus .tabs li').clone(), 20 $headerMenuList = $('header .Menu .tabs>li').clone(), 21 $sectionMenuList = $('section .Menu .tabs'); 22 23 $ul.append($headerMenuList); 24 $ul.append($endUserList); 25 $nav.append(mobileToggle()); 26 $nav.append($ul); 27 28 $sectionMenuList.wrapAll('<nav class="mobile-menu"></nav>').parent().prepend(mobileToggle('Side Menu')); 29 30 $('body').append($nav); 31 $('.mobile-menu a.toggle-nav').on('click', function(e) { 32 e.preventDefault(); 33 e.stopPropagation(); 34 $(this).parent().toggleClass('active'); 35 }); 36 37 $('.mobile-menu').on('click touchstart', 'li>a', function() { 38 var $this = $(this); 39 if ($this.next('ul.dropdown').length) { 40 $('.mobile-menu li.active').not($(this).parents('li')).removeClass('active'); 41 $(this).parent('li').toggleClass('active'); 42 return false; 43 } 44 return true; 45 }); 46 47 return true; 48 } 49 50 function asi_getSmallestViewportWidth() { 51 // for the purpose of logic using this function, we want to know size of currently-viewable viewport 52 // different browsers report "viewable viewport" size inconsistently, sometimes reporting the entire (larger) document's size 53 // so we will look for the smallest number out of all relevant methods 54 // except that iPhone safari aways reports width of phone in portrait mode, regardless of orientation, so smallest is always "width in portrait" 55 var jqW = $(window).width(); 56 57 var orientation = window.orientation !== undefined ? window.orientation : window.screen && window.screen.orientation ? window.screen.orientation.angle : undefined; 58 59 var wsW = window.screen.width; 60 var wsAw = window.screen.availWidth; 61 var wsH = window.screen.height; 62 var wsAh = window.screen.availHeight; 63 var wIw = window.innerWidth; 64 var ret = 9999; 65 if (jqW && jqW < ret) ret = jqW; 66 if (wsW && wsW < ret) ret = wsW; 67 if (wsAw && wsAw < ret) ret = wsAw; 68 if (wIw && wIw < ret) ret = wIw; 69 70 // this is a "heuristic" determination assuming that 1) entire documents fits in the viewport, 2) wsW was chosen as "smallest", but 3) phone is in landscape orientation and 4) (implicitely) that wsW < wsH 71 // i.e. if this is a phone that always reports "width in portait mode as wsW", but phone is in landscape, overwrite the width to be wsH 72 if (Math.abs(orientation) === 90 && wsW < wsH && ret === wsW) { 73 ret = wsH; 74 } 75 return ret; 76 } 77 78 function setScreenWidth() { 79 var viewport = document.querySelector("meta[name=viewport]"); 80 // at time of writing this correct report of asi_getSmallestViewportWidth() depends on width=device-width being present (chicken-and-egg problem) 81 // downside of unneccessarily changing viewport's content is unneccessary firing of "resize" event 82 // todo: consider finding a way to limit this condition further, body only executes when asi_getSmallestViewportWidth() is (or about to become) under mobile menu threshold 83 if (viewport) { 84 viewport.setAttribute('content', 'width=device-width, initial-scale=1.0'); 85 } 86 87 window.asi_screenWidth = asi_getSmallestViewportWidth(); 88 } 89 90 function addClass(e, className) { 91 if (!e) return; 92 93 if (typeof e.classList === "object") { 94 if (!e.classList.contains(className)) { 95 e.classList.add(className); 96 } 97 } else { 98 $(e).addClass(className); 99 } 100 } 101 102 function removeClass(e, className) { 103 if (!e) return; 104 105 if (typeof e.classList === "object") { 106 e.classList.remove(className); 107 } else { 108 $(e).removeClass(className); 109 } 110 } 111 112 function changeWindowClass() { 113 var viewport = document.querySelector('meta[name=viewport]'); 114 if (!viewport) { 115 var metaTag = document.createElement('meta'); 116 metaTag.name = 'viewport'; 117 metaTag.content = ''; 118 document.getElementsByTagName('head')[0].appendChild(metaTag); 119 viewport = document.querySelector('meta[name=viewport]'); 120 } 121 var el = document.getElementsByTagName('body')[0]; 122 if (window.asi_screenWidth <= 480) { // todo: consider evaluating actual media query 123 viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0'); 124 if (buildMenu) { 125 consolidateMenus(); 126 buildMenu = false; 127 } 128 removeClass(el, 'tablet'); 129 addClass(el, 'mobile'); 130 } else if (window.asi_screenWidth < 768) { // todo: consider evaluating actual media query 131 viewport.setAttribute('content', 'width=device-width, initial-scale=.45, user-scalable=yes'); 132 removeClass(el, 'mobile'); 133 addClass(el, 'tablet'); 134 } else { 135 viewport.setAttribute('content', ''); 136 removeClass(el, 'mobile'); 137 removeClass(el, 'tablet'); 138 } 139 } 140 141 changeWindowClass(); 142 143 $(document).ready(function() { 144 $.ui.dialog.prototype.options.autoReposition = true; 145 146 // todo: consider evaluating actual media query
147 if (window.asi_screenWidth <= (parseInt(window.mobileMenuWidth) || 480)) { 148 consolidateMenus(); 149 } 150 151 $(window).on('resize orientationchange', function(event) { 152 // idea is to a) handle only one of possibly many events during orientation change, and 153 // b) give the browser a little time before we query for viewport size 154 if (window.asi_resizeHandlerLock) { 155 // don't do anything - already handled 156 return; 157 } 158 159 //window.console.trace(event.type); 160 window.asi_resizeHandlerLock = true; 161 window.asi_resizeHandler = setTimeout(function() { 162 try { 163 var vpw = asi_getSmallestViewportWidth(); 164 if (vpw === window.asi_screenWidth) { 165 return; 166 } 167 setScreenWidth(); 168 changeWindowClass(); 169 $('.ui-tooltip').remove(); // remove tooltips 170 $('.ui-dialog-content:visible').each(function() { // reposition modal 171 if ($(this).dialog) { 172 $(this).dialog('option', 'position', $(this).dialog('option', 'position')); 173 } 174 }); 175 } finally { 176 window.asi_resizeHandlerLock = false; 177 } 178 }, 100); 179 }); 180 181 $(document).on('click touchstart', function(event) { 182 if (!$(event.target).closest('#mobile-menu').length && !$(event.target).is('#mobile-menu')) { 183 if ($('#mobile-menu').hasClass('active')) { 184 $('#mobile-menu').removeClass('active'); 185 } 186 } 187 }); 188 }); 189})(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.