MediaWiki:Common.js
Jump to navigation
Jump to search
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)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
//Adapted from Terraria Wiki MediaWiki:Common.js
$(function() {
// Disable triggering of new browser tab when clicking URL links that point to internal wiki addresses (purge, edit, etc)
$('a[href^="//thoriummod.wiki.gg/"]').removeAttr('target');
// Select links to new tabs for Template:ilnt and Template:elnt
$('.linkNewTab a').attr('target','_blank');
});
// Implement border-collapse + border-radius workaround for "terraria"-class tables
/* (temporarily?) disabled, broke display for tables with percentage widths
$('.terraria:not(.outer)')
.removeClass('terraria')
.addClass('inner')
.wrap('<table class="terraria outer"></table>');
*/
// Desktop view for mobile screen
$(window).on('load', function(){
// desktop view for mobile screen.
var $btn = $('#mw-panel .resize-sensor');
var $menu = $('#mw-panel .portal');
$btn.on('click', function(){
$('#mw-panel').toggleClass('on');
});
});
// Disable creation of non-talk pages by anonymous IP editors and link to registration (also disabled by abuse filter but this provides warning before attempting edit)
var wgPageName = mw.config.get( 'wgPageName' );
var wgUserName = mw.config.get( 'wgUserName' );
var isTalk = false, isAnon = false;
if (wgPageName.indexOf('talk:') > -1 || wgPageName.indexOf('Talk:') > -1) isTalk = true;
if (wgUserName === null) isAnon = true;
if (isAnon == true){
$('a.new').each(function(){
var href = $(this).attr('href');
$(this).attr('href', href.replace(/&action=edit/g, '') );
});
}
if (isAnon == true && isTalk == false) {
var anonWarnText = 'Page creation by anonymous editors is currently disabled. <br/> To create this page, please <a href="http://thoriummod.gamepedia.com/Special:CreateAccount">register an account</a> first.';
$('body').append('<div class="anonWarnOverlay" style="display:none; background-color: #000; opacity: 0.4; position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 500;"></div>');
$('body').prepend('<div class="anonWarnBox" style="display:none; text-align:center; font-weight: bold; box-shadow: 7px 7px 5px #000; font-size: 0.9em; line-height: 1.5em; z-index: 501; opacity: 1; position: fixed; width: 50%; left: 25%; top: 30%; background: #F7F7F7; border: #222 ridge 1px; padding: 20px;">' + anonWarnText + '</div>');
$('#ca-edit a:contains(Create), #ca-ve-edit a:contains(Create), a.external.text:contains(edit this page)').attr('href', '#').click(function(){
$('.anonWarnBox').show();
$('.anonWarnOverlay').show();
});
$('.anonWarnOverlay').click(function(){
$('.anonWarnBox').hide();
$(this).hide();
});
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* common Utilities
*/
var util = (function(){
var exports = {
/* common l10n factory */
l10nFactory: function($lang, $data) {
return function ($key) {
return $data[$key] && ($data[$key][$lang] || $data[$key]['en']) || '';
};
}
};
function throttle(t, e, o, n) {
var r, i = !1,
u = 0;
function c() {
r && clearTimeout(r)
}
function a() {
for (var a = arguments.length, d = new Array(a), l = 0; l < a; l++) d[l] = arguments[l];
var f = this,
v = Date.now() - u;
function p() {
u = Date.now(), o.apply(f, d)
}
function h() {
r = void 0
}
i || (n && !r && p(), c(), void 0 === n && v > t ? p() : !0 !== e && (r = setTimeout(n ? h : p, void 0 === n ? t - v : t)))
}
return "boolean" != typeof e && (n = o, o = e, e = void 0), a.cancel = function() {
c(), i = !0
}, a
}
function debounce(t, e, o) {
return void 0 === o ? throttle(t, e, !1) : throttle(t, o, !1 !== e)
}
exports.debounce = debounce;
exports.throttle = throttle;
return exports;
})();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Handle wide tables
*
* Display a horizontal floating scroll bar when the table width exceeds the page width.
*/
$.when($.ready, mw.loader.using(['mediawiki.util'])).then( function() {
var TABLE_WIDE_CLASS = "table-wide";
var TABLE_WIDE_INNER_CLASS = "table-wide-inner";
var handleWideTables = function(tables) {
var handler = mw.util.debounce(100, function() {
if(!tables){
return;
}
tables.forEach(function(table) {
var $table = $(table);
if(!$table.data('container')){
$table.data('container', table.parentNode);
}
var container = $table.data('container');
if(!container){
return;
}
var $innerBox = $table.parent();
var $outerBox = $innerBox.parent();
var overwide = table.getBoundingClientRect().width > container.getBoundingClientRect().width;
if($outerBox.hasClass(TABLE_WIDE_CLASS)){
if(overwide){
$innerBox.floatingScroll("update");
}else{
$outerBox.before($table).remove();
}
}else{
if(overwide) {
$('<div/>').addClass(TABLE_WIDE_INNER_CLASS).appendTo(
$('<div/>').addClass(TABLE_WIDE_CLASS).insertBefore($table)
).append($table).floatingScroll("init").floatingScroll("update");
}
}
});
});
handler();
window.addEventListener("resize", handler);
};
var isEditorActive = function() {
var e = new URLSearchParams(window.location.search);
return "edit" === e.get("action") || "submit" === e.get("action") || ("edit" === e.get("veaction")
|| "submit" === e.get("veaction") || "editsource" === e.get("veaction"));
}
mw.hook("wikipage.content").add(function() {
if (!isEditorActive()) {
var el = document.querySelector("#bodyContent");
if (el) {
handleWideTables(el.querySelectorAll("table"));
}
}
});
});
// AJAX tables
$(function() {
$("table.ajax").each(function (i) {
var table = $(this).attr("id", "ajaxTable" + i);
table.find(".nojs-message").remove();
var headerLinks = $('<span style="float: right;">').appendTo(table.find('th').first());
var cell = table.find("td").first();
var needLink = true;
cell.parent().show();
if (cell.hasClass("showLinkHere")) {
var old = cell.html();
var rep = old.replace(/\[link\](.*?)\[\/link\]/, '<a href="javascript:;" class="ajax-load-link">$1</a>');
if (rep !== old) {
cell.html(rep);
needLink = false;
}
}
if (needLink) {
headerLinks.html('[<a href="javascript:;" class="ajax-load-link">show data</a>]');
}
table.find(".ajax-load-link").parent().addBack().filter('a').click(function(event) {
event.preventDefault();
var sourceTitle = table.data('ajax-source-page'), baseLink = mw.config.get('wgScript') + '?';
cell.text('Please wait, the content is being loaded...');
$.get(baseLink + $.param({ action: 'render', title: sourceTitle }), function (data) {
if (!data) {
return;
}
cell.html(data);
cell.find('.ajaxHide').remove();
cell.find('.terraria:not(.ajaxForceTerraria)').removeClass('terraria');
if (cell.find("table.sortable").length) {
mw.loader.using('jquery.tablesorter', function() {
cell.find("table.sortable").tablesorter();
});
}
headerLinks.text('[');
headerLinks.append($('<a>edit</a>').attr('href', baseLink + $.param({ action: 'edit', title: sourceTitle })));
headerLinks.append(document.createTextNode(']\u00A0['));
var shown = true;
$("<a href='javascript:;'>hide</a>").click(function() {
shown = !shown;
cell.toggle(shown);
$(this).text(shown ? "hide" : "show");
}).appendTo(headerLinks);
headerLinks.append(document.createTextNode(']'));
}).fail(function() {
cell.text('Unable to load table; the source article for it might not exist.');
});
});
});
});
//$(addAjaxDisplayLink);
/*$.when( $.ready ).then(function() {
// Document is ready.
// desktop view for mobile screen.
$('#mw-panel').append('<div id="menu-toggle-button"></div>');
var $btn = $('#menu-toggle-button');
var $menu = $('#mw-panel .portal');
$btn.on('click', function(){
$('#mw-panel').toggleClass('on');
});
});
$(window).on('load', function(){
//main page header.
var $btn = $('#mf-wikiheader #mf-wikiheader-toggle-link');
if($btn.length){
var $box = $('#mf-wikiheader');
$btn.css('display', 'inline');
if($box.innerHeight() > 180){
$box.addClass('collapsed');
}
$btn.on('click', function(){
$box.toggleClass('collapsed');
});
}
//sidebar height fix.
var $sidebar = $('#mw-panel');
var $bottom = $sidebar.offset().top + $sidebar.outerHeight(true);
var $wrapper = $('#global-wrapper');
var $left_height = $bottom-($wrapper.outerHeight(true)-$wrapper.outerHeight());
if ($left_height > $wrapper.height()){
$wrapper.css('min-height', $left_height+'px');
}
});*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Make sidebar sections collapsible
*/
$(function(){
$panel = $('#mw-panel');
$("#mw-panel .portal").each(function(index, el){
var $el = $(el);
var $id = $el.attr("id");
if(!$id){
return;
}
// for < 1366px
$el.removeClass('expanded');
// for >= 1366px
if(localStorage.getItem('sidebar_c_'+$id) === "y"){
$el.addClass('collapsed').find('.body').slideUp(0);
}
});
$("#mw-panel .portal").on("click", "h3", function(event){
var $el = $(this).parent();
var $id = $el.attr("id");
if(!$id){
return;
}
event.stopPropagation();
if($panel.width() < 200){
$el.toggleClass('collapsed');
if($el.hasClass('collapsed')){ // more consistent between class and slide status.
localStorage.setItem('sidebar_c_'+$id, "y");
$el.find('.body').slideUp('fast');
}
else{
localStorage.setItem('sidebar_c_'+$id, "n");
$el.find('.body').slideDown('fast');
}
}
else{
$("#mw-panel .portal").not($el).removeClass('expanded');
$el.toggleClass('expanded');
}
});
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* content width toggle
*/
$(function(){
$body = $('body');
$('<div id="nav-content-size-toggle"><span></span></div>')
.prependTo($('#mw-head'))
.on('click', function(){
$body.toggleClass('content-size-expanded');
});
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* floating-scroll v3.2.0
* https://amphiluke.github.io/floating-scroll/
* (c) 2022 Amphiluke
*/
! function(t, i) {
"object" == typeof exports && "undefined" != typeof module ? i(require("jquery")) : "function" == typeof define && define.amd ? define(["jquery"], i) : i((t = "undefined" != typeof globalThis ? globalThis : t || self).jQuery)
}(this, (function(t) {
"use strict";
var i = "horizontal",
n = "vertical",
e = {
init: function(t, n) {
var e = this;
e.orientationProps = function(t) {
var n = t === i;
return {
ORIENTATION: t,
SIZE: n ? "width" : "height",
X_SIZE: n ? "height" : "width",
OFFSET_SIZE: n ? "offsetWidth" : "offsetHeight",
OFFSET_X_SIZE: n ? "offsetHeight" : "offsetWidth",
CLIENT_SIZE: n ? "clientWidth" : "clientHeight",
CLIENT_X_SIZE: n ? "clientHeight" : "clientWidth",
INNER_X_SIZE: n ? "innerHeight" : "innerWidth",
SCROLL_SIZE: n ? "scrollWidth" : "scrollHeight",
SCROLL_POS: n ? "scrollLeft" : "scrollTop",
START: n ? "left" : "top",
X_START: n ? "top" : "left",
X_END: n ? "bottom" : "right"
}
}(n);
var o = t.closest(".fl-scrolls-body");
o.length && (e.scrollBody = o), e.container = t[0], e.visible = !0, e.initWidget(), e.updateAPI(), e.addEventHandlers(), e.skipSyncContainer = e.skipSyncWidget = !1
},
initWidget: function() {
var i = this,
n = i.orientationProps,
e = n.ORIENTATION,
o = n.SIZE,
r = n.SCROLL_SIZE,
c = i.widget = t('<div class="fl-scrolls" data-orientation="' + e + '"></div>');
t("<div></div>").appendTo(c)[o](i.container[r]), c.appendTo(i.container)
},
addEventHandlers: function() {
var i = this;
(i.eventHandlers = [{
$el: t(window),
handlers: {
"destroyDetached.fscroll": function(t) {
"fscroll" === t.namespace && i.destroyDetachedAPI()
}
}
}, {
$el: i.scrollBody || t(window),
handlers: {
scroll: function() {
i.updateAPI()
},
resize: function() {
i.updateAPI()
}
}
}, {
$el: i.widget,
handlers: {
scroll: function() {
i.visible && !i.skipSyncContainer && i.syncContainer(), i.skipSyncContainer = !1
}
}
}, {
$el: t(i.container),
handlers: {
scroll: function() {
i.skipSyncWidget || i.syncWidget(), i.skipSyncWidget = !1
},
focusin: function() {
setTimeout((function() {
i.widget && i.syncWidget()
}), 0)
},
"update.fscroll": function(t) {
"fscroll" === t.namespace && i.updateAPI()
},
"destroy.fscroll": function(t) {
"fscroll" === t.namespace && i.destroyAPI()
}
}
}]).forEach((function(t) {
var i = t.$el,
n = t.handlers;
return i.bind(n)
}))
},
checkVisibility: function() {
var t = this,
i = t.widget,
n = t.container,
e = t.scrollBody,
o = t.orientationProps,
r = o.SCROLL_SIZE,
c = o.OFFSET_SIZE,
l = o.X_START,
s = o.X_END,
d = o.INNER_X_SIZE,
a = o.CLIENT_X_SIZE,
f = i[0][r] <= i[0][c];
if (!f) {
var h = n.getBoundingClientRect(),
u = e ? e[0].getBoundingClientRect()[s] : window[d] || document.documentElement[a];
f = h[s] <= u || h[l] > u
}
t.visible === f && (t.visible = !f, i.toggleClass("fl-scrolls-hidden"))
},
syncContainer: function() {
var t = this,
i = t.orientationProps.SCROLL_POS,
n = t.widget[0][i];
t.container[i] !== n && (t.skipSyncWidget = !0, t.container[i] = n)
},
syncWidget: function() {
var t = this,
i = t.orientationProps.SCROLL_POS,
n = t.container[i];
t.widget[0][i] !== n && (t.skipSyncContainer = !0, t.widget[0][i] = n)
},
updateAPI: function() {
var i = this,
n = i.orientationProps,
e = n.SIZE,
o = n.X_SIZE,
r = n.OFFSET_X_SIZE,
c = n.CLIENT_SIZE,
l = n.CLIENT_X_SIZE,
s = n.SCROLL_SIZE,
d = n.START,
a = i.widget,
f = i.container,
h = i.scrollBody,
u = f[c],
S = f[s];
a[e](u), h || a.css(d, f.getBoundingClientRect()[d] + "px"), t("div", a)[e](S), S > u && a[o](a[0][r] - a[0][l] + 1), i.syncWidget(), i.checkVisibility()
},
destroyAPI: function() {
var t = this;
t.eventHandlers.forEach((function(t) {
var i = t.$el,
n = t.handlers;
return i.unbind(n)
})), t.widget.remove(), t.eventHandlers = t.widget = t.container = t.scrollBody = null
},
destroyDetachedAPI: function() {
t.contains(document.body, this.container) || this.destroyAPI()
}
};
t.fn.floatingScroll = function(o, r) {
if (void 0 === o && (o = "init"), void 0 === r && (r = {}), "init" === o) {
var c = r.orientation,
l = void 0 === c ? i : c;
if (l !== i && l !== n) throw new Error("Scrollbar orientation should be either “horizontal” or “vertical”");
this.each((function(i, n) {
return Object.create(e).init(t(n), l)
}))
} else Object.prototype.hasOwnProperty.call(e, o + "API") && this.trigger(o + ".fscroll");
return this
}, t((function() {
t("body [data-fl-scrolls]").each((function(i, n) {
var e = t(n);
e.floatingScroll("init", e.data("flScrolls") || {})
}))
}))
}));
/**
* custom control for [[Template:Sound]]
* Original ported from https://minecraft.gamepedia.com/MediaWiki:Gadget-sound.js.
*/
$(function(){
$('.mw-parser-output .sound').prop('title', 'Click to play').on('click', function(e){
// Ignore links
if (e.target.tagName === 'A') {
return;
}
var audio = $(this).find('audio')[0];
if (audio) {
audio.paused ? audio.play() : audio.pause();
}
}).find('audio').on('play', function(){
// Stop any already playing sounds
var playing = $('.sound-playing audio')[0];
playing && playing.pause();
$(this).closest('.sound').addClass('sound-playing').prop('title', 'Click to stop');
}).on('pause', function(){
// Reset back to the start
this.currentTime = 0;
$(this).closest('.sound').removeClass('sound-playing').prop('title', 'Click to play');
});
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* for other templates
*/
$(function(){
/* mode tabs switch for [[Template:npcinfobox]] and [[Template:npcinfobtable]] and so on */
$('.modesbox .modetabs .tab').on('click', function(){
var $this = $(this);
if($this.hasClass('current')){
return;
}
$this.parent().children().removeClass('current');
$this.addClass('current');
$this.closest('.modesbox').removeClass('c-expert c-master c-normal').addClass($this.hasClass('normal')?'c-normal':($this.hasClass('expert')?'c-expert':'c-master'));
});
});
// Recipe finder functionality - by Philo04
if(mw.config.get("wgPageName") == "Thorium_Mod_Wiki:Recipe_Finder"){
var RecipeFinderSearchBox = $("<input>")
.addClass("mw-inputbox-input mw-ui-input mw-ui-input-inline")
.css("vertical-align", "top")
.attr("id", "RecipeFinderSearchInput")
.attr("autocomplete", "off");
var RecipeFinderSearchButton = $("<button>")
.addClass("mw-ui-button mw-ui-progressive")
.attr("id", "RecipeFinderSearchButton")
.attr("title", "Search")
.append("Search");
$("#RecipeFinderInput").append(RecipeFinderSearchBox, RecipeFinderSearchButton);
function FindRecipes(){
var inputArray = $("#RecipeFinderSearchInput").val().trim().toLowerCase().split(" ");
var excludedWords = ["of"];
for (var i = 0; i < inputArray.length; i++){
if (!excludedWords.includes(inputArray[i])) {
inputArray[i] = inputArray[i][0].toUpperCase() + inputArray[i].substr(1);
}
}
var RecipeFinderSearchQuery = inputArray.join(" ");
new mw.Api().get({
action: "parse",
text: "{{#if:{{recipes/exist|ingredient=" + RecipeFinderSearchQuery + "}}|{{recipes|ingredient=" + RecipeFinderSearchQuery + "|title={{item|" + RecipeFinderSearchQuery.replace(/^#/, "") + "|note=({{recipes/count|ingredient=" + RecipeFinderSearchQuery + "}} recipes)}}}}|<span style=\"color:red;font-weight:bold;\">Recipes: No result</span>}}",
disablelimitreport: true,
format: "json"
}).then(function(data){
$("#RecipeFinderOutput").empty();
$("#RecipeFinderOutput").append(data.parse.text['*']);
mw.loader.using(["jquery.tablesorter"], function(){// have to load separately to make the table sortable
$("#RecipeFinderOutput table.sortable").tablesorter();
});
});
}
$("#RecipeFinderSearchButton").on("click", FindRecipes);
$("#RecipeFinderSearchInput").on("keyup", function(event){
if(event.key == "Enter"){
FindRecipes();
}
});
}