MediaWiki:Gadget-usermenuDropdown.js

From Enshrouded Wiki
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// <big> Usermenu in dropdown widget </big> <pre>
// ==UserScript==
// @name         Usermenu in dropdown
// @version      0.2.0
// @description  Packs mediawiki vector skin's personal menu on the header into 3 icons: Notifications, Messages, User menu. Supports ext:ThemeToggle (wiki.gg).
// @author       GoboZen
// @license      MIT
// @namespace    https://gitlab.com/enshrouded-wiki/enshrouded-wiki-theme
// @homepageURL  https://gitlab.com/enshrouded-wiki/enshrouded-wiki-theme
// @supportURL   https://gitlab.com/enshrouded-wiki/enshrouded-wiki-theme/-/issues
// @downloadURL  https://gitlab.com/enshrouded-wiki/enshrouded-wiki-theme/-/raw/main/usermenu/usermenu-dropdown.js
// @match        https://*.wiki.gg/*
// @icon         https://icons.duckduckgo.com/ip2/wiki.gg.ico
// @grant        none
// ==/UserScript==


// The usermenu is part of the initial page html, so ready when the widget loads.
// Also the reason why caching for logged in users is not possible.
if (false === convertUsermenu()) {
  // Just in case
  console.warn("[usermenu-dropdown.js]: #p-personal element was not ready when the widget loaded.");
  document.addEventListener("DOMContentLoaded", convertUsermenu);
}


function convertUsermenu() {
  var ppersonal = document.getElementById('p-personal');
  if (!ppersonal) return false;
  var ppersonalList = ppersonal.querySelector('.vector-menu-content-list') || ppersonal.querySelector('ul');
  if (!ppersonalList) return false;

  // Create usermenu tree - does not exist on page-load
  var pusermenu = document.getElementById('p-usermenu') || document.createElement('li');
  pusermenu.id = 'p-usermenu';
  pusermenu.classList.add('mw-list-item');
  pusermenu.classList.add('ext-iconbutton');
  var pusermenuDiv = make(pusermenu, 'div', 'vector-menu-content');
  pusermenuDiv.classList.add('ext-dropdown');
  var pusermenuList = make(pusermenuDiv, 'ul', 'vector-menu-content-list');

  function make(parent, tag, class_) {
    var e = parent.querySelector('.' + class_);
    if (e) return e;
    e = document.createElement(tag);
    e.classList.add(class_);
    parent.appendChild(e);
    return e;
  }

  var trayContents = [
    'pt-themes',  // ThemeToggle dropdownSwitcher
    'p-themes',   // ThemeToggle dayNightSwitcher
    'pt-notifications-alert',   // Echo Alerts (Notifications)
    'pt-notifications-notice',  // Echo Notices (Messag
    pusermenu.id,  // usermenu dropdown
  ];

  // Copy children array before starting to remove them to avoid skipping
  var children = ppersonalList.children;
  var items = [];
  for (var i = 0; i < children.length; i++) items.push(children[i]);
  
  // Move children from #p-personal into #p-usermenu
  for (var i = 0; i < items.length; i++) {
    var child = items[i];
    if (!trayContents.includes(child.id))
      pusermenuList.appendChild(child);
  }

  // Set tooltip text
  // var pusermenuText = plabel?.textContent ?? "User menu";  // localized in [[MediaWiki:Personaltools]], default "Personal tools"
  // var pusermenuText = mw.msg('tooltip-p-personal') ?? "User menu";  // localized in [[MediaWiki:Tooltip-p-personal]], default "User menu"
  var pusermenuText = "User menu";
  pusermenu.setAttribute('title', pusermenuText);
  /*
  // Add span for pusermenu button text
  var sp = d.createElement("span");
  sp.classList.add("vector-menu-heading-label");
  sp.textContent = pusermenuText;
  pusermenu.insertBefore(sp, pusermenu.firstChild);
  */

  // Make the li focusable so it stays open after being clicked
  pusermenu.setAttribute('tabindex', '0');

  // Add #p-usermenu to end of #p-personal
  if (!pusermenu.parentElement)
    ppersonalList.appendChild(pusermenu);

  (window.RLQ = RLQ || []).push(loadResources);
  // (window.RLQ = RLQ || []).push(['mw.hook', loadResources]);
  if (mw && mw.hook) {
    hookThemes();
  } else {
    document.addEventListener('DOMContentLoaded', hookThemes);
  }

  function loadResources() {
    // Anonymous (not-logged-in) users don't need a dropdown, there's just 2 buttons: login and register
    if (mw.user.isAnon()) {
      return;
    }

    // Only load the dropdown CSS for logged-in users
    mw.loader.load('https://enshrouded.wiki.gg/wiki/MediaWiki:Gadget-usermenuDropdown.css?action=raw&ctype=text/css', 'text/css');
  }

  function hookThemes() {
    // Hook runs even if triggered already
    mw.hook('ext.themes.dropdownSwitcherReady').add(convertThemes);
    // mw.loader.using('ext.themes', () => mw.hook(convertThemes));
    // RLQ.push([ ['ext.themes'], () => mw.hook('ext.themes.dropdownSwitcherReady').add(convertThemes) ]);
  }

  function convertThemes( ptthemes ) {
    // var ptthemes = document.getElementById('pt-themes');
    // Make the li focusable so it stays open after being clicked
    ptthemes.setAttribute('tabindex', '0');
    // Add classes necessary for the css to ThemeToggle
    var th1 = ptthemes.querySelector('.ext-themetoggle-popup');
    var th2 = ptthemes.querySelector('ul');
    if (th1 && th1.classList) th1.classList.add('ext-dropdown');
    if (th2 && th1.classList) th2.classList.add('vector-menu-content-list');
  }

  return true;
}