PageSourceSearch

https://vs-forum.jp/wp-content/themes/affinger/js/st-countdown.js?ver=6.1.1

js vs-forum.jp collected 2026-10-02 18:32:10 UTC 5,111 bytes, 216 lines download raw bytes

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.