All Downloads are FREE. Search and download functionalities are using the official Maven repository.

application.tabs.js Maven / Gradle / Ivy

There is a newer version: 1.2.21
Show newest version
const observer = new MutationObserver(updateTabs);
const observerOptions = {childList: true, subtree: true};
const tabCache = new Map();
let isRestoringTabs = false;

export function updateTabs() {
    const tabButtons = document.querySelectorAll('.tab-button');
    const tabsContainers = new Set();
    tabButtons.forEach(button => {
        const tabsContainer = button.closest('.tabs-container');
        tabsContainers.add(tabsContainer);
        if (button.hasListener) return;
        button.hasListener = true;
        button.addEventListener('click', (event) => {
            event.stopPropagation();
            const forTab = button.getAttribute('data-for-tab');
            let tabsContainerId = button.closest('.tabs-container').id;
            if (button.classList.contains('active')) return; // Skip if already active
            try {
                localStorage.setItem(`selectedTab_${tabsContainerId}`, forTab);
                tabCache.set(tabsContainerId, forTab); // Update the cache
            } catch (e) {
                console.warn('Failed to save tab state to localStorage:', e);
            }
            let tabsParent = button.closest('.tabs-container');
            const allTabButtons = tabsParent.querySelectorAll('.tab-button');
            allTabButtons.forEach(btn => {
                btn.classList.remove('active');
            });
            button.classList.add('active');
            console.log(`Active tab set to: ${forTab}, button:`, button);
            let selectedContent = null;
            const tabContents = tabsParent.querySelectorAll('.tab-content');
            tabContents.forEach(content => {
                if (content.getAttribute('data-tab') === forTab) {
                    content.classList.add('active');
                    content.style.display = 'block'; // Ensure the content is displayed
                    selectedContent = content;
                    // Recursively update nested tabs
                    updateNestedTabs(selectedContent);
                } else {
                    content.classList.remove('active');
                    content.style.display = 'none'; // Hide the content instead of removing it
                }
            });
        });
    });

    // Restore the selected tabs from localStorage
    isRestoringTabs = true;
    try {
        tabsContainers.forEach(tabsContainer => {
            const savedTab = getSavedTab(tabsContainer.id);
            if (savedTab) {
                const savedButton = tabsContainer.querySelector(`.tab-button[data-for-tab="${savedTab}"]`);
                if (savedButton) {
                    savedButton.click(); // Activate the tab
                }
            } else {
                tabsContainer.querySelector('.tab-button')?.click(); // Activate the first tab
            }
        });
    } finally {
        isRestoringTabs = false;
    }
}

export function restoreTabs() {
    isRestoringTabs = true;
    // Restore the selected tabs from localStorage before adding event listeners
    try {
        document.querySelectorAll('.tabs-container').forEach(tabsContainer => {
            const savedTab = localStorage.getItem(`selectedTab_${tabsContainer.id}`);
            if (savedTab) {
                const savedButton = tabsContainer.querySelector(`.tab-button[data-for-tab="${savedTab}"]`);
                tabsContainer.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
                if (savedButton) {
                    savedButton.classList.add('active');
                    const forTab = savedButton.getAttribute('data-for-tab');
                    const selectedContent = tabsContainer.querySelector(`.tab-content[data-tab="${forTab}"]`);
                    if (selectedContent) {
                        selectedContent.classList.add('active');
                        selectedContent.style.display = 'block'; // Ensure the content is displayed
                        updateNestedTabs(selectedContent);
                    }
                    // Hide other tab contents
                    tabsContainer.querySelectorAll(`.tab-content:not([data-tab="${forTab}"])`).forEach(content => {
                        content.style.display = 'none';
                    });
                } else {
                    tabsContainer.querySelector('.tab-button')?.click(); // Activate the first tab if no saved tab
                }
            }
        });
    } finally {
        isRestoringTabs = false;
    }
}

function getSavedTab(containerId) {
    if (tabCache.has(containerId)) {
        return tabCache.get(containerId);
    }
    try {
        const savedTab = localStorage.getItem(`selectedTab_${containerId}`);
        tabCache.set(containerId, savedTab);
        return savedTab;
    } catch (e) {
        console.warn('Failed to retrieve saved tab from localStorage:', e);
        return null;
    }
}

function updateNestedTabs(element) {
    const tabsContainers = element.querySelectorAll('.tabs-container');
    tabsContainers.forEach(tabsContainer => {
        try {
            tabsContainer.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
            let hasActiveButton = false;
            const nestedButtons = tabsContainer.querySelectorAll('.tab-button');
            nestedButtons.forEach(nestedButton => {
                if (nestedButton.classList.contains('active')) {
                    hasActiveButton = true;
                }
            });
            if (!hasActiveButton) {
                const activeContent = tabsContainer.querySelector('.tab-content.active');
                if (activeContent) {
                    const activeTab = activeContent.getAttribute('data-tab');
                    const activeButton = tabsContainer.querySelector(`.tab-button[data-for-tab="${activeTab}"]`);
                    if (activeButton) {
                        setTimeout(() => activeButton.click(), 0); // Activate the tab asynchronously
                    }
                } else {
                    setTimeout(() => tabsContainer.querySelector('.tab-button')?.click(), 0); // Activate the first tab asynchronously
                }
            }
             const savedTab = getSavedTab(tabsContainer.id);
            console.log(`Saved tab for container ${tabsContainer.id}: ${savedTab}`);
             if (savedTab) {
                 const savedButton = tabsContainer.querySelector(`.tab-button[data-for-tab="${savedTab}"]`);
                 if (savedButton) {
                     if (!savedButton.classList.contains('active')) {
                         setTimeout(() => savedButton.click(), 0); // Activate the tab only if it's not already active, asynchronously
                    }
                 }
             }
         } catch (e) {
             console.warn('Failed to update nested tabs:', e);
         }
     });
 }

document.addEventListener('DOMContentLoaded', () => {
    updateTabs();
    observer.observe(document.body, observerOptions);
});

window.addEventListener('beforeunload', () => {
    observer.disconnect();
});

window.updateTabs = updateTabs; // Expose updateTabs to the global scope




© 2015 - 2024 Weber Informatics LLC | Privacy Policy