MediaWiki:Common.js
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- The following documentation is located at MediaWiki:Common.js/documentation. [edit]
- Useful links: subpage list • links • redirects
This script executes for every user, anonymous or logged-in, using any skin. Additions to this script should be kept to a minimum, as it is a major single point of failure, and for the sake of allowing per-user customisations. Preferably write a gadget instead.
To make sure your script executes after this one, make it depend on the ResourceLoader module site
. See mw:ResourceLoader/Developing with ResourceLoader for details.
Note that this code does not run on the mobile website: see MediaWiki:Mobile.js.
See also: Special:Gadgets.
/**
* Keep code in MediaWiki:Common.js to a minimum as it is unconditionally
* loaded for all users on every wiki page. If possible create a gadget that is
* enabled by default instead of adding it here (since gadgets are fully
* optimized ResourceLoader modules with possibility to add dependencies etc.)
*
* Since Common.js isn't a gadget, there is no place to declare its
* dependencies, so we have to lazy load them with mw.loader.using on demand and
* then execute the rest in the callback. In most cases these dependencies will
* be loaded (or loading) already and the callback will not be delayed. In case a
* dependency hasn't arrived yet it'll make sure those are loaded before this.
*/
"use strict";
// [[Category:Wiktionary scripts]] <nowiki>
/*jshint shadow:true, undef:true, latedef:true, unused:true, esversion:3 */
/*global window, jQuery, mw, importScript, importStylesheet, $ */
/** [[WT:PREFS]] v2.0 **/
// Note: copied into Mobile.js - please keep in sync
try {
(function () {
var prefs;
try {
prefs = window.localStorage.getItem("AGprefs");
} catch (e) {
prefs = jQuery.cookie("AGprefs");
}
prefs = prefs && JSON.parse(prefs);
if (mw.config.get("wgUserGroups").indexOf("autoconfirmed") !== -1) return;
if (mw.config.get("wgUserGroups").indexOf("user") === -1) {
// XXX: [[Wiktionary:Preferences/V2]] is just a temporary page
mw.loader.using(["mediawiki.util"], function () {
mw.util.addPortletLink(
mw.config.get("skin") === "vector-2022"
? "p-vector-user-menu-overflow"
: "p-personal",
mw.util.getUrl("Wiktionary:Preferences for users without an account"),
"Preferences",
"pt-agprefs",
"Personalise Wiktionary (settings are kept per-browser).",
"",
document.getElementById("pt-createaccount-2") ||
document.getElementById("pt-createaccount")
);
});
if (
mw.config.get("wgAction") === "view" &&
mw.config.get("wgPageName") ===
"Wiktionary:Preferences_for_users_without_an_account"
) {
mw.loader.load("ext.gadget.AGprefs"); // [[MediaWiki:Gadget-AGprefs.js]]
}
}
if (!prefs) return;
mw.loader.state(
"wiktionary_this_gadget_has_been_disabled_by_the_user",
"missing"
);
for (var key in prefs.modules) {
if (prefs.modules[key]) {
mw.loader.load([key]);
} else {
// unavoidable race condition. to prevent it, every enabled-by-default gadget should have "site" as a dependency
if (mw.loader.getState(key) !== "ready") {
mw.loader.moduleRegistry[key].dependencies.push(
"wiktionary_this_gadget_has_been_disabled_by_the_user"
);
mw.loader.state(key, "missing");
} else {
// XXX
mw.log.warn(
key +
" could not be disabled; make sure it has 'site' declared as a dependency"
);
}
}
}
for (var key in prefs.sheets) {
importStylesheet("MediaWiki:Gadget-" + key);
}
for (var key in prefs.scripts) {
importScript("MediaWiki:Gadget-" + key);
}
if (mw.config.get("wgUserGroups").indexOf("user") !== -1)
mw.loader.using(["mediawiki.api"], function () {
var changes = [];
for (var key in prefs.gadgets)
changes.push(
"gadget-" + key + "=" + (prefs.gadgets[key] ? "1" : "0")
);
new mw.Api()
.postWithToken("options", {
action: "options",
change: changes.join("|"),
})
.then(function () {
jQuery.cookie("AGprefs", null);
try {
window.localStorage.removeItem("AGprefs");
} catch (e) {
/* */
}
mw.notify(
jQuery(
'<b>Your <a href="/wiki/Wiktionary:Preferences/V2">per-browser preferences</a> have been migrated</b><br/><br/>' +
'From now on, you should use your <a href="/wiki/Special:Preferences">user preferences page</a>. ' +
"Preferences will no longer apply after you log out."
)
);
});
});
})();
} catch (e) {
mw.log.warn(e);
}
// Append #English to all links in definition sense lines
// Note: copied into Mobile.js - please keep in sync
mw.loader.using("user").then(function () {
if (!window.noDefinitionLineFragmentAddition)
$(function () {
var ns = mw.config.get("wgNamespaceNumber");
var re = /[#?:]/;
// Run this code in the main or Reconstruction namespaces,
// and on the Main Page (for WOTD and FWOTD),
// and in the Appendix namespace when there is a lemma or non-lemma form category.
if (
ns === 0 ||
ns === 118 ||
(ns === 4 && mw.config.get("wgTitle") === "Main Page") ||
(ns === 100 &&
mw.config.get("wgCategories").some(function (c) {
return / (?:lemmas|non-lemma forms)$/.test(c);
}))
) {
// Look for links inside a numbered list (<ol> tag).
// Must use [lang|=en] rather than :lang(en) because, at least in Firefox,
// :lang(en) always matches wherever it is put in a selector
// because all text is within <html lang="en">.
document
.querySelectorAll(
".mw-parser-output ol a:not(.mw-parser-output [lang] a), .mw-parser-output ol [lang|=en] a"
)
.forEach(function (el) {
// Only append to local existing main-namespace links without an existing anchor
var href = el.getAttribute("href");
if (href && !re.test(href) && href[1] !== "/") {
el.href += "#English";
}
});
}
});
});
mw.loader.using("mediawiki.util").done(function () {
/** &withmodule= query parameter **/
if (mw.util.getParamValue("withmodule"))
mw.loader.load(mw.util.getParamValue("withmodule").split(","));
/** &preloadtext= and &preloadminor= **/
if (mw.config.get("wgAction") === "edit")
jQuery(document).ready(function () {
var wpTextbox1 = document.getElementById("wpTextbox1");
var wpMinoredit = document.getElementById("wpMinoredit");
if (!wpTextbox1) return;
var preloadtext = mw.util.getParamValue("preloadtext");
var preloadminor = mw.util.getParamValue("preloadminor");
if (preloadtext && !wpTextbox1.value) wpTextbox1.value = preloadtext;
if (preloadminor !== null && wpMinoredit)
wpMinoredit.checked = !/^(0|false|no|)$/i.test(preloadminor);
});
/** Monthly subpages; see [[Template:discussion recent months|discussion recent months]] **/
/* See also: [[Special:AbuseFilter/43]] */
if (
/^Wiktionary:(Beer_parlour|Grease_pit|Tea_room|Etymology_scriptorium|Information_desk)$/.test(
mw.config.get("wgPageName")
)
)
jQuery(document).ready(function () {
var nNSR = document
.getElementById("new-section-redirect")
.getElementsByTagName("a")[0];
var caAddSection = document.getElementById("ca-addsection");
if (!caAddSection) {
caAddSection = mw.util.addPortletLink(
mw.config.get("skin") === "vector" ? "p-views" : "p-cactions",
nNSR.href,
"+",
"ca-addsection",
"Start a new section",
"+",
document.getElementById("ca-history")
);
} else {
if (caAddSection.tagName === "A") {
caAddSection.href = nNSR.href;
} else {
caAddSection.getElementsByTagName("a")[0].href = nNSR.href;
}
}
});
});
// On category pages, remove "0 c" or "0 e" from parentheses in listing of
// subcategories.
document
.querySelectorAll(".CategoryTreeItem bdi + span")
.forEach(function (elem) {
elem.innerHTML = elem.innerHTML.replace(/(?:, )?(?<!\d)0 [ce](?:, )?/, "");
});
// == "Did you mean" auto redirect ==
/**
* This will redirect in 3 seconds if a link enclosed in id="did-you-mean"
* is found, and add the text "Auto-redirected from X" under the top header
* if a rdfrom is passed in the get parameters.
* Pages with wynn ([[ƿ]]) will be redirected immediately.
**/
$.when(mw.loader.using(["user", "mediawiki.util"]), $.ready).done(function () {
if (window.disableAutoRedirect) return;
var rdFromValue = mw.util.getParamValue("rdfrom");
if (rdFromValue) {
$("#siteSub").after(
$("<div>")
.attr("id", "contentSub")
.append(document.createTextNode("(Auto-redirected from "))
.append(
$("<a>", {
href: mw.util.getUrl(rdFromValue, { redirect: "no" }),
addClass: "new",
}).text(rdFromValue)
)
.append(document.createTextNode(")"))
);
} else {
// Redirect as quickly as possible from [[ƿ]] title to [[w]] title.
var pageTitle = mw.config.get("wgTitle");
var isWynnTitle = /ƿ/i.test(pageTitle);
var didYouMean = $("#did-you-mean a").html();
var target = didYouMean
? didYouMean
: isWynnTitle
? $("#go-to-search-page a").html()
: null;
var timeout = isWynnTitle ? 0 : 3000;
window.setTimeout(function () {
var canRedirect = mw.util.getParamValue("redirect") != "no";
var action = mw.config.get("wgAction");
if (
target &&
target !== pageTitle &&
canRedirect &&
!window.disableAutoRedirect &&
(action == "view" || (isWynnTitle && action == "edit")) &&
mw.config.get("wgArticleId") === 0 &&
mw.config.get("wgNamespaceNumber") === 0 &&
!/Redirected from/.test(jQuery("#contentSub").html())
) {
window.location = mw.util.getUrl(target, { rdfrom: pageTitle });
}
}, timeout);
}
});
/* ==Page specific extensions== */
/* ===[[Wiktionary:Main Page]]=== */
// Note: copied into Mobile.js - please keep in sync
mw.loader.using("mediawiki.util", function () {
// Hide the title and "Redirected from" (maybe we should keep the redirected from so's people update their bookmarks ;)
// Broken in IE!
if (
mw.config.get("wgIsMainPage") &&
!(
mw.config.get("wgAction") === "view" ||
mw.config.get("wgAction") === "submit"
)
) {
mw.util.addCSS(".firstHeading { display: block !important; }");
mw.util.addCSS("#contentSub { display: inline !important; }");
}
if (mw.config.get("wgIsMainPage")) {
$(function () {
mw.util.addPortletLink(
"p-lang",
"//meta.wikimedia.org/wiki/Wiktionary#List_of_Wiktionaries",
"Complete list",
"interwiki-completelist",
"Complete list of Wiktionaries"
);
});
// Workaround for [[phab:T335552]].
document.querySelector(".mw-searchInput").autocapitalize = "off";
}
});
/* ===[[Special:Search]]=== */
// [[MediaWiki:FindTrans.js]], formerly [[User:Yair rand/FindTrans.js]]
if (mw.config.get("wgPageName") === "Special:Search") {
mw.loader.load(
"/w/index.php?title=MediaWiki:FindTrans.js&action=raw&ctype=text/javascript"
);
}
/* ===[[Wiktionary:Fonts/list]]=== */
if (
mw.config.get("wgAction") === "view" &&
mw.config.get("wgPageName") === "Wiktionary:Fonts/list"
) {
mw.loader.load("ext.gadget.InteractiveFontList"); // [[MediaWiki:Gadget-InteractiveFontList.js]]
}
/* ===[[Wiktionary:Gadget preferences]]=== */
// Note: copied into Mobile.js - please keep in sync
if (
mw.config.get("wgAction") === "view" &&
mw.config.get("wgPageName") === "Wiktionary:Gadget_preferences"
) {
mw.loader.load("ext.gadget.WiktGadgetPrefsPage"); // [[MediaWiki:Gadget-WiktGadgetPrefsPage.js]]
}
/* == [[WT:FEED]] == */
// used to be [[User:Conrad.Irwin/feedback.js]]
$.when(mw.loader.using("mediawiki.util"), $.ready).done(function () {
var fb_comment_url = mw.util.getUrl("Wiktionary:Feedback", {
action: "edit",
section: "new",
preload: "Wiktionary:Feedback/preload",
editintro: "Wiktionary:Feedback/intro",
preloadtitle: "[[:" + mw.config.get("wgPageName") + "]]",
});
var fb_comment = "If you have time, leave us a note.";
if (mw.config.get("skin") === "vector-2022") {
var vectorMenuContent = $("<a>")
.attr("href", fb_comment_url)
.text(fb_comment)
.appendTo($("<li>").addClass("mw-list-item"))
.parent()
.appendTo($("<ul>").addClass("vector-menu-content-list"))
.parent()
.appendTo($("<div>").addClass("vector-menu-content"))
.parent();
var vectorMenuHeading = $("<div>")
.addClass("vector-menu-heading")
.text("Feedback");
var vectorMenu = $("<div>")
.addClass("vector-menu mw-portlet mw-portlet-navigation")
.attr("id", "p-feedback")
.append(vectorMenuHeading)
.append(vectorMenuContent);
vectorMenu.appendTo($("#vector-main-menu"));
} else {
$("<a>")
.attr("href", fb_comment_url)
.text(fb_comment)
.appendTo($("<p>").css("font-size", "80%"))
.parent()
.appendTo($("<div>").addClass("body"))
.parent()
.before($("<h3>Feedback</h3>"))
.appendTo($("<div>").addClass("portal expanded").attr("id", "p-feedback"))
.parent()
.appendTo($("#mw-panel"));
}
});
/* == Toggle functionality only failed test == */
// all tests for module testcases
$(function () {
$("table.unit-tests th.unit-tests-img-corner").on("click", function () {
$(this).closest("table.unit-tests").toggleClass("unit-tests-hide-passing");
});
});
// Text after → on history pages is plain wikitext but on the page it is expanded. Fixing only [[Template:temp]]
// Also update it in change summaries
$(function () {
if (/\.7B\.7Btemp\.7C(.*?)\.7D\.7D/.test(location.href)) {
window.location = location.href.replace(/\.7B\.7Btemp.7C/g, ".7B.7B");
}
if (mw.config.get("wgAction") !== "edit") return;
if (!/[?&]section=\d/.test(location.href)) return;
var wpSummary = document.getElementById("wpSummary");
if (!wpSummary) return;
if (wpSummary.value.substr(0, 3) !== "/* ") return;
if (wpSummary.value.substr(wpSummary.value.length - 4) !== " */ ") return;
wpSummary.value = wpSummary.value.replace(/\{\{temp(late)?\|/g, "{{");
});
// Various fixes for the trees generated by [[Module:family tree]].
$(function () {
// Show the top toggle.
$(".familytree-toptoggle").css("display", "");
// Initialize the text of the toggles.
$(".familytree")
.get()
.forEach(function (tree) {
var isCollapsed = tree.classList.contains("mw-collapsed");
var toggles = $(tree).find(".familytree-toggle");
if (toggles[0]) {
var customToggleClass = Array.prototype.filter.call(
toggles[0].classList,
function (className) {
return className.indexOf("mw-customtoggle") === 0;
}
)[0];
if (customToggleClass) {
var toggledElement = $(
"#" +
customToggleClass.replace(
"mw-customtoggle",
"mw-customcollapsible"
)
);
if (toggledElement) {
toggles.html(
toggledElement.data(isCollapsed ? "expandtext" : "collapsetext")
);
}
}
}
});
// Change the text in the custom toggles generated by [[Module:family tree]]
// when they are clicked.
$(".mw-collapsible").on(
"beforeExpand.mw-collapsible beforeCollapse.mw-collapsible",
function (event) {
if (this.id.indexOf("mw-customcollapsible") === 0) {
var toggle = $(
"." + this.id.replace("mw-customcollapsible", "mw-customtoggle")
);
if (event.type === "beforeExpand") {
toggle.html(this.dataset.collapsetext);
} else {
// beforeCollapse
toggle.html(this.dataset.expandtext);
}
event.stopPropagation();
}
}
);
});
/* == RFC, RFD, RFV category lists == */
// Replaces full category name in [[WT:RFC]], [[WT:RFD]], [[WT:RFV]]
// with name of language:
// Category:Requests for cleanup in English entries → English
$(".tagged-rfcs, .tagged-rfds, .tagged-rfvs")
.find(".CategoryTreeItem a")
.html(function (i, content) {
return content.replace(
/^Requests for (?:cleanup|deletion|verification) in (.+?) entries$/,
"$1"
);
});
// XXX is the following code redundant to the above?
if (mw.config.get("wgTitle").indexOf("by language") != -1)
$("a.CategoryTreeLabelCategory").text(function (index, content) {
return content.replace(
/^Requests for (?:verification|deletion|cleanup) in (.+) entries$/,
"$1"
);
});
/* == Make it easy to update language name-to-code and code-to-name data modules == */
// This regex will always match.
if (
[
"Module:languages/code_to_canonical_name",
"Module:languages/canonical_names",
"Module:etymology_languages/code_to_canonical_name",
"Module:etymology_languages/canonical_names",
"Module:families/code_to_canonical_name",
"Module:families/canonical_names",
"Module:Hani-sortkey/data/serialized",
].indexOf(mw.config.get("wgPageName").match(/^[^\/]*(?:\/[^\/]+)?/)[0]) !== -1
)
importScript("MediaWiki:UpdateLanguageNameAndCode.js");
/* == WikiHiero kludge == */
$("table.mw-hiero-outer")
.first()
.each(function () {
importScript("MediaWiki:WikiHieroTempFix.js");
});
/* == Hide certain parts of the page from Google snippets == */
$(".mw-editsection, #toc, #catlinks").attr("data-nosnippet", "");
if (window.navigator.userAgent.toLowerCase().includes("googlebot")) {
$(".mw-editsection, #toc, #catlinks").css("display", "none");
}
// </nowiki>
// The rest of the scripts are at [[MediaWiki:Gadget-legacy.js]].
// Most of them should be converted into gadgets as time and resources allow.