مدیاویکی:Common.js

نسخهٔ تاریخ ۲۲ مهٔ ۲۰۲۶، ساعت ۰۴:۲۸ توسط Esfandiari (بحث | مشارکت‌ها)
(تفاوت) → نسخهٔ قدیمی‌تر | نمایش نسخهٔ فعلی (تفاوت) | نسخهٔ جدیدتر ← (تفاوت)

نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.

  • فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلید‌های Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-R)
  • گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-Shift-R)
  • Edge: کلید Ctrl را نگه‌دارید و روی دکمهٔ Refresh کلیک کنید، یا کلید‌های Ctrl-F5 را با هم فشار دهید
/* global mw, $ */

/**********************************************************************
 *  Load edit.js for edit-related pages
 **********************************************************************/
if (
    mw.config.get("wgAction") === "edit" ||
    mw.config.get("wgAction") === "submit" ||
    mw.config.get("wgCanonicalSpecialPageName") === "Upload"
) {
    importScript("مدیاویکی:Common.js/edit.js");
}

/**********************************************************************
 *  Magic editintros
 **********************************************************************/
function addEditIntro(name) {
    $(".mw-editsection, #ca-edit")
        .find("a")
        .each(function () {
            this.href = $(this).attr("href") + "&editintro=" + name;
        });
}

if (mw.config.get("wgNamespaceNumber") === 0) {
    $(function () {
        if (document.getElementById("disambigbox")) {
            addEditIntro("Template:Disambig_editintro");
        }
    });

    $(function () {
        var cats = mw.config.get("wgCategories") || [];
        if (cats.includes("افراد زنده")) {
            addEditIntro("Template:BLP_editintro");
        }
    });
}

/**********************************************************************
 *  Load additional JS/CSS via URL (Secure)
 **********************************************************************/
mw.loader.using(["mediawiki.util"], function () {
    var extraCSS = mw.util.getParamValue("withCSS"),
        extraJS = mw.util.getParamValue("withJS");

    if (extraCSS) {
        if (/^MediaWiki:[^&<>=%#]*\.css$/.test(extraCSS)) {
            mw.loader.load(
                "/w/index.php?title=" +
                    encodeURIComponent(extraCSS) +
                    "&action=raw&ctype=text/css",
                "text/css"
            );
        } else {
            mw.notify("Only pages from the MediaWiki namespace are allowed.", {
                title: "Invalid withCSS value",
            });
        }
    }

    if (extraJS) {
        if (/^MediaWiki:[^&<>=%#]*\.js$/.test(extraJS)) {
            mw.loader.load(
                "/w/index.php?title=" +
                    encodeURIComponent(extraJS) +
                    "&action=raw&ctype=text/javascript"
            );
        } else {
            mw.notify("Only pages from the MediaWiki namespace are allowed.", {
                title: "Invalid withJS value",
            });
        }
    }
});

/**********************************************************************
 *  Auto-load Preloaded.js when needed
 **********************************************************************/
mw.loader.using(["mediawiki.util"], function () {
    if (mw.util.getParamValue("preload")) {
        mw.loader.load("MediaWiki:Preloaded.js");
    }
});

/**********************************************************************
 *  Collapsible tables (modern, safe)
 **********************************************************************/
function makeCollapsibleMwCollapsible($content) {
    var $tables = $content
        .find("table.collapsible:not(.mw-collapsible)")
        .addClass("mw-collapsible");

    $.each($tables, function (index, table) {
        if ($(table).hasClass("collapsed")) {
            $(table).addClass("mw-collapsed");
        }
    });

    if ($tables.length > 0) {
        mw.loader.using("jquery.makeCollapsible").then(function () {
            $tables.makeCollapsible();
        });
    }
}
mw.hook("wikipage.content").add(makeCollapsibleMwCollapsible);

/**********************************************************************
 *  AutoCollapse, InnerCollapse, OuterCollapse
 **********************************************************************/
function mwCollapsibleSetup($collapsibleContent) {
    var autoCollapseThreshold = 2;

    $.each($collapsibleContent, function (index, element) {
        var $element = $(element);

        if ($element.hasClass("collapsible")) {
            $element
                .find("tr:first-child > th:first-child")
                .prepend(
                    $element.find("tr:first-child > * > .mw-collapsible-toggle")
                );
        }

        // Auto collapse
        if (
            $collapsibleContent.length >= autoCollapseThreshold &&
            $element.hasClass("autocollapse")
        ) {
            $element.data("mw-collapsible").collapse();
        }

        // Inner collapse (requires outercollapse ancestor)
        if ($element.hasClass("innercollapse")) {
            if ($element.parents(".outercollapse").length > 0) {
                $element.data("mw-collapsible").collapse();
            }
        }

        // Ensure toggle inherits proper text color
        var $toggle = $element.find(".mw-collapsible-toggle");
        if ($toggle.length && $toggle.parent()[0].style.color) {
            $toggle.find("a").css("color", "inherit");
        }
    });
}
mw.hook("wikipage.collapsibleContent").add(mwCollapsibleSetup);

/**********************************************************************
 *  Dynamic Navigation Bars (single clean version)
 **********************************************************************/
var collapseCaption = "نهفتن";
var expandCaption = "نمایش";
var navigationBarHide = "[" + collapseCaption + "]";
var navigationBarShow = "[" + expandCaption + "]";

function toggleNavigationBar(indexNavigationBar, event) {
    var navToggle = document.getElementById("NavToggle" + indexNavigationBar);
    var navFrame = document.getElementById("NavFrame" + indexNavigationBar);
    var navChild;

    if (!navFrame || !navToggle) return false;

    var isShown = navToggle.firstChild.data === navigationBarHide;

    for (
        navChild = navFrame.firstChild;
        navChild !== null;
        navChild = navChild.nextSibling
    ) {
        if (navChild.nodeType === 1) {
            if (
                $(navChild).hasClass("NavContent") ||
                $(navChild).hasClass("NavPic")
            ) {
                navChild.style.display = isShown ? "none" : "block";
            }
        }
    }

    navToggle.firstChild.data = isShown
        ? navigationBarShow
        : navigationBarHide;

    event.preventDefault();
}

function createNavigationBarToggleButton($content) {
    var indexNavigationBar = 0;

    $content.find("div.NavFrame:not(.mw-collapsible)").each(function (_, navFrame) {
        indexNavigationBar++;

        var $navFrame = $(navFrame);
        var navToggle = document.createElement("a");
        navToggle.className = "NavToggle";
        navToggle.id = "NavToggle" + indexNavigationBar;
        navToggle.href = "#";

        $(navToggle).on(
            "click",
            $.proxy(toggleNavigationBar, null, indexNavigationBar)
        );

        var isCollapsed = $navFrame.hasClass("collapsed");

        // Determine if any child is hidden (compatibility)
        $(navFrame)
            .children()
            .each(function () {
                if (
                    this.nodeType === 1 &&
                    (this.style.display === "none") &&
                    ($(this).hasClass("NavContent") || $(this).hasClass("NavPic"))
                ) {
                    isCollapsed = true;
                }
            });

        // Apply initial collapsed state
        if (isCollapsed) {
            $(navFrame)
                .children()
                .each(function () {
                    if (
                        $(this).hasClass("NavContent") ||
                        $(this).hasClass("NavPic")
                    ) {
                        this.style.display = "none";
                    }
                });
        }

        navToggle.appendChild(
            document.createTextNode(
                isCollapsed ? navigationBarShow : navigationBarHide
            )
        );

        // Attach toggle to NavHead
        $(navFrame)
            .children()
            .each(function () {
                if ($(this).hasClass("NavHead")) {
                    navToggle.style.color = this.style.color;
                    this.appendChild(navToggle);
                }
            });

        navFrame.id = "NavFrame" + indexNavigationBar;
    });
}

mw.hook("wikipage.content").add(createNavigationBarToggleButton);

/**********************************************************************
 *  Add “Complete list of languages” link on Main Page
 **********************************************************************/
mw.loader.using(["mediawiki.util"], function () {
    mw.log.deprecate(
        window,
        "addPortletLink",
        mw.util.addPortletLink,
        "Use mw.util.addPortletLink instead"
    );

    if (["صفحهٔ_اصلی", "بحث:صفحه_اصلی"].includes(mw.config.get("wgPageName"))) {
        $(function () {
            mw.util.addPortletLink(
                "p-lang",
                "//meta.wikimedia.org/wiki/List_of_Wikipedias/fa",
                "فهرست کامل",
                "interwiki-completelist",
                "فهرست کامل"
            );
        });
    }
});

/**********************************************************************
 *  WikiMiniAtlas loader
 **********************************************************************/
(function () {
    var require_wikiminiatlas = false;
    var coord_filter = /geohack/;

    $(function () {
        $("a.external.text").each(function (_, link) {
            if (link.href && coord_filter.test(link.href)) {
                require_wikiminiatlas = true;
                return false;
            }
        });

        if ($("div.kmldata").length) {
            require_wikiminiatlas = true;
        }

        if (require_wikiminiatlas) {
            mw.loader.load(
                "//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript"
            );
        }
    });
})();

/**********************************************************************
 *  Source code pages should be LTR
 **********************************************************************/
mw.loader.using(["mediawiki.util"], function () {
    if ([2, 4, 8].includes(mw.config.get("wgNamespaceNumber"))) {
        if (/\.(js|css|py)$/.test(mw.config.get("wgPageName"))) {
            mw.util.addCSS(
                ".diff-addedline, .diff-deletedline, .diff-context { direction: ltr; } " +
                    "#wpTextbox1 { direction: ltr; }"
            );
        }
    }

    // Hide WikiLove for newbies
    if (
        !mw.config.get("wgUserGroups").includes("autoconfirmed") ||
        mw.config.get("wgUserEditCount") < 100
    ) {
        mw.util.addCSS("#ca-wikilove { display: none; }");
    }
});

/**********************************************************************
 *  بهتر کردن نمایش فرمول‌ها در RTL
 **********************************************************************/
$(function () {
    $("span.mwe-math-mathml-inline").each(function () {
        var $parent = $(this).parent();
        var $grand = $parent.parent();

        if (
            $grand.is("p, dd") &&
            $grand.text().trim() === $parent.text().trim()
        ) {
            $grand.css({
                direction: "ltr",
                padding: "1em 0",
            });
        }
    });
});

/**********************************************************************
 *  هشدار برای عنوان نادرست ایمیل
 **********************************************************************/
$(function () {
    var row = $("#mw-input-wpSubject").parents("tr");
    if (row.length) {
        row.before(
            '<tr><td></td><td style="color:red;font-weight:bold">لطفاً عبارت Wikipedia e-mail ‌را با یک عنوان مناسب جایگزین کنید!</td></tr>'
        );
    }
});

/**********************************************************************
 *  Bold reference numbers on click
 **********************************************************************/
$("sup.reference").click(function () {
    var citeId = $(this).attr("id");
    var selector = 'sup > a[href="#' + citeId + '"]';

    $(selector).css({ color: "#2a4b8d", "font-weight": "bold" });
    $(selector).one("click", function () {
        $(this).css({ color: "", "font-weight": "" });
    });
});

/**********************************************************************
 *  Hide FileExporter for non-free files  (fixed)
 **********************************************************************/
$(function () {
    var nonFreeCats = [
        "محتویات غیر آزاد",
        "تصویرهای با منبع نامعلوم",
        "تصویرهای با پدیدآور نامشخص",
    ];

    if (
        $("#ca-fileExporter").length === 1 &&
        (mw.config.get("wgCategories") || []).some(function (cat) {
            return nonFreeCats.includes(cat);
        })
    ) {
        $("#ca-fileExporter").hide();
    }
});

/**********************************************************************
 *  Advertisement banner (only for logged-out users)
 **********************************************************************/
mw.loader.using("jquery", function () {
    $(function () {
        var disableAd = false;

        if (mw.config.get("wgUserName") !== null || disableAd) return;

        var adBanner = $(
            '<div id="site-ad-banner">' +
                '<a href="https://ble.ir/iranian_law" target="_blank">' +
                '<img src="https://www.illrc.ac.ir/wp-content/uploads/2026/03/1.jpg" alt="Advertisement" class="ad-img">' +
                "</a>" +
                '<button id="close-ad" title="بستن">✖</button>' +
                "</div>"
        );

        $("body").append(adBanner);

        $("#close-ad").on("click", function () {
            $("#site-ad-banner").fadeOut();
        });
    });
});
`