1/*1788237616000*/ 2/** 3 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com 4 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 5 */ 6 7/* 8 * This function gets loaded when all the HTML, not including the portlets, is 9 * loaded. 10 */ 11 12AUI().ready(function () { 13}); 14 15/* 16 * This function gets loaded after each and every portlet on the page. 17 * 18 * portletId: the current portlet's id 19 * node: the Alloy Node object of the current portlet 20 */ 21Liferay.Portlet.ready(function (_portletId, _node) { 22}); 23 24 25(function () { 26 const initDropdowns = () => { 27 28 document.querySelectorAll('[data-controls-for-dropdown]').forEach(dropdownToggle => { 29 let menuIsOpen = false 30 const menu = dropdownToggle.querySelector('.dropdown-menu'); 31 32 const showMenu = () => { 33 dropdownToggle.classList.add('show'); 34 menu.classList.add('show'); 35 menuIsOpen = true 36 console.log("Showing menu") 37 } 38 39 40 41 const hideMenu = () => { 42 setTimeout(() => { 43 if (!dropdownToggle.matches(':hover') && !menu.matches(':hover')) { 44 dropdownToggle.classList.remove('show'); 45 menu.classList.remove('show'); 46 menuIsOpen = false 47 } 48 }, 200); 49 } 50 const dontRedirect=(e)=>{ 51 if(!menuIsOpen){ 52 e.stopPropagation() 53 e.preventDefault() 54 } 55 56 } 57 58 if (menu) { 59 dropdownToggle.addEventListener('mouseenter', () => { 60 showMenu() 61 }); 62 dropdownToggle.addEventListener('mouseleave', (event) => { 63 hideMenu() 64 }); 65 const dropdownLink = dropdownToggle.querySelector("a") 66 67 const onLinkClick=(event0)=>{ 68 const dropdownLinks = document.querySelectorAll('[data-controls-for-dropdown]') 69 dropdownLinks.forEach(link => { 70 const dropdown0 = link.querySelector(".dropdown-menu") 71 if (dropdown0 && dropdown0 !== dropdownToggle && dropdown0.classList.contains("show")) { 72 dropdown0.classList.remove("show") 73 link.classList.remove("show") 74 } 75 }) 76 77 const clickedInsideButton = menu.contains(event0.target.parentNode); 78 const clickedInsideDropdown = dropdownToggle.contains(event0.target.parentNode); 79 if (!clickedInsideButton && !clickedInsideDropdown) { 80 hideMenu() 81 } else { 82 dontRedirect(event0) 83 showMenu() 84 } 85 } 86 87 dropdownLink.addEventListener('click', (event0) => { 88 onLinkClick(event0) 89 }); 90 91 dropdownLink.addEventListener('keydown', (event0) => { 92 if(event0.code === "Enter"){ 93 onLinkClick(event0) 94 } 95 96 }); 97 98 document.addEventListener('click', (event) => { 99 if (!menu.contains(event.target)) { 100 hideMenu() 101 } 102 }) 103 104 document.addEventListener('keydown', (event) => { 105 if (event.code === "Enter" && !menu.contains(event.target)) { 106 hideMenu() 107 } 108 }) 109 } 110 }); 111 } 112 113 const keepScrollPosOnLocaleChange = () => { 114 const sessionYPos = sessionStorage.getItem("scroll-position-y") 115 if (sessionYPos) { 116 window.scrollTo(0, parseInt(sessionYPos)) 117 } 118 } 119 120 121 const initSearchButton = () => { 122 try { 123 const searchBtn = document.querySelector(".nav-search-btn") 124 const iconClose = searchBtn.querySelector(".if-close") 125 const iconSearch = searchBtn.querySelector(".if-search") 126 const searchBar = document.querySelector(".main-row.header-search-bar") 127 searchBtn.addEventListener("click", () => { 128 if (searchBar.classList.contains("d-none")) { 129 searchBar.classList.remove("d-none") 130 iconClose.classList.remove("d-none") 131 iconSearch.classList.add("d-none") 132 } else { 133 searchBar.classList.add("d-none") 134 iconClose.classList.add("d-none") 135 iconSearch.classList.remove("d-none") 136 } 137 }) 138 } catch (e) { 139 140 } 141 142 } 143 144 const addLanguageIdForInnerLinks = () => { 145 const localesSet = new Set(["fi", "sv", "en", "et", "fr", "es", "uk", "tr", "ru", "zh", "fa", "ar"]) 146 const langPrefix = `/${Liferay.ThemeDisplay.getLanguageId().substring(0, 2)}` 147 document.querySelectorAll("#main-content a[href^='/']").forEach(link => { 148 const href = link.getAttribute("href") 149 const firstSegment = href.split("/")[1] 150 if (!localesSet.has(firstSegment) && !href.includes("/documents/")) { 151 link.setAttribute("href", `${langPrefix}${href}`) 152 } 153 }) 154 } 155 156 const initTableOfContents = () => { 157 const tableOfContents = document.querySelector("#table-of-contents"); 158 159 if (!tableOfContents) { 160 return; 161 } 162 163 tableOfContents.innerHTML = ""; 164 165 const generateHeadingId = (heading => { 166 return Math.random().toString(36).substring(2, 10); 167 }) 168 169 const headings = document.querySelectorAll("#main-content .col-xl-8 h2"); 170
171 headings.forEach(h => { 172 const headerOffsetHeight = document.querySelector("#banner").offsetHeight; 173 h.setAttribute("style", `padding-top: ${headerOffsetHeight}px; margin-top:-${headerOffsetHeight}px;`); 174 let id = h.id; 175 if (id === null || id === '') { 176 id = generateHeadingId(h); 177 h.id = id; 178 } 179 const li = document.createElement("li"); 180 const a = document.createElement("a"); 181 a.href = "#" + id; 182 a.innerText = h.innerText; 183 li.append(a); 184 tableOfContents.append(li); 185 }) 186 187 if (headings) { 188 tableOfContents.classList.remove("hide"); 189 } 190 } 191 192 const setSearchBarPlaceholders = () => { 193 194 function applyPlaceholder() { 195 document.querySelectorAll("input[data-qa-id='searchInput']").forEach(sb => { 196 sb.setAttribute("placeholder", 'Search\x2e\x2e\x2e') 197 }) 198 } 199 200 // ToDo find better solution to fix placeholder texts 201 setTimeout(applyPlaceholder, 1000); 202 203 } 204 205 /* 206 * This function gets loaded when everything, including the portlets, is on 207 * the page. 208 */ 209 210 211 const initMobileMenus = () => { 212 const mobileControls = document.querySelectorAll("[data-cc-for-menu]") 213 mobileControls.forEach((mb) => { 214 const controlElementId = mb.getAttribute("data-cc-for-menu") 215 const controlElement = document.getElementById(controlElementId.replace("#", "")) 216 if (controlElement) { 217 const hasAriaExpanded = mb.getAttribute("aria-expanded") !== undefined 218 mb.addEventListener('click', () => { 219 controlElement.classList.add("d-block") 220 if (hasAriaExpanded) { 221 mb.setAttribute("aria-expanded", "true") 222 } 223 }) 224 const closeBtn = controlElement.querySelector(".mobile-menu-close-btn") 225 closeBtn.addEventListener('click', () => { 226 controlElement.classList.remove("d-block") 227 if (hasAriaExpanded) { 228 mb.setAttribute("aria-expanded", "false") 229 } 230 }) 231 } 232 }) 233 } 234 235 Liferay.on('allPortletsReady', function () { 236 initMobileMenus() 237 initDropdowns() 238 keepScrollPosOnLocaleChange() 239 addLanguageIdForInnerLinks() 240 initSearchButton() 241 initTableOfContents() 242 setSearchBarPlaceholders() 243 }) 244})() 245
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.