MediaWiki:Common.js

Z Oświetleniowo
Przejdź do nawigacji Przejdź do wyszukiwania

Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.

  • Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
  • Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
  • Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
  • Opera: Naciśnij klawisze Ctrl+F5.
/* Umieszczony tutaj kod JavaScript zostanie załadowany przez każdego użytkownika, podczas każdego ładowania strony. */

// Dark Mode Manager with Cookie Storage
(function() {
    'use strict';
    
    const DARK_MODE_CLASS = 'skin-dark-mode';
    const COOKIE_NAME = 'mw_dark_mode';
    const COOKIE_EXPIRE_DAYS = 365;
    
    class DarkModeManager {
        constructor() {
            this.init();
        }
        
        init() {
            this.applySavedPreference();
            this.processTemplateMarkers();
            this.createFixedToggle();
            this.watchForDynamicContent();
        }
        
        // Cookie management
        setCookie(name, value, days) {
            const date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            const expires = "expires=" + date.toUTCString();
            document.cookie = name + "=" + value + ";" + expires + ";path=/";
        }
        
        getCookie(name) {
            const nameEQ = name + "=";
            const ca = document.cookie.split(';');
            for(let i = 0; i < ca.length; i++) {
                let c = ca[i];
                while (c.charAt(0) === ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        }
        
        isDarkMode() {
            const cookie = this.getCookie(COOKIE_NAME);
            return cookie === 'true';
        }
        
        setDarkMode(enabled) {
            this.setCookie(COOKIE_NAME, enabled, COOKIE_EXPIRE_DAYS);
            this.applyDarkMode(enabled);
            this.updateAllToggleButtons(enabled);
        }
        
        toggle() {
            this.setDarkMode(!this.isDarkMode());
        }
        
        applyDarkMode(enabled) {
            if (enabled) {
                document.documentElement.classList.add(DARK_MODE_CLASS);
            } else {
                document.documentElement.classList.remove(DARK_MODE_CLASS);
            }
            
            // Protect images from any dark mode filters
            this.protectImages();
        }
        
        applySavedPreference() {
            const isDark = this.isDarkMode();
            this.applyDarkMode(isDark);
        }
        
        // Protect images from any color modifications
        protectImages() {
            const images = document.querySelectorAll('img, .image, .thumbimage, .mw-file-element');
            images.forEach(img => {
                img.style.filter = 'none';
                img.style.backgroundColor = 'transparent';
            });
        }
        
        // Process {{dark_toggle}} template markers
        processTemplateMarkers() {
            // Method 1: Look for specific text patterns
            this.replaceTextMarkers();
            
            // Method 2: Look for elements with specific classes (if your template adds them)
            this.replaceElementMarkers();
        }
        
        replaceTextMarkers() {
            const walker = document.createTreeWalker(
                document.body,
                NodeFilter.SHOW_TEXT,
                null,
                false
            );
            
            let node;
            while (node = walker.nextNode()) {
                if (node.nodeValue.includes('{{dark_toggle}}')) {
                    const span = document.createElement('span');
                    span.className = 'dark-toggle-container';
                    span.innerHTML = this.createToggleButtonHTML(this.isDarkMode());
                    
                    const parent = node.parentNode;
                    if (parent.nodeType === Node.ELEMENT_NODE) {
                        parent.replaceChild(span, node);
                    }
                }
            }
        }
        
        replaceElementMarkers() {
            const markers = document.querySelectorAll('[class*="dark_toggle"], [id*="dark_toggle"]');
            markers.forEach(marker => {
                marker.innerHTML = this.createToggleButtonHTML(this.isDarkMode());
                marker.className = 'dark-toggle-container';
            });
        }
        
        createToggleButtonHTML(isDark) {
            const icon = isDark ? '☀️' : '🌙';
            const text = isDark ? ' Light Mode' : ' Dark Mode';
            const modeClass = isDark ? 'light' : '';
            
            return `<button class="dark-mode-toggle-button ${modeClass}" onclick="window.DarkModeManager.toggle()">
                <span class="toggle-icon">${icon}</span>
                <span class="toggle-text">${text}</span>
            </button>`;
        }
        
        createFixedToggle() {
            // Remove existing fixed toggle if any
            const existingToggle = document.getElementById('darkModeToggleFixed');
            if (existingToggle) {
                existingToggle.remove();
            }
            
            const button = document.createElement('button');
            button.id = 'darkModeToggleFixed';
            button.className = `dark-mode-toggle-fixed ${this.isDarkMode() ? 'light' : ''}`;
            button.innerHTML = this.isDarkMode() ? 
                '<span class="toggle-icon">☀️</span><span class="toggle-text">Light Mode</span>' :
                '<span class="toggle-icon">🌙</span><span class="toggle-text">Dark Mode</span>';
            button.title = this.isDarkMode() ? 'Switch to light mode' : 'Switch to dark mode';
            
            button.addEventListener('click', () => this.toggle());
            
            document.body.appendChild(button);
        }
        
        updateAllToggleButtons(isDark) {
            // Update inline toggle buttons
            const inlineButtons = document.querySelectorAll('.dark-mode-toggle-button');
            inlineButtons.forEach(button => {
                const icon = button.querySelector('.toggle-icon');
                const text = button.querySelector('.toggle-text');
                
                if (isDark) {
                    icon.textContent = '☀️';
                    text.textContent = ' Light Mode';
                    button.classList.add('light');
                } else {
                    icon.textContent = '🌙';
                    text.textContent = ' Dark Mode';
                    button.classList.remove('light');
                }
            });
            
            // Update fixed toggle button
            const fixedButton = document.getElementById('darkModeToggleFixed');
            if (fixedButton) {
                const icon = fixedButton.querySelector('.toggle-icon');
                const text = fixedButton.querySelector('.toggle-text');
                
                if (isDark) {
                    icon.textContent = '☀️';
                    text.textContent = 'Light Mode';
                    fixedButton.classList.add('light');
                    fixedButton.title = 'Switch to light mode';
                } else {
                    icon.textContent = '🌙';
                    text.textContent = 'Dark Mode';
                    fixedButton.classList.remove('light');
                    fixedButton.title = 'Switch to dark mode';
                }
            }
        }
        
        watchForDynamicContent() {
            // Watch for DOM changes to process new {{dark_toggle}} markers
            const observer = new MutationObserver((mutations) => {
                mutations.forEach((mutation) => {
                    if (mutation.addedNodes.length) {
                        mutation.addedNodes.forEach((node) => {
                            if (node.nodeType === Node.ELEMENT_NODE) {
                                if (node.textContent.includes('{{dark_toggle}}')) {
                                    this.processTemplateMarkers();
                                }
                            }
                        });
                    }
                });
            });
            
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }
    }
    
    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            window.DarkModeManager = new DarkModeManager();
        });
    } else {
        window.DarkModeManager = new DarkModeManager();
    }
})();