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.
/* Any JavaScript here will be loaded for all users on every page load. */
mw.loader.using( ['mediawiki.user', 'mediawiki.util', 'mediawiki.notify', 'jquery.client'] ).done( function () {
/* Content tabber, version 1.0.5 by Greenpickle (GPL3) */
var switchableAnchorPrefix = '';
var switchableClass = 'switchable';
var switchableSectionClass = 'switch';
var switchableTabsClass = 'switchabletabs';
var switchableSectionTitleAttr = 'switchable-title';
function initialiseSwitchable () {
// get the elements we care about
switchable = myGetElementsByClassName(document, switchableClass);
// some functions
switchable.createTab = function (label, isAnchor, i, j) {
var tab = document.createElement('li');
var child;
if (isAnchor) {
child = document.createElement('a');
child.href =
'javascript:switchable.setVisible(' + i + ', ' + j + ');';
} else child = document.createElement('strong');
child.appendChild(document.createTextNode(label));
tab.appendChild(child);
return tab;
}
switchable.getVisible = function (i) {
var visible = this[i].getAttribute('visiblesection');
if (visible) visible = parseInt(visible);
if (visible === null || isNaN(visible)) {
visible = 0;
this[i].setAttribute('visiblesection', visible.toString());
}
return Math.max(0, Math.min(visible, this[i].sections.length - 1));
}
switchable.updateVisible = function (i) {
if (isNaN(parseInt(i))) {
// update all switchables if no valid number given
for (var i = 0; i < this.length; i++)
this.updateVisible(i);
} else {
var visible = this.getVisible(i);
var sections = this[i].sections;
var tc = this[i].tabContainer;
var currentTab;
for (var j = 0; j < sections.length; j++) {
if (j == visible) {
// change 'show' link
currentTab = this.createTab(sections[j].sectionName,
false);
currentTab.j = j;
tc.replaceChild(currentTab, tc.tabs[j]);
// show section
sections[j].style.display = '';
} else {
// change 'show' link
if (tc.currentTab !== undefined && tc.currentTab.j == j)
tc.replaceChild(tc.tabs[j], tc.currentTab);
// hide section
sections[j].style.display = 'none';
}
}
if (currentTab !== undefined) tc.currentTab = currentTab;
}
}
switchable.setVisible = function (i, j) {
this[i].setAttribute('visiblesection', j);
this.updateVisible(i);
}
// initialise
for (var i = 0; i < switchable.length; i++) {
var sections = myGetElementsByClassName(switchable[i],
switchableSectionClass);
switchable[i].sections = sections;
// create show/hide anchors
var tabContainer = document.createElement('ul');
tabContainer.className = switchableTabsClass;
switchable[i].appendChild(tabContainer);
switchable[i].tabContainer = tabContainer;
tabContainer.tabs = [];
for (var j = 0; j < sections.length; j++) {
// re-append section to place it after links
switchable[i].appendChild(sections[j]);
// use section's name if it has one
var sectionName = sections[j].getAttribute(
switchableSectionTitleAttr);
if (!sectionName) sectionName = j.toString();
sections[j].sectionName = sectionName;
// create anchor
var tab = switchable.createTab(
switchableAnchorPrefix + sectionName, true, i, j);
tabContainer.appendChild(tab);
tabContainer.tabs.push(tab);
}
}
this.switchable = switchable;
// initial show/hide
switchable.updateVisible();
}
initialiseSwitchable();
// I'd extend Node.prototype, but apparently IE fails...
function myGetElementsByClassName (node, cls) {
var result = [];
var pool = node.getElementsByTagName("*");
var re = new RegExp('\\b' + cls + '\\b');
for (var i = 0; i < pool.length; i++)
if (re.test(pool[i].className)) result.push(pool[i]);
return result;
}
/* table.hideable, version 1.1.1 by Greenpickle (GPL3) */
var hideImageURL = '/images/hide.png';
var showImageURL = '/images/show.png';
var hideableColClass = 'hideable';
var hiddenColClass = 'hidden';
var hideableShowClass = 'showcol';
function getElementsByTagNames (node) {
// return an array of elements in the node with the given tag names
var nodes = [];
for (var i = 1; i < arguments.length; i++) {
var newNodes = node.getElementsByTagName(arguments[i]);
try {
// no idea where this'll fail if it does
newNodes = Array.prototype.slice.call(newNodes);
nodes = nodes.concat(newNodes);
} catch (e) {
// do it the slow way
for (var j = 0; j < newNodes.length; j++) nodes.push(newNodes[j]);
}
}
return nodes;
}
function matchTagName (node) {
// check if node.tagName is one of given names, case-insensitively
if (node.tagName === undefined) return false;
tag = node.tagName.toLowerCase();
for (var i = 1; i < arguments.length; i++) {
if (arguments[i].toLowerCase() == tag) return true;
}
return false;
}
function getContainer (node, tag) {
// return nearest parent with given tag name
tag = tag.toLowerCase();
var container = node;
do {
container = container.parentNode;
if (container === document) return undefined;
} while (container.tagName.toLowerCase() != tag);
return container;
}
function nextElement (e) {
do e = e.nextSibling;
while (e !== null && e.nodeType != 1);
return e;
}
function previousElement (e) {
do e = e.previousSibling;
while (e !== null && e.nodeType != 1);
return e;
}
var hasClass = (function () {
var reCache = {};
return function (element, className) {
return (reCache[className] ? reCache[className] : (reCache[className]
= new RegExp("(?:\\s|^)" + className + "(?:\\s|$)")))
.test(element.className);
};
})();
var hideable = {};
hideable.showCallback = function () {
hideable.show(this.parentNode);
return false;
};
hideable.hideCallback = function () {
hideable.hide(this.parentNode);
return false;
};
hideable.createLink = function (isHide) {
// create a show/hide link
var lnk = document.createElement('a');
lnk.href = '#';
lnk.onclick = isHide ? hideable.hideCallback : hideable.showCallback;
var img = document.createElement('img');
img.alt = isHide ? 'hide' : 'show';
img.src = isHide ? hideImageURL : showImageURL;
lnk.appendChild(img);
return lnk;
};
hideable.getColSpan = function (cell, orig) {
return orig ? cell.origColSpan || cell.colSpan : cell.colSpan;
};
hideable.setColSpan = function (cell, colSpan) {
if (cell.origColSpan === undefined)
// store original colspan
cell.origColSpan = cell.colSpan;
cell.colSpan = colSpan;
};
hideable.getCol = function (targetCell, orig) {
var row = getContainer(targetCell, 'tr');
if (row === undefined) throw('cell not in a table row');
// sum colspans along row
var col = 0;
var children = getElementsByTagNames(row, 'th', 'td');
for (var i = 0; i < children.length; i++) {
var cell = children[i];
if (cell === targetCell) break;
if (orig || cell.style.display != 'none')
// cell is not hidden, or we want hidden cells: add its colspan
col += hideable.getColSpan(cell, orig);
}
return col;
};
hideable.cellAtCol = function (row, targetCol, orig) {
var col = 0;
var cells = getElementsByTagNames(row, 'th', 'td');
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
if (orig || cell.style.display != 'none') {
// cell is not hidden, or we want hidden cells: add its colspan
col += hideable.getColSpan(cell, orig);
if (col > targetCol) return cell;
}
}
}
hideable.cellsInCol = function (cell) {
// return array of cells in the same column as the given one
if (!matchTagName(cell, 'td', 'th')) throw('not a table cell');
var table = getContainer(cell, 'table');
if (table === undefined) throw('cell not in a table');
var col = hideable.getCol(cell, true);
var rows = table.getElementsByTagName('tr');
var cells = [];
for (var i = 0; i < rows.length; i++) {
cells.push(hideable.cellAtCol(rows[i], col, true));
}
return cells;
};
hideable.hide = function (cell) {
var cells = hideable.cellsInCol(cell);
for (var i = 0; i < cells.length; i++) {
if (i == 0) {
// replace header with 'show' button
var showCell = document.createElement(cells[i].tagName);
showCell.colspan = cells[i].colSpan;
showCell.className = hideableShowClass;
showCell.appendChild(hideable.createLink(false));
hideable.hiddenHeaders[hideable.getCol(cells[i], false)] =
cells[i].parentNode.replaceChild(showCell, cells[i]);
} else {
// hide this column's cells
cells[i].style.display = 'none';
// expand next visible column's cells, if any, to this one
var expand = cells[i];
do expand = nextElement(expand);
while (expand !== null &&
(expand.nodeType != 1 || expand.style.display == 'none'))
if (expand === null) {
// couldn't find a next column: look for a previous one
expand = cells[i];
do expand = previousElement(expand);
while (expand !== null &&
(expand.nodeType != 1 || expand.style.display == 'none'))
}
if (expand !== null)
hideable.setColSpan(expand, expand.colSpan + cells[i].colSpan);
}
}
};
hideable.show = function (cell) {
var cells = hideable.cellsInCol(cell);
for (var i = 0; i < cells.length; i++) {
// show this column's cells
cells[i].style.display = '';
if (i == 0) {
// remove 'show' button
var col = hideable.getCol(cells[i], false);
var origCell = hideable.hiddenHeaders[col];
cells[i] = cells[i].parentNode.replaceChild(origCell, cells[i]);
} else {
cell = cells[i];
// work out where we want the ends of the cell to be
var leftEdge = hideable.getCol(cell, true);
var rightEdge = leftEdge + (cell.origColSpan || cell.colSpan);
var change = 0;
var prevCell = previousElement(cell);
while (prevCell !== null) {
if (prevCell.style.display == 'none')
// move left to cover hidden cells directly to the left
leftEdge -= prevCell.origColSpan || prevCell.colSpan;
else {
// shrink the first visible cell to the left if it covers
// any hidden cells we want this cell to cover
var pos = hideable.getCol(prevCell, false);
if (pos + prevCell.colSpan > leftEdge) {
change = pos + prevCell.colSpan - leftEdge;
hideable.setColSpan(prevCell, leftEdge - pos);
}
break;
}
prevCell = previousElement(prevCell);
}
var nextCell = nextElement(cell);
var flowRight = 0;
// need to explicitly set to undefined as we reuse it
var nextVisible = undefined;
while (nextCell !== null) {
if (nextCell.style.display == 'none')
// expand to cover hidden cells to the right
flowRight += nextCell.origColSpan || nextCell.colSpan;
else {
// until we encounter a visible one, which should cover
// them instead
flowRight = 0;
nextVisible = nextCell;
break;
}
nextCell = nextElement(nextCell);
}
rightEdge += flowRight;
// expand cell as far right as needed
hideable.setColSpan(cell, rightEdge - leftEdge);
change -= cell.colSpan;
if (nextVisible !== undefined)
// expand or shrink the visible cell directly to the right to
// adjust for the changes we've made
hideable.setColSpan(nextVisible, nextVisible.colSpan + change);
}
}
};
hideable.init = function () {
var tables = document.getElementsByTagName('table');
if (tables.length == 0) return;
hideable.hiddenHeaders = [];
// load images
new Image().src = hideImageURL;
new Image().src = showImageURL;
for (var i = 0; i < tables.length; i++) {
// operate on first row
var row = tables[i].getElementsByTagName('tr')[0];
if(row === undefined) return;
var cells = getElementsByTagNames(row, 'th', 'td');
for (var j = 0; j < cells.length; j++) {
if (hasClass(cells[j], hideableColClass)) {
// add 'hide' button
cells[j].appendChild(hideable.createLink(true));
// hide column now if want to
if (hasClass(cells[j], hiddenColClass))
hideable.hide(cells[j]);
}
}
}
};
$( hideable.init );
// JavaScript countdown timer 2.0, by Splarka
//
// <span class="countdown" style="display:none;">
// Only <span class="countdowndate">January 01 2013 00:00:00 PST</span> until New years.
// </span>
// <span class="nocountdown">Javascript disabled.</span>
if ($('body.page-Main_Page').length) {
;(function (module, mw, $) {
'use strict';
var translations = $.extend(true, {
en: {
and: 'and',
second: 'second',
seconds: 'seconds',
minute: 'minute',
minutes: 'minutes',
hour: 'hour',
hours: 'hours',
day: 'day',
days: 'days'
}
}, module.translations || {}),
i18n = translations[
mw.config.get('wgContentLanguage')
] || translations.en;
var countdowns = [];
var NO_LEADING_ZEROS = 1;
function output (i, diff) {
/*jshint bitwise:false*/
var delta, result, parts = [];
delta = diff % 60;
parts.unshift(delta + ' ' + i18n[delta === 1 ? 'second' : 'seconds']);
diff = Math.floor(diff / 60);
delta = diff % 60;
parts.unshift(delta + ' ' + i18n[delta === 1 ? 'minute' : 'minutes']);
diff = Math.floor(diff / 60);
delta = diff % 24;
parts.unshift(delta + ' ' + i18n[delta === 1 ? 'hour' : 'hours' ]);
diff = Math.floor(diff / 24);
parts.unshift(diff + ' ' + i18n[diff === 1 ? 'day' : 'days' ]);
result = parts.pop();
if (countdowns[i].opts & NO_LEADING_ZEROS) {
while (parts.length && parts[0][0] === '0') {
parts.shift();
}
}
if (parts.length) {
result = parts.join(', ') + ' ' + i18n.and + ' ' + result;
}
countdowns[i].node.text(result);
}
function end(i) {
var c = countdowns[i].node.parent();
switch (c.attr('data-end')) {
case 'remove':
c.remove();
countdowns.splice(i, 1);
return;
case 'stop':
output(i, 0);
countdowns.splice(i, 1);
return;
case 'toggle':
var toggle = c.attr('data-toggle');
if (toggle && $(toggle).length) {
$(toggle).css('display', 'inline');
c.css('display', 'none');
countdowns.splice(i, 1);
return;
}
break;
case 'callback':
var callback = c.attr('data-callback');
if (callback && $.isFunction(module[callback])) {
output(i, 0);
countdowns.splice(i, 1);
module[callback].call(c);
return;
}
break;
}
countdowns[i].countup = true;
output(i, 0);
}
function update () {
var now = Date.now();
$.each(countdowns.slice(0), function (i, countdown) {
var diff = Math.floor((countdown.date - now) / 1000);
if (diff <= 0 && !countdown.countup) {
end(i);
} else {
output(i, Math.abs(diff));
}
});
if (countdowns.length) {
window.setTimeout(function () {
update();
}, 1000);
}
}
function getOptions (node) {
/*jshint bitwise:false*/
var text = node.parent().attr('data-options'),
opts = 0;
if (text) {
if (/no-leading-zeros/.test(text)) {
opts |= NO_LEADING_ZEROS;
}
}
return opts;
}
$(function () {
var countdown = $('.countdown');
if (!countdown.length) return;
$('.nocountdown').css('display', 'none');
countdown
.css('display', 'inline')
.find('.countdowndate')
.each(function () {
var $this = $(this),
date = (new Date($this.text())).valueOf();
if (isNaN(date)) {
$this.text('BAD DATE');
return;
}
countdowns.push({
node: $this,
opts: getOptions($this),
date: date,
});
});
if (countdowns.length) {
update();
}
});
}(window.countdownTimer = window.countdownTimer || {}, mediaWiki, jQuery));
}
/* Make it so users can click on "explain" spans to toggle their content.
Useful for mobile users, since there's no mouse-over. */
var explain_spans = document.getElementsByClassName("explain");
for(var e = 0; e < explain_spans.length; e++) {
explain_spans[e].onclick = function(){ toggleExplain(this); };
}
function toggleExplain(e) {
var old = e.getAttribute("oldContent");
if(old && old.length > 0) {
e.innerHTML = old;
e.setAttribute("oldContent", "");
e.style.textDecoration = "underline dotted";
} else {
e.setAttribute("oldContent", e.innerHTML);
e.innerHTML = e.getAttribute(switchableSectionTitleAttr);
e.style.textDecoration = "underline dashed";
}
}
/* move game icons into #content for more consistent positioning */
$(function () {$('#game-icons').css('margin-top', '5px').insertBefore($('#firstHeading'))})
/* Pikan */
$.getScript('/index.php?title=User:Espyo/pikan-core.js'
+ '&action=raw&ctype=text/javascript', function () {
mw.loader.load('/index.php?title=User:Espyo/pikan-pikipedia.js'
+ '&action=raw&ctype=text/javascript');
});
/* Upload page script */
mw.loader.load('/index.php?title=MediaWiki:PikipediaUpload.js'
+ '&action=raw&ctype=text/javascript');
/* End of mw.loader.using callback */
} );
/* DO NOT ADD CODE BELOW THIS LINE */