MediaWiki:Gadget-countdown.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.
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>