User:Unready/ui.clock.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Unready/ui.clock. This user script seems to have an accompanying .css page at User:Unready/ui.clock.css. |
/**
* Implement a UTC clock and calendar
* Attach it to the portlet bar
*
* Version 1.0: 18 Jul 2014
* Original version for Wikia
* Purge on click
* Use the interval idea from
* mw:MediaWiki:Gadget-UTCLiveClock.js
* Version 2.0: 8 Oct 2016
* Rewrite and refactor
* Remove purge & add calendar
* Support generic MediaWiki skins only
*/
((window.user = window.user || {}).ui = user.ui || {}).clock =
user.ui.clock || (function (mw, $) {
'use strict';
var
self = {
run : run,
stop : stop,
message: new Date().toISOString() + ' Initializing',
version : 'Version 2.0: 8 Oct 2016'
},
gCancel = false,
gID = -1, // cannot run = -1; okay to run = 0; already running > 0
gLast = -1, // current month on the last tick
gTime = document.createTextNode('');
// calculate day of week using Zeller's algorithm
// 0 = Saturday, ..., 6 = Friday
function zeller(d, m, y) {
var
Y = y - (m < 3 ? 1 : 0),
c = Math.floor(Y / 100),
w;
m += (m < 3) ? 12 : 0;
y = Y % 100;
w = (d + Math.floor(13 * (m + 1) / 5) + y +
Math.floor(y / 4) + Math.floor(c / 4) - 2 * c) % 7;
return (w < 0) ? w + 7 : w;
}
// generate an array of weeks for a month table
// m = month, 0 = January
// y = 4-digit year
function month(m, y) {
var
month = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
],
last = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
cal = [
'<tr><th colspan="7">' +
month[m] + ' ' + y +
'</th></tr>',
'<tr>' +
'<th>Su</th><th>Mo</th><th>Tu</th><th>We</th>' +
'<th>Th</th><th>Fr</th><th>Sa</th>' +
'</tr>'
],
i, offset, tr;
// leap year
if (((y % 100 !== 0) && (y % 4 === 0)) || (y % 400 === 0)) {
last[1] = 29;
}
offset = (zeller(1, m + 1, y) + 6) % 7; // 0 = Sunday
if (offset) {
tr = '<tr><td colspan="' + offset + '"></td>';
}
for ( i = 1; i <= last[m]; ++i ) {
if (offset === 0) {
tr = '<tr>';
}
tr += '<td>' + i + '</td>';
if (++offset === 7) {
tr += '</tr>';
cal.push(tr);
offset = 0;
}
}
if (offset) {
tr += '<td colspan="' + (7 - offset) + '"></td></tr>';
cal.push(tr);
}
return cal;
}
// generate 3 months of calendars
// m = current month, 0 = January
// y = 4-digit year
function updateCal(m, y) {
var
tbody = $('tbody', '#js-clock-cal').empty();
if (--m < 0) {
m = 11;
--y;
}
tbody.append(month(m, y));
if (++m > 11) {
m = 0;
++y;
}
tbody.append(month(m, y));
if (++m > 11) {
m = 0;
++y;
}
tbody.append(month(m, y));
}
// update the displayed time
function onTick() {
var
n = Date.now(),
d = new Date(n),
m = d.getUTCMonth(),
y = d.getUTCFullYear(),
s = d.toUTCString() // mostly RFC-822/RFC-1123 time string
.replace(/\d{4}/, '$&,')
.replace('GMT', '(UTC)')
.replace(/ 0/g, ' ')
.substr(5);
if (!gCancel) {
gID = setTimeout(onTick, 1100 - n % 1000);
gTime.data = s;
if (m !== gLast) {
gLast = m;
updateCal(m, y);
}
}
}
// start the clock, if it's stopped
function run() {
if (gID === 0) {
gCancel = false;
self.message += '\n' + new Date().toISOString() +
' Restarted';
onTick();
}
}
// stop the clock, if it's running
function stop() {
if (gID > 0) {
clearTimeout(gID);
gID = 0;
gCancel = true;
self.message += '\n' + new Date().toISOString() +
' Stopped';
}
}
// insert nodes into the DOM & run
$(function () {
var
wgSkin = mw.config.get('skin'),
a = [
$('<a id="js-clock-time"></a>').append(gTime),
'<table id="js-clock-cal" class="wikitable"><tbody></tbody></table>'
];
// insert the clock into the DOM
// support generic MediaWiki skins only
switch (wgSkin) {
case 'cologneblue':
$('#syslinks')
.prepend(document.createTextNode(' | '))
.prepend(
$('<span id="pt-clock"></span>')
.append(a)
);
break;
case 'modern':
$('#p-personal > .pBody > ul')
.append(
$('<li id="pt-clock"></li>')
.append(a)
);
break;
case 'monobook':
$('#p-personal > .pBody > ul')
.prepend(
$('<li id="pt-clock"></li>')
.append(a)
);
break;
case 'vector':
$('#p-personal > ul')
.prepend(
$('<li id="pt-clock"></li>')
.append(a)
);
break;
default:
self.message += '\n' + new Date().toISOString() +
' main :: unsupported skin : ' + wgSkin;
delete self.run;
delete self.stop;
return;
}
// run it
onTick();
});
return self;
}(mediaWiki, jQuery));