T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/public_html/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/js/ajax_navigation.js
// AJAX Navigation System - Preserves Global Player State
// Handles seamless page transitions without breaking music playback

(function() {
    'use strict';
    
    let isNavigating = false;
    let currentPage = null;
    
    // Initialize AJAX navigation when DOM is ready
    function initAjaxNavigation() {
        console.log('🔄 Initializing AJAX Navigation');
        
        // Get current page from URL
        currentPage = getCurrentPageFromURL();
        
        // Set up click handlers for navigation links
        setupNavigationHandlers();
        
        // Handle browser back/forward buttons
        setupHistoryHandlers();
    }
    
    // Get current page info from URL
    function getCurrentPageFromURL() {
        const path = window.location.pathname;
        const search = window.location.search;
        
        if (path.includes('track.php')) return { type: 'track', url: path + search };
        if (path.includes('artist_profile.php')) return { type: 'artist_profile', url: path + search };
        if (path.includes('library.php')) return { type: 'library', url: path + search };
        if (path.includes('community_fixed.php')) return { type: 'community_fixed', url: path + search };
        // Removed artist_dashboard and artists from page detection - uses normal navigation
        
        return { type: 'unknown', url: path + search };
    }
    
    // Set up click handlers for navigation links
    function setupNavigationHandlers() {
        document.addEventListener('click', function(e) {
            const link = e.target.closest('a');
            if (!link) return;
            
            const href = link.getAttribute('href');
            if (!href || href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:')) return;
            
            // Additional safety: Force normal navigation for links with specific classes (check this FIRST)
            if (link.classList.contains('no-ajax') || link.classList.contains('profile-username-link') || link.classList.contains('social-item') || link.classList.contains('nav-tab')) {
                console.log('🔒 Link has no-ajax/nav-tab class - forcing normal navigation:', href);
                return; // Don't prevent default, let it work normally
            }
            
            // CRITICAL FIX: Allow normal navigation for relative query string links (e.g., ?tab=tracks) when on artist_dashboard.php
            const currentPath = window.location.pathname;
            if (currentPath.includes('artist_dashboard.php') && href.startsWith('?')) {
                console.log('🎵 Tab link clicked on artist_dashboard - allowing normal navigation:', href);
                return; // Don't prevent default, let it work normally
            }
            
            // CRITICAL FIX: Allow normal navigation for track.php, artist_profile.php, community_fixed.php, artist_dashboard.php, and artists.php links
            if (href.includes('track.php') || href.includes('artist_profile.php') || href.includes('community_fixed.php') || href.includes('artist_dashboard.php') || href.includes('artists.php')) {
                console.log('🎵 Link clicked - allowing normal navigation:', href);
                return; // Don't prevent default, let it work normally
            }
            
            // Check if this is a link we should handle with AJAX
            if (shouldHandleWithAjax(href)) {
                e.preventDefault();
                navigateToPage(href);
            }
        });
    }
    
    // Determine if a link should be handled with AJAX
    function shouldHandleWithAjax(href) {
        // Handle internal PHP pages that should preserve global player
        // CRITICAL FIX: Removed track.php, artist_profile.php, dashboard.php, community_fixed.php, artist_dashboard.php, and artists.php from AJAX handling
        const ajaxPages = [
            '/admin.php' // This one works
            // Removed problematic pages: track, artist_profile, dashboard, community_fixed, artist_dashboard, artists, library, studio, events, charts, messages, notifications
        ];
        
        return ajaxPages.some(page => href.includes(page));
    }
    
    // Navigate to a page using AJAX
    function navigateToPage(href) {
        if (isNavigating) {
            console.log('🔄 Navigation already in progress, skipping');
            return;
        }
        
        isNavigating = true;
        const startTime = performance.now();
        console.log('🔄 AJAX Navigation to:', href);
        
        // Log navigation attempt
        logNavigation(currentPage?.url || window.location.href, href, 'ajax');
        
        // Show loading indicator
        showLoadingIndicator();
        
        // Parse the URL to get page type and parameters
        const { pageType, params } = parsePageURL(href);
        
        if (!pageType) {
            console.error('❌ Unable to parse page type from:', href);
            // Fallback to normal navigation
            window.location.href = href;
            return;
        }
        
        // Build AJAX request URL with cache-busting timestamp
        const cacheBuster = '&_t=' + Date.now();
        const ajaxUrl = '/ajax_load_page.php?page=' + pageType + '&' + new URLSearchParams(params).toString() + cacheBuster;
        
        // Make AJAX request with cache-busting
        fetch(ajaxUrl, {
            cache: 'no-store',
            headers: {
                'Cache-Control': 'no-cache',
                'Pragma': 'no-cache'
            }
        })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Update page content
                    updatePageContent(data.content);
                    
                    // Update browser history
                    updateBrowserHistory(href, data.title);
                    
                    // Update current page tracking
                    currentPage = { type: pageType, url: href };
                    
                    console.log('✅ AJAX Navigation successful to:', pageType);
                    
                    // Log performance metrics
                    const loadTime = performance.now() - startTime;
                    logPerformance(pageType, loadTime, data.content.length);
                    
                    // Trigger page-specific initialization if needed
                    triggerPageInit(pageType);
                    
                } else {
                    throw new Error(data.error || 'Unknown error');
                }
            })
            .catch(error => {
                console.error('❌ AJAX Navigation failed:', error);
                // Fallback to normal navigation
                window.location.href = href;
            })
            .finally(() => {
                hideLoadingIndicator();
                isNavigating = false;
            });
    }
    
    // Parse URL to extract page type and parameters
    function parsePageURL(href) {
        try {
            const url = new URL(href, window.location.origin);
            const pathname = url.pathname;
            const params = Object.fromEntries(url.searchParams.entries());
            
            // CRITICAL FIX: Removed track.php, artist_profile.php, dashboard.php, community_fixed.php, artist_dashboard.php, and artists.php from AJAX parsing
            if (pathname.includes('admin.php')) {
                return { pageType: 'admin', params };
            }
            // Removed problematic pages: track, artist_profile, dashboard, community_fixed, artist_dashboard, artists, library, studio, events, charts, messages, notifications
            
            return { pageType: null, params: {} };
        } catch (e) {
            console.error('❌ Error parsing URL:', href, e);
            return { pageType: null, params: {} };
        }
    }
    
    // Update the main page content - PRESERVE HEADER approach
    function updatePageContent(content) {
        try {
            // Preserve global player
            const globalPlayer = document.querySelector('#enhancedGlobalPlayer');
            
            // Create a temporary container to parse the new content
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = content;
            
            // Find the main content container
            const mainContainer = document.querySelector('#pageContainer') || document.querySelector('.main-content') || document.querySelector('main');
            
            if (mainContainer) {
                // Extract main content from the response
                let newMainContent = tempDiv.querySelector('#pageContainer') || tempDiv.querySelector('.main-content') || tempDiv.querySelector('main');
                
                // Remove any style tags that might interfere with existing page styles
                const styleTags = tempDiv.querySelectorAll('style');
                styleTags.forEach(style => {
                    // Only remove styles that target body or might conflict
                    if (style.textContent.includes('body {') || style.textContent.includes('body::')) {
                        style.remove();
                    }
                });
                
                if (newMainContent) {
                    // Update only the main content area
                    mainContainer.innerHTML = newMainContent.innerHTML;
                } else {
                    // Fallback: look for body content but preserve header
                    let newBodyContent = tempDiv.querySelector('body');
                    if (newBodyContent) {
                        // Extract main content from body, excluding header
                        const bodyMainContent = newBodyContent.querySelector('#pageContainer') || newBodyContent.querySelector('.main-content') || newBodyContent.querySelector('main');
                        if (bodyMainContent) {
                            mainContainer.innerHTML = bodyMainContent.innerHTML;
                        } else {
                            // Extract everything except header and footer
                            const header = newBodyContent.querySelector('header');
                            const footer = newBodyContent.querySelector('footer');
                            if (header) header.remove();
                            if (footer) footer.remove();
                            mainContainer.innerHTML = newBodyContent.innerHTML;
                        }
                    } else {
                        // If no body tag found, assume it's just content
                        mainContainer.innerHTML = content;
                    }
                }
            } else {
                // Fallback: replace only main content, preserve header
                let newBodyContent = tempDiv.querySelector('body');
                if (newBodyContent) {
                    // Remove header and footer from new content
                    const header = newBodyContent.querySelector('header');
                    const footer = newBodyContent.querySelector('footer');
                    if (header) header.remove();
                    if (footer) footer.remove();
                    
                    // Find the main content in the current page
                    const currentMain = document.querySelector('#pageContainer') || document.querySelector('.main-content') || document.querySelector('main');
                    if (currentMain) {
                        // Extract main content from new body
                        const newMain = newBodyContent.querySelector('#pageContainer') || newBodyContent.querySelector('.main-content') || newBodyContent.querySelector('main');
                        if (newMain) {
                            currentMain.innerHTML = newMain.innerHTML;
                        } else {
                            currentMain.innerHTML = newBodyContent.innerHTML;
                        }
                    } else {
                        // Last resort: replace body but preserve global player
                        document.body.innerHTML = newBodyContent.innerHTML;
                        if (globalPlayer) {
                            document.body.appendChild(globalPlayer);
                        }
                    }
                } else {
                    // If no body tag found, assume it's just content
                    const currentMain = document.querySelector('#pageContainer') || document.querySelector('.main-content') || document.querySelector('main');
                    if (currentMain) {
                        currentMain.innerHTML = content;
                    } else {
                document.body.innerHTML = content;
                if (globalPlayer) {
                    document.body.appendChild(globalPlayer);
                        }
                    }
                }
            }
            
            // Reinitialize any JavaScript that might be needed
            reinitializePageScripts();
            
            // Dispatch custom event for pages to reinitialize
            document.dispatchEvent(new CustomEvent('ajaxPageLoaded', {
                detail: { url: currentPage?.url || window.location.href }
            }));
            
        } catch (error) {
            console.error('❌ Error updating page content:', error);
            // Fallback to normal navigation
            throw error;
        }
    }
    
    // Update browser history for back/forward button support
    function updateBrowserHistory(href, title) {
        const state = { 
            page: currentPage?.type || 'unknown',
            url: href,
            timestamp: Date.now()
        };
        
        // Update page title
        document.title = title + ' - SoundStudioPro';
        
        // Push new state to history
        history.pushState(state, title, href);
    }
    
    // Handle browser back/forward buttons
    function setupHistoryHandlers() {
        window.addEventListener('popstate', function(e) {
            if (e.state && e.state.url) {
                console.log('🔄 Browser back/forward to:', e.state.url);
                navigateToPage(e.state.url);
            } else {
                // Fallback: reload page
                window.location.reload();
            }
        });
    }
    
    // Show loading indicator during navigation
    function showLoadingIndicator() {
        // Add loading overlay if it doesn't exist
        if (!document.getElementById('ajax-loading')) {
            const loading = document.createElement('div');
            loading.id = 'ajax-loading';
            loading.innerHTML = `
                <div class="loading-overlay">
                    <div class="loading-spinner">
                        <i class="fas fa-spinner fa-spin"></i>
                        <span>Loading...</span>
                    </div>
                </div>
            `;
            loading.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.3);
                z-index: 9999;
                display: flex;
                align-items: center;
                justify-content: center;
            `;
            document.body.appendChild(loading);
        }
        
        document.getElementById('ajax-loading').style.display = 'flex';
    }
    
    // Hide loading indicator
    function hideLoadingIndicator() {
        const loading = document.getElementById('ajax-loading');
        if (loading) {
            loading.style.display = 'none';
        }
    }
    
    // Reinitialize page scripts after content update
    function reinitializePageScripts() {
        // Reinitialize any page-specific JavaScript
        // This is called after AJAX content is loaded
        
        // Re-setup cart functionality if present
        if (typeof window.setupCartHandlers === 'function') {
                window.setupCartHandlers();
        }
        
        // Re-setup dashboard play buttons if present
        if (document.querySelector('.play-track-btn')) {
            console.log('🎵 Dashboard: Reinitializing play buttons after AJAX');
            // Play buttons will work automatically with onclick handlers
        }
        
        // Re-setup any other dynamic elements
        // Add more reinitialization calls as needed
    }
    
    // Trigger page-specific initialization
    function triggerPageInit(pageType) {
        // Dispatch custom event for page-specific scripts
        const event = new CustomEvent('ajaxPageLoaded', { 
            detail: { pageType: pageType } 
        });
        document.dispatchEvent(event);
    }
    
    // Public API
    window.ajaxNavigation = {
        navigateToPage: navigateToPage,
        getCurrentPage: () => currentPage,
        isNavigating: () => isNavigating
    };
    
    // Performance and usage logging
    function logNavigation(fromPage, toPage, method) {
        // Log navigation for analytics (optional)
        if (typeof fetch !== 'undefined') {
            fetch('/ajax_monitor.php', {
                method: 'POST',
                headers: { 
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-Requested-With': 'XMLHttpRequest'
                },
                body: new URLSearchParams({
                    action: 'log_navigation',
                    from_page: fromPage,
                    to_page: toPage,
                    method: method
                })
            }).catch(() => {}); // Fail silently
        }
    }
    
    function logPerformance(page, loadTime, contentSize) {
        // Log performance metrics (optional)
        if (typeof fetch !== 'undefined') {
            fetch('/ajax_monitor.php', {
                method: 'POST',
                headers: { 
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-Requested-With': 'XMLHttpRequest'
                },
                body: new URLSearchParams({
                    action: 'log_performance',
                    page: page,
                    load_time: loadTime.toFixed(2),
                    content_size: contentSize
                })
            }).catch(() => {}); // Fail silently
        }
    }
    
    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initAjaxNavigation);
    } else {
        initAjaxNavigation();
    }
    
})();

CasperSecurity Mini