1const mainHeader = document.querySelector(".dda-main-header"); 2const getKeyboardFocusableElements = (element = document) => { 3 return [ 4 ...element.querySelectorAll( 5 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])' 6 ), 7 ].filter( 8 (el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden") 9 ); 10}; 11 12const isSafari = () => { 13 const isSafariBrowser = /^((?!chrome|android).)*safari/i.test( 14 navigator.userAgent 15 ); 16 17 const isWebKit = "WebkitAppearance" in document.documentElement.style; 18 const isAppleDevice = navigator.vendor && navigator.vendor.includes("Apple"); 19 20 const isNotChromeIOS = !/CriOS/i.test(navigator.userAgent); 21 const isNotFirefoxIOS = !/FxiOS/i.test(navigator.userAgent); 22 23 return ( 24 isSafariBrowser && 25 isWebKit && 26 isAppleDevice && 27 isNotChromeIOS && 28 isNotFirefoxIOS 29 ); 30}; 31 32const applyDropdownAccessibility = (element, show) => { 33 element.setAttribute("aria-hidden", !show); 34 const triggerEl = element.previousElementSibling; 35 36 if (show) { 37 if (triggerEl) { 38 triggerEl.classList.add("active"); 39 triggerEl.setAttribute("aria-expanded", show); 40 } 41 const elementId = element.id; 42 const focussables = getKeyboardFocusableElements(element); 43 setTimeout(() => { 44 focussables[0].focus(); 45 }, 100); 46 let triggerMouseDown = false; 47 48 const cleanup = () => {
49 focussables.forEach((el) => { 50 el.removeEventListener("blur", blurHandler); 51 }); 52 triggerEl.removeEventListener("mousedown", triggerClickHandler); 53 triggerEl.classList.remove("active"); 54 }; 55 56 const blurHandler = (e) => { 57 if (triggerMouseDown) { 58 setTimeout(() => triggerEl.blur(), 100); 59 cleanup(); 60 triggerMouseDown = false; 61 return; 62 } 63 if ( 64 (!e.relatedTarget || 65 e.relatedTarget.closest(`#${elementId}`) === null) && 66 !e.target.classList.contains("dropdown-btn") 67 ) { 68 if (!triggerEl.classList.contains("mega-dropdown")) { 69 updateVisibility(element, false); 70 } 71 cleanup(); 72 } 73 }; 74 const triggerClickHandler = () => { 75 triggerMouseDown = true; 76 }; 77 78 triggerEl.addEventListener("mousedown", triggerClickHandler);
79 focussables.forEach((el) => { 80 el.addEventListener("blur", blurHandler); 81 }); 82 } else { 83 if (triggerEl) { 84 triggerEl.classList.remove("active"); 85 triggerEl.setAttribute("aria-expanded", show); 86 } 87 } 88}; 89 90var toggleNavVisibility = function (element, visibility) { 91 // if (!element.classList.contains("dropdown-container")) { 92 // mainHeader.style.zIndex = visibility ? 0 : 2; 93 // } 94 95 if (element.classList.contains("dda-side-nav")) { 96 element.closest("#sub-header").classList.toggle("dda-sub-header--normal"); 97 } 98}; 99 100var toggleVisibility = function (element) { 101 if (!element) return; 102 const isDisplayed = window.getComputedStyle(element).display !== "none"; 103 element.style.cssText += `; display: ${!isDisplayed ? "block" : "none"} !important;`; 104 105 106 toggleNavVisibility(element, !isDisplayed); 107 applyDropdownAccessibility(element, !isDisplayed); 108}; 109 110var updateVisibility = function (element, visibility) { 111 if (!element) return; 112 const existingStyle = window.getComputedStyle(element); 113 if (existingStyle.display !== "none") { 114 toggleNavVisibility(element, visibility); 115 } 116 if (existingStyle.display === "none" && !visibility) return; 117 element.style.cssText += `; display: ${visibility ? "block" : "none"} !important;`; 118 119 120 applyDropdownAccessibility(element, visibility); 121}; 122 123window.onload = function () { 124 const profileBtn = document.getElementById("profileBtn"); 125 const loginSection = document.getElementById("loginSection"); 126 const accessBtn = document.getElementById("accessBtn"); 127 const accessSection = document.getElementById("accessSection"); 128 const selectEntity = document.getElementById("selectEntity"); 129 const entitiesList = document.getElementById("entitiesList"); 130 const chatBtn = document.getElementById("chatBtn"); 131 const chatBtnAi = document.getElementById("chatBtnAi"); 132 const chatPopup = document.getElementById("chatPopup"); 133 const sideNavCloseBtn = document.getElementById("sideNavCloseBtn"); 134 const sideMenu = document.getElementById("side-nav"); 135 const mobileLoginBtn = document.getElementById("mobileLoginBtn"); 136 const mobileAccessBtn = document.getElementById("mobileAccessBtn"); 137 const iconMenuBtn = document.querySelector("#iconMenu"); 138 const megaBtns = document.querySelectorAll(".mega-dropdown"); 139 const mobileSearchBtn = document.getElementById("mobileSearchBtn"); 140 const mobileSearchSection = document.getElementById("mobileSearchSection"); 141 const bannerDescriptions = document.querySelectorAll( 142 ".banner__description--desktop" 143 ); 144 145 megaBtns.forEach((btn) => { 146 btn.addEventListener("mouseover", (e) => { 147 megaBtns.forEach((mbtn) => { 148 mbtn.classList.remove("active"); 149 }); 150 }); 151 }); 152 153 document.addEventListener("click", (event) => { 154 const target = event.target; 155 let isClickInsideLoginSection; 156 if (loginSection) { 157 isClickInsideLoginSection = loginSection.contains(target); 158 } 159 const isClickInsideProfileBtn = profileBtn?.contains(target); 160 const isClickInsideAccessBtn = accessBtn?.contains(target); 161 const isClickInsideAccessSection = accessSection?.contains(target); 162 const isClickInsideSelectEntity = selectEntity.contains(target); 163 // const isClickInsideEntitySearch = entitySearch.contains(target) 164 const isClickInsideChatBtn = chatBtn?.contains(target); 165 const isClickInsideChatBtnAi = chatBtnAi?.contains(target); 166 const isCloseSideNavBtnClicked = sideNavCloseBtn?.contains(target); 167 const isMobileLoginClicked = mobileLoginBtn?.contains(target); 168 const isMobileAccessClicked = mobileAccessBtn?.contains(target); 169 const isMobileSearchClicked = mobileSearchBtn?.contains(target); 170 171 if (isCloseSideNavBtnClicked) { 172 toggleVisibility(sideMenu); 173 } 174 175 if (target.classList.contains("mega-dropdown")) { 176 event.preventDefault(); 177 applyDropdownAccessibility( 178 target.nextElementSibling, 179 target.classList.toggle("active") 180 ); 181 } 182 183 if (isClickInsideChatBtn) { 184 event.preventDefault(); 185 toggleVisibility(chatPopup); 186 } 187 188 if (isClickInsideChatBtnAi) { 189 if (isSafari()) { 190 window.open("https://chat.dubai.ae/?lang=en-US&mode=modal&source=DDA", "_blank").focus(); 191 } else { 192 193 } 194 } 195 196 if (isMobileSearchClicked) { 197 updateVisibility(sideMenu, false); 198 toggleVisibility(mobileSearchSection); 199 } else if (isMobileAccessClicked) { 200 event.preventDefault(); 201 toggleVisibility(accessSection); 202 } else if (isMobileLoginClicked) { 203 event.preventDefault(); 204 toggleVisibility(loginSection); 205 } else if (isClickInsideProfileBtn) { 206 updateVisibility(accessSection, false); 207 toggleVisibility(loginSection); 208 } else if (isClickInsideLoginSection) { 209 // TODO 210 } else if (isClickInsideAccessBtn) { 211 updateVisibility(loginSection, false); 212 toggleVisibility(accessSection); 213 } else if (isClickInsideAccessSection) { 214 // TODO 215 } else if (isClickInsideSelectEntity) { 216 if (!isClickInsideEntitySearch) { 217 toggleVisibility(entitiesList); 218 } 219 } else { 220 updateVisibility(entitiesList, false); 221 updateVisibility(loginSection, false); 222 updateVisibility(accessSection, false); 223 } 224 });
225 226 //* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This allows the user to have multiple dropdowns without any conflict */ 227 const dropdown = document.getElementsByClassName("dropdown-btn"); 228 let i; 229 230 for (i = 0; i < dropdown.length; i++) { 231 dropdown[i].addEventListener("click", function () { 232 this.classList.toggle("active"); 233 const dropdownContent = this.nextElementSibling; 234 toggleVisibility(dropdownContent); 235 }); 236 } 237 238 if (iconMenuBtn) { 239 iconMenuBtn.addEventListener("click", function () { 240 updateVisibility(mobileSearchSection, false); 241 toggleVisibility(sideMenu); 242 }); 243 } 244 245 bannerDescriptions.forEach((desc) => { 246 const text = desc.innerHTML.trim().substr(0, 90); 247 desc.innerHTML = text + "... "; 248 }); 249 250 if (window.location.href.includes("normal.html")) { 251 document.getElementById("chatBtnAiImage").src = 252 "./assets/images/dubai-ai-blue.svg"; 253 } 254};
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.