1/** 2 * DLsite ã«ã¦ã³ããã¦ã³è¡¨ç¤º 3 * 4 * ã«ã¦ã³ããã¦ã³è¡¨ç¤ºã¨ã?ããã¿ã³ã®å®è£ ï¼ãã¼ã«ã¢ãã¡ã¼ã·ã§ã³ä»ãï¼ 5 */ 6(function () { 7 'use strict'; 8 9 // === 宿°å®ç¾© === 10 11 // 表示æéï¼JSTï¼ 12 const START_DATE = new Date('2026-04-01T00:00:00+09:00'); 13 const END_DATE = new Date('2026-11-02T14:00:00+09:00'); 14 15 // ã«ã¦ã³ããã¦ã³é ç½®å¤æ´æ¥æï¼JSTï¼ 16 const MOVE_DATE = new Date('2026-04-02T00:00:00+09:00'); 17 18 // ãããã°ç¨æå»ãªãã»ãã 19 const TIME_OFFSET = (function () { 20 if (!/(?:^|;\s*)dlsite_debug=1/.test(document.cookie)) { 21 return 0; 22 } 23 const params = new URLSearchParams(window.location.search); 24 const time_param = params.get('time'); 25 if (!time_param || !/^\d{12}$/.test(time_param)) { 26 return 0; 27 } 28 const y = time_param.slice(0, 4); 29 const m = time_param.slice(4, 6); 30 const d = time_param.slice(6, 8); 31 const h = time_param.slice(8, 10); 32 const min = time_param.slice(10, 12); 33 const debug_date = new Date(`${y}-${m}-${d}T${h}:${min}:00+09:00`); 34 if (isNaN(debug_date.getTime())) { 35 return 0; // ç¡å¹ãªæ¥ä»ã®å ´åã¯ãªãã»ãããªã 36 } 37 return debug_date.getTime() - Date.now(); 38 })(); 39 40 // å¤è¨èªå¯¾å¿ï¼Xæç¨¿ããã¹ãï¼ 41 // cspell:disable 42 const SHARE_TEXT = { 43 'ja-jp': 'ãã®ã«ã¦ã³ããã¦ã³ã¯ä½ï¼\n#DLsiteã«ã¦ã³ããã¦ã³', 44 'en-us': 'Anyone know what this countdown is about?\n#DLsiteCountDown', 45 'zh-cn': 'è¿æ¯ä»ä¹çå计æ¶ï¼\n#DLsiteå计æ¶', 46 'zh-tw': '鿝ä»éº¼åæ¸ï¼\n#DLsiteåæ¸è¨æ', 47 'ko-kr': 'ì¨ ì¹´ì´í¸ë¤ì´ì¼ê¹ì?\n#DLsiteì¹´ì´í¸ë¤ì´', 48 }; 49 // cspell:enable 50 51 // Xæç¨¿URLï¼ããã¼ãã¼ã¸çµç±ã§OGPåºãåãï¼ 52 const SHARE_URL = 'https://dlsharing.com/modpub/lp/home/countdown/'; 53 54 // ãªã¼ã«ã¢ãã¡ã¼ã·ã§ã³è¨å® 55 const DIGIT_HEIGHT = 24; // 1æ¡ãããã®é«ãï¼pxï¼= line-height 56 const UNITS = [3, 2, 2, 2]; // æ¥(3æ¡), æ(2æ¡), å(2æ¡), ç§(2æ¡) 57 58 // ãªã¼ã«ç¨ã¹ã¿ã¤ã«å®æ° 59 // cspell:disable-next-line 60 const FONT_STYLE = '\'Familjen Grotesk\', Arial, sans-serif'; 61 const TEXT_COLOR = '#0b2a83'; 62 63 // === ã°ãã¼ãã«å¤æ° === 64 let countdown_interval = null; 65 let reels_map = new Map(); // ã³ã³ãããã¨ã®ãªã¼ã«é åã管ç Map<Element, Array> 66 let is_built = false; // ãªã¼ã«DOMæ§ç¯æ¸ã¿ãã©ã° 67 68 // === 颿°å®ç¾© === 69 70 /** 71 * ç¾å¨æå»ãåå¾ï¼ãããã°ç¨ ?time= ãããã°ãªãã»ãããå ç®ï¼ 72 * @returns {Date} 73 */ 74 function getNow() { 75 return new Date(Date.now() + TIME_OFFSET); 76 } 77 78 /** 79 * ãã±ã¼ã«å¤å® 80 * @returns {string} ãã±ã¼ã«æååï¼ä¾: 'ja-jp'ï¼ 81 */ 82 function getLocale() { 83 const cookies = document.cookie.split('; '); 84 for (let i = 0; i < cookies.length; i++) { 85 const cookie = cookies[i].split('='); 86 if (cookie[0] === 'locale') { 87 const locale = decodeURIComponent(cookie[1]); 88 if (/^[a-z]{2}-[a-z]{2}$/i.test(locale)) { 89 return locale.toLowerCase(); 90 } 91 } 92 } 93 94 // fallback 1: window.dlsite.getLocale() 95 if (window.dlsite && typeof window.dlsite.getLocale === 'function') { 96 return window.dlsite.getLocale(); 97 } 98 99 // fallback 2: <html lang="..."> 屿§ããåå¾ 100 const html_lang = document.documentElement.lang || 'ja-jp'; 101 return html_lang.toLowerCase(); 102 } 103 104 /** 105 * Xæç¨¿ããã¹ãåå¾ï¼å¤è¨èªå¯¾å¿ï¼ 106 * @returns {string} Xæç¨¿ç¨ããã¹ã 107 */ 108 function getShareText() { 109 const locale = getLocale(); 110 return SHARE_TEXT[locale] || SHARE_TEXT['en-us']; // 主è¦5è¨èªä»¥å¤ã¯è±èª 111 } 112 113 /** 114 * Xæç¨¿URLçæ 115 * @returns {string} Xæç¨¿ãã©ã¼ã URL 116 */ 117 function generateShareURL() { 118 const text = encodeURIComponent(getShareText()); 119 const url = encodeURIComponent(SHARE_URL); 120 return `https://x.com/intent/tweet?text=${text}&url=${url}`; 121 } 122 123 /** 124 * 表示æéå¤å® 125 * @returns {boolean} 表示æéå ã§ããã°true 126 */ 127 function checkVisibility() { 128 const now = getNow(); 129 return now >= START_DATE && now < END_DATE; 130 } 131 132 /** 133 * ã«ã¦ã³ããã¦ã³è¨ç® 134 * @returns {Object|null} { days, hours, minutes, seconds } ã¾ã㯠nullï¼è¡¨ç¤ºæéå¤ï¼ 135 */ 136 function calculateCountdown() { 137 if (!checkVisibility()) { 138 return null; 139 } 140 141 const now = getNow(); 142 const diff = END_DATE - now; // ããªç§åä½ã®å·®å 143 144 if (diff <= 0) { 145 return null; // ã«ã¦ã³ããã¦ã³çµäº 146 } 147 148 const seconds = Math.floor((diff / 1000) % 60); 149 const minutes = Math.floor((diff / 1000 / 60) % 60); 150 const hours = Math.floor((diff / 1000 / 60 / 60) % 24); 151 const days = Math.floor(diff / 1000 / 60 / 60 / 24); 152 153 return { days, hours, minutes, seconds }; 154 } 155 156 /** 157 * ãªã¼ã«DOMãæ§ç¯ï¼ååã®ã¿ï¼ 158 * åæ¡ã«0ã9ã縦ã«ä¸¦ã¹ããªã¼ã«ã使ããoverflow:hiddenã§1æ¡åã ã表示ãã 159 * â» SCSSãã«ãä¸è¦ã§åä½ããããã¤ã³ã©ã¤ã³ã¹ã¿ã¤ã«ã§å®çµ 160 */ 161 function buildReels() { 162 if (is_built) { 163 return; 164 } 165 166 const text_containers = document.querySelectorAll('[data-countdown="text"]'); 167 if (text_containers.length === 0) { 168 return; 169 } 170
171 text_containers.forEach(function (text_container) { 172 text_container.textContent = ''; // åæããã¹ããã¯ãªã¢ 173 text_container.style.display = 'inline-flex'; 174 text_container.style.alignItems = 'center'; 175 text_container.style.gap = '2.4px'; 176 177 const container_reels = []; 178 179 UNITS.forEach(function (digits, ui) { 180 for (let i = 0; i < digits; i++) { 181 // æ¡ã®æ ï¼ã¯ã¿åºãæ°åãé ãï¼ 182 const wrap = document.createElement('span'); 183 wrap.style.display = 'inline-block'; 184 wrap.style.height = DIGIT_HEIGHT + 'px'; 185 wrap.style.overflow = 'hidden'; 186 187 // 0ã9ã縦ã«ä¸¦ã¹ããªã¼ã« 188 const reel = document.createElement('span'); 189 reel.style.display = 'block'; 190 reel.style.transition = 'transform 0.35s cubic-bezier(0.4, 0, 0.2, 1)'; 191 for (let n = 0; n <= 9; n++) { 192 const s = document.createElement('span'); 193 s.textContent = n; // XSS対ç: textContentä½¿ç¨ 194 s.style.display = 'block'; 195 s.style.height = DIGIT_HEIGHT + 'px'; 196 s.style.lineHeight = DIGIT_HEIGHT + 'px'; 197 s.style.fontFamily = FONT_STYLE; 198 s.style.fontSize = '24px'; 199 s.style.textAlign = 'center'; 200 s.style.color = TEXT_COLOR; 201 reel.appendChild(s); 202 } 203 204 wrap.appendChild(reel); 205 text_container.appendChild(wrap); 206 container_reels.push({ reel: reel, current: -1 }); 207 } 208 209 // ã¦ãããéã«ã³ãã³åºåãã追å 210 if (ui < UNITS.length - 1) { 211 const sep = document.createElement('span'); 212 sep.style.fontFamily = FONT_STYLE; 213 sep.style.fontSize = '24px'; 214 sep.style.lineHeight = DIGIT_HEIGHT + 'px'; 215 sep.style.color = TEXT_COLOR; 216 sep.textContent = ':'; 217 text_container.appendChild(sep); 218 } 219 }); 220 221 reels_map.set(text_container, container_reels); 222 }); 223 224 is_built = true; 225 } 226 227 /** 228 * æå®æ¡ã®ãªã¼ã«ãã¹ã¯ãã¼ã«ï¼å¤ãå¤ãã£ãã¨ãã ãã¢ãã¡ã¼ã·ã§ã³ï¼ 229 * @param {Array} reels ãªã¼ã«é å 230 * @param {number} idx ãªã¼ã«ã®ã¤ã³ããã¯ã¹ 231 * @param {number} val 表示ããæ°åï¼0ã9ï¼ 232 */ 233 function setDigit(reels, idx, val) { 234 const r = reels[idx]; 235 if (r.current === val) { 236 return; // å¤ãå¤ãã£ã¦ããªããã°ä½ãããªã 237 } 238 r.current = val; 239 r.reel.style.transform = 'translateY(' + (val * -DIGIT_HEIGHT) + 'px)'; 240 } 241 242 /** 243 * ã«ã¦ã³ããã¦ã³ãã¼ã¿ãåæ¡ã«åæ 244 * @param {Object} data { days, hours, minutes, seconds } 245 */ 246 function renderReels(data) { 247 const parts = [data.days, data.hours, data.minutes, data.seconds]; 248 249 // åã³ã³ããã®ãªã¼ã«ãæ´æ° 250 reels_map.forEach(function (reels) { 251 let ri = 0; 252 UNITS.forEach(function (digits, ui) { 253 const str = String(parts[ui]).padStart(digits, '0'); 254 for (let ci = 0; ci < str.length; ci++) { 255 setDigit(reels, ri++, +str[ci]); 256 } 257 }); 258 }); 259 } 260 261 /** 262 * ã«ã¦ã³ããã¦ã³è¡¨ç¤ºæ´æ° 263 */ 264 function updateDisplay() { 265 const countdown_data = calculateCountdown(); 266 const containers = document.querySelectorAll('[data-countdown="container"]'); 267 268 if (containers.length === 0) { 269 return; // ã³ã³ãããåå¨ããªãå ´åã¯ä½ãããªã 270 } 271 272 if (!countdown_data) { 273 // 表示æéå¤ or ã«ã¦ã³ããã¦ã³çµäº 274 containers.forEach(function (container) { 275 container.style.display = 'none'; 276 }); 277 cleanup(); 278 return; 279 } 280 281 // 表示æéå - ãã¹ã¦ã®ã³ã³ããã表示 282 containers.forEach(function (container) { 283 container.style.display = ''; 284 }); 285 286 // ãªã¼ã«DOMæ§ç¯ï¼ååã®ã¿ï¼ 287 buildReels(); 288 289 // ãªã¼ã«ã¢ãã¡ã¼ã·ã§ã³ã§ã«ã¦ã³ããã¦ã³è¡¨ç¤ºæ´æ° 290 renderReels(countdown_data); 291 292 // Xæç¨¿ãªã³ã¯ã®hrefæ´æ° - ãã¹ã¦ã®ãªã³ã¯ãæ´æ° 293 const share_links = document.querySelectorAll('[data-countdown="share"]'); 294 share_links.forEach(function (share_link) { 295 share_link.href = generateShareURL(); 296 }); 297 } 298 299 /** 300 * æ¥ä»ã«å¿ãã¦ã«ã¦ã³ããã¦ã³ã®è¡¨ç¤ºä½ç½®ãèª¿æ´ 301 * PCç: .inner_creator ã®ç´å¾ 302 * SPç: ul.index_floor_link.creator ã®ç´å¾ 303 */ 304 function positionCountdowns() { 305 const now = getNow(); 306 if (now < MOVE_DATE) { 307 return; 308 } 309 310 // ã¯ãªã¨ã¤ã¿ã¼åãã»ã¯ã·ã§ã³ã®ç´å¾ã«ç§»å 311 const countdown_elements = document.querySelectorAll('[data-countdown="container"]');
312 countdown_elements.forEach(function (countdown_element) { 313 const parent = countdown_element.parentElement; 314 if (!parent) { 315 return; 316 } 317 // PCç: .inner_creator ã®ç´å¾ 318 const inner_creator = parent.querySelector('.inner_creator'); 319 if (inner_creator) { 320 inner_creator.insertAdjacentElement('afterend', countdown_element); 321 return; 322 } 323 // SPç: ul.index_floor_link.creator ã®ç´å¾ 324 const sp_creator = parent.querySelector('ul.index_floor_link.creator'); 325 if (sp_creator) { 326 sp_creator.insertAdjacentElement('afterend', countdown_element); 327 } 328 }); 329 } 330 331 /** 332 * ã«ã¦ã³ããã¦ã³åæå 333 */ 334 function initCountdown() { 335 // æ¥ä»ã«å¿ããé ç½®èª¿æ´ 336 positionCountdowns(); 337 338 // ååè¡¨ç¤ºæ´æ° 339 updateDisplay(); 340 341 // 1ç§ãã¨ã«è¡¨ç¤ºæ´æ° 342 countdown_interval = setInterval(updateDisplay, 1000); 343 } 344 345 /** 346 * ã¯ãªã¼ã³ã¢ããï¼ã¡ã¢ãªãªã¼ã¯é²æ¢ï¼ 347 */ 348 function cleanup() { 349 if (countdown_interval) { 350 clearInterval(countdown_interval); 351 countdown_interval = null; 352 } 353 } 354 355 // === å®è¡ === 356 357 // DOMContentLoadedå¾ã«èªåå®è¡ 358 if (document.readyState === 'loading') { 359 document.addEventListener('DOMContentLoaded', initCountdown); 360 } else {
361 initCountdown(); 362 } 363 364 // ãã¼ã¸é¢è±æã«ã¯ãªã¼ã³ã¢ããï¼ã¡ã¢ãªãªã¼ã¯é²æ¢ï¼ 365 window.addEventListener('beforeunload', cleanup); 366})();
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.