File manager - Edit - /usr/local/cpanel/base/sharedjs/ssl_tabs.js
Back
// Copyright 2025 WebPros International, LLC // All rights reserved. // copyright@cpanel.net http://cpanel.net // This code is subject to the cPanel license. Unauthorized copying is prohibited. /** * Provides functionality for use by the SSL/TLS Certificates tab bar. */ (function initializeTabNavigation() { "use strict"; // Prevent multiple initializations if (window.__cpsslTabsInit) { return; } window.__cpsslTabsInit = true; var navigation = document.querySelector(".tls-tabs"); if (!navigation) { return; } var overlayParent = findBestContainer(); var overlay = createOverlayElement(); var tabs = navigation.querySelectorAll(".tls-tabs__tab"); var navigationLocked = false; setupOverlayParent(overlayParent); overlayParent.appendChild(overlay); attachTabClickHandlers(tabs); setupPageShowHandler(); /** * Finds a container element to overlay. * Checks for common content containers and Angular app containers. * * @returns {HTMLElement} The container element or document.body as fallback */ function findBestContainer() { return document.querySelector(".body-content") || document.querySelector(".content") || document.querySelector("#app_tlsWizard") // angularjs app || document.querySelector("#app_tlsStatus") // angularjs app || document.body; } /** * Creates the overlay element that covers the main content during navigation. * * @returns {HTMLElement} The overlay div element */ function createOverlayElement() { var overlayElement = document.createElement("div"); overlayElement.className = "tls-tabs__overlay"; overlayElement.setAttribute("aria-hidden", "true"); overlayElement.hidden = true; return overlayElement; } /** * Sets up the overlay parent element with proper positioning. * So absolutely positioned overlay children will be releative to this partent, not the page * * @param {HTMLElement} parent - The parent element for the overlay */ function setupOverlayParent(parent) { if (!parent) { return; } parent.classList.add("tls-tabs__overlay-parent"); if (parent !== document.body) { var parentStyle = window.getComputedStyle(parent); if (parentStyle.position === "static") { parent.style.position = "relative"; } } } /** * Attempts to find a better container if the current one is document.body. * This handles cases where the container may not be available during initial load. */ function ensureOverlayParent() { if (overlayParent !== document.body) { return; } var betterContainer = findBestContainer(); if (betterContainer && betterContainer !== document.body) { overlayParent = betterContainer; setupOverlayParent(overlayParent); overlayParent.appendChild(overlay); } } /** * Sets or clears the busy state for navigation. * * @param {boolean} isBusy - Whether the navigation is busy * @param {HTMLElement} [activeTab] - The tab that was clicked (optional) */ function setBusy(isBusy, activeTab) { ensureOverlayParent(); if (isBusy) { showBusyState(activeTab); } else { clearBusyState(); } } /** * Shows the busy state with overlay and loading spinner. * * @param {HTMLElement} [activeTab] - The tab that was clicked */ function showBusyState(activeTab) { overlay.hidden = false; overlay.classList.add("is-visible"); overlayParent.setAttribute("aria-busy", "true"); navigation.querySelector(".tls-tabs__nav").classList.add("is-busy"); if (activeTab) { activeTab.classList.add("is-loading"); activeTab.setAttribute("aria-busy", "true"); } } /** * Clears the busy state if navigation is not locked. */ function clearBusyState() { if (navigationLocked) { return; } overlay.classList.remove("is-visible"); overlay.hidden = true; overlayParent.removeAttribute("aria-busy"); navigation.querySelector(".tls-tabs__nav").classList.remove("is-busy"); Array.from(tabs).forEach(tab => { tab.classList.remove("is-loading"); tab.removeAttribute("aria-busy"); }); } /** * Handles click events on tab links. * * @param {Event} event - The click event */ function handleTabClick(event) { var tab = event.currentTarget; if (!tab) { return; } if (tab.classList.contains("is-active")) { event.preventDefault(); return; } var href = tab.getAttribute("href"); if (!href) { return; } event.preventDefault(); // Lock navigation state to prevent any code from clearing the spinner navigationLocked = true; setBusy(true, tab); // Use requestAnimationFrame to ensure the browser renders the loading state. // Frame 1: Browser applies the is-loading class and calculates styles // Frame 2: Browser renders the spinner and starts the animation // Then we navigate, keeping the animation visible during page unload // TODO: Not sure if absolutely necessary; maybe replace or remove this requestAnimationFrame(function() { requestAnimationFrame(function() { // Small delay to ensure spinner completes at least one partial rotation setTimeout(function() { window.location.href = href; }, 100); }); }); } /** * Attaches click handlers to all tab links. * * @param {NodeList} tabElements - The tab link elements */ function attachTabClickHandlers(tabElements) { Array.from(tabElements).forEach(el => { el.addEventListener("click", handleTabClick); }); } /** * Sets up the pageshow event handler for browser back/forward navigation. */ function setupPageShowHandler() { window.addEventListener("pageshow", function(event) { // event.persisted is true when page is restored from browser back/forward cache (bfcache) if (event.persisted) { navigationLocked = false; setBusy(false); } }); } })();
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.04 |
proxy
|
phpinfo
|
Settings