1;(function (window, document, $, moment, undefined) { 2 'use strict'; 3 4 var INTERVAL_NONE = 'none'; 5 var INTERVAL_DAILY = 'daily'; 6 var INTERVAL_MONTHLY = 'monthly'; 7 8 /** 9 * @param {number} number 10 * @param {number} [width=2] 11 * @param {string} [pad='0'] 12 * 13 * @returns {string} 14 */ 15 function pad(number, width, pad) { 16 var _number = '' + number; 17 var _width = width || 2; 18 var _pad = pad || '0'; 19 20 return (_number.length >= width) ? _number : Array.apply(null, Array(_width - _number.length + 1)).join(_pad) + _number; 21 } 22 23 var CountDownTimer = (function () { 24 /** 25 * @param {jQuery} $element 26 * @param {string} expiredAtString 27 * @param {string} interval 28 * @param {boolean} invert 29 * 30 * @constructor 31 */ 32 function Counter($element, expiredAtString, interval, invert) { 33 var now = moment(); 34 var expiredAt = moment(expiredAtString); 35 var _expiredAt; 36 37 this._$element = $element; 38 this._interval = interval; 39 this._invert = !!invert; 40 41 switch (this._interval) { 42 case INTERVAL_DAILY: 43 _expiredAt = expiredAt.clone(); 44 45 _expiredAt.year(now.year()); 46 _expiredAt.month(now.month()); 47 _expiredAt.date(now.date()); 48 49 break; 50 51 case INTERVAL_MONTHLY: 52 _expiredAt = expiredAt.clone(); 53 54 _expiredAt.year(now.year()); 55 _expiredAt.month(now.month()); 56 57 break; 58 59 case INTERVAL_NONE: 60 default: 61 _expiredAt = expiredAt.clone(); 62 63 break; 64 } 65 66 this._expiredAt = _expiredAt; 67 this._timerId = null; 68 } 69 70 /** 71 * @private 72 * 73 * @param {Object} timer 74 */ 75 Counter.prototype._updateTimer = function (timer) { 76 var $itemDay = this._$element.find('[data-st-countdown-item-day]'); 77 var $countDay = this._$element.find('[data-st-countdown-count-day]'); 78 var $countHour = this._$element.find('[data-st-countdown-count-hour]'); 79 var $countMinute = this._$element.find('[data-st-countdown-count-minute]'); 80 var $countSecond = this._$element.find('[data-st-countdown-count-second]'); 81 var $countMs = this._$element.find('[data-st-countdown-count-ms]'); 82 83 if ($itemDay.length) { 84 if (timer.day > 0) { 85 $itemDay.show(); 86 } else { 87 $itemDay.hide(); 88 } 89 } 90 91 if ($countDay.length) { 92 $countDay.text(timer.day); 93 } 94 95 if ($countHour.length) { 96 $countHour.text(pad(timer.hour)); 97 } 98 99 if ($countMinute.length) { 100 $countMinute.text(pad(timer.minute)); 101 } 102 103 if ($countSecond.length) { 104 $countSecond.text(pad(timer.second)); 105 } 106 107 if ($countMs.length) { 108 $countMs.text(pad(timer.ms)); 109 } 110 }; 111 112 /** 113 * @returns {boolean} 114 */ 115 Counter.prototype.onTick = function () { 116 var now = moment(); 117 var diff = this._expiredAt.diff(now); 118 var $expired = this._$element.find('[data-st-countdown-expired]'); 119 120 var timer = { 121 day : Math.max(0, Math.floor(diff / (24 * 60 * 60 * 1000))), 122 hour : Math.max(0, Math.floor((diff % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000))), 123 minute: Math.max(0, Math.floor((diff % (24 * 60 * 60 * 1000)) / (60 * 1000)) % 60), 124 second: Math.max(0, Math.floor((diff % (24 * 60 * 60 * 1000)) / 1000) % 60 % 60), 125 ms : Math.max(0, Math.floor((diff % (24 * 60 * 60 * 1000)) / 10) % 100) 126 }; 127 128 this._updateTimer(timer); 129 130 if (diff > 0) { 131 this._$element.removeClass('is-expired') 132 .addClass('is-active'); 133 134 if (this._invert) { 135 $expired.show(); 136 } else { 137 $expired.hide(); 138 } 139 140 return true; 141 } 142 143 switch (this._interval) { 144 case INTERVAL_DAILY: 145 this._expiredAt = this._expiredAt.clone().add(1, 'day'); 146 147 return true; 148 149 case INTERVAL_MONTHLY: 150 this._expiredAt = this._expiredAt.clone().add(1, 'month'); 151 152 return true; 153 154 case INTERVAL_NONE: 155 default: 156 this._$element.removeClass('is-active') 157 .addClass('is-expired'); 158 159 if (this._invert) { 160 $expired.hide(); 161 } else { 162 $expired.show(); 163 } 164 165 break; 166 } 167 168 return false; 169 }; 170 171 Counter.prototype.initialize = function () { 172 var self = this; 173 174 (function tick(interval) { 175 var nextTick; 176 177 clearTimeout(self._timerId); 178 179 nextTick = self.onTick(); 180 181 if (nextTick) { 182 self._timerId = setTimeout(function () { 183 tick(interval) 184 }, interval); 185 } 186 }(10)); 187 }; 188 189 return Counter; 190 }()); 191 192 function onReady() { 193 var timers = []; 194 195 $('[data-st-countdown]').each(function () { 196 var $element = $(this); 197 var expiredAt = $element.attr('data-st-countdown-expired-at'); 198 var interval = $element.attr('data-st-countdown-interval') || INTERVAL_NONE; 199 var invert = ($element.attr('data-st-countdown-invert') === 'true'); 200 201 if (typeof expiredAt === 'undefined') { 202 return; 203 } 204 205 var timer = new CountDownTimer($element, expiredAt, interval, invert); 206 207 timers.push(timer); 208 209 timer.initialize(); 210 }); 211 212 return timers; 213 } 214 215 $(onReady); 216}(window, window.document, jQuery, moment));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.