User:Aliser/common.js: Difference between revisions

From Space Station 14 Wiki
Aliser (talk | contribs)
No edit summary
Aliser (talk | contribs)
No edit summary
Line 1: Line 1:
// ********************************
// ******* Start DRUID js *********
// ********************************


// DRUID Infobox.
/** Class name of an element that holds a collapse all button. */
// source: https://support.wiki.gg/wiki/MediaWiki:Gadget-druidInfoboxes.js
const collapseAllButtonContainerClass = "collapsible-toggle-container";
// license: CC BY-SA 4.0


$(function () {
/** Class name of an actual collapse all button. */
  $(".druid-title-tab").off("click")
const collapseAllButtonClass = "mw-collapsible-toggle";
    .on('click', function () {
      var $parent = $(this).closest(".druid-container");
      $parent.find(".druid-toggleable").removeClass("focused");
      var i = $(this).attr("data-druid");
      $parent.find(".druid-toggleable[data-druid=" + i + "]").addClass("focused");
  });
   
  $(".druid-section-tab").off("click")
    .on('click', function () {
      var $parent = $(this).closest(".druid-section-container");
      $parent.find(".druid-toggleable").removeClass("focused");
      var i = $(this).attr("data-druid");
      $parent.find(".druid-toggleable[data-druid=" + i + "]").addClass("focused");
  });


  $(".druid-collapsible").off("click")
/** Data attribute on the collapse all button container element,
    .on('click', function () {
* that specifies a class name for a collapsable elements container that the collapse all button shall target. */
      var kind = $(this).attr("data-druid-section");
const collapsibleContainerDataAttr = "data-target-class";
      $(this).toggleClass("druid-collapsible-collapsed");
 
      $(this)
/** The initial part of a custom toggle class name. */
        .closest(".druid-container")
const customToggleClassPrefix = "mw-customtoggle";
        .find("[data-druid-section-row=" + kind + "]")
 
        .toggleClass("druid-collapsed");
/** Class name for collapsible elements. */
  });
const collapsibleClass = "mw-collapsible";
 
/** Class name for collapsed elements. */
const collapsedClass = "mw-collapsed";
 
const logPrefix = "Gadget-ExpandAllReagents"
 
// ===========
 
mw.hook('wikipage.content').add((content) => {
    /** @type {HTMLElement} */
    const contentEl = content[0];
 
    // small timeout to prevent race condition with underlying jquery
    // that works the collapsible magic.
    setTimeout(() => {
        for (const collapseAllButtonContainerEl of contentEl.getElementsByClassName(collapseAllButtonContainerClass)) {
            const collapseAllButton = collapseAllButtonContainerEl.getElementsByClassName(collapseAllButtonClass)[0];
            if (!collapseAllButton) {
                logWarn("failed to find a collapse all button inside a collapse all button container element");
                console.warn({
                    collapseAllButtonContainerEl
                })
                continue;
            }
 
            const collapsibleContainerClass = collapseAllButtonContainerEl.getAttribute(collapsibleContainerDataAttr);
            if (!collapsibleContainerClass) {
                logWarn("collapsible container data attribute not found on the collapse all button container element");
                console.warn({
                    collapseAllButtonContainerEl
                })
                continue;
            }
 
            let toggleEls = new Set();
            /** Whether the initial querying of the toggle elements has been done. */
            let initialized = false;
 
            collapseAllButton.addEventListener('click', () => {
                if (!initialized) {
                    const collapsibleContainerEls = contentEl.getElementsByClassName(collapsibleContainerClass);
 
                    for (const collapsibleContainerEl of collapsibleContainerEls) {
                        for (const toggleEl of collapsibleContainerEl.querySelectorAll(`[class*='${customToggleClassPrefix}']`)) {
                            toggleEls.add(toggleEl);
                        }
                    }
 
                    initialized = true;
                }
 
                toggleEls.forEach(el => el.click());
            });
        }
    }, 250)
});
});


// ********************************
// ===========
// ******* End DRUID js *********
 
// ********************************
function joinLogPrefixWithMessage(msg) {
    return logPrefix + " " + msg;
}
 
function logWarn(msg) {
    console.warn(joinLogPrefixWithMessage(msg));
}
 
function throwErr(msg) {
    throw new Error(joinLogPrefixWithMessage(msg));
}

Revision as of 13:27, 24 May 2025

/** Class name of an element that holds a collapse all button. */
const collapseAllButtonContainerClass = "collapsible-toggle-container";

/** Class name of an actual collapse all button. */
const collapseAllButtonClass = "mw-collapsible-toggle";

/** Data attribute on the collapse all button container element, 
 * that specifies a class name for a collapsable elements container that the collapse all button shall target. */
const collapsibleContainerDataAttr = "data-target-class";

/** The initial part of a custom toggle class name. */
const customToggleClassPrefix = "mw-customtoggle";

/** Class name for collapsible elements. */
const collapsibleClass = "mw-collapsible";

/** Class name for collapsed elements. */
const collapsedClass = "mw-collapsed";

const logPrefix = "Gadget-ExpandAllReagents"

// ===========

mw.hook('wikipage.content').add((content) => {
    /** @type {HTMLElement} */
    const contentEl = content[0];

    // small timeout to prevent race condition with underlying jquery
    // that works the collapsible magic.
    setTimeout(() => {
        for (const collapseAllButtonContainerEl of contentEl.getElementsByClassName(collapseAllButtonContainerClass)) {
            const collapseAllButton = collapseAllButtonContainerEl.getElementsByClassName(collapseAllButtonClass)[0];
            if (!collapseAllButton) {
                logWarn("failed to find a collapse all button inside a collapse all button container element");
                console.warn({
                    collapseAllButtonContainerEl
                })
                continue;
            }

            const collapsibleContainerClass = collapseAllButtonContainerEl.getAttribute(collapsibleContainerDataAttr);
            if (!collapsibleContainerClass) {
                logWarn("collapsible container data attribute not found on the collapse all button container element");
                console.warn({
                    collapseAllButtonContainerEl
                })
                continue;
            }

            let toggleEls = new Set();
            /** Whether the initial querying of the toggle elements has been done. */
            let initialized = false;

            collapseAllButton.addEventListener('click', () => {
                if (!initialized) {
                    const collapsibleContainerEls = contentEl.getElementsByClassName(collapsibleContainerClass);

                    for (const collapsibleContainerEl of collapsibleContainerEls) {
                        for (const toggleEl of collapsibleContainerEl.querySelectorAll(`[class*='${customToggleClassPrefix}']`)) {
                            toggleEls.add(toggleEl);
                        }
                    }

                    initialized = true;
                }

                toggleEls.forEach(el => el.click());
            });
        }
    }, 250)
});

// ===========

function joinLogPrefixWithMessage(msg) {
    return logPrefix + " " + msg;
}

function logWarn(msg) {
    console.warn(joinLogPrefixWithMessage(msg));
}

function throwErr(msg) {
    throw new Error(joinLogPrefixWithMessage(msg));
}