MediaWiki:Gadget-countdown.js

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.
  1 // <nowiki>
  2 /**
  3  * Countdown
  4  *
  5  * @version 2.1
  6  *
  7  * @author Pecoes <https://c.wikia.com/wiki/User:Pecoes>
  8  * @author Asaba <https://dev.wikia.com/wiki/User:Asaba>
  9  *
 10  * Version 1 authors:
 11  * - Splarka <https://c.wikia.com/wiki/User:Splarka>
 12  * - Eladkse <https://c.wikia.com/wiki/User:Eladkse>
 13  *
 14  * documentation and examples at:
 15  * <https://dev.wikia.com/wiki/Countdown>
 16  */
 17 
 18 /*jshint jquery:true, browser:true, devel:true, camelcase:true, curly:false, undef:true, bitwise:true, eqeqeq:true, forin:true, immed:true, latedef:true, newcap:true, noarg:true, unused:true, regexp:true, strict:true, trailing:false */
 19 /*global mediaWiki:true*/
 20 
 21 ;(function (module, mw, $, undefined) {
 22 
 23 	'use strict';
 24 
 25 	var translations = $.extend(true, {
 26 		// English (English)
 27 		en: {
 28 			and: 'and',
 29 			second: 'second',
 30 			seconds: 'seconds',
 31 			minute: 'minute',
 32 			minutes: 'minutes',
 33 			hour: 'hour',
 34 			hours: 'hours',
 35 			day: 'day',
 36 			days: 'days'
 37 		},
 38 	}, module.translations || {}),
 39 	i18n = translations[
 40 		mw.config.get('wgContentLanguage')
 41 	] || translations.en;
 42 
 43 	var countdowns = [];
 44 
 45 	var NO_LEADING_ZEROS = 1,
 46 	SHORT_FORMAT = 2,
 47 	NO_ZEROS = 4;
 48 
 49 	function output (i, diff) {
 50 		/*jshint bitwise:false*/
 51 		var delta, result, parts = [];
 52 		delta = diff % 60;
 53 		result = ' ' + i18n[delta === 1 ? 'second' : 'seconds'];
 54 		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
 55 		parts.unshift(delta + result);
 56 		diff = Math.floor(diff / 60);
 57 		delta = diff % 60;
 58 		result = ' ' + i18n[delta === 1 ? 'minute' : 'minutes'];
 59 		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
 60 		parts.unshift(delta + result);
 61 		diff = Math.floor(diff / 60);
 62 		delta = diff % 24;
 63 		result = ' ' + i18n[delta === 1 ? 'hour'   : 'hours'  ];
 64 		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
 65 		parts.unshift(delta + result);
 66 		diff = Math.floor(diff / 24);
 67 		result = ' ' + i18n[diff  === 1 ? 'day'    : 'days'   ];
 68 		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
 69 		parts.unshift(diff  + result);
 70 		result = parts.pop();
 71 		if (countdowns[i].opts & NO_LEADING_ZEROS) {
 72 			while (parts.length && parts[0][0] === '0') {
 73 				parts.shift();
 74 			}
 75 		}
 76 		if (countdowns[i].opts & NO_ZEROS) {
 77 			parts = parts.filter(function(part) {
 78 				return part[0] !== '0';
 79 			});
 80 		}
 81 		if (parts.length) {
 82 			if (countdowns[i].opts & SHORT_FORMAT) {
 83 				result = parts.join(' ') + ' ' + result;
 84 			} else {
 85 				result = parts.join(', ') + ' ' + i18n.and + ' ' + result;
 86 			}
 87 		}
 88 		countdowns[i].node.text(result);
 89 	}
 90 
 91 	function end(i) {
 92 		var c = countdowns[i].node.parent();
 93 		switch (c.attr('data-end')) {
 94 		case 'remove':
 95 			c.remove();
 96 			return true;
 97 		case 'stop':
 98 			output(i, 0);
 99 			return true;
100 		case 'toggle':
101 			var toggle = c.attr('data-toggle');
102 			if (toggle && toggle == 'next') {
103 				c.next().css('display', 'inline');
104 				c.css('display', 'none');
105 				return true;
106 			}
107 			if (toggle && $(toggle).length) {
108 				$(toggle).css('display', 'inline');
109 				c.css('display', 'none');
110 				return true;
111 			}
112 			break;
113 		case 'callback':
114 			var callback = c.attr('data-callback');
115 			if (callback && $.isFunction(module[callback])) {
116 				output(i, 0);
117 				module[callback].call(c);
118 				return true;
119 			}
120 			break;
121 		}
122 		countdowns[i].countup = true;
123 		output(i, 0);
124 		return false;
125 	}
126 
127 	function update () {
128 		var now = Date.now();
129 		var countdownsToRemove = [];
130 		$.each(countdowns.slice(0), function (i, countdown) {
131 			var diff = Math.floor((countdown.date - now) / 1000);
132 			if (diff <= 0 && !countdown.countup) {
133 				if (end(i)) countdownsToRemove.push(i);
134 			} else {
135 				output(i, Math.abs(diff));
136 			}
137 		});
138 		var x;
139 		while((x = countdownsToRemove.pop()) !== undefined) {
140 			countdowns.splice(x, 1);
141 		}
142 		if (countdowns.length) {
143 			window.setTimeout(function () {
144 				update();
145 			}, 1000);
146 		}
147 	}
148 
149 	function getOptions (node) {
150 		/*jshint bitwise:false*/
151 		var text = node.parent().attr('data-options'),
152 			opts = 0;
153 		if (text) {
154 			if (/no-leading-zeros/.test(text)) {
155 				opts |= NO_LEADING_ZEROS;
156 			}
157 			if (/short-format/.test(text)) {
158 				opts |= SHORT_FORMAT;
159 			}
160 			if (/no-zeros/.test(text)) {
161 				opts |= NO_ZEROS;
162 			}
163 		}
164 		return opts;
165 	}
166 
167 	function init() {
168 		var countdown = $('.countdown:not(.handled)');
169 		if (!countdown.length) return;
170 		$('.nocountdown').css('display', 'none');
171 		countdown
172 		.css('display', 'inline')
173 		.find('.countdowndate')
174 		.each(function () {
175 			var $this = $(this),
176 				date = (new Date($this.text())).valueOf();
177 			if (isNaN(date)) {
178 				$this.text('BAD DATE');
179 				return;
180 			}
181 			countdowns.push({
182 				node: $this,
183 				opts: getOptions($this),
184 				date: date,
185 			});
186 		});
187 		countdown.addClass('handled');
188 		if (countdowns.length) {
189 			update();
190 		}
191 	}
192 
193 	mw.hook('wikipage.content').add(init);
194 
195 }(window.countdownTimer = window.countdownTimer || {}, mediaWiki, jQuery));
196 // </nowiki>