- Welcome to the Kancolle Wiki!
- If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord
Difference between revisions of "MediaWiki:Common.js"
Jump to navigation
Jump to search
Benlisquare (talk | contribs) (wrong description) |
Gensui Hime (talk | contribs) |
||
Line 236: | Line 236: | ||
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton ); | mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton ); | ||
+ | |||
+ | //Countdown timer | ||
+ | ;(function (module, mw, $, undefined) { | ||
+ | |||
+ | 'use strict'; | ||
+ | |||
+ | var translations = $.extend(true, { | ||
+ | // Catalan (Català) | ||
+ | ca: { | ||
+ | and: 'i', | ||
+ | second: 'segon', | ||
+ | seconds: 'segons', | ||
+ | minute: 'minut', | ||
+ | minutes: 'minuts', | ||
+ | hour: 'hora', | ||
+ | hours: 'hores', | ||
+ | day: 'dia', | ||
+ | days: 'dies' | ||
+ | }, | ||
+ | // German (Deutsch) | ||
+ | de: { | ||
+ | and: 'und', | ||
+ | second: 'Sekunde', | ||
+ | seconds: 'Sekunden', | ||
+ | minute: 'Minute', | ||
+ | minutes: 'Minuten', | ||
+ | hour: 'Stunde', | ||
+ | hours: 'Stunden', | ||
+ | day: 'Tag', | ||
+ | days: 'Tage' | ||
+ | }, | ||
+ | // English (English) | ||
+ | en: { | ||
+ | and: 'and', | ||
+ | second: 'second', | ||
+ | seconds: 'seconds', | ||
+ | minute: 'minute', | ||
+ | minutes: 'minutes', | ||
+ | hour: 'hour', | ||
+ | hours: 'hours', | ||
+ | day: 'day', | ||
+ | days: 'days' | ||
+ | }, | ||
+ | // Spanish (Español) | ||
+ | es: { | ||
+ | and: 'y', | ||
+ | second: 'segundo', | ||
+ | seconds: 'segundos', | ||
+ | minute: 'minuto', | ||
+ | minutes: 'minutos', | ||
+ | hour: 'hora', | ||
+ | hours: 'horas', | ||
+ | day: 'día', | ||
+ | days: 'días' | ||
+ | }, | ||
+ | // French (Français) | ||
+ | fr: { | ||
+ | and: 'et', | ||
+ | second: 'seconde', | ||
+ | seconds: 'secondes', | ||
+ | minute: 'minute', | ||
+ | minutes: 'minutes', | ||
+ | hour: 'heure', | ||
+ | hours: 'heures', | ||
+ | day: 'jour', | ||
+ | days: 'jours' | ||
+ | }, | ||
+ | // Hungarian (Magyar) | ||
+ | hu: { | ||
+ | and: 'és', | ||
+ | second: 'másodperc', | ||
+ | seconds: 'másodperc', | ||
+ | minute: 'perc', | ||
+ | minutes: 'perc', | ||
+ | hour: 'óra', | ||
+ | hours: 'óra', | ||
+ | day: 'nap', | ||
+ | days: 'nap' | ||
+ | }, | ||
+ | // Italian (Italiano) | ||
+ | it: { | ||
+ | and: 'e', | ||
+ | second: 'secondo', | ||
+ | seconds: 'secondi', | ||
+ | minute: 'minuto', | ||
+ | minutes: 'minuti', | ||
+ | hour: 'ora', | ||
+ | hours: 'ore', | ||
+ | day: 'giorno', | ||
+ | days: 'giorni' | ||
+ | }, | ||
+ | // Japanese (日本語) | ||
+ | ja: { | ||
+ | and: '', | ||
+ | second: '秒', | ||
+ | seconds: '秒', | ||
+ | minute: '分', | ||
+ | minutes: '分', | ||
+ | hour: '時間', | ||
+ | hours: '時間', | ||
+ | day: '日', | ||
+ | days: '日' | ||
+ | }, | ||
+ | // Malay (Bahasa Melayu) | ||
+ | ms: { | ||
+ | and: 'dan', | ||
+ | second: 'saat', | ||
+ | seconds: 'saat', | ||
+ | minute: 'minit', | ||
+ | minutes: 'minit', | ||
+ | hour: 'jam', | ||
+ | hours: 'jam', | ||
+ | day: 'hari', | ||
+ | days: 'hari' | ||
+ | }, | ||
+ | // Dutch (Nederlands) | ||
+ | nl: { | ||
+ | and: 'en', | ||
+ | second: 'seconde', | ||
+ | seconds: 'seconden', | ||
+ | minute: 'minuut', | ||
+ | minutes: 'minuten', | ||
+ | hour: 'uur', | ||
+ | hours: 'uur', | ||
+ | day: 'dag', | ||
+ | days: 'dagen' | ||
+ | }, | ||
+ | // Polish (Polski) | ||
+ | pl: { | ||
+ | and: 'i', | ||
+ | second: 'sekunda', | ||
+ | seconds: 'sekund(y)', | ||
+ | minute: 'minuta', | ||
+ | minutes: 'minut(y)', | ||
+ | hour: 'godzina', | ||
+ | hours: 'godzin(y)', | ||
+ | day: 'dzień', | ||
+ | days: 'dni' | ||
+ | }, | ||
+ | // Portuguese (Português) | ||
+ | pt: { | ||
+ | and: 'e', | ||
+ | second: 'segundo', | ||
+ | seconds: 'segundos', | ||
+ | minute: 'minuto', | ||
+ | minutes: 'minutos', | ||
+ | hour: 'hora', | ||
+ | hours: 'horas', | ||
+ | day: 'dia', | ||
+ | days: 'dias' | ||
+ | |||
+ | }, | ||
+ | // Brazilian Portuguese (Português do Brasil) | ||
+ | 'pt-br': { | ||
+ | and: 'e', | ||
+ | second: 'segundo', | ||
+ | seconds: 'segundos', | ||
+ | minute: 'minuto', | ||
+ | minutes: 'minutos', | ||
+ | hour: 'hora', | ||
+ | hours: 'horas', | ||
+ | day: 'dia', | ||
+ | days: 'dias' | ||
+ | |||
+ | }, | ||
+ | // Russian (русский) | ||
+ | ru: { | ||
+ | and: 'и', | ||
+ | second: 'секунда', | ||
+ | seconds: 'секунд', | ||
+ | minute: 'минута', | ||
+ | minutes: 'минут', | ||
+ | hour: 'час', | ||
+ | hours: 'часов', | ||
+ | day: 'день', | ||
+ | days: 'дней' | ||
+ | }, | ||
+ | // Serbian (српски језик) | ||
+ | sr: { | ||
+ | and: 'i', | ||
+ | second: 'sekundu', | ||
+ | seconds: 'sekunde/-i', | ||
+ | minute: 'minutu', | ||
+ | minutes: 'minute/-a', | ||
+ | hour: 'sat', | ||
+ | hours: 'sata/-i', | ||
+ | day: 'dan', | ||
+ | days: 'dana' | ||
+ | }, | ||
+ | // Vietnamese (Tiếng Việt) | ||
+ | vi: { | ||
+ | and: 'và', | ||
+ | second: 'giây', | ||
+ | seconds: 'giây', | ||
+ | minute: 'phút', | ||
+ | minutes: 'phút', | ||
+ | hour: 'giờ', | ||
+ | hours: 'giờ', | ||
+ | day: 'ngày', | ||
+ | days: 'ngày' | ||
+ | }, | ||
+ | // Chinese (中文) | ||
+ | zh: { | ||
+ | and: ' ', | ||
+ | second: '秒', | ||
+ | seconds: '秒', | ||
+ | minute: '分', | ||
+ | minutes: '分', | ||
+ | hour: '小时', | ||
+ | hours: '小时', | ||
+ | day: '天', | ||
+ | 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(); | ||
+ | return true; | ||
+ | case 'stop': | ||
+ | output(i, 0); | ||
+ | return true; | ||
+ | case 'toggle': | ||
+ | var toggle = c.attr('data-toggle'); | ||
+ | if (toggle && $(toggle).length) { | ||
+ | $(toggle).css('display', 'inline'); | ||
+ | c.css('display', 'none'); | ||
+ | return true; | ||
+ | } | ||
+ | break; | ||
+ | case 'callback': | ||
+ | var callback = c.attr('data-callback'); | ||
+ | if (callback && $.isFunction(module[callback])) { | ||
+ | output(i, 0); | ||
+ | module[callback].call(c); | ||
+ | return true; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | countdowns[i].countup = true; | ||
+ | output(i, 0); | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | function update () { | ||
+ | var now = Date.now(); | ||
+ | var countdownsToRemove = []; | ||
+ | $.each(countdowns.slice(0), function (i, countdown) { | ||
+ | var diff = Math.floor((countdown.date - now) / 1000); | ||
+ | if (diff <= 0 && !countdown.countup) { | ||
+ | if (end(i)) countdownsToRemove.push(i); | ||
+ | } else { | ||
+ | output(i, Math.abs(diff)); | ||
+ | } | ||
+ | }); | ||
+ | var x; | ||
+ | while((x = countdownsToRemove.pop()) !== undefined) { | ||
+ | countdowns.splice(x, 1); | ||
+ | } | ||
+ | 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)); | ||
+ | // |
Revision as of 09:58, 21 April 2015
/**
* Scrolling text
*
* Copied from zh.kcwiki.moe
*/
function AutoScroll(objNotice) {
$(objNotice).find("ul:first").animate({
marginTop:"-25px"
},500,function(){
$(this).css({marginTop: "0px"}).find("li:first").appendTo(this);
});
}
$(document).ready(function() {
setInterval('AutoScroll("#scrollDiv")',5000);
//image loading effect
$('img').on('load', function(e){
var target = $(this);
target.css('opacity', 0).animate({opacity: 1}, 1000);
});
});
/**
* Collapsible tables
*
* Allows tables to be collapsed, showing only the header. See [[Wikipedia:NavFrame]].
*
* @version 2.0.3 (2014-03-14)
* @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
* @author [[User:R. Koot]]
* @author [[User:Krinkle]]
* @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
* is supported in MediaWiki core.
*/
var autoCollapse = 2;
var collapseCaption = 'hide';
var expandCaption = 'show';
var tableIndex = 0;
function collapseTable( tableIndex ) {
var Button = document.getElementById( 'collapseButton' + tableIndex );
var Table = document.getElementById( 'collapsibleTable' + tableIndex );
if ( !Table || !Button ) {
return false;
}
var Rows = Table.rows;
var i;
if ( Button.firstChild.data === collapseCaption ) {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = 'none';
}
Button.firstChild.data = expandCaption;
} else {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = Rows[0].style.display;
}
Button.firstChild.data = collapseCaption;
}
}
function createClickHandler( tableIndex ) {
return function ( e ) {
e.preventDefault();
collapseTable( tableIndex );
};
}
function createCollapseButtons( $content ) {
var NavigationBoxes = {};
var $Tables = $content.find( 'table' );
var i;
$Tables.each( function( i, table ) {
if ( $(table).hasClass( 'collapsible' ) ) {
/* only add button and increment count if there is a header row to work with */
var HeaderRow = table.getElementsByTagName( 'tr' )[0];
if ( !HeaderRow ) {
return;
}
var Header = table.getElementsByTagName( 'th' )[0];
if ( !Header ) {
return;
}
NavigationBoxes[ tableIndex ] = table;
table.setAttribute( 'id', 'collapsibleTable' + tableIndex );
var Button = document.createElement( 'span' );
var ButtonLink = document.createElement( 'a' );
var ButtonText = document.createTextNode( collapseCaption );
// Styles are declared in [[MediaWiki:Common.css]]
Button.className = 'collapseButton';
ButtonLink.style.color = Header.style.color;
ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
ButtonLink.setAttribute( 'href', '#' );
$( ButtonLink ).on( 'click', createClickHandler( tableIndex ) );
ButtonLink.appendChild( ButtonText );
Button.appendChild( document.createTextNode( '[' ) );
Button.appendChild( ButtonLink );
Button.appendChild( document.createTextNode( ']' ) );
Header.insertBefore( Button, Header.firstChild );
tableIndex++;
}
} );
for ( i = 0; i < tableIndex; i++ ) {
if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||
( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )
) {
collapseTable( i );
}
else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
var element = NavigationBoxes[i];
while ((element = element.parentNode)) {
if ( $( element ).hasClass( 'outercollapse' ) ) {
collapseTable ( i );
break;
}
}
}
}
}
mw.hook( 'wikipage.content' ).add( createCollapseButtons );
/**
* Dynamic Navigation Bars (experimental)
*
* Description: See [[Wikipedia:NavFrame]].
* Maintainers: UNMAINTAINED
*/
/* set up the words in your language */
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
var indexNavigationBar = 0;
/**
* Shows and hides content and picture (if available) of navigation bars
* Parameters:
* indexNavigationBar: the index of navigation bar to be toggled
**/
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
var NavChild;
if ( !NavFrame || !NavToggle ) {
return false;
}
/* if shown now */
if ( NavToggle.firstChild.data === NavigationBarHide ) {
for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
NavChild.style.display = 'none';
}
}
NavToggle.firstChild.data = NavigationBarShow;
/* if hidden now */
} else if ( NavToggle.firstChild.data === NavigationBarShow ) {
for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
NavChild.style.display = 'block';
}
}
NavToggle.firstChild.data = NavigationBarHide;
}
event.preventDefault();
};
/* adds show/hide-button to navigation bars */
function createNavigationBarToggleButton( $content ) {
var NavChild;
/* iterate over all < div >-elements */
var $divs = $content.find( 'div' );
$divs.each( function ( i, NavFrame ) {
/* if found a navigation bar */
if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {
indexNavigationBar++;
var NavToggle = document.createElement( 'a' );
NavToggle.className = 'NavToggle';
NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
NavToggle.setAttribute( 'href', '#' );
$( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
/**
* Check if any children are already hidden. This loop is here for backwards compatibility:
* the old way of making NavFrames start out collapsed was to manually add style="display:none"
* to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make
* the content visible without JavaScript support), the new recommended way is to add the class
* "collapsed" to the NavFrame itself, just like with collapsible tables.
*/
for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
if ( NavChild.style.display === 'none' ) {
isCollapsed = true;
}
}
}
if ( isCollapsed ) {
for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
NavChild.style.display = 'none';
}
}
}
var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
NavToggle.appendChild( NavToggleText );
/* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
NavToggle.style.color = NavFrame.childNodes[j].style.color;
NavFrame.childNodes[j].appendChild( NavToggle );
}
}
NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
}
} );
}
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );
//Countdown timer
;(function (module, mw, $, undefined) {
'use strict';
var translations = $.extend(true, {
// Catalan (Català)
ca: {
and: 'i',
second: 'segon',
seconds: 'segons',
minute: 'minut',
minutes: 'minuts',
hour: 'hora',
hours: 'hores',
day: 'dia',
days: 'dies'
},
// German (Deutsch)
de: {
and: 'und',
second: 'Sekunde',
seconds: 'Sekunden',
minute: 'Minute',
minutes: 'Minuten',
hour: 'Stunde',
hours: 'Stunden',
day: 'Tag',
days: 'Tage'
},
// English (English)
en: {
and: 'and',
second: 'second',
seconds: 'seconds',
minute: 'minute',
minutes: 'minutes',
hour: 'hour',
hours: 'hours',
day: 'day',
days: 'days'
},
// Spanish (Español)
es: {
and: 'y',
second: 'segundo',
seconds: 'segundos',
minute: 'minuto',
minutes: 'minutos',
hour: 'hora',
hours: 'horas',
day: 'día',
days: 'días'
},
// French (Français)
fr: {
and: 'et',
second: 'seconde',
seconds: 'secondes',
minute: 'minute',
minutes: 'minutes',
hour: 'heure',
hours: 'heures',
day: 'jour',
days: 'jours'
},
// Hungarian (Magyar)
hu: {
and: 'és',
second: 'másodperc',
seconds: 'másodperc',
minute: 'perc',
minutes: 'perc',
hour: 'óra',
hours: 'óra',
day: 'nap',
days: 'nap'
},
// Italian (Italiano)
it: {
and: 'e',
second: 'secondo',
seconds: 'secondi',
minute: 'minuto',
minutes: 'minuti',
hour: 'ora',
hours: 'ore',
day: 'giorno',
days: 'giorni'
},
// Japanese (日本語)
ja: {
and: '',
second: '秒',
seconds: '秒',
minute: '分',
minutes: '分',
hour: '時間',
hours: '時間',
day: '日',
days: '日'
},
// Malay (Bahasa Melayu)
ms: {
and: 'dan',
second: 'saat',
seconds: 'saat',
minute: 'minit',
minutes: 'minit',
hour: 'jam',
hours: 'jam',
day: 'hari',
days: 'hari'
},
// Dutch (Nederlands)
nl: {
and: 'en',
second: 'seconde',
seconds: 'seconden',
minute: 'minuut',
minutes: 'minuten',
hour: 'uur',
hours: 'uur',
day: 'dag',
days: 'dagen'
},
// Polish (Polski)
pl: {
and: 'i',
second: 'sekunda',
seconds: 'sekund(y)',
minute: 'minuta',
minutes: 'minut(y)',
hour: 'godzina',
hours: 'godzin(y)',
day: 'dzień',
days: 'dni'
},
// Portuguese (Português)
pt: {
and: 'e',
second: 'segundo',
seconds: 'segundos',
minute: 'minuto',
minutes: 'minutos',
hour: 'hora',
hours: 'horas',
day: 'dia',
days: 'dias'
},
// Brazilian Portuguese (Português do Brasil)
'pt-br': {
and: 'e',
second: 'segundo',
seconds: 'segundos',
minute: 'minuto',
minutes: 'minutos',
hour: 'hora',
hours: 'horas',
day: 'dia',
days: 'dias'
},
// Russian (русский)
ru: {
and: 'и',
second: 'секунда',
seconds: 'секунд',
minute: 'минута',
minutes: 'минут',
hour: 'час',
hours: 'часов',
day: 'день',
days: 'дней'
},
// Serbian (српски језик)
sr: {
and: 'i',
second: 'sekundu',
seconds: 'sekunde/-i',
minute: 'minutu',
minutes: 'minute/-a',
hour: 'sat',
hours: 'sata/-i',
day: 'dan',
days: 'dana'
},
// Vietnamese (Tiếng Việt)
vi: {
and: 'và',
second: 'giây',
seconds: 'giây',
minute: 'phút',
minutes: 'phút',
hour: 'giờ',
hours: 'giờ',
day: 'ngày',
days: 'ngày'
},
// Chinese (中文)
zh: {
and: ' ',
second: '秒',
seconds: '秒',
minute: '分',
minutes: '分',
hour: '小时',
hours: '小时',
day: '天',
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();
return true;
case 'stop':
output(i, 0);
return true;
case 'toggle':
var toggle = c.attr('data-toggle');
if (toggle && $(toggle).length) {
$(toggle).css('display', 'inline');
c.css('display', 'none');
return true;
}
break;
case 'callback':
var callback = c.attr('data-callback');
if (callback && $.isFunction(module[callback])) {
output(i, 0);
module[callback].call(c);
return true;
}
break;
}
countdowns[i].countup = true;
output(i, 0);
return false;
}
function update () {
var now = Date.now();
var countdownsToRemove = [];
$.each(countdowns.slice(0), function (i, countdown) {
var diff = Math.floor((countdown.date - now) / 1000);
if (diff <= 0 && !countdown.countup) {
if (end(i)) countdownsToRemove.push(i);
} else {
output(i, Math.abs(diff));
}
});
var x;
while((x = countdownsToRemove.pop()) !== undefined) {
countdowns.splice(x, 1);
}
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));
//