X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/3ac9cb26acd9b7c5ba421dac123ba8f75b782bd2..ce268f7e02d3c4cfb11f700d2ae179abc151f8ae:/wolnelektury/static/js/jquery.countdown.js diff --git a/wolnelektury/static/js/jquery.countdown.js b/wolnelektury/static/js/jquery.countdown.js index 5375ce815..f9c58d370 100644 --- a/wolnelektury/static/js/jquery.countdown.js +++ b/wolnelektury/static/js/jquery.countdown.js @@ -1,12 +1,10 @@ /* http://keith-wood.name/countdown.html - Countdown for jQuery v1.5.7. + Countdown for jQuery v1.5.8. Written by Keith Wood (kbwood{at}iinet.com.au) January 2008. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and + MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. Please attribute the author if you use it. */ -/* Modified by Radek Czajka, Fundacja Nowoczesna Polska (radoslaw.czajka(at)nowoczesnapolska.org.pl) */ - /* Display a countdown timer. Attach it with options like: $('div selector').countdown( @@ -23,9 +21,9 @@ function Countdown() { // The display texts for the counters if only one labels1: ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minute', 'Second'], compactLabels: ['y', 'm', 'w', 'd'], // The compact texts for the counters + whichLabels: null, // Function to determine which labels to use timeSeparator: ':', // Separator for time periods - isRTL: false, // True for right-to-left languages, false for left-to-right - which: function(n) {return n} + isRTL: false // True for right-to-left languages, false for left-to-right }; this._defaults = { until: null, // new Date(year, mth - 1, day, hr, min, sec) - date/time to count down to @@ -41,6 +39,7 @@ function Countdown() { // 'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds layout: '', // Build your own layout for the countdown compact: false, // True to display in a compact format, false for an expanded one + significant: 0, // The number of periods with values to show, zero for all description: '', // The description displayed for the countdown expiryUrl: '', // A URL to load upon expiry, replacing the current page expiryText: '', // Text to display upon expiry, replacing the countdown @@ -69,12 +68,12 @@ var S = 6; // Seconds $.extend(Countdown.prototype, { /* Class name added to elements to indicate already configured with countdown. */ markerClassName: 'hasCountdown', - + /* Shared timer for all countdowns. */ _timer: setInterval(function() { $.countdown._updateTargets(); }, 980), /* List of currently active countdown targets. */ _timerTargets: [], - + /* Override the default settings for all instances of the countdown widget. @param options (object) the new settings to use as defaults */ setDefaults: function(options) { @@ -194,7 +193,7 @@ $.extend(Countdown.prototype, { var onTick = this._get(inst, 'onTick'); if (onTick) { var periods = inst._hold != 'lap' ? inst._periods : - this._calculatePeriods(inst, inst._show, new Date()); + this._calculatePeriods(inst, inst._show, this._get(inst, 'significant'), new Date()); var tickInterval = this._get(inst, 'tickInterval'); if (tickInterval == 1 || this.periodsToSeconds(periods) % tickInterval == 0) { onTick.apply(target, [periods]); @@ -265,7 +264,7 @@ $.extend(Countdown.prototype, { _resetExtraLabels: function(base, options) { var changingLabels = false; for (var n in options) { - if (n.match(/[Ll]abels/)) { + if (n != 'whichLabels' && n.match(/[Ll]abels/)) { changingLabels = true; break; } @@ -278,7 +277,7 @@ $.extend(Countdown.prototype, { } } }, - + /* Calculate interal settings for an instance. @param target (element) the containing division @param inst (object) the current settings for this instance */ @@ -363,7 +362,7 @@ $.extend(Countdown.prototype, { inst[inst._since ? '_since' : '_until'] = this._determineTime(sign + inst._periods[0] + 'y' + sign + inst._periods[1] + 'o' + sign + inst._periods[2] + 'w' + - sign + inst._periods[3] + 'd' + sign + inst._periods[4] + 'h' + + sign + inst._periods[3] + 'd' + sign + inst._periods[4] + 'h' + sign + inst._periods[5] + 'm' + sign + inst._periods[6] + 's'); this._addTarget(target); } @@ -380,7 +379,7 @@ $.extend(Countdown.prototype, { _getTimesCountdown: function(target) { var inst = $.data(target, PROP_NAME); return (!inst ? null : (!inst._hold ? inst._periods : - this._calculatePeriods(inst, inst._show, new Date()))); + this._calculatePeriods(inst, inst._show, this._get(inst, 'significant'), new Date()))); }, /* Get a setting value, defaulting if necessary. @@ -422,7 +421,7 @@ $.extend(Countdown.prototype, { case 'd': day += parseInt(matches[1], 10); break; case 'w': day += parseInt(matches[1], 10) * 7; break; case 'o': - month += parseInt(matches[1], 10); + month += parseInt(matches[1], 10); day = Math.min(day, $.countdown._getDaysInMonth(year, month)); break; case 'y': @@ -449,54 +448,75 @@ $.extend(Countdown.prototype, { return 32 - new Date(year, month, 32).getDate(); }, + /* Determine which set of labels should be used for an amount. + @param num (number) the amount to be displayed + @return (number) the set of labels to be used for this amount */ + _normalLabels: function(num) { + return num; + }, + /* Generate the HTML to display the countdown widget. @param inst (object) the current settings for this instance @return (string) the new HTML for the countdown display */ _generateHTML: function(inst) { // Determine what to show - inst._periods = periods = (inst._hold ? inst._periods : - this._calculatePeriods(inst, inst._show, new Date())); + var significant = this._get(inst, 'significant'); + inst._periods = (inst._hold ? inst._periods : + this._calculatePeriods(inst, inst._show, significant, new Date())); // Show all 'asNeeded' after first non-zero value var shownNonZero = false; var showCount = 0; + var sigCount = significant; var show = $.extend({}, inst._show); - for (var period = 0; period < inst._show.length; period++) { - shownNonZero |= (inst._show[period] == '?' && periods[period] > 0); + for (var period = Y; period <= S; period++) { + shownNonZero |= (inst._show[period] == '?' && inst._periods[period] > 0); show[period] = (inst._show[period] == '?' && !shownNonZero ? null : inst._show[period]); showCount += (show[period] ? 1 : 0); + sigCount -= (inst._periods[period] > 0 ? 1 : 0); + } + var showSignificant = [false, false, false, false, false, false, false]; + for (var period = S; period >= Y; period--) { // Determine significant periods + if (inst._show[period]) { + if (inst._periods[period]) { + showSignificant[period] = true; + } + else { + showSignificant[period] = sigCount > 0; + sigCount--; + } + } } var compact = this._get(inst, 'compact'); var layout = this._get(inst, 'layout'); var labels = (compact ? this._get(inst, 'compactLabels') : this._get(inst, 'labels')); + var whichLabels = this._get(inst, 'whichLabels') || this._normalLabels; var timeSeparator = this._get(inst, 'timeSeparator'); var description = this._get(inst, 'description') || ''; var showCompact = function(period) { - var labelsNum = $.countdown._get(inst, 'compactLabels' + periods[period]); - return (show[period] ? periods[period] + + var labelsNum = $.countdown._get(inst, + 'compactLabels' + whichLabels(inst._periods[period])); + return (show[period] ? inst._periods[period] + (labelsNum ? labelsNum[period] : labels[period]) + ' ' : ''); }; var showFull = function(period) { - var which = $.countdown._get(inst, 'which'); - if (which) { - var labelsNum = $.countdown._get(inst, 'labels' + which(periods[period])); - } - return (show[period] ? + var labelsNum = $.countdown._get(inst, 'labels' + whichLabels(inst._periods[period])); + return ((!significant && show[period]) || (significant && showSignificant[period]) ? '' + - periods[period] + '
' + + inst._periods[period] + '

' + (labelsNum ? labelsNum[period] : labels[period]) + '' : ''); }; - return (layout ? this._buildLayout(inst, show, layout, compact) : + return (layout ? this._buildLayout(inst, show, layout, compact, significant, showSignificant) : ((compact ? // Compact version '' + - showCompact(Y) + showCompact(O) + showCompact(W) + showCompact(D) + - (show[H] ? this._minDigits(periods[H], 2) : '') + + (inst._hold ? ' countdown_holding' : '') + '">' + + showCompact(Y) + showCompact(O) + showCompact(W) + showCompact(D) + + (show[H] ? this._minDigits(inst._periods[H], 2) : '') + (show[M] ? (show[H] ? timeSeparator : '') + - this._minDigits(periods[M], 2) : '') + + this._minDigits(inst._periods[M], 2) : '') + (show[S] ? (show[H] || show[M] ? timeSeparator : '') + - this._minDigits(periods[S], 2) : '') : + this._minDigits(inst._periods[S], 2) : '') : // Full version - '' + showFull(Y) + showFull(O) + showFull(W) + showFull(D) + showFull(H) + showFull(M) + showFull(S)) + '' + @@ -504,16 +524,19 @@ $.extend(Countdown.prototype, { }, /* Construct a custom layout. - @param inst (object) the current settings for this instance - @param show (string[7]) flags indicating which periods are requested - @param layout (string) the customised layout - @param compact (boolean) true if using compact labels + @param inst (object) the current settings for this instance + @param show (string[7]) flags indicating which periods are requested + @param layout (string) the customised layout + @param compact (boolean) true if using compact labels + @param significant (number) the number of periods with values to show, zero for all + @param showSignificant (boolean[7]) other periods to show for significance @return (string) the custom HTML */ - _buildLayout: function(inst, show, layout, compact) { + _buildLayout: function(inst, show, layout, compact, significant, showSignificant) { var labels = this._get(inst, (compact ? 'compactLabels' : 'labels')); + var whichLabels = this._get(inst, 'whichLabels') || this._normalLabels; var labelFor = function(index) { return ($.countdown._get(inst, - (compact ? 'compactLabels' : 'labels') + inst._periods[index]) || + (compact ? 'compactLabels' : 'labels') + whichLabels(inst._periods[index])) || labels)[index]; }; var digit = function(value, position) { @@ -550,10 +573,11 @@ $.extend(Countdown.prototype, { s1000: digit(inst._periods[S], 1000)}; var html = layout; // Replace period containers: {p<}...{p>} - for (var i = 0; i < 7; i++) { + for (var i = Y; i <= S; i++) { var period = 'yowdhms'.charAt(i); var re = new RegExp('\\{' + period + '<\\}(.*)\\{' + period + '>\\}', 'g'); - html = html.replace(re, (show[i] ? '$1' : '')); + html = html.replace(re, ((!significant && show[i]) || + (significant && showSignificant[i]) ? '$1' : '')); } // Replace period values: {pn} $.each(subs, function(n, v) { @@ -592,14 +616,15 @@ $.extend(Countdown.prototype, { show[S] = (format.match('s') ? '?' : (format.match('S') ? '!' : null)); return show; }, - + /* Calculate the requested periods between now and the target time. - @param inst (object) the current settings for this instance - @param show (string[7]) flags indicating which periods are requested/required - @param now (Date) the current date and time + @param inst (object) the current settings for this instance + @param show (string[7]) flags indicating which periods are requested/required + @param significant (number) the number of periods with values to show, zero for all + @param now (Date) the current date and time @return (number[7]) the current time periods (always positive) by year, month, week, day, hour, minute, second */ - _calculatePeriods: function(inst, show, now) { + _calculatePeriods: function(inst, show, significant, now) { // Find endpoints inst._now = now; inst._now.setMilliseconds(0); @@ -637,25 +662,17 @@ $.extend(Countdown.prototype, { periods[Y] = (show[Y] ? Math.floor(months / 12) : 0); periods[O] = (show[O] ? months - periods[Y] * 12 : 0); // Adjust for months difference and end of month if necessary - var adjustDate = function(date, offset, last) { - var wasLastDay = (date.getDate() == last); - var lastDay = $.countdown._getDaysInMonth(date.getFullYear() + offset * periods[Y], - date.getMonth() + offset * periods[O]); - if (date.getDate() > lastDay) { - date.setDate(lastDay); - } - date.setFullYear(date.getFullYear() + offset * periods[Y]); - date.setMonth(date.getMonth() + offset * periods[O]); - if (wasLastDay) { - date.setDate(lastDay); - } - return date; - }; - if (inst._since) { - until = adjustDate(until, -1, lastUntil); + now = new Date(now.getTime()); + var wasLastDay = (now.getDate() == lastNow); + var lastDay = $.countdown._getDaysInMonth(now.getFullYear() + periods[Y], + now.getMonth() + periods[O]); + if (now.getDate() > lastDay) { + now.setDate(lastDay); } - else { - now = adjustDate(new Date(now.getTime()), +1, lastNow); + now.setFullYear(now.getFullYear() + periods[Y]); + now.setMonth(now.getMonth() + periods[O]); + if (wasLastDay) { + now.setDate(lastDay); } } var diff = Math.floor((until.getTime() - now.getTime()) / 1000); @@ -688,6 +705,16 @@ $.extend(Countdown.prototype, { max *= multiplier[period]; } } + if (significant) { // Zero out insignificant periods + for (var period = Y; period <= S; period++) { + if (significant && periods[period]) { + significant--; + } + else if (!significant) { + periods[period] = 0; + } + } + } return periods; } });