1import { common } from '../core/core.js'; 2import { setShowMoreOnSp } from './ShowMoreOnSp.js'; 3 4const { lang: langType } = common; 5const blankSvg = `<svg class="m-link__icon" viewBox="0 0 100 100" role="img"><title>${langType === 'ja' ? 'å¥ã¦ã£ã³ãã¦ã§éã' : 'Open in a new window'}</title><use href="#icon-windowRed"></use></svg>`; 6const pdfSvg = `<svg class="m-link__icon" viewBox="0 0 100 100" role="img"><title>${langType === 'ja' ? 'PDFãã¡ã¤ã«ãéã' : 'open the PDF file'}</title><use href="#icon-filePdf"></use></svg>`; 7 8/** 9 * JSONæ å ±ãåå¾ 10 * 11 * @param {string} path 12 * @param {RequestInit} [option] fetchã®ç¬¬2弿°ã§æå®ãããªãã·ã§ã³ãåå¥ã«æå®ã追å ãããå ´å 13 */ 14const fetchJson = async (path, option = {}) => { 15 const timeoutController = new AbortController(); 16 const timeoutSeconds = 3000; 17 const timeout = window.setTimeout(() => { 18 timeoutController.abort(); 19 }, timeoutSeconds); 20 21 try { 22 const res = await fetch(path, { 23 method: 'GET', 24 signal: timeoutController.signal, 25 cache: 'no-cache', 26 ...option, 27 }); 28 29 if (!res.ok) { 30 throw new Error( 31 langType === 'ja' 32 ? 'ãã¼ã¿ãåå¾ã§ãã¾ããã§ãã' 33 : 'Unable to load news' 34 ); 35 } 36 37 /** @type {TopNewsReleaseInfo} */ 38 const resJson = await res.json(); 39 40 return resJson; 41 } finally { 42 window.clearTimeout(timeout); 43 } 44}; 45 46/** 47 * ãã¥ã¼ã¹ãªãªã¼ã¹ã¨ãªã¢ã®åºåã宿½ 48 * 49 * @export 50 * @class RenderNewsRelease 51 */ 52export class RenderNewsRelease { 53 /** 54 * @param {HTMLElement} renderRoot 55 * @memberof RenderNewsRelease 56 */ 57 constructor(renderRoot) { 58 /** @type {HTMLElement} */ 59 this.renderRoot = renderRoot; 60 /** @type {HTMLTemplateElement | null} */ 61 this.renderTemplate = this.renderRoot.querySelector( 62 '.js-render-news__template' 63 ); 64 /** @type {HTMLTemplateElement | null} */ 65 this.renderTemplateError = this.renderRoot.querySelector( 66 '.js-render-news__error' 67 ); 68 /** @type {string} */ 69 this.jsonPath = 70 langType === 'ja' 71 ? '/jp/newsroom/release/inc/top_newsrelease.json' 72 : '/en/newsroom/release/inc/top_newsrelease.json'; 73 /** @type {TopNewsReleaseInfo} */ 74 this.jsonData = {}; 75 /** @type {Object<string, string[]>} */ 76 this.category = { 77 '01': ['m-badge--ir', 'IR', 'IR'], 78 '02': ['m-badge--csv', 'CSV', 'CSV'], 79 '03': ['m-badge--product', 'ååã»ãµã¼ãã¹', 'Products and Services'], 80 '04': ['m-badge--other', 'ãã£ã³ãã¼ã³', 'Marketing Campaigns'], 81 '05': ['m-badge--technology', 'ç ç©¶ã»æè¡', 'Research and Technology'], 82 '06': ['m-badge--other', '調æ»', '調æ»'], 83 '07': ['m-badge--hr', '人äº', 'Human Resources'], 84 '08': ['m-badge--other', 'ãã®ä»', 'Other'], 85 }; 86 } 87 88 async init() { 89 if (!this.renderTemplate || !this.renderTemplateError) { 90 return; 91 } 92 93 try { 94 this.jsonData = await fetchJson(this.jsonPath); 95 } catch (e) { 96 this.renderError(e.message); 97 } 98 99 if (this.jsonData.length === 0) { 100 this.renderError( 101 langType === 'ja' ? 'ç¾å¨ãã¥ã¼ã¹ã¯ããã¾ãã' : 'No news to display' 102 ); 103 104 return; 105 } 106 107 this.render(this.jsonData); 108 } 109 110 /** 111 * å¹´è¡¨è¨æååãåå¾ 112 * 113 * @static 114 * @param {string} baseFormat æ¥ä»æ å ±æååï¼yyyy-MM-dd HH:mm:sså½¢å¼ï¼ 115 * @param {string} lang è¨èªã¿ã¤ã 116 * @return {{dateText: string, datetime: string}} åºåãã©ã¼ãããã«å¯¾å¿ããæ å ± 117 */ 118 static getFormattedDateString(baseFormat, lang = 'ja') { 119 const date = new Date(baseFormat); 120 const YEAR = String(date.getFullYear()); 121 const MONTH = String(date.getMonth() + 1); 122 const DAY = String(date.getDate()); 123 const MONTH_EN = [ 124 'January', 125 'February', 126 'March', 127 'April', 128 'May', 129 'June', 130 'July', 131 'August', 132 'September', 133 'October', 134 'November', 135 'December', 136 ][date.getMonth()];
137 const textFormat = 138 lang === 'ja' 139 ? `${YEAR}å¹´${MONTH}æ${DAY}æ¥` 140 : `${MONTH_EN} ${DAY}, ${YEAR}`; 141 142 return { 143 dateText: textFormat, 144 datetime: `${YEAR}-${MONTH.padStart(2, '0')}-${DAY.padStart(2, '0')}`, 145 }; 146 } 147 148 /** 149 * ãã¥ã¼ã¹ãªãªã¼ã¹æ å ±ã®åºå 150 * 151 * @param {TopNewsReleaseInfo} renderData 152 */ 153 render(renderData) { 154 /** @type {HTMLElement} */ 155 const clone = this.renderTemplate.content.cloneNode(true); 156 /** @type {HTMLElement | null} */ 157 const list = clone.querySelector('.js-render-news__list'); 158 /** @type {HTMLElement | null} */ 159 const listItem = clone.querySelector('.js-render-news__listItem'); 160 161 if (!list && !listItem) { 162 this.renderError( 163 langType === 'ja' 164 ? 'ãã¥ã¼ã¹ã表示ã§ãã¾ããã§ãã' 165 : 'Unable to display news.' 166 ); 167 168 return; 169 } 170 171 if (renderData.kh_sitetop.length === 0) { 172 this.renderError( 173 langType === 'ja' ? 'ç¾å¨ãã¥ã¼ã¹ã¯ããã¾ãã' : 'No news to display' 174 ); 175 176 return; 177 } 178 179 for (const data of renderData.kh_sitetop) { 180 /** @type {HTMLElement} */ 181 const listItemClone = listItem.cloneNode(true); 182 /** @type {HTMLAnchorElement | null} */ 183 const link = listItemClone.querySelector('.js-render-news__link'); 184 /** @type {HTMLElement | null} */ 185 const linkText = listItemClone.querySelector('.js-render-news__linkText'); 186 /** @type {HTMLTimeElement | null} */ 187 const releaseDate = listItemClone.querySelector('.js-render-news__date'); 188 /** @type {HTMLElement | null} */ 189 const listLabel = listItemClone.querySelector( 190 '.js-render-news__listLabel' 191 ); 192 const listLabelItem = listItemClone.querySelector( 193 '.js-render-news__listLabelItem' 194 ); 195 196 if (!link || !linkText || !releaseDate || !listLabel || !listLabelItem) { 197 this.renderError(); 198 199 break; 200 } 201 202 link.setAttribute('href', data.link); 203 linkText.textContent = data.title; 204 205 if (data.target === '_blank') { 206 link.setAttribute('target', '_blank'); 207 } 208 209 if (data.filesize) { 210 linkText.textContent = `${data.title} ${data.filesize}`; 211 linkText.insertAdjacentHTML('afterend', pdfSvg); 212 } else if (data.target === '_blank') { 213 linkText.insertAdjacentHTML('afterend', blankSvg); 214 } 215 216 const { dateText, datetime } = RenderNewsRelease.getFormattedDateString( 217 data.date, 218 langType 219 ); 220 221 releaseDate.textContent = dateText; 222 releaseDate.setAttribute('datetime', datetime); 223 224 // ã«ãã´ãªæ å ± 225 for (const category of data.categories) { 226 if (!(category in this.category)) { 227 continue; 228 } 229 230 const [categoryColorType, categoryText, categoryTextGlobal] = 231 this.category[category]; 232 const listLabelItemClone = listLabelItem.cloneNode(true); 233 /** @type {HTMLElement | null} */ 234 const listLabelText = listLabelItemClone.querySelector( 235 '.js-render-news__listLabelText' 236 ); 237 238 if (!listLabelText) { 239 continue; 240 } 241 242 listLabelText.textContent = 243 langType === 'ja' ? categoryText : categoryTextGlobal; 244 listLabelText.classList.add(categoryColorType); 245 246 listLabel.append(listLabelItemClone); 247 } 248 249 listLabelItem.remove(); // 復å å ã®ãªã¹ãåé¤ 250 list.append(listItemClone); 251 } 252 253 listItem.remove(); // è¤è£½å ã®ãªã¹ãåé¤ 254 this.renderTemplate.replaceWith(clone); 255 this.renderRoot.classList.add('is-rendered'); 256 } 257 258 /** 259 * ã¨ã©ã¼æ å ±åºå 260 * @param {string} errorText 261 */ 262 renderError(errorText) { 263 /** @type {HTMLElement} */ 264 const clone = this.renderTemplateError.content.cloneNode(true); 265 const label = clone.querySelector('.js-render-news__errorText'); 266 267 if (label) { 268 label.textContent = errorText; 269 } 270 271 this.renderRoot.innerHTML = ''; 272 this.renderRoot.append(clone); 273 } 274} 275 276/** 277 * éè¦ãªãç¥ããã¨ãªã¢ã®åºåã宿½ 278 * 279 * @export 280 * @class RenderImportantTopics 281 */ 282export class RenderImportantTopics { 283 /** 284 * @param {HTMLElement} renderRoot 285 * @memberof RenderNewsRelease 286 */ 287 constructor(renderRoot) { 288 /** @type {HTMLElement} */ 289 this.renderRoot = renderRoot; 290 /** @type {HTMLTemplateElement | null} */ 291 this.renderTemplate = this.renderRoot.querySelector( 292 '.js-render-important__template' 293 ); 294 /** @type {HTMLTemplateElement | null} */ 295 this.renderTemplateError = this.renderRoot.querySelector( 296 '.js-render-important__error' 297 ); 298 /** @type {string} */ 299 this.jsonPath = 300 langType === 'ja' 301 ? 'https://info.kirinholdings.com/parts/multi_faq_for_json.php?category=2001&num=50' 302 : 'https://info.kirinholdings.com/parts/multi_faq_for_json.php?category=2002&num=50&_=1748912240765'; 303 /** @type {TopImportantTopicsInfo} */ 304 this.jsonData = {}; 305 this.showMoreOnSpElement = 306 this.renderRoot.querySelector('.js-showMoreOnSp'); 307 } 308
309 async init() { 310 try { 311 this.jsonData = await fetchJson(this.jsonPath); 312 313 if (this.jsonData.length === 0) { 314 this.renderError(); 315 316 return; 317 } 318 319 this.render(this.jsonData); 320 } catch { 321 this.renderError(); 322 } 323 } 324 325 /** 326 * å¹´è¡¨è¨æååãåå¾ 327 * 328 * @static 329 * @param {string} baseFormat æ¥ä»æ å ±æååï¼yyyy-MM-dd HH:mm:sså½¢å¼ï¼ 330 * @param {string} lang è¨èªã¿ã¤ã 331 * @return {{dateText: string, datetime: string}} åºåãã©ã¼ãããã«å¯¾å¿ããæ å ± 332 */ 333 static getFormattedDateString(baseFormat, lang = 'ja') { 334 let datetimeFormat = ''; 335 336 switch (lang) { 337 case 'ja': { 338 const [yearText, monthText, dayText] = baseFormat 339 .replace(/[å¹´æ]/gu, '-') 340 .replace('æ¥', '') 341 .split('-'); 342 343 datetimeFormat = `${yearText}-${monthText.padStart(2, '0')}-${dayText.padStart(2, '0')}`; 344 break; 345 } 346 case 'en': { 347 // ex) 'May 13, 2025' â ['May', '13', '2025'] 348 const [monthEnText, dayEnText, yearEnText] = baseFormat 349 .replace(/,/gu, '') 350 .replace(/\s/gu, ',') 351 .split(','); 352 const monthMap = { 353 January: '01', 354 February: '02', 355 March: '03', 356 April: '04', 357 May: '05', 358 June: '06', 359 July: '07', 360 August: '08', 361 September: '09', 362 October: '10', 363 November: '11', 364 December: '12', 365 }; 366 367 datetimeFormat = `${yearEnText}-${monthMap[monthEnText]}-${dayEnText.padStart(2, '0')}`; 368 break; 369 } 370 default: 371 break; 372 } 373 374 return { 375 dateText: baseFormat, 376 datetime: datetimeFormat, 377 }; 378 } 379 380 /** 381 * 対象è¦ç´ ã®ã¬ã³ããªã³ã° 382 * 383 * @param {TopImportantTopicsInfo[]} renderData 384 */ 385 render(renderData) { 386 /** @type {HTMLElement} */ 387 const clone = this.renderTemplate.content.cloneNode(true); 388 /** @type {HTMLElement | null} */ 389 const list = clone.querySelector('.js-render-important__list'); 390 /** @type {HTMLElement | null} */ 391 const listItem = clone.querySelector('.js-render-important__listItem'); 392 393 if (!list && !listItem) { 394 this.renderError(); 395 396 return; 397 } 398 399 for (const data of renderData) { 400 /** @type {HTMLElement} */ 401 const listItemClone = listItem.cloneNode(true); 402 const releaseDate = listItemClone.querySelector( 403 '.js-render-important__date' 404 ); 405 const link = listItemClone.querySelector('.js-render-important__link'); 406 const linkText = listItemClone.querySelector( 407 '.js-render-important__linkText' 408 ); 409 410 if (!releaseDate && !link && !linkText && !releaseDate) { 411 this.renderError(); 412 413 break; 414 } 415 416 linkText.textContent = data.title; 417 link.setAttribute('href', data.link); 418 419 if (data.target === '_blank') { 420 link.setAttribute('target', '_blank'); 421 422 if (!data.pdf) { 423 linkText.insertAdjacentHTML('afterend', blankSvg); 424 } else { 425 linkText.insertAdjacentHTML('afterend', pdfSvg); 426 } 427 } 428 429 const { dateText, datetime } = 430 RenderImportantTopics.getFormattedDateString(data.date, langType); 431 432 releaseDate.textContent = dateText; 433 releaseDate.setAttribute('datetime', datetime); 434 435 list.append(listItemClone); 436 } 437 438 listItem.remove(); 439 this.renderTemplate.replaceWith(clone); 440 this.renderRoot.classList.add('is-rendered'); 441 442 if (this.showMoreOnSpElement) { 443 setShowMoreOnSp(this.showMoreOnSpElement); 444 } 445 } 446 447 renderError() { 448 this.renderRoot.remove(); 449 } 450}
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.