MediaWiki:Common.js: Difference between revisions

No edit summary
No edit summary
 
Line 228: Line 228:


/**
/**
  * Quick Search Widget Custom autocomplete for CRT model lookup
  * Quick Search Widgets Reusable autocomplete for CRT & AV device lookup
  * The Main Page wikitext contains the styled container, label, and a
  * Each widget is configured via a simple object (container ID, controls ID,
  * "Loading search…" placeholder (using only MW-allowed HTML tags).
* category, placeholder text). The Main Page wikitext contains the styled
  * This script replaces the placeholder with the actual input, button,
  * containers with "Loading search…" placeholders; this script replaces them
* and dropdown, then wires up event handlers.
  * with the actual input, button, and dropdown, then wires up event handlers.
  */
  */
(function () {
(function () {
Line 239: Line 239:
     if (mw.config.get('wgPageName') !== 'Main_Page') return;
     if (mw.config.get('wgPageName') !== 'Main_Page') return;


     // ── Config ──────────────────────────────────────────────────────
     // ── Shared config ───────────────────────────────────────────────
     var API_URL      = mw.util.wikiScript('api');
     var API_URL      = mw.util.wikiScript('api');
    var CATEGORY    = 'CRT models';
     var DEBOUNCE_MS  = 250;
     var DEBOUNCE_MS  = 250;
     var MIN_CHARS    = 2;
     var MIN_CHARS    = 2;
Line 257: Line 256:
         style.id = 'ecrt-qs-styles';
         style.id = 'ecrt-qs-styles';
         style.textContent = [
         style.textContent = [
             /* Container & label — match the server-rendered box */
             /* ── Base (blue) container & label ── */
             '.ecrt-qs-container {',
             '.ecrt-qs-container {',
             '  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);',
             '  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);',
Line 271: Line 270:
             '  margin-bottom: 0.5rem;',
             '  margin-bottom: 0.5rem;',
             '  font-size: 0.9rem;',
             '  font-size: 0.9rem;',
            '}',
            /* ── Green variant (AV devices) ── */
            '.ecrt-qs-container--av {',
            '  background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);',
            '  border-color: #86efac;',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-label {',
            '  color: #15803d;',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-input:focus {',
            '  border-color: #16a34a;',
            '  box-shadow: 0 0 0 3px rgba(22,163,74,0.15);',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-btn {',
            '  background: #16a34a;',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-btn:hover {',
            '  background: #15803d;',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-btn:active {',
            '  background: #166534;',
            '}',
            '.ecrt-qs-container--av .ecrt-qs-item:hover,',
            '.ecrt-qs-container--av .ecrt-qs-item.is-active {',
            '  background: #dcfce7;',
            '  color: #14532d;',
             '}',
             '}',


Line 363: Line 389:
             '}',
             '}',


             /* Night-mode overrides */
             /* ── Night-mode overrides (base / blue) ── */
             '.skin-theme-clientpref-night .ecrt-qs-container {',
             '.skin-theme-clientpref-night .ecrt-qs-container {',
             '  background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);',
             '  background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);',
Line 399: Line 425:
             '  border-top-color: #334155;',
             '  border-top-color: #334155;',
             '}',
             '}',
             '.skin-theme-clientpref-night .ecrt-qs-status { color: #64748b; }'
             '.skin-theme-clientpref-night .ecrt-qs-status { color: #64748b; }',
 
            /* ── Night-mode overrides (green / AV) ── */
            '.skin-theme-clientpref-night .ecrt-qs-container--av {',
            '  background: linear-gradient(135deg, #0a1f0f 0%, #14291a 100%);',
            '  border-color: #1e4d2b;',
            '}',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-label {',
            '  color: #86efac;',
            '}',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-input:focus {',
            '  border-color: #4ade80;',
            '  box-shadow: 0 0 0 3px rgba(74,222,128,0.2);',
            '}',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-btn {',
            '  background: #15803d;',
            '}',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-btn:hover {',
            '  background: #16a34a;',
            '}',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-item:hover,',
            '.skin-theme-clientpref-night .ecrt-qs-container--av .ecrt-qs-item.is-active {',
            '  background: #14532d;',
            '  color: #bbf7d0;',
            '}'
         ].join('\n');
         ].join('\n');
         document.head.appendChild(style);
         document.head.appendChild(style);
     }
     }


     // ── Init ────────────────────────────────────────────────────────
     // ── Generic widget initializer ──────────────────────────────────
     function init() {
    // cfg = { containerId, controlsId, category, placeholder }
         var container = document.getElementById('crt-quick-search');
     function initWidget(cfg) {
         var wrap      = document.getElementById('ecrt-qs-controls');
         var container = document.getElementById(cfg.containerId);
         var wrap      = document.getElementById(cfg.controlsId);
         if (!container || !wrap) return;
         if (!container || !wrap) return;
        injectStyles();


         // ── Build interactive controls ──────────────────────────────
         // ── Build interactive controls ──────────────────────────────
Line 419: Line 468:
         input.type = 'text';
         input.type = 'text';
         input.className = 'ecrt-qs-input';
         input.className = 'ecrt-qs-input';
         input.placeholder = 'Type a CRT model name (e.g. Sony KV-27S42)';
         input.placeholder = cfg.placeholder;
         input.setAttribute('autocomplete', 'off');
         input.setAttribute('autocomplete', 'off');


Line 505: Line 554:
             var url = API_URL + '?action=pfautocomplete&format=json'
             var url = API_URL + '?action=pfautocomplete&format=json'
                 + '&substr=' + encodeURIComponent(substr)
                 + '&substr=' + encodeURIComponent(substr)
                 + '&category=' + encodeURIComponent(CATEGORY);
                 + '&category=' + encodeURIComponent(cfg.category);


             fetch(url)
             fetch(url)
Line 579: Line 628:
                 openDropdown();
                 openDropdown();
             }
             }
        });
    }
    // ── Init all widgets ────────────────────────────────────────────
    function init() {
        injectStyles();
        // CRT Quick Search
        initWidget({
            containerId: 'crt-quick-search',
            controlsId:  'ecrt-qs-controls-crt',
            category:    'CRT models',
            placeholder: 'Type a CRT model name (e.g. Sony KV-27S42)'
        });
        // AV Device Quick Search
        initWidget({
            containerId: 'av-quick-search',
            controlsId:  'ecrt-qs-controls-av',
            category:    'AV devices',
            placeholder: 'Type an AV device name (e.g. JVC SR-V10U)'
         });
         });
     }
     }
Line 589: Line 659:
     }
     }
})();
})();




MediaWiki Appliance - Powered by TurnKey Linux