User:Saftzie/ui.clock.js
ShoutWiki — express yourself and be heard!
Jump to navigation
Jump to search
Note: After saving, 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: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/**
* 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
* Version 2.0.1: 1 Mar 2023
* Update for skin changes (vector)
*/
((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.1: 1 Mar 2023'
},
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 > .vector-menu-content > .vector-menu-content-list')
.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));