Jump to content

MediaWiki:Common.js

From Consumer Rights Wiki
Revision as of 22:42, 27 January 2026 by JakeL (talk | contribs)

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */
// stolen from Lajos Mészáros on this post https://stackoverflow.com/questions/13358292/capture-tap-event-with-pure-javascript
const onClickOrTap = (element, handler) => {
  let touchMoveHappened = false;
  element.addEventListener('touchstart', () => {
    // on mobile this is the 1st event that happens
    touchMoveHappened = false;
  });
  element.addEventListener('touchmove', () => {
    // on mobile this might get triggered in which case the
    // click or tap will get cancelled
    // we'll keep a track of it
    touchMoveHappened = true;
  });
  element.addEventListener('touchend', (e) => {
    // happens after touchstart, but before click
    // if touch happened then we'll exit
    if (touchMoveHappened) {
      return;
    }
    // calling preventDefault() will make sure the
    // subsequent click will not get triggered
    e.preventDefault();
    // at this point we are ready to call our original handler
    handler(e);
  });
  element.addEventListener('click', (e) => {
    // this will only get triggered on desktop
    // because we call preventDefault for the "touchend" event
    handler(e);
  });
}

/* Create Page */
const createPageTargetIdDataSetString = "[data-create-page-target-id]";

if (document.querySelector(createPageTargetIdDataSetString)) {
  /**
   * @type {HTMLElement[]}
   */
  let itemsCreateInputPageGrid = [];
  let itemsCreatePageGrid = [];
  const createPageTargetId = "createPageTargetId";
  const createPageInputHiddenClass = "hidden";
  const createPageInputActiveClass = "pageInputActive";

  /**
   * @param {HTMLElement} element
   */
  function getGridTarget(element) {
    const targetId = element.dataset[createPageTargetId];

    return document.getElementById(targetId);
  }

  /**
   * @this {HTMLDivElement}
   */
  function toggleGridTarget(element, targetElement) {
    for (let index = 0; index < itemsCreateInputPageGrid.length; index += 1) {
      const target = itemsCreateInputPageGrid[index];

      target.classList.add(createPageInputHiddenClass);

      if (target === targetElement) {
        target.classList.remove(createPageInputHiddenClass);
      }

      const clickedElement = itemsCreatePageGrid[index];
      
      clickedElement.classList.remove(createPageInputActiveClass);

      if (clickedElement === element) {
        clickedElement.classList.add(createPageInputActiveClass);
      }
    }
  }

  /**
   * @param {HTMLElement} element
   * @param {HTMLElement} targetElement
   */
  function addToggleGridTargetEvent(element, targetElement) {
    itemsCreatePageGrid.push(element);
    itemsCreateInputPageGrid.push(targetElement);
    
    onClickOrTap(element, (e) => {
     toggleGridTarget(element, targetElement)
    });
    //element.addEventListener("click", () =>
    //    toggleGridTarget(element, targetElement)
    //);
  }

  const createPageTargetElements = document.querySelectorAll(
    createPageTargetIdDataSetString
  );

  for (let index = 0; index < createPageTargetElements.length; index += 1) {
    const element = createPageTargetElements[index];

    const targetElement = getGridTarget(element);

    if (targetElement) {
      addToggleGridTargetEvent(element, targetElement);
    }
  }
}
/* Jake */
(function () {
  function jakeTimeAgo(d) {
    var s = Math.floor((Date.now() - d.getTime()) / 1000);
    if (s < 60) return s + "s ago";
    var m = Math.floor(s / 60);
    if (m < 60) return m + "m ago";
    var h = Math.floor(m / 60);
    if (h < 24) return h + "h ago";
    var days = Math.floor(h / 24);
    return days + "d ago";
  }

  function jakeBuildRecentChangesPortlet() {
    var jakeMenu = document.getElementById("vector-main-menu") || document.getElementById("mw-panel");
    if (!jakeMenu) return null;

    if (document.getElementById("p-jake-recentchanges")) return null;

    var jakePortlet = document.createElement("div");
    jakePortlet.id = "p-jake-recentchanges";
    jakePortlet.className = "vector-menu mw-portlet";

    var jakeHeading = document.createElement("div");
    jakeHeading.className = "vector-menu-heading";
    jakeHeading.textContent = "Recent changes";

    var jakeContent = document.createElement("div");
    jakeContent.className = "vector-menu-content";

    var jakeList = document.createElement("ul");
    jakeList.className = "vector-menu-content-list";
    jakeList.id = "jake-rc-list";

    var jakeMoreWrap = document.createElement("div");
    jakeMoreWrap.className = "jake-rc-more";

    var jakeMoreLink = document.createElement("a");
    jakeMoreLink.href = mw.util.getUrl("Special:RecentChanges");
    jakeMoreLink.textContent = "Show more…";

    jakeMoreWrap.appendChild(jakeMoreLink);

    jakeContent.appendChild(jakeList);
    jakeContent.appendChild(jakeMoreWrap);

    jakePortlet.appendChild(jakeHeading);
    jakePortlet.appendChild(jakeContent);

    var jakeAfter = jakeMenu.querySelector("#p-navigation") || jakeMenu.firstElementChild;
    if (jakeAfter && jakeAfter.parentNode) {
      jakeAfter.parentNode.insertBefore(jakePortlet, jakeAfter.nextSibling);
    } else {
      jakeMenu.appendChild(jakePortlet);
    }

    return jakeList;
  }

  function jakeLoadRecentChanges(jakeListEl) {
    if (!jakeListEl) return;

    var jakeApi = new mw.Api();
    jakeApi.get({
      action: "query",
      list: "recentchanges",
      rcnamespace: 0,
      rclimit: 5,
      rcprop: "title|timestamp|user",
      rcshow: "!bot",
      formatversion: 2
    }).then(function (res) {
      var jakeItems = (res && res.query && res.query.recentchanges) ? res.query.recentchanges : [];
      jakeListEl.textContent = "";

      for (var i = 0; i < jakeItems.length; i++) {
        var rc = jakeItems[i];

        var li = document.createElement("li");
        li.className = "mw-list-item jake-rc-item";

        var link = document.createElement("a");
        link.href = mw.util.getUrl(rc.title);
        link.textContent = rc.title;

        var meta = document.createElement("div");
        meta.className = "jake-rc-meta";
        meta.textContent = jakeTimeAgo(new Date(rc.timestamp)) + " · " + (rc.user || "");

        li.appendChild(link);
        li.appendChild(meta);
        jakeListEl.appendChild(li);
      }
    }).catch(function () {
      jakeListEl.textContent = "";

      var li = document.createElement("li");
      li.className = "mw-list-item jake-rc-item";

      var link = document.createElement("a");
      link.href = mw.util.getUrl("Special:RecentChanges");
      link.textContent = "View recent changes";

      li.appendChild(link);
      jakeListEl.appendChild(li);
    });
  }

  function jakeInitRecentChanges() {
    if (!mw || !mw.util || !mw.Api) return;

    var jakeListEl = jakeBuildRecentChangesPortlet();
    if (!jakeListEl) jakeListEl = document.getElementById("jake-rc-list");
    if (!jakeListEl) return;

    jakeLoadRecentChanges(jakeListEl);
    setInterval(function () {
      jakeLoadRecentChanges(jakeListEl);
    }, 60000);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", jakeInitRecentChanges);
  } else {
    jakeInitRecentChanges();
  }
})();