MediaWiki:Gadget-defaultVisibilityToggles.js: Difference between revisions

From Linguifex
Jump to navigation Jump to search
No edit summary
Tag: Reverted
No edit summary
Tag: Reverted
Line 1: Line 1:
/* jshint undef: true, esversion: 6 */
/* jshint undef: true, esversion: 5 */
/* globals $, jQuery, mw, window, getComputedStyle */
/* globals $, jQuery, mw, window, getComputedStyle */


(function defaultVisibilityTogglesIIFE() {
"use strict";
if (window.noDefaultVisibilityToggles) return;
/* == NavBars == */
var NavigationBarHide = "hide ▲";
var NavigationBarShow = "show ▼";
var nbsp = "\u00a0";
// Check if an element has been activated with a toggle.
// For convenience, this has the side effect of marking the element as having
// a toggle, if it is not already marked.
// Allows the functions to avoid toggleifying elements more than once, which
// can lead to multiple "show" buttons, for instance.
// The argument must be an Element, not a jQuery object.
function checkAndSetToggleified(element) {
if (element.isToggleified) {
return true;
}
element.isToggleified = true;
}
function getToggleCategory(element, defaultCategory) {
if ($(element).find("table").first().is(".translations"))
return "translations";
var heading = element;
while ((heading = heading.previousElementSibling)) {
// tagName is always uppercase:
// https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName
var num = heading.tagName.match(/H(\d)/);
if (num)
num = Number(num[1]);
else
continue;
if (4 <= num && num <= 6) {
if (heading.getElementsByTagName("span")[1])
heading = heading.getElementsByTagName("span")[0];
var text = jQuery(heading).text()
.toLowerCase()
// jQuery's .text() is inconsistent about whitespace:
.replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ")
// remove numbers added by the "Auto-number headings" pref:
.replace(/^[1-9][0-9.]+ ?/, "");
// Toggle category must be convertible to a valid CSS identifier so
// that it can be used in an id selector in jQuery in
// ToggleCategory.prototype.newSidebarToggle
// in [[MediaWiki:Gadget-VisibilityToggles.js]].
// Spaces must later be converted to hyphens or underscores.
// Reference: https://drafts.csswg.org/selectors-4/#id-selectors
if (/^[a-zA-Z0-9\s_-]+$/.test(text))
return text;
else
break;
} else if (num)
break;
}
return defaultCategory;
}
function createNavToggle(navFrame) {
if (checkAndSetToggleified(navFrame)) {
return;
}
var navHead, navContent;
for (var i = 0, children = navFrame.childNodes; i < children.length; ++i) {
var child = children[i];
if (child.nodeName === "DIV") {
var classList = child.classList;
if (classList.contains("NavHead"))
navHead = child;
if (classList.contains("NavContent"))
navContent = child;
}
}
if (!(navHead && navContent))
return;
// Step 1, don't react when a subitem is clicked.
$(navHead).find("a").on("click", function (e) {
e.stopPropagation();
e.stopImmediatePropagation();
});
// Step 2, toggle visibility when bar is clicked.
// NOTE This function was chosen due to some funny behaviour in Safari.
var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
$("<span>").addClass("NavToggle").attr("data-nosnippet", "")
.append($navToggle)
.prependTo(navHead);
navHead.style.cursor = "pointer";
var toggleCategory = $(navFrame).data("toggle-category") || getToggleCategory(navFrame, "other boxes");
navHead.onclick = window.VisibilityToggles.register(toggleCategory,
function show() {
$navToggle.text(NavigationBarHide);
if (navContent)
navContent.style.display = "block";
},
function hide() {
$navToggle.text(NavigationBarShow);
if (navContent)
navContent.style.display = "none";
});
}
function createNavToggleForInflectionTable(it) {
if (checkAndSetToggleified(it)) {
return;
}
// The table caption is the clickable element
var itCaption = $(it).find("caption").get(0);
// Step 1, don't react when a subitem is clicked.
$(itCaption).find("a").on("click", function (e) {
e.stopPropagation();
e.stopImmediatePropagation();
});
// Step 2, toggle visibility when bar is clicked.
// NOTE This function was chosen due to some funny behaviour in Safari.
var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
$("<span>").addClass("NavToggle").attr("data-nosnippet", "")
.append($navToggle)
.prependTo(itCaption);
itCaption.style.cursor = "pointer";
var toggleCategory = $(it).data("toggle-category") || getToggleCategory(it, "other boxes");
itCaption.onclick = window.VisibilityToggles.register(toggleCategory,
function show() {
$navToggle.text(NavigationBarHide);
if (it) {
it.classList.remove("inflection-table-collapsed");
}
},
function hide() {
$navToggle.text(NavigationBarShow);
if (it) {
it.classList.add("inflection-table-collapsed");
}
});
// Check to see if we are on a browser that is known to support
// visibility: collapse, which permits inflection table headings to wrap.
// WebKit needs to be special-cased, as technically it does support
// visibility: collapse, but it just implements it as a synonym for
// visibility: hidden, which is useless. (as of November 2024)
// Yes, I know User-Agent sniffing is so 2004... but WebKit is the new IE
if (
CSS && CSS.supports && CSS.supports("visibility:collapse") &&
// exclude WebKit/Safari, excepting Blink engines which have a frozen WebKit version number
(navigator.userAgent.indexOf("AppleWebKit/") === -1 || navigator.userAgent.indexOf("AppleWebKit/537.36") > -1)
) {
it.classList.remove("no-vc");
} else {
// Strange behaviour occurs when you set the table caption to nowrap
// The [show/hide] toggle crashes into the caption text
// This spacer element prevents that
$("<span>").addClass("no-vc-spacer").appendTo(itCaption);
}
}
/* ==Hidden Quotes== */
function setupHiddenQuotes(li) {
if (checkAndSetToggleified(li))
return;
let HQToggleButton, liComp, dl;


function show() {
(function () {
HQToggleButton.text("quotations ▲");
    "use strict";
$(li).children("ul").show();
}
function hide() {
HQToggleButton.text("quotations ▼");
$(li).children("ul").hide();
}
for (const liComp of li.childNodes) {
// Look at each component of the definition.
if (liComp.tagName === "DL" && !dl)
dl = liComp;


// If we find a ul or dl, we have quotes or example sentences, and thus need a button.
    if (window.noDefaultVisibilityToggles) return;
if (liComp.tagName === "UL") {
 
$(li).children("ul").addClass("wikt-quote-container");
    var NavigationBarHide = "hide ▲";
HQToggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
    var NavigationBarShow = "show ▼";
$(dl || liComp).before($("<span>").addClass("HQToggle").attr("data-nosnippet", "").append(HQToggleButton).css("margin-left", "5px"));
 
HQToggleButton.on("click", window.VisibilityToggles.register("quotations", show, hide));
    var nbsp = "\u00a0";
break;
 
}
    function checkAndSetToggleified(element) {
}
        if (element.isToggleified) {
}
            return true;
        }
/* == View Switching == */
        element.isToggleified = true;
    }
function viewSwitching(rootElement) {
 
if (checkAndSetToggleified(rootElement)) {
    function getToggleCategory(element, defaultCategory) {
return;
        if ($(element).find("table").first().is(".translations"))
}
            return "translations";
 
var $rootElement = $(rootElement);
        var heading = element;
var showButtonText = $rootElement.data("vs-showtext") || "more ▼";
        while ((heading = heading.previousElementSibling)) {
var hideButtonText = $rootElement.data("vs-hidetext") || "less ▲";
            var num = heading.tagName.match(/H(\d)/);
            if (num)
var toSkip = $rootElement.find(".vsSwitcher").find("*");
                num = Number(num[1]);
var elemsToHide = $rootElement.find(".vsHide").not(toSkip);
            else
var elemsToShow = $rootElement.find(".vsShow").not(toSkip);
                continue;
            if (4 <= num && num <= 6) {
// Find the element to place the toggle button in.
                if (heading.getElementsByTagName("span")[1])
var toggleElement = $rootElement.find(".vsToggleElement").not(toSkip).first();
                    heading = heading.getElementsByTagName("span")[0];
                var text = jQuery(heading).text()
// The toggleElement becomes clickable in its entirety, but
                    .toLowerCase()
// we need to prevent this if a contained link is clicked instead.
                    .replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ")
toggleElement.find("a").on("click", function (e) {
                    .replace(/^[1-9][0-9.]+ ?/, "");
e.stopPropagation();
                if (/^[a-zA-Z0-9\s_-]+$/.test(text))
e.stopImmediatePropagation();
                    return text;
});
                else
                    break;
// Add the toggle button.
            } else if (num)
var toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
                break;
        }
$("<span>").addClass("NavToggle").attr("data-nosnippet", "").append(toggleButton).prependTo(toggleElement);
 
        return defaultCategory;
// Determine the visibility toggle category (for the links in the bar on the left).
    }
var toggleCategory = $rootElement.data("toggle-category");
 
if (!toggleCategory) {
    function createNavToggle(navFrame) {
var classNames = $rootElement.attr("class").split(/\s+/);
        if (checkAndSetToggleified(navFrame)) {
            return;
for (var i = 0; i < classNames.length; ++i) {
        }
var className = classNames[i].split("-");
 
        var navHead, navContent;
if (className[0] == "vsToggleCategory") {
        var children = navFrame.childNodes;
toggleCategory = className[1];
        for (var i = 0; i < children.length; ++i) {
}
            var child = children[i];
}
            if (child.nodeName === "DIV") {
}
                var classList = child.classList;
                if (classList.contains("NavHead"))
if (!toggleCategory)
                    navHead = child;
toggleCategory = "others";
                if (classList.contains("NavContent"))
                    navContent = child;
// Register the visibility toggle.
            }
toggleElement.css("cursor", "pointer");
        }
toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
        if (!(navHead && navContent))
function show() {
            return;
toggleButton.text(hideButtonText);
 
elemsToShow.hide();
        $(navHead).find("a").on("click", function (e) {
elemsToHide.show();
            e.stopPropagation();
},
            e.stopImmediatePropagation();
function hide() {
        });
toggleButton.text(showButtonText);
 
elemsToShow.show();
        var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
elemsToHide.hide();
 
}));
        $("<span>").addClass("NavToggle").attr("data-nosnippet", "")
}
            .append($navToggle)
            .prependTo(navHead);
/* ==List switching== */
 
function enableListSwitchGeneric(rootElement) {
        navHead.style.cursor = "pointer";
if (checkAndSetToggleified(rootElement)) {
        var toggleCategory = $(navFrame).data("toggle-category") || getToggleCategory(navFrame, "other boxes");
return;
        navHead.onclick = window.VisibilityToggles.register(toggleCategory,
}
            function show() {
                $navToggle.text(NavigationBarHide);
var $rootElement = $(rootElement);
                if (navContent)
                    navContent.style.display = "block";
// Create a toggle button.
            },
var $toggleElement = $("<div>").addClass("list-switcher-element");
            function hide() {
var $navToggle = $("<span>").addClass("NavToggle").attr("data-nosnippet", "");
                $navToggle.text(NavigationBarShow);
var $toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
                if (navContent)
                    navContent.style.display = "none";
// Add the toggle button to the DOM tree.
            });
$navToggle.append($toggleButton).prependTo($toggleElement);
    }
$toggleElement.insertAfter($rootElement);
 
$toggleElement.show();
    function createNavToggleForInflectionTable(it) {
        if (checkAndSetToggleified(it)) {
// Determine the visibility toggle category (for the links in the bar on the
            return;
// left). It will either be the value of the "data-toggle-category"
        }
// attribute or will be based on the text of the closest preceding
 
// fourth-to-sixth-level header.
        var itCaption = $(it).find("caption").get(0);
var toggleCategory = $rootElement.data("toggle-category") || getToggleCategory($rootElement[0], "other lists");
 
        $(itCaption).find("a").on("click", function (e) {
// Determine the text for the $toggleButton.
            e.stopPropagation();
var showButtonText = "show more ▼";
            e.stopImmediatePropagation();
var hideButtonText = "show less ▲";
        });
var numItems;
 
// special handling for [[Module:collapsible category tree]]
        var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
var $categoryTreeTag = $rootElement.children(".CategoryTreeTag");
 
if ($categoryTreeTag) {
        $("<span>").addClass("NavToggle").attr("data-nosnippet", "")
if ($categoryTreeTag.attr("data-pages-left-over") !== "0") {
            .append($navToggle)
// some category members are omitted from the list (MediaWiki limitation)
            .prependTo(itCaption);
// just use basic "show more/less" in this case for now, this is a big change
 
//showButtonText = "show first 200 of " + $categoryTreeTag.attr("data-pages-in-cat") + " ▼";
        itCaption.style.cursor = "pointer";
//hideButtonText = "show fewer ▲";
        var toggleCategory = $(it).data("toggle-category") || getToggleCategory(it, "other boxes");
} else {
        itCaption.onclick = window.VisibilityToggles.register(toggleCategory,
// all category members are included in the list
            function show() {
numItems = $categoryTreeTag.attr("data-pages-in-cat");
                $navToggle.text(NavigationBarHide);
}
                if (it) {
} else {
                    it.classList.remove("inflection-table-collapsed");
// standard list-switcher using <li> elements
                }
numItems = $rootElement.find("li").length;
            },
}
            function hide() {
if (numItems) {
                $navToggle.text(NavigationBarShow);
showButtonText = "show all " + numItems + " ▼";
                if (it) {
hideButtonText = "show fewer ▲";
                    it.classList.add("inflection-table-collapsed");
}
                }
            });
// Register the visibility toggle.
 
$toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
        if (
function show() {
            CSS && CSS.supports && CSS.supports("visibility:collapse") &&
$toggleButton.text(hideButtonText);
            (navigator.userAgent.indexOf("AppleWebKit/") === -1 || navigator.userAgent.indexOf("AppleWebKit/537.36") > -1)
if (rootElement) {
        ) {
rootElement.classList.remove("list-switcher-collapsed");
            it.classList.remove("no-vc");
}
        } else {
},
            $("<span>").addClass("no-vc-spacer").appendTo(itCaption);
function hide() {
        }
$toggleButton.text(showButtonText);
    }
if (rootElement) {
 
rootElement.classList.add("list-switcher-collapsed");
    function setupHiddenQuotes(li) {
}
        if (checkAndSetToggleified(li))
}));
            return;
 
// Register a resize observer to see if we need to keep the
        var HQToggleButton, dl;
// show/hide toggle visible
 
var termList = rootElement.querySelector(':scope > .term-list');
        function show() {
if (termList && window.ResizeObserver) {
            HQToggleButton.text("quotations ▲");
var resizeObserver = new ResizeObserver(function(entries) {
            $(li).children("ul").show();
if (entries[0] && entries[0].contentBoxSize[0]) {
        }
// Work out what the max-height would be, in pixels
        function hide() {
// As a hack, this value is stored in the CSS `bottom`
            HQToggleButton.text("quotations ▼");
// property, as `max-height` is only in place when
            $(li).children("ul").hide();
// the list is collapsed, but we need to do this check
        }
// even when the list is not collapsed
 
var maxHeightPx = parseFloat(getComputedStyle(rootElement).bottom);
        var liComp;
        for (var i = 0; i < li.childNodes.length; i++) {
// If box height is less than its max height + 20 px, suppress
            liComp = li.childNodes[i];
// collapsibility. The 20 px buffer prevents the situation where
            if (liComp.tagName === "DL" && !dl)
// clicking "show more" expands the box by just a few pixels
                dl = liComp;
if (entries[0].contentBoxSize[0].blockSize <= maxHeightPx + 20) {
            if (liComp.tagName === "UL") {
$toggleElement.hide();
                $(li).children("ul").addClass("wikt-quote-container");
if (rootElement.classList.contains("list-switcher-collapsed")) {
                HQToggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
rootElement.classList.remove("list-switcher-collapsed");
                $(dl || liComp).before($("<span>").addClass("HQToggle").attr("data-nosnippet", "").append(HQToggleButton).css("margin-left", "5px"));
rootElement.classList.add("list-switcher-collapsibility-suppressed");
                HQToggleButton.on("click", window.VisibilityToggles.register("quotations", show, hide));
}
                break;
} else {
            }
$toggleElement.show();
        }
if (rootElement.classList.contains("list-switcher-collapsibility-suppressed")) {
    }
rootElement.classList.remove("list-switcher-collapsibility-suppressed");
 
rootElement.classList.add("list-switcher-collapsed");
    function viewSwitching(rootElement) {
}
        if (checkAndSetToggleified(rootElement)) {
}
            return;
}
        }
});
 
        var $rootElement = $(rootElement);
resizeObserver.observe(termList);
        var showButtonText = $rootElement.data("vs-showtext") || "more ▼";
}
        var hideButtonText = $rootElement.data("vs-hidetext") || "less ▲";
}
 
        var toSkip = $rootElement.find(".vsSwitcher").find("*");
// based on [[User:Erutuon/scripts/semhide.js]], [[User:Jberkel/semhide.js]],
        var elemsToHide = $rootElement.find(".vsHide").not(toSkip);
// [[User:Ungoliant_MMDCCLXIV/synshide.js]]
        var elemsToShow = $rootElement.find(".vsShow").not(toSkip);
function setupNyms(index, dlTag) {
 
// [[Wiktionary:Semantic relations]]
        var toggleElement = $rootElement.find(".vsToggleElement").not(toSkip).first();
var relationClasses = [ "synonym", "antonym", "hypernym", "hyponym", "meronym",
 
"holonym", "troponym", "comeronym", "coordinate-term",
        toggleElement.find("a").on("click", function (e) {
"near-synonym", "imperfective", "perfective", "alternative-form" ];
            e.stopPropagation();
            e.stopImmediatePropagation();
var relations = $(dlTag).find("dd > .nyms").get().filter(
        });
function(element) {
 
return Array.prototype.some.call(element.classList, function (className) {
        var toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
if (relationClasses.indexOf(className) !== -1) {
 
element.dataset.relationClass = className;
        $("<span>").addClass("NavToggle").attr("data-nosnippet", "").append(toggleButton).prependTo(toggleElement);
return true;
 
}
        var toggleCategory = $rootElement.data("toggle-category");
});
        if (!toggleCategory) {
});
            var classNames = $rootElement.attr("class").split(/\s+/);
 
function setupToggle(elements, category, visibleByDefault) {
            for (var i = 0; i < classNames.length; ++i) {
if (elements.length === 0) return null;
                var className = classNames[i].split("-");
var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
 
var text = elements.map(function (e) {
                if (className[0] == "vsToggleCategory") {
var linkCount = e.querySelectorAll("span[lang]").length;
                    toggleCategory = className[1];
return e.dataset.relationClass.replace("-", " ") +
                }
(linkCount > 1 ? "s" : "");
            }
}).join(", ");
        }
 
function show() {
        if (!toggleCategory)
toggler.text(text + nbsp + "▲");
            toggleCategory = "others";
$(dlTag).show();
 
$(elements).show();
        toggleElement.css("cursor", "pointer");
}
        toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
function hide() {
            function show() {
toggler.text(text + nbsp + "▼");
                toggleButton.text(hideButtonText);
if ($(dlTag).children().length === elements.length) {
                elemsToShow.hide();
$(dlTag).hide();
                elemsToHide.show();
} else {
            },
$(elements).hide();
            function hide() {
}
                toggleButton.text(showButtonText);
}
                elemsToShow.show();
                elemsToHide.hide();
$(dlTag).before($("<span>")
            }));
.addClass("nyms-toggle")
    }
.attr("data-nosnippet", "")
 
.append(toggler)
    function enableListSwitchGeneric(rootElement) {
.css("margin-left", "5px"));
        if (checkAndSetToggleified(rootElement)) {
            return;
toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
        }
}
 
        var $rootElement = $(rootElement);
var synonyms = relations.filter(function (e) {
 
return ["synonym", "antonym", "near-synonym", "coordinate-term", "alternative-form"].indexOf(e.dataset.relationClass) !== -1;
        var $toggleElement = $("<div>").addClass("list-switcher-element");
});
        var $navToggle = $("<span>").addClass("NavToggle").attr("data-nosnippet", "");
var other = relations.filter(function (e) { return synonyms.indexOf(e) === -1; });
        var $toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
 
setupToggle(synonyms, "synonyms", true /* show by default  */);
        $navToggle.append($toggleButton).prependTo($toggleElement);
setupToggle(other, "semantic relations");
        $toggleElement.insertAfter($rootElement);
}
        $toggleElement.show();
 
        var toggleCategory = $rootElement.data("toggle-category") || getToggleCategory($rootElement[0], "other lists");
function setupUsageExampleCollapses(index, dlTag) {
 
var usexTags = $(dlTag).find("dd > .h-usage-example").get();
        var showButtonText = "show more ▼";
        var hideButtonText = "show less ▲";
function setupToggle(elements, category, visibleByDefault) {
        var numItems;
if (elements.length === 0) return null;
        var $categoryTreeTag = $rootElement.children(".CategoryTreeTag");
var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
        if ($categoryTreeTag) {
            if ($categoryTreeTag.attr("data-pages-left-over") !== "0") {
function show() {
            } else {
toggler.text(category + nbsp + "▲");
                numItems = $categoryTreeTag.attr("data-pages-in-cat");
$(dlTag).show();
            }
$(elements).show();
        } else {
}
            numItems = $rootElement.find("li").length;
function hide() {
        }
toggler.text(category + nbsp + "▼");
        if (numItems) {
if ($(dlTag).children().length === elements.length) {
            showButtonText = "show all " + numItems + " ▼";
$(dlTag).hide();
            hideButtonText = "show fewer ▲";
} else {
        }
$(elements).hide();
 
}
        $toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
}
            function show() {
                $toggleButton.text(hideButtonText);
$(dlTag).before($("<span>")
                if (rootElement) {
.addClass("nyms-toggle")
                    rootElement.classList.remove("list-switcher-collapsed");
.append(toggler)
                }
.css("margin-left", "5px"));
            },
            function hide() {
toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
                $toggleButton.text(showButtonText);
}
                if (rootElement) {
                    rootElement.classList.add("list-switcher-collapsed");
var collocations = usexTags.filter(function (e) {
                }
return $(e).hasClass("collocation");
            }));
});
 
var usexes = usexTags.filter(function (e) { return collocations.indexOf(e) === -1; });
        var termList = rootElement.querySelector(':scope > .term-list');
        if (termList && window.ResizeObserver) {
setupToggle(usexes, "usage examples", true /* show by default */);
            var resizeObserver = new ResizeObserver(function (entries) {
setupToggle(collocations, "collocations", true /* show by default */);
                if (entries[0] && entries[0].contentBoxSize[0]) {
}
                    var maxHeightPx = parseFloat(getComputedStyle(rootElement).bottom);
 
                    if (entries[0].contentBoxSize[0].blockSize <= maxHeightPx + 20) {
window.createNavToggle = createNavToggle;
                        $toggleElement.hide();
window.setupHiddenQuotes = setupHiddenQuotes;
                        if (rootElement.classList.contains("list-switcher-collapsed")) {
window.viewSwitching = viewSwitching;
                            rootElement.classList.remove("list-switcher-collapsed");
window.getToggleCategory = getToggleCategory;
                            rootElement.classList.add("list-switcher-collapsibility-suppressed");
                        }
/* == Apply four functions defined above == */
                    } else {
mw.hook("wikipage.content").add(function($content) {
                        $toggleElement.show();
// NavToggles
                        if (rootElement.classList.contains("list-switcher-collapsibility-suppressed")) {
$(".NavFrame", $content).each(function(){
                            rootElement.classList.remove("list-switcher-collapsibility-suppressed");
createNavToggle(this);
                            rootElement.classList.add("list-switcher-collapsed");
});
                        }
$(".inflection-table-collapsible", $content).each(function(){
                    }
createNavToggleForInflectionTable(this);
                }
});
            });
 
// order nyms -> usexes -> quotes, to match the conventional order in entries
            resizeObserver.observe(termList);
        }
// synonyms and such under definitions
    }
// if (mw.config.get("wgNamespaceNumber") === 0) {
 
$("dl:has(dd > .nyms)", $content).each(setupNyms);
    function setupNyms(index, dlTag) {
// }
        var relationClasses = ["synonym", "antonym", "hypernym", "hyponym", "meronym",
            "holonym", "troponym", "comeronym", "coordinate-term",
// usage examples and collocations
            "near-synonym", "imperfective", "perfective", "alternative-form"];
var namespaceNumber = mw.config.get("wgNamespaceNumber");
 
if (window.defaultVisibilityTogglesForUsageExamples) {
        var relations = $(dlTag).find("dd > .nyms").get().filter(
if (namespaceNumber === 0) {
            function (element) {
$("ol > li dl:has(dd > .h-usage-example)", $content).each(setupUsageExampleCollapses);
                return Array.prototype.some.call(element.classList, function (className) {
}
                    if (relationClasses.indexOf(className) !== -1) {
}
                        element.dataset.relationClass = className;
                        return true;
// quotes
                    }
if (namespaceNumber === 0 || namespaceNumber === 100 || namespaceNumber === 118) {
                });
// First, find all the ordered lists, i.e. all the series of definitions.
            });
$("ol > li", $content).each(function(){
 
setupHiddenQuotes(this);
        function setupToggle(elements, category, visibleByDefault) {
});
            if (elements.length === 0) return null;
}
            var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
            var text = elements.map(function (e) {
//view switching
                var linkCount = e.querySelectorAll("span[lang]").length;
$(".vsSwitcher", $content).each(function(){
                return e.dataset.relationClass.replace("-", " ") +
viewSwitching(this);
                    (linkCount > 1 ? "s" : "");
});
            }).join(", ");
 
// list switching
            function show() {
$(".list-switcher", $content).each(function () {
                toggler.text(text + nbsp + "▲");
enableListSwitchGeneric(this);
                $(dlTag).show();
});
                $(elements).show();
});
            }
            function hide() {
jQuery(mw).on("LivePreviewDone", function (ev, sels) {
                toggler.text(text + nbsp + "▼");
var ols = jQuery(sels.join(",")).find("ol");
                if ($(dlTag).children().length === elements.length) {
for (var i = 0; i < ols.length; i++) {
                    $(dlTag).hide();
for (var j = 0; j < ols[i].childNodes.length; j++) {
                } else {
var li = ols[i].childNodes[j];
                    $(elements).hide();
if (li.nodeName.toUpperCase() == "LI") {
                }
setupHiddenQuotes(li);
            }
}
 
}
            $(dlTag).before($("<span>")
}
                .addClass("nyms-toggle")
});
                .attr("data-nosnippet", "")
                .append(toggler)
                .css("margin-left", "5px"));
 
            toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
        }
 
        var synonyms = relations.filter(function (e) {
            return ["synonym", "antonym", "near-synonym", "coordinate-term", "alternative-form"].indexOf(e.dataset.relationClass) !== -1;
        });
        var other = relations.filter(function (e) { return synonyms.indexOf(e) === -1; });
 
        setupToggle(synonyms, "synonyms", true);
        setupToggle(other, "semantic relations");
    }
 
    function setupUsageExampleCollapses(index, dlTag) {
        var usexTags = $(dlTag).find("dd > .h-usage-example").get();
 
        function setupToggle(elements, category, visibleByDefault) {
            if (elements.length === 0) return null;
            var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
 
            function show() {
                toggler.text(category + nbsp + "▲");
                $(dlTag).show();
                $(elements).show();
            }
            function hide() {
                toggler.text(category + nbsp + "▼");
                if ($(dlTag).children().length === elements.length) {
                    $(dlTag).hide();
                } else {
                    $(elements).hide();
                }
            }
 
            $(dlTag).before($("<span>")
                .addClass("nyms-toggle")
                .append(toggler)
                .css("margin-left", "5px"));
 
            toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
        }
 
        var collocations = usexTags.filter(function (e) {
            return $(e).hasClass("collocation");
        });
        var usexes = usexTags.filter(function (e) { return collocations.indexOf(e) === -1; });
 
        setupToggle(usexes, "usage examples", true);
        setupToggle(collocations, "collocations", true);
    }
 
    window.createNavToggle = createNavToggle;
    window.setupHiddenQuotes = setupHiddenQuotes;
    window.viewSwitching = viewSwitching;
    window.getToggleCategory = getToggleCategory;
 
    mw.hook("wikipage.content").add(function ($content) {
        $(".NavFrame", $content).each(function () {
            createNavToggle(this);
        });
        $(".inflection-table-collapsible", $content).each(function () {
            createNavToggleForInflectionTable(this);
        });
 
        $("dl:has(dd > .nyms)", $content).each(setupNyms);
 
        var namespaceNumber = mw.config.get("wgNamespaceNumber");
        if (window.defaultVisibilityTogglesForUsageExamples) {
            if (namespaceNumber === 0) {
                $("ol > li dl:has(dd > .h-usage-example)", $content).each(setupUsageExampleCollapses);
            }
        }
 
        if (namespaceNumber === 0 || namespaceNumber === 100 || namespaceNumber === 118) {
            $("ol > li", $content).each(function () {
                setupHiddenQuotes(this);
            });
        }
 
        $(".vsSwitcher", $content).each(function () {
            viewSwitching(this);
        });
 
        $(".list-switcher", $content).each(function () {
            enableListSwitchGeneric(this);
        });
    });
 
    jQuery(mw).on("LivePreviewDone", function (ev, sels) {
        var ols = jQuery(sels.join(",")).find("ol");
        for (var i = 0; i < ols.length; i++) {
            for (var j = 0; j < ols[i].childNodes.length; j++) {
                var li = ols[i].childNodes[j];
                if (li.nodeName.toUpperCase() == "LI") {
                    setupHiddenQuotes(li);
                }
            }
        }
    });
})();
})();

Revision as of 13:05, 15 November 2025

/* jshint undef: true, esversion: 5 */
/* globals $, jQuery, mw, window, getComputedStyle */


(function () {
    "use strict";

    if (window.noDefaultVisibilityToggles) return;

    var NavigationBarHide = "hide ▲";
    var NavigationBarShow = "show ▼";

    var nbsp = "\u00a0";

    function checkAndSetToggleified(element) {
        if (element.isToggleified) {
            return true;
        }
        element.isToggleified = true;
    }

    function getToggleCategory(element, defaultCategory) {
        if ($(element).find("table").first().is(".translations"))
            return "translations";

        var heading = element;
        while ((heading = heading.previousElementSibling)) {
            var num = heading.tagName.match(/H(\d)/);
            if (num)
                num = Number(num[1]);
            else
                continue;
            if (4 <= num && num <= 6) {
                if (heading.getElementsByTagName("span")[1])
                    heading = heading.getElementsByTagName("span")[0];
                var text = jQuery(heading).text()
                    .toLowerCase()
                    .replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ")
                    .replace(/^[1-9][0-9.]+ ?/, "");
                if (/^[a-zA-Z0-9\s_-]+$/.test(text))
                    return text;
                else
                    break;
            } else if (num)
                break;
        }

        return defaultCategory;
    }

    function createNavToggle(navFrame) {
        if (checkAndSetToggleified(navFrame)) {
            return;
        }

        var navHead, navContent;
        var children = navFrame.childNodes;
        for (var i = 0; i < children.length; ++i) {
            var child = children[i];
            if (child.nodeName === "DIV") {
                var classList = child.classList;
                if (classList.contains("NavHead"))
                    navHead = child;
                if (classList.contains("NavContent"))
                    navContent = child;
            }
        }
        if (!(navHead && navContent))
            return;

        $(navHead).find("a").on("click", function (e) {
            e.stopPropagation();
            e.stopImmediatePropagation();
        });

        var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");

        $("<span>").addClass("NavToggle").attr("data-nosnippet", "")
            .append($navToggle)
            .prependTo(navHead);

        navHead.style.cursor = "pointer";
        var toggleCategory = $(navFrame).data("toggle-category") || getToggleCategory(navFrame, "other boxes");
        navHead.onclick = window.VisibilityToggles.register(toggleCategory,
            function show() {
                $navToggle.text(NavigationBarHide);
                if (navContent)
                    navContent.style.display = "block";
            },
            function hide() {
                $navToggle.text(NavigationBarShow);
                if (navContent)
                    navContent.style.display = "none";
            });
    }

    function createNavToggleForInflectionTable(it) {
        if (checkAndSetToggleified(it)) {
            return;
        }

        var itCaption = $(it).find("caption").get(0);

        $(itCaption).find("a").on("click", function (e) {
            e.stopPropagation();
            e.stopImmediatePropagation();
        });

        var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");

        $("<span>").addClass("NavToggle").attr("data-nosnippet", "")
            .append($navToggle)
            .prependTo(itCaption);

        itCaption.style.cursor = "pointer";
        var toggleCategory = $(it).data("toggle-category") || getToggleCategory(it, "other boxes");
        itCaption.onclick = window.VisibilityToggles.register(toggleCategory,
            function show() {
                $navToggle.text(NavigationBarHide);
                if (it) {
                    it.classList.remove("inflection-table-collapsed");
                }
            },
            function hide() {
                $navToggle.text(NavigationBarShow);
                if (it) {
                    it.classList.add("inflection-table-collapsed");
                }
            });

        if (
            CSS && CSS.supports && CSS.supports("visibility:collapse") &&
            (navigator.userAgent.indexOf("AppleWebKit/") === -1 || navigator.userAgent.indexOf("AppleWebKit/537.36") > -1)
        ) {
            it.classList.remove("no-vc");
        } else {
            $("<span>").addClass("no-vc-spacer").appendTo(itCaption);
        }
    }

    function setupHiddenQuotes(li) {
        if (checkAndSetToggleified(li))
            return;

        var HQToggleButton, dl;

        function show() {
            HQToggleButton.text("quotations ▲");
            $(li).children("ul").show();
        }
        function hide() {
            HQToggleButton.text("quotations ▼");
            $(li).children("ul").hide();
        }

        var liComp;
        for (var i = 0; i < li.childNodes.length; i++) {
            liComp = li.childNodes[i];
            if (liComp.tagName === "DL" && !dl)
                dl = liComp;
            if (liComp.tagName === "UL") {
                $(li).children("ul").addClass("wikt-quote-container");
                HQToggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
                $(dl || liComp).before($("<span>").addClass("HQToggle").attr("data-nosnippet", "").append(HQToggleButton).css("margin-left", "5px"));
                HQToggleButton.on("click", window.VisibilityToggles.register("quotations", show, hide));
                break;
            }
        }
    }

    function viewSwitching(rootElement) {
        if (checkAndSetToggleified(rootElement)) {
            return;
        }

        var $rootElement = $(rootElement);
        var showButtonText = $rootElement.data("vs-showtext") || "more ▼";
        var hideButtonText = $rootElement.data("vs-hidetext") || "less ▲";

        var toSkip = $rootElement.find(".vsSwitcher").find("*");
        var elemsToHide = $rootElement.find(".vsHide").not(toSkip);
        var elemsToShow = $rootElement.find(".vsShow").not(toSkip);

        var toggleElement = $rootElement.find(".vsToggleElement").not(toSkip).first();

        toggleElement.find("a").on("click", function (e) {
            e.stopPropagation();
            e.stopImmediatePropagation();
        });

        var toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");

        $("<span>").addClass("NavToggle").attr("data-nosnippet", "").append(toggleButton).prependTo(toggleElement);

        var toggleCategory = $rootElement.data("toggle-category");
        if (!toggleCategory) {
            var classNames = $rootElement.attr("class").split(/\s+/);

            for (var i = 0; i < classNames.length; ++i) {
                var className = classNames[i].split("-");

                if (className[0] == "vsToggleCategory") {
                    toggleCategory = className[1];
                }
            }
        }

        if (!toggleCategory)
            toggleCategory = "others";

        toggleElement.css("cursor", "pointer");
        toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
            function show() {
                toggleButton.text(hideButtonText);
                elemsToShow.hide();
                elemsToHide.show();
            },
            function hide() {
                toggleButton.text(showButtonText);
                elemsToShow.show();
                elemsToHide.hide();
            }));
    }

    function enableListSwitchGeneric(rootElement) {
        if (checkAndSetToggleified(rootElement)) {
            return;
        }

        var $rootElement = $(rootElement);

        var $toggleElement = $("<div>").addClass("list-switcher-element");
        var $navToggle = $("<span>").addClass("NavToggle").attr("data-nosnippet", "");
        var $toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");

        $navToggle.append($toggleButton).prependTo($toggleElement);
        $toggleElement.insertAfter($rootElement);
        $toggleElement.show();

        var toggleCategory = $rootElement.data("toggle-category") || getToggleCategory($rootElement[0], "other lists");

        var showButtonText = "show more ▼";
        var hideButtonText = "show less ▲";
        var numItems;
        var $categoryTreeTag = $rootElement.children(".CategoryTreeTag");
        if ($categoryTreeTag) {
            if ($categoryTreeTag.attr("data-pages-left-over") !== "0") {
            } else {
                numItems = $categoryTreeTag.attr("data-pages-in-cat");
            }
        } else {
            numItems = $rootElement.find("li").length;
        }
        if (numItems) {
            showButtonText = "show all " + numItems + " ▼";
            hideButtonText = "show fewer ▲";
        }

        $toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
            function show() {
                $toggleButton.text(hideButtonText);
                if (rootElement) {
                    rootElement.classList.remove("list-switcher-collapsed");
                }
            },
            function hide() {
                $toggleButton.text(showButtonText);
                if (rootElement) {
                    rootElement.classList.add("list-switcher-collapsed");
                }
            }));

        var termList = rootElement.querySelector(':scope > .term-list');
        if (termList && window.ResizeObserver) {
            var resizeObserver = new ResizeObserver(function (entries) {
                if (entries[0] && entries[0].contentBoxSize[0]) {
                    var maxHeightPx = parseFloat(getComputedStyle(rootElement).bottom);

                    if (entries[0].contentBoxSize[0].blockSize <= maxHeightPx + 20) {
                        $toggleElement.hide();
                        if (rootElement.classList.contains("list-switcher-collapsed")) {
                            rootElement.classList.remove("list-switcher-collapsed");
                            rootElement.classList.add("list-switcher-collapsibility-suppressed");
                        }
                    } else {
                        $toggleElement.show();
                        if (rootElement.classList.contains("list-switcher-collapsibility-suppressed")) {
                            rootElement.classList.remove("list-switcher-collapsibility-suppressed");
                            rootElement.classList.add("list-switcher-collapsed");
                        }
                    }
                }
            });

            resizeObserver.observe(termList);
        }
    }

    function setupNyms(index, dlTag) {
        var relationClasses = ["synonym", "antonym", "hypernym", "hyponym", "meronym",
            "holonym", "troponym", "comeronym", "coordinate-term",
            "near-synonym", "imperfective", "perfective", "alternative-form"];

        var relations = $(dlTag).find("dd > .nyms").get().filter(
            function (element) {
                return Array.prototype.some.call(element.classList, function (className) {
                    if (relationClasses.indexOf(className) !== -1) {
                        element.dataset.relationClass = className;
                        return true;
                    }
                });
            });

        function setupToggle(elements, category, visibleByDefault) {
            if (elements.length === 0) return null;
            var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
            var text = elements.map(function (e) {
                var linkCount = e.querySelectorAll("span[lang]").length;
                return e.dataset.relationClass.replace("-", " ") +
                    (linkCount > 1 ? "s" : "");
            }).join(", ");

            function show() {
                toggler.text(text + nbsp + "▲");
                $(dlTag).show();
                $(elements).show();
            }
            function hide() {
                toggler.text(text + nbsp + "▼");
                if ($(dlTag).children().length === elements.length) {
                    $(dlTag).hide();
                } else {
                    $(elements).hide();
                }
            }

            $(dlTag).before($("<span>")
                .addClass("nyms-toggle")
                .attr("data-nosnippet", "")
                .append(toggler)
                .css("margin-left", "5px"));

            toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
        }

        var synonyms = relations.filter(function (e) {
            return ["synonym", "antonym", "near-synonym", "coordinate-term", "alternative-form"].indexOf(e.dataset.relationClass) !== -1;
        });
        var other = relations.filter(function (e) { return synonyms.indexOf(e) === -1; });

        setupToggle(synonyms, "synonyms", true);
        setupToggle(other, "semantic relations");
    }

    function setupUsageExampleCollapses(index, dlTag) {
        var usexTags = $(dlTag).find("dd > .h-usage-example").get();

        function setupToggle(elements, category, visibleByDefault) {
            if (elements.length === 0) return null;
            var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");

            function show() {
                toggler.text(category + nbsp + "▲");
                $(dlTag).show();
                $(elements).show();
            }
            function hide() {
                toggler.text(category + nbsp + "▼");
                if ($(dlTag).children().length === elements.length) {
                    $(dlTag).hide();
                } else {
                    $(elements).hide();
                }
            }

            $(dlTag).before($("<span>")
                .addClass("nyms-toggle")
                .append(toggler)
                .css("margin-left", "5px"));

            toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
        }

        var collocations = usexTags.filter(function (e) {
            return $(e).hasClass("collocation");
        });
        var usexes = usexTags.filter(function (e) { return collocations.indexOf(e) === -1; });

        setupToggle(usexes, "usage examples", true);
        setupToggle(collocations, "collocations", true);
    }

    window.createNavToggle = createNavToggle;
    window.setupHiddenQuotes = setupHiddenQuotes;
    window.viewSwitching = viewSwitching;
    window.getToggleCategory = getToggleCategory;

    mw.hook("wikipage.content").add(function ($content) {
        $(".NavFrame", $content).each(function () {
            createNavToggle(this);
        });
        $(".inflection-table-collapsible", $content).each(function () {
            createNavToggleForInflectionTable(this);
        });

        $("dl:has(dd > .nyms)", $content).each(setupNyms);

        var namespaceNumber = mw.config.get("wgNamespaceNumber");
        if (window.defaultVisibilityTogglesForUsageExamples) {
            if (namespaceNumber === 0) {
                $("ol > li dl:has(dd > .h-usage-example)", $content).each(setupUsageExampleCollapses);
            }
        }

        if (namespaceNumber === 0 || namespaceNumber === 100 || namespaceNumber === 118) {
            $("ol > li", $content).each(function () {
                setupHiddenQuotes(this);
            });
        }

        $(".vsSwitcher", $content).each(function () {
            viewSwitching(this);
        });

        $(".list-switcher", $content).each(function () {
            enableListSwitchGeneric(this);
        });
    });

    jQuery(mw).on("LivePreviewDone", function (ev, sels) {
        var ols = jQuery(sels.join(",")).find("ol");
        for (var i = 0; i < ols.length; i++) {
            for (var j = 0; j < ols[i].childNodes.length; j++) {
                var li = ols[i].childNodes[j];
                if (li.nodeName.toUpperCase() == "LI") {
                    setupHiddenQuotes(li);
                }
            }
        }
    });
})();