LEFT | RIGHT |
1 (function(){ | 1 (function() |
| 2 { |
2 document.addEventListener("DOMContentLoaded", function() | 3 document.addEventListener("DOMContentLoaded", function() |
3 { | 4 { |
4 | 5 |
| 6 /************************************************************************** |
| 7 * General |
| 8 **************************************************************************/ |
| 9 |
5 // Change html class name from "no-js" to "js" | 10 // Change html class name from "no-js" to "js" |
6 document.documentElement.className = "js"; | 11 document.documentElement.className = "js"; |
7 | 12 |
8 // Toggle Navbar Collapse | 13 /************************************************************************** |
| 14 * Navbar |
| 15 **************************************************************************/ |
| 16 |
9 function toggleNavbarCollapse() | 17 function toggleNavbarCollapse() |
10 { | 18 { |
11 var navbarCollapseEls = this.parentElement.getElementsByClassName("navbar-
collapse"); | 19 var navbarCollapseEls = this.parentElement.getElementsByClassName("navbar-
collapse"); |
12 for (var i = 0; i < navbarCollapseEls.length; i++) | 20 for (var i = 0; i < navbarCollapseEls.length; i++) |
13 { | 21 { |
14 navbarCollapseEls[i] | 22 navbarCollapseEls[i] |
15 .classList.toggle("open") | 23 .classList.toggle("open") |
16 } | 24 } |
17 } | 25 } |
18 | 26 |
19 var toggleNavbarCollapseEls = document.getElementsByClassName("toggle-navbar
-collapse"); | 27 var toggleNavbarCollapseEls = document.getElementsByClassName("toggle-navbar
-collapse"); |
20 for (var i = 0; i < toggleNavbarCollapseEls.length; i++) | 28 for (var i = 0; i < toggleNavbarCollapseEls.length; i++) |
21 { | 29 { |
22 toggleNavbarCollapseEls[i] | 30 toggleNavbarCollapseEls[i] |
23 .addEventListener("click", toggleNavbarCollapse, false); | 31 .addEventListener("click", toggleNavbarCollapse, false); |
24 } | 32 } |
25 | 33 |
26 // Custom Select | 34 /************************************************************************** |
27 function onClickCustomSelect() | 35 * CustomSelect |
28 { | 36 **************************************************************************/ |
29 var options = this.nextElementSibling; | 37 |
30 if (options.getAttribute("aria-hidden") == "true") | 38 function CustomSelect(select) |
31 { | 39 { |
32 options.removeAttribute("aria-hidden"); | 40 this.select = select; |
33 this.setAttribute("aria-expanded", "true"); | 41 this.close(); |
| 42 this.select |
| 43 .addEventListener("click", this._onClick.bind(this), false); |
| 44 this.select |
| 45 .addEventListener("focusout", this._onFocusOut.bind(this), false); |
| 46 } |
| 47 |
| 48 CustomSelect.prototype._onFocusOut = function() |
| 49 { |
| 50 // setTimeout to allow document.activeElement |
| 51 // to move to newly focused element |
| 52 setTimeout(function() |
| 53 { |
| 54 var newFocus = document.activeElement; |
| 55 |
| 56 if (newFocus |
| 57 .classList.contains("custom-select-selected") || |
| 58 newFocus |
| 59 .classList.contains("custom-select-option") || |
| 60 newFocus |
| 61 .parentElement |
| 62 .classList.contains("custom-select-option")) |
| 63 { |
| 64 return; |
| 65 } |
| 66 |
| 67 this.close(); |
| 68 |
| 69 }.bind(this), 1); |
| 70 } |
| 71 |
| 72 CustomSelect.prototype._onClick = function(event) |
| 73 { |
| 74 if (event.target.classList.contains("custom-select-selected")) |
| 75 { |
| 76 var options = this.select.querySelector(".custom-select-options"); |
| 77 if (options.getAttribute("aria-hidden") == "true") |
| 78 { |
| 79 this.open(); |
| 80 } |
| 81 else |
| 82 { |
| 83 this.close(); |
| 84 } |
| 85 } |
| 86 } |
| 87 |
| 88 CustomSelect.prototype.open = function() |
| 89 { |
| 90 this.select |
| 91 .querySelector(".custom-select-selected") |
| 92 .setAttribute("aria-expanded", "true"); |
| 93 |
| 94 this.select |
| 95 .querySelector(".custom-select-options") |
| 96 .removeAttribute("aria-hidden"); |
| 97 } |
| 98 |
| 99 CustomSelect.prototype.close = function() |
| 100 { |
| 101 this.select |
| 102 .querySelector(".custom-select-selected") |
| 103 .setAttribute("aria-expanded", "false"); |
| 104 |
| 105 this.select |
| 106 .querySelector(".custom-select-options") |
| 107 .setAttribute("aria-hidden", "true"); |
| 108 } |
| 109 |
| 110 new CustomSelect(document.getElementById("language-select")); |
| 111 |
| 112 /************************************************************************** |
| 113 * Accordion |
| 114 **************************************************************************/ |
| 115 |
| 116 function Accordion(accordion) |
| 117 { |
| 118 this.accordion = accordion; |
| 119 |
| 120 var accordionButtons = this.accordion.getElementsByClassName('accordion-to
ggle-button'); |
| 121 for (var i = 0; i < accordionButtons.length; i++) |
| 122 { |
| 123 // Close all sections except the first |
| 124 if (i !== 0) |
| 125 { |
| 126 accordionButtons[i].setAttribute("aria-expanded", "false"); |
| 127 document |
| 128 .getElementById( accordionButtons[i].getAttribute("aria-controls") ) |
| 129 .setAttribute("hidden", "true"); |
| 130 } |
| 131 } |
| 132 |
| 133 this.accordion |
| 134 .addEventListener("click", this._onClick.bind(this), false); |
| 135 this.accordion |
| 136 .addEventListener("keydown", this._onKeyDown.bind(this), false); |
| 137 } |
| 138 |
| 139 Accordion.prototype.toggleSection = function(clickedButton) |
| 140 { |
| 141 // Hide currently expanded section |
| 142 var expandedButton = this.accordion.querySelector("button[aria-expanded='t
rue']"); |
| 143 if (expandedButton) |
| 144 { |
| 145 expandedButton.setAttribute("aria-expanded", "false"); |
| 146 document |
| 147 .getElementById( expandedButton.getAttribute("aria-controls") ) |
| 148 .setAttribute("hidden", "true"); |
| 149 } |
| 150 |
| 151 // If currently expanded section is clicked |
| 152 if (expandedButton === clickedButton) return; |
| 153 |
| 154 // Expand new section |
| 155 clickedButton.setAttribute("aria-expanded", "true"); |
| 156 document |
| 157 .getElementById( clickedButton.getAttribute("aria-controls") ) |
| 158 .removeAttribute("hidden"); |
| 159 } |
| 160 |
| 161 Accordion.prototype.focusNextSection = function() |
| 162 { |
| 163 var currentFocus = document.activeElement; |
| 164 var nextheading = currentFocus.parentElement.nextElementSibling.nextElemen
tSibling; |
| 165 |
| 166 if (nextheading) |
| 167 { |
| 168 nextheading // .accordion-heading |
| 169 .firstElementChild // .accordion-toggle-button |
| 170 .focus(); |
34 } | 171 } |
35 else | 172 else |
36 { | 173 { |
37 options.setAttribute("aria-hidden", "true"); | 174 this.accordion |
38 this.setAttribute("aria-expanded", "false"); | 175 .firstElementChild // .accordion-heading |
39 } | 176 .firstElementChild // .accordion-toggle-button |
40 } | 177 .focus(); |
41 | 178 } |
42 var customSelectEls = document.getElementsByClassName('custom-select-selecte
d'); | 179 } |
43 for (var i = 0; i < customSelectEls.length; i++) | 180 |
44 { | 181 Accordion.prototype.focusPrevSection = function() |
45 customSelectEls[i] | 182 { |
46 .addEventListener("click", onClickCustomSelect, false); | 183 var currentFocus = document.activeElement; |
47 customSelectEls[i] | 184 var prevAccordionBody = currentFocus.parentElement.previousElementSibling; |
48 .nextElementSibling | 185 |
49 .setAttribute("aria-hidden", "true"); | 186 if (prevAccordionBody) |
50 } | 187 { |
51 | 188 prevAccordionBody // .accordion-body |
52 // Browser Select | 189 .previousElementSibling // .accordion-heading |
| 190 .firstElementChild // .accordion-toggle-button |
| 191 .focus(); |
| 192 } |
| 193 else |
| 194 { |
| 195 this.accordion |
| 196 .lastElementChild // .accordion-body |
| 197 .previousElementSibling // .accordion-heading |
| 198 .firstElementChild // .accordion-toggle-button |
| 199 .focus(); |
| 200 } |
| 201 } |
| 202 |
| 203 Accordion.prototype._onKeyDown = function(event) |
| 204 { |
| 205 if (!event.target.classList.contains("accordion-toggle-button")) return; |
| 206 |
| 207 if (event.key == "ArrowUp" || event.keyCode == 38) |
| 208 { |
| 209 this.focusPrevSection(); |
| 210 } |
| 211 else if (event.key == "ArrowDown" || event.keyCode == 40) |
| 212 { |
| 213 this.focusNextSection(); |
| 214 } |
| 215 } |
| 216 |
| 217 Accordion.prototype._onClick = function(event) |
| 218 { |
| 219 if (!event.target.classList.contains("accordion-toggle-button")) return; |
| 220 |
| 221 this.toggleSection(event.target); |
| 222 } |
| 223 |
| 224 var productTopicsAccordion = document.getElementById('product-topics-accordi
on'); |
| 225 if (productTopicsAccordion) |
| 226 { |
| 227 new Accordion(productTopicsAccordion); |
| 228 } |
| 229 |
| 230 /************************************************************************** |
| 231 * BrowserSelect |
| 232 **************************************************************************/ |
| 233 |
53 function BrowserSelect(select) | 234 function BrowserSelect(select) |
54 { | 235 { |
55 this.browserSelect = select; | 236 this.select = select; |
56 | 237 CustomSelect.apply(this, [this.select]); |
57 this.DEFAULT_BROWSER = "chrome"; | 238 |
58 this.BROWSER_STORAGE_KEY = "BROWSER"; | 239 this.BROWSER_STORAGE_KEY = "BROWSER"; |
59 this.BROWSER_AUTODETECTED_STORAGE_KEY = "BROWSER_AUTODETECTED"; | 240 this.BROWSER_AUTODETECTED_STORAGE_KEY = "BROWSER_AUTODETECTED"; |
60 | 241 this.SUPPORTED_BROWSERS = ["chrome", "opera", "samsungBrowser", |
61 this.browserSelect | 242 "yandexbrowser", "maxthon", "msie", |
| 243 "msedge", "firefox", "ios", "safari"]; |
| 244 this.DEFAULT_BROWSER = "chrome"; |
| 245 |
| 246 this.select |
62 .addEventListener("click", this._onClickOrKeyDown.bind(this), false); | 247 .addEventListener("click", this._onClickOrKeyDown.bind(this), false); |
63 | 248 |
64 this.browserSelect | 249 this.select |
65 .addEventListener("keydown", this._onClickOrKeyDown.bind(this), false); | 250 .addEventListener("keydown", this._onClickOrKeyDown.bind(this), false); |
66 | 251 |
67 var storedBrowser = localStorage.getItem(this.BROWSER_STORAGE_KEY); | 252 var storedBrowser = localStorage.getItem(this.BROWSER_STORAGE_KEY); |
68 if (storedBrowser) | 253 if (storedBrowser) this.selectOption(storedBrowser); |
69 { | 254 else this.detectBrowser(); |
70 this.selectOption(storedBrowser); | 255 } |
71 } | 256 |
72 else | 257 BrowserSelect.prototype = Object.create(CustomSelect.prototype); |
73 { | 258 BrowserSelect.prototype.constructor = BrowserSelect; |
74 this.detectBrowser(); | |
75 } | |
76 } | |
77 | 259 |
78 BrowserSelect.prototype.detectBrowser = function() | 260 BrowserSelect.prototype.detectBrowser = function() |
79 { | 261 { |
80 localStorage.setItem(this.BROWSER_AUTODETECTED_STORAGE_KEY, "true"); | 262 for (var i = 0; i < this.SUPPORTED_BROWSERS.length; i++) |
81 | 263 { |
82 var browser; | 264 var supportedBrowser = this.SUPPORTED_BROWSERS[i]; |
83 if (bowser.chrome) browser = "chrome"; | 265 if (bowser[supportedBrowser]) |
84 else if (bowser.opera) browser = "opera"; | 266 { |
85 else if (bowser.coast) browser = "opera"; | 267 localStorage.setItem(this.BROWSER_AUTODETECTED_STORAGE_KEY, "true"); |
86 else if (bowser.samsungBrowser) browser = "samsung"; | 268 return this.selectOption(supportedBrowser); |
87 else if (bowser.yandexbrowser) browser = "yandex"; | 269 } |
88 else if (bowser.maxthon) browser = "maxthon"; | 270 } |
89 else if (bowser.msie) browser = "ie"; | 271 |
90 else if (bowser.msedge) browser = "edge"; | 272 this.selectOption(this.DEFAULT_BROWSER); |
91 else if (bowser.firefox) browser = "firefox"; | 273 }; |
92 else if (bowser.ios) browser = "ios"; | |
93 else if (bowser.safari) browser = "safari"; | |
94 else | |
95 { | |
96 localStorage.removeItem(this.BROWSER_AUTODETECTED_STORAGE_KEY); | |
97 browser = this.DEFAULT_BROWSER; | |
98 } | |
99 | |
100 this.selectOption(browser); | |
101 } | |
102 | 274 |
103 BrowserSelect.prototype.selectOption = function(browser) | 275 BrowserSelect.prototype.selectOption = function(browser) |
104 { | 276 { |
105 // Save value to Local Storage | |
106 localStorage.setItem(this.BROWSER_STORAGE_KEY, browser); | 277 localStorage.setItem(this.BROWSER_STORAGE_KEY, browser); |
107 | 278 |
108 // Change body class | 279 // Change body class |
109 document.body.className = "ua-"+browser; | 280 var bodyClassList = Array.prototype.slice.call(document.body.classList); |
| 281 for (var i = 0; i < bodyClassList.length; i++) |
| 282 { |
| 283 if (bodyClassList[i].indexOf('ua-') > -1) |
| 284 { |
| 285 document.body.classList.remove(bodyClassList[i]); |
| 286 } |
| 287 } |
| 288 document.body.classList.add("ua-" + browser); |
| 289 |
| 290 // Check selected option |
| 291 var selectedItem = this.select |
| 292 .querySelector("[data-value='" + browser + "']"); |
| 293 selectedItem.setAttribute("aria-checked", "true"); |
110 | 294 |
111 // Set selected option | 295 // Set selected option |
112 var selectedOption = document.createElement("li"); | 296 var selectedOption = selectedItem.innerHTML; |
113 selectedOption.innerHTML = this | |
114 .browserSelect | |
115 .querySelector("[data-value='"+browser+"']") | |
116 .innerHTML; | |
117 | 297 |
118 if (localStorage.getItem(this.BROWSER_AUTODETECTED_STORAGE_KEY)) | 298 if (localStorage.getItem(this.BROWSER_AUTODETECTED_STORAGE_KEY)) |
119 { | 299 { |
120 selectedOption.innerHTML += "<span class='muted'>(autodetected)</span>"; | 300 var autodetected = document |
121 } | 301 .getElementById('browser-select-autodetected') |
122 | 302 .innerHTML; |
123 this.browserSelect | 303 selectedOption += "<span class='muted'>(" + autodetected + ")</span>"; |
124 .querySelector(".custom-select-selected") | 304 } |
125 .innerHTML = selectedOption.innerHTML; | 305 |
126 } | 306 this.select |
| 307 .querySelector(".custom-select-selected") |
| 308 .innerHTML = selectedOption; |
| 309 }; |
127 | 310 |
128 BrowserSelect.prototype._onClickOrKeyDown = function(event) | 311 BrowserSelect.prototype._onClickOrKeyDown = function(event) |
129 { | 312 { |
130 if (!event.target.classList.contains("custom-select-option")) return; | 313 if (!event.target.classList.contains("custom-select-option")) return; |
131 | 314 |
132 var IS_ENTER_KEY = event.key == "Enter" || event.keyCode == 13; | 315 var IS_ENTER_KEY = event.key == "Enter" || event.keyCode == 13; |
133 if (event.keyCode && !IS_ENTER_KEY) return; | 316 if (event.keyCode && !IS_ENTER_KEY) return; |
134 | 317 |
135 localStorage.removeItem(this.BROWSER_AUTODETECTED_STORAGE_KEY); | 318 localStorage.removeItem(this.BROWSER_AUTODETECTED_STORAGE_KEY); |
136 | 319 |
| 320 // Uncheck previously checked option |
| 321 this.select |
| 322 .querySelector("[aria-checked='true']") |
| 323 .setAttribute("aria-checked", "false"); |
| 324 |
137 this.selectOption(event.target.getAttribute("data-value")); | 325 this.selectOption(event.target.getAttribute("data-value")); |
138 | 326 |
139 // Close Select | 327 this.close(); |
140 document | 328 }; |
141 .querySelector("#browser-select .custom-select-selected") | |
142 .setAttribute("aria-expanded", "false"); | |
143 | |
144 document | |
145 .querySelector("#browser-select .custom-select-options") | |
146 .setAttribute("aria-hidden", "true"); | |
147 } | |
148 | 329 |
149 var browserSelect = document.getElementById("browser-select"); | 330 var browserSelect = document.getElementById("browser-select"); |
150 if (browserSelect) | 331 if (browserSelect) |
151 { | 332 { |
152 new BrowserSelect(document.getElementById("browser-select")); | 333 new BrowserSelect(browserSelect); |
153 } | 334 } |
154 | 335 |
155 }, false); | 336 }, false); |
156 }()); | 337 }()); |
LEFT | RIGHT |