Jump to content

MediaWiki:Mobile.js: Difference between revisions

From Vanipedia
Kashya (talk | contribs)
Created page with "→PERMANENT VANI-SEARCH ICON & KEYBOARD ROUTER (DESKTOP + MOBILE): (function() { function setupVaniSearch() { // 1. Force the #p-search box to stay open on mobile Vector (defeats the collapsed icon toggle) var searchBox = document.querySelector('#p-search'); if (searchBox) { searchBox.classList.add('vector-search-box-show-thumbnail'); } // 2. Find all search inputs on the page var inputs = document.query..."
 
Kashya (talk | contribs)
No edit summary
Line 1: Line 1:
/* PERMANENT VANI-SEARCH ICON & KEYBOARD ROUTER (DESKTOP + MOBILE) */
/* ==========================================================================
  DEFINITIVE MOBILE & DESKTOP VANI-SEARCH CONTROLLER
  Defeats Minerva's #/search blank overlay and provides a direct search bar
  ========================================================================== */
(function() {
(function() {
     function setupVaniSearch() {
     // 1. If Minerva's #/search hash is in the URL, strip it immediately so the blank overlay closes
        // 1. Force the #p-search box to stay open on mobile Vector (defeats the collapsed icon toggle)
    if (window.location.hash === '#/search') {
         var searchBox = document.querySelector('#p-search');
         history.replaceState(null, document.title, window.location.pathname + window.location.search);
         if (searchBox) {
    }
             searchBox.classList.add('vector-search-box-show-thumbnail');
    window.addEventListener('hashchange', function() {
         if (window.location.hash === '#/search') {
             history.replaceState(null, document.title, window.location.pathname + window.location.search);
            $('.search-overlay, .minerva-search-overlay').remove();
            $('body').removeClass('search-enabled overlay-enabled');
         }
         }
    });


        // 2. Find all search inputs on the page
    // 2. Build a dedicated, always-visible mobile search drawer right under the 52px top bar
         var inputs = document.querySelectorAll('input[type="search"], input[name="search"], #searchInput');
    function toggleVaniMobileSearch() {
         inputs.forEach(function(input) {
         var existing = document.getElementById('vani-custom-mobile-search');
            // Turn off native browser autocomplete
         if (existing) {
            input.setAttribute('autocomplete', 'off');
            if (existing.style.display === 'none') {
                existing.style.display = 'flex';
                existing.querySelector('input').focus();
            } else {
                existing.style.display = 'none';
            }
            return;
        }


            var wrapper = input.parentElement;
        var bar = document.createElement('div');
            if (!wrapper) return;
        bar.id = 'vani-custom-mobile-search';
        bar.style.cssText = 'position:fixed !important; top:52px !important; left:0 !important; right:0 !important; height:54px !important; background:#1f3e45 !important; border-bottom:2px solid #b1873d !important; z-index:2147483647 !important; display:flex !important; align-items:center !important; padding:0 12px !important; gap:8px !important; box-shadow:0 6px 16px rgba(0,0,0,0.45) !important; box-sizing:border-box !important;';


            // Only inject the 🔍 button once per search bar
        var input = document.createElement('input');
            if (!wrapper.querySelector('.vani-search-trigger-btn')) {
        input.type = 'text';
                wrapper.style.setProperty('position', 'relative', 'important');
        input.placeholder = 'Search Vanipedia...';
                wrapper.style.setProperty('display', 'flex', 'important');
        input.autocomplete = 'off';
                wrapper.style.setProperty('align-items', 'center', 'important');
        input.style.cssText = 'flex:1 1 auto !important; height:36px !important; background:#ffffff !important; color:#1e353b !important; -webkit-text-fill-color:#1e353b !important; border:1.5px solid #f5d77f !important; border-radius:18px !important; padding:0 14px !important; font-size:16px !important; outline:none !important; display:block !important; visibility:visible !important; opacity:1 !important;';


                var btn = document.createElement('button');
        var goBtn = document.createElement('button');
                btn.type = 'button';
        goBtn.type = 'button';
                btn.className = 'vani-search-trigger-btn';
        goBtn.innerHTML = '🔍';
                btn.innerHTML = '🔍';
        goBtn.style.cssText = 'flex:0 0 38px !important; width:38px !important; height:36px !important; border-radius:50% !important; background:#b1873d !important; color:#ffffff !important; border:none !important; font-size:18px !important; cursor:pointer !important; display:flex !important; align-items:center !important; justify-content:center !important;';
                btn.title = 'Search VaniSearch';
                btn.style.cssText = 'position:absolute !important; right:6px !important; top:50% !important; transform:translateY(-50%) !important; background:transparent !important; border:none !important; font-size:15px !important; line-height:1 !important; padding:4px !important; cursor:pointer !important; z-index:9999 !important; display:flex !important; align-items:center !important; justify-content:center !important;';


                btn.addEventListener('click', function(e) {
        function runSearch() {
                    e.preventDefault();
            var val = input.value.trim();
                    e.stopPropagation();
            if (val !== '') {
                    var val = input.value.trim();
                window.location.href = '/wiki/Special:VaniSearch?search=' + encodeURIComponent(val);
                    if (val !== '') {
            }
                        window.location.href = '/wiki/Special:VaniSearch?search=' + encodeURIComponent(val);
        }
                    } else {
                        input.focus();
                    }
                });


                 wrapper.appendChild(btn);
        goBtn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            runSearch();
        });
 
        input.addEventListener('keydown', function(e) {
            if (e.key === 'Enter' || e.keyCode === 13) {
                 e.preventDefault();
                e.stopImmediatePropagation();
                runSearch();
             }
             }
         });
         });
        bar.appendChild(input);
        bar.appendChild(goBtn);
        document.body.appendChild(bar);
        setTimeout(function() { input.focus(); }, 50);
     }
     }


     // Intercept Enter / Mobile Keyboard "Search/Go" key in Capture Phase (beats Vue.js)
     // 3. Intercept the Minerva mobile magnifying glass (#searchIcon) BEFORE Minerva's router sees it
    document.addEventListener('click', function(e) {
        var searchTrigger = e.target.closest('#searchIcon, .minerva-header .minerva-search-form, .minerva-icon--search');
        if (searchTrigger && (window.innerWidth <= 999 || document.body.classList.contains('skin-minerva'))) {
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            toggleVaniMobileSearch();
            return false;
        }
    }, true); // Capture phase = true beats Minerva's native click handler
 
    // 4. Desktop Search Bar: Add 🔍 icon and route Enter key to Special:VaniSearch
     document.addEventListener('keydown', function(e) {
     document.addEventListener('keydown', function(e) {
         if (e.key === 'Enter' || e.keyCode === 13) {
         if (e.key === 'Enter' || e.keyCode === 13) {
Line 60: Line 97:
         }
         }
     }, true);
     }, true);
    // Intercept any form submission as a backup for mobile virtual keyboards
    document.addEventListener('submit', function(e) {
        var form = e.target;
        var input = form && form.querySelector('input[type="search"], input[name="search"], #searchInput');
        if (input) {
            e.preventDefault();
            e.stopImmediatePropagation();
            var val = input.value.trim();
            if (val !== '') {
                window.location.href = '/wiki/Special:VaniSearch?search=' + encodeURIComponent(val);
            }
        }
    }, true);
    // Run immediately, on DOM ready, and briefly poll in case Vue rebuilds the input
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', setupVaniSearch);
    } else {
        setupVaniSearch();
    }
    setInterval(setupVaniSearch, 800);
})();
})();

Revision as of 01:42, 13 November 2026

/* ==========================================================================
   DEFINITIVE MOBILE & DESKTOP VANI-SEARCH CONTROLLER
   Defeats Minerva's #/search blank overlay and provides a direct search bar
   ========================================================================== */
(function() {
    // 1. If Minerva's #/search hash is in the URL, strip it immediately so the blank overlay closes
    if (window.location.hash === '#/search') {
        history.replaceState(null, document.title, window.location.pathname + window.location.search);
    }
    window.addEventListener('hashchange', function() {
        if (window.location.hash === '#/search') {
            history.replaceState(null, document.title, window.location.pathname + window.location.search);
            $('.search-overlay, .minerva-search-overlay').remove();
            $('body').removeClass('search-enabled overlay-enabled');
        }
    });

    // 2. Build a dedicated, always-visible mobile search drawer right under the 52px top bar
    function toggleVaniMobileSearch() {
        var existing = document.getElementById('vani-custom-mobile-search');
        if (existing) {
            if (existing.style.display === 'none') {
                existing.style.display = 'flex';
                existing.querySelector('input').focus();
            } else {
                existing.style.display = 'none';
            }
            return;
        }

        var bar = document.createElement('div');
        bar.id = 'vani-custom-mobile-search';
        bar.style.cssText = 'position:fixed !important; top:52px !important; left:0 !important; right:0 !important; height:54px !important; background:#1f3e45 !important; border-bottom:2px solid #b1873d !important; z-index:2147483647 !important; display:flex !important; align-items:center !important; padding:0 12px !important; gap:8px !important; box-shadow:0 6px 16px rgba(0,0,0,0.45) !important; box-sizing:border-box !important;';

        var input = document.createElement('input');
        input.type = 'text';
        input.placeholder = 'Search Vanipedia...';
        input.autocomplete = 'off';
        input.style.cssText = 'flex:1 1 auto !important; height:36px !important; background:#ffffff !important; color:#1e353b !important; -webkit-text-fill-color:#1e353b !important; border:1.5px solid #f5d77f !important; border-radius:18px !important; padding:0 14px !important; font-size:16px !important; outline:none !important; display:block !important; visibility:visible !important; opacity:1 !important;';

        var goBtn = document.createElement('button');
        goBtn.type = 'button';
        goBtn.innerHTML = '🔍';
        goBtn.style.cssText = 'flex:0 0 38px !important; width:38px !important; height:36px !important; border-radius:50% !important; background:#b1873d !important; color:#ffffff !important; border:none !important; font-size:18px !important; cursor:pointer !important; display:flex !important; align-items:center !important; justify-content:center !important;';

        function runSearch() {
            var val = input.value.trim();
            if (val !== '') {
                window.location.href = '/wiki/Special:VaniSearch?search=' + encodeURIComponent(val);
            }
        }

        goBtn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            runSearch();
        });

        input.addEventListener('keydown', function(e) {
            if (e.key === 'Enter' || e.keyCode === 13) {
                e.preventDefault();
                e.stopImmediatePropagation();
                runSearch();
            }
        });

        bar.appendChild(input);
        bar.appendChild(goBtn);
        document.body.appendChild(bar);
        setTimeout(function() { input.focus(); }, 50);
    }

    // 3. Intercept the Minerva mobile magnifying glass (#searchIcon) BEFORE Minerva's router sees it
    document.addEventListener('click', function(e) {
        var searchTrigger = e.target.closest('#searchIcon, .minerva-header .minerva-search-form, .minerva-icon--search');
        if (searchTrigger && (window.innerWidth <= 999 || document.body.classList.contains('skin-minerva'))) {
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            toggleVaniMobileSearch();
            return false;
        }
    }, true); // Capture phase = true beats Minerva's native click handler

    // 4. Desktop Search Bar: Add 🔍 icon and route Enter key to Special:VaniSearch
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Enter' || e.keyCode === 13) {
            var el = e.target;
            if (el && el.tagName === 'INPUT' && (el.type === 'search' || el.name === 'search' || el.id === 'searchInput')) {
                e.preventDefault();
                e.stopImmediatePropagation();
                var val = el.value.trim();
                if (val !== '') {
                    window.location.href = '/wiki/Special:VaniSearch?search=' + encodeURIComponent(val);
                }
            }
        }
    }, true);
})();