PageSourceSearch

https://www.gmo-pg.com/news/js/script.js?ver=202609151625

js gmo-pg.com collected 2026-09-24 08:38:18 UTC 17,670 bytes, 506 lines download raw bytes

1"use strict";
2const POPSTATE_NEWS_ENTRIES = 'popstate:news:entries';
3const NEWS_ENTRIES_JSON = '/news/json/entries_all.json';
4const NEWS_ENTRIES_JSON_EN = '/news/json/entries_all_en.json';
5const ROWS_PER_PAGE = 10;
6const NewsConditionController = class {
7  init() {
8    const { subCategory } = this.getConditionFromParams();
9    if (subCategory) {
10      const subCategoryNodes = document.querySelectorAll('[data-news-condition="subCategory"]');
11      subCategoryNodes.forEach(node => {
12        if (subCategory.includes(node.value))
13          node.checked = true;
14      });
15    }
16  }
17  submit() {
18    const condition = this.getConditionFromForm();
19    const path = this.getNextPath(condition);
20    location.href = path;
21  }
22  changePage(page) {
23    const condition = { ...this.getConditionFromForm(), page };
24    const path = this.getNextPath(condition);
25    location.href = path;
26  }
27  getNextPath(condition) {
28    const url = new URL(window.location.href);
29    const searchParams = new URLSearchParams();
30    if (condition.subCategory && condition.subCategory.length > 0) {
31      searchParams.set('subCategory', condition.subCategory.join(','));
32    }
33    if (condition.page && condition.page > 1) {
34      searchParams.set('page', String(condition.page));
35    }
36    url.search = searchParams.toString();
37
38    const rootPath = location.pathname;
39    if (rootPath.startsWith('/en/')) {
40      const basePath = rootPath.split('/').slice(0, 3 + (condition.category ? 1 : 0)).join('/');
41      return `${basePath}/${condition.year ? `${condition.year}/` : ''}${url.search}`;
42    } else {
43      const basePath = rootPath.split('/').slice(0, 2 + (condition.category ? 1 : 0)).join('/');
44      return `${basePath}/${condition.year ? `${condition.year}/` : ''}${url.search}`;
45    }
46  }
47  getConditionFromForm() {
48    const rootPath = location.pathname;
49    const subCategory = Array.from(document.querySelectorAll('[data-news-condition="subCategory"]')).map(node => node.checked ? node.value : undefined).filter((v) => !!v);
50    const year = Number(document.querySelector('[data-news-condition="year"]')?.value) || undefined;
51
52    if (rootPath.startsWith('/en/')) {
53      const category = Number(location.pathname.split('/').at(3)) ? "" : location.pathname.split('/').at(3);
54      return { category, subCategory, year };
55    } else {
56      const category = Number(location.pathname.split('/').at(2)) ? "" : location.pathname.split('/').at(2);
57      return { category, subCategory, year };
58    }
59  }
60getConditionFromParams() {
61  const params = new URLSearchParams(window.location.search);
62  const rootPath = location.pathname;
63  const paramArgs = rootPath.split('/');
64
65  // CMSから出力されたチェックボックスのvalueだけを許可する
66  const allowedSubCategories = new Set(
67    Array.from(
68      document.querySelectorAll(
69        '[data-news-condition="subCategory"]'
70      ),
71      node =>
71 node.value
72    )
73  );
74
75  const requestedSubCategories = (
76    params.get('subCategory') ?? ''
77  )
78    .split(',')
79    .map(value => value.trim())
80    .filter(value => value !== '');
81
82  // slugとして妥当で、かつ画面上に存在する値だけを採用
83  const subCategory = requestedSubCategories.filter(value => {
84    return (
85      /^[a-zA-Z0-9_-]{1,64}$/.test(value) &&
86      allowedSubCategories.has(value)
87    );
88  });
89
90  // pageは1以上の整数だけを許可する
91  const pageParam = params.get('page') ?? '1';
92
93  const page = /^\d+$/.test(pageParam) &&
94    Number.isSafeInteger(Number(pageParam)) &&
95    Number(pageParam) >= 1
96      ? Number(pageParam)
97      : 1;
98
99  if (rootPath.startsWith('/en/')) {
100    const year =
101      Number(paramArgs.at(4)) ||
102      Number(paramArgs.at(3)) ||
103      undefined;
104
105    const category = Number(paramArgs.at(3))
106      ? undefined
107      : paramArgs.at(3);
108
109    return {
110      category,
111      subCategory,
112      year,
113      page
114    };
115  }
116
117  const year =
118    Number(paramArgs.at(3)) ||
119    Number(paramArgs.at(2)) ||
120    undefined;
121
122  const category = Number(paramArgs.at(2))
123    ? undefined
124    : paramArgs.at(2);
125
126  return {
127    category,
128    subCategory,
129    year,
130    page
131  };
132}
133};
134const NewsEntryClient = class {
135  entries;
136  filteredEntries;
137  constructor() {
138    this.entries = [];
139    this.filteredEntries = [];
140    this.fetch().then(data => {
141      this.entries = data;
142      this.filteredEntries = data;
143      if (document.readyState === 'loading') {
144        document.addEventListener('DOMContentLoaded', () => document.dispatchEvent(new Event(POPSTATE_NEWS_ENTRIES)));
145      }
146      else {
147        document.dispatchEvent(new Event(POPSTATE_NEWS_ENTRIES));
148      }
149    });
150  }
151  async fetch() {
152    const rootPath = location.pathname;
153    if (rootPath.startsWith('/en/')) {
154      const response = await fetch(NEWS_ENTRIES_JSON_EN);
155      const data = await response.json();
156      return data;
157    } else {
158      const response = await fetch(NEWS_ENTRIES_JSON);
159      const data = await response.json();
160      return data;
161    }
162  }
163  reset() {
164    this.filteredEntries = this.entries;
165    return this;
166  }
167  get count() {
168    return this.filteredEntries.length;
169  }
170  filter({ category, subCategory, year, page = 1 }) {
171    this.reset().filterCategory(category).filterSubCategory(subCategory).filterYear(year);
172    return this.filteredEntries.slice((page - 1) * ROWS_PER_PAGE, page * ROWS_PER_PAGE);
173  }
174  filterCategory(category) {
175    if (!category)
176      return this;
177    this.filteredEntries = this.filteredEntries.filter(entry => {
178      return entry.category.map(v => v.slug).at(0) === category;
179    });
180    return this;
181  }
182  filterSubCategory(subCategory) {
183    if (!subCategory || subCategory.length < 1)
184      return this;
185    this.filteredEntries = this.filteredEntries.filter(entry => {
186      return subCategory?.includes(entry.category.map(v => v.slug).at(1) ?? "");
187    });
188    return this;
189  }
190  filterYear(year) {
191    if (!year)
192      return this;
193    this.filteredEntries = this.filteredEntries.filter(entry => {
194      return entry.year === String(year);
195    });
196    return this;
197  }
198};
199const createNewsEntryNode = (entry) => {
200  const baseTemplate = `
201    <div class="c-infoNewsItem" data-news-item>
202      <div class="c-infoNewsItem__head">
203        <time class="c-infoNewsItem__date" data-news-date></time>
204      </div>
205      <div class="c-infoNewsItem__body">
206        <ul class="c-infoNewsItem__tagList" data-news-tags></ul>
207        <p class="c-infoNewsItem__title">
208          <a href="/news/news/info/2024/0729.html" data-news-link="true" data-news-title></a>
209          <span data-news-title data-news-link="false"></span>
210        </p>
211      </div>
212    </div>
213  `;
214  const tagTemplate = `<li class="c-infoNewItem__tag"><span class="c-tag" data-news-tag>お知らせ</span></li>`;
215  const iconTemplate = `<li class="c-infoNewsItem__icon"><img /></li>`;
216  const element = document.createElement('div');
217  element.innerHTML = baseTemplate;
218  // リンク
219  const linkNode = element.querySelectorAll('[data-news-link="true"]');
220  linkNode.forEach(node => {
221    node.href = entry.permalink;
222    node.target = entry.blankFlag ? '_blank' : '_self';
223  });
224  if (entry.noLinkFlag)
225    element.querySelector('[data-news-link="true"]')?.remove();
226  else
227    element.querySelector('[data-news-link="false"]')?.remove();
228  // NEWマーク
229//   if (!entry.newIcon)
230//     element.querySelector('[data-news-new]')?.remove();
231  // 日付
232  const imgNode = element.querySelector('[data-news-date]');
233  imgNode.setAttribute('datetime', entry.date);
234  imgNode.textContent = entry.date;
235  // タイトル
236  const titleNode = element.querySelector('[data-news-title]');
237  titleNode.textContent = entry.title;
238  // タグ
239  const tagsNode = element.querySelector('[data-news-tags]');
240  entry.category.forEach(v => {
241    const wrapTagsElement = document.createElement('div');
242    wrapTagsElement.innerHTML = tagTemplate;
243    const tagElement = wrapTagsElement.children[0];
244    const tagNode = tagElement.querySelector('[data-news-tag]');
245    tagNode.textContent = v.label;
246    switch (v.slug) {
247      case 'news':
248        tagNode.classList.add('c-tag--news');
249        break;
250      case 'ir':
251        tagNode.classList.add('c-tag--ir');
252        break;
253      case 'press':
254        tagNode.classList.add('c-tag--press');
255        break;
256      default:
257        tagNode.classList.add('c-tag--white');
258        break;
259    }
260    tagsNode.appendChild(tagElement);
261  });
262  // アイコン
263  if (entry.typeIcon) {
264    const wrapIconElement = document.createElement('div');
265    wrapIconElement.innerHTML = iconTemplate;
266    const iconElement = wrapIconElement.children[0];
267    switch (entry.typeIcon) {
268      case 'pdf':
269        iconElement.querySelector('img').src = '/common/image/ico/ico_pdf.svg';
270        iconElement.querySelector('img').alt = 'PDFアイコン';
271        break;
272      case 'movie':
273        iconElement.querySelector('img').src = '/common/image/ico/ico_video.svg';
274        iconElement.querySelector('img').alt = 'videoファイル';
275        break;
276      case 'xls':
277        iconElement.querySelector('img').src = '/common/image/ico/ico_xls_gray.svg';
278        iconElement.querySelector('img').alt = 'エクセルファイル';
279        break;
280      default:
281        break;
282    }
283    tagsNode.appendChild(iconElement);
284  }
285  const elementChildren = element.children;
286  return elementChildren[0];
287};
288const createPaginationNode = (total, page = 1) => {
289  const totalPage = Math.max(Math.ceil(total / ROWS_PER_PAGE), 1);
290  const element = document.createElement('ul');
291  element.classList.add('c-pagination__list');
292  // 「PREV」ボタンを生成
293  const createPreviewNode = ({ page, isActive = true }) => {
294    const prevElement = document.createElement('li');
295    prevElement.classList.add('c-pagination__item', 'c-pagination__item--prev');
296    if (isActive) {
297      const prevArrowElement = document.createElement("a");
298      prevArrowElement.classList.add('c-pagination__arrow', 'c-pagination__arrow--prev');
299      prevArrowElement.setAttribute('data-news-page', String(page + -1));
300      prevArrowElement.href = `#`;
301      const prevTextElement = document.createElement('span');
302      prevTextElement.classList.add('c-pagination__text');
303      prevTextElement.textContent = 'PREV';
304      prevArrowElement.appendChild(prevTextElement);
305      prevElement.appendChild(prevArrowElement);
306    }
307    else {
308      const prevArrowElement = document.createElement("span");
309      prevArrowElement.classList.add('c-pagination__arrow', 'c-pagination__arrow--prev');
310      const prevTextElement = document.createElement('span');
311      prevTextElement.classList.add('c-pagination__text');
312      prevTextElement.textContent = 'PREV';
313      prevArrowElement.appendChild(prevTextElement);
314      prevElement.appendChild(prevArrowElement);
315    }
316    element.appendChild(prevElement);
317    return prevElement;
318  };
319  //「NEXT」ボタンを生成
320  const createNextNode = ({ page, isActive = true }) => {
321    const nextElement = document.createElement('li');
322    nextElement.classList.add('c-pagination__item', 'c-pagination__item--next');
323    if (isActive) {
324      const nextArrowElement = document.createElement("a");
325      nextArrowElement.classList.add('c-pagination__arrow', 'c-pagination__arrow--next');
326      nextArrowElement.setAttribute('data-news-page', String(page + 1));
327      nextArrowElement.href = `#`;
328      const nextTextElement = document.createElement('span');
329      nextTextElement.classList.add('c-pagination__text');
330      nextTextElement.textContent = 'NEXT';
331      nextArrowElement.appendChild(nextTextElement);
332      nextElement.appendChild(nextArrowElement);
333    }
334    else {
335      const nextArrowElement = document.createElement("span");
336      nextArrowElement.classList.add('c-pagination__arrow', 'c-pagination__arrow--next');
337      const nextTextElement = document.createElement('span');
338      nextTextElement.classList.add('c-pagination__text');
339      nextTextElement.textContent = 'NEXT';
340      nextArrowElement.appendChild(nextTextElement);
341      nextElement.appendChild(nextArrowElement);
342    }
343    element.appendChild(nextElement);
344    return nextElement;
345  };
346  // 数字リストを生成
347  const createNavigationNode = ({ page, isActive = false, }) => {
348    const itemElement = document.createElement('li');
349    itemElement.classList.add('c-pagination__item');
350    if (isActive) {
351      itemElement.classList.add('is-active');
352      const numElement = document.createElement('span');
353      numElement.classList.add('c-pagination__num');
354      numElement.textContent = String(page);
355      itemElement.appendChild(numElement);
356    }
357    else {
358      const numElement = document.createElement('a');
359      numElement.classList.add('c-pagination__num');
360      numElement.textContent = String(page);
361      numElement.href = `#`;
362      numElement.setAttribute('data-news-page', String(page));
363      itemElement.appendChild(numElement);
364    }
365    return itemElement;
366  };
367  // 「...」のリストを生成
368  const createEllipsisNode = () => {
369    const ellipsisElement = document.createElement('li');
370    ellipsisElement.classList.add('c-pagination__item', 'c-pagination__item--ellipsis');
371    ellipsisElement.textContent = '…';
372    return ellipsisElement;
373  };
374
375  /**
376   * PREV
377   */
378  const previewNode = createPreviewNode({ page, isActive: page !== 1 });
379  element.appendChild(previewNode);
380  for (let i = 1; i <= totalPage; i++) {
381    let node = null;
382    if (page === 1) { // 最初のページ目のとき
383      if (i === 1) {
384        node = createNavigationNode({ page: i, isActive: true });
385      }
386      else if (i > 1 && i <= 5 || i === totalPage) {
387        node = createNavigationNode({ page: i });
388      }
389      else if (i === 6) {
390        node = createEllipsisNode();
391      }
392    } else if (page === totalPage) { // 最後のページ目のとき
393      if (i === totalPage) {
394        node = createNavigationNode({ page: i, isActive: true });
395      }
396      else if (i <= totalPage - 1 && i > totalPage - 5 || i === 1) {
397        node = createNavigationNode({ page: i });
398      }
399      else if (i === totalPage - 5) {
400        node = createEllipsisNode();
401      }
402    } else { // 最初と最後以外
403      if (page < 5) {
404        if (i === page) {
405          node = createNavigationNode({ page: i, isActive: true });
406        }
407        if (i >= 1 && i <= 5 && i !== page || i === totalPage) {
408          node = createNavigationNode({ page: i });
409        }
410        else if (i === 6) {
411          node = createEllipsisNode();
412        }
413      } else if(page > totalPage - 4) {
414        if (i === page) {
415          node = createNavigationNode({ page: i, isActive: true });
416        }
417        if (i > totalPage - 5 && i !== page || i === 1) {
418          node = createNavigationNode({ page: i });
419        }
420        else if (i === totalPage - 6) {
421          node = createEllipsisNode();
422        }
423        if (totalPage > 5) {
424          if(i === 2) {
425            node = createEllipsisNode();
426          }
427        }
428      } else {
429        if (i === page) {
430          node = createNavigationNode({ page: i, isActive: true });
431        }
432        else if (i === 1 || i === totalPage || i - 1 === page || i + 1 === page || i - 2 === page || i + 2 === page) {
433          node = createNavigationNode({ page: i });
434        }
435        else if (i - 3 === page || i + 3 === page) {
436          node = createEllipsisNode();
437        }
438      }
439    }
440    // HTML生成
441    if (node) {
442      element.appendChild(node);
443    }
444  }
445
446  /**
447   * PREV
448   */
449  const nextElement = createNextNode({ page, isActive: page !== totalPage });
450  element.appendChild(nextElement);
451
452  /**
453   * 作成したページネーションを返す
454   */
455  return element;
456};
457const newsEntryClient = new NewsEntryClient();
458const newsConditionController = new NewsConditionController();
459// 検索条件
460document.addEventListener('DOMContentLoaded', () => {
461  newsConditionController.init();
462  // 検索条件の変更
463  const submitButton = document.querySelector('[data-news-condition="submit"]');
464  if (submitButton)
465    submitButton.addEventListener('click', () => newsConditionController.submit());
466  // ページネーション
467  document.addEventListener('click', (e) => {
468    const target = e.target.closest('[data-news-page]');
469    if (!target)
470      return;
471    e.preventDefault();
472    const page = target.getAttribute('data-news-page');
473    if (page)
474      newsConditionController.changePage(Number(page));
475    // 検索条件までスクロール
476    const searchTop = document.querySelector('[data-cs-head]')?.getBoundingClientRect().top;
477    if (searchTop)
478      window.scrollTo({ top: window.scrollY + searchTop - 100 });
479  });
480});
481// 検索結果
482document.addEventListener(POPSTATE_NEWS_ENTRIES, () => {
483  // 記事一覧
484  const root = document.querySelector('[data-news-root]');
485  const condition = newsConditionController.getConditionFromParams();
486  const entries = newsEntryClient.filter(condition);
487  if (root) {
488    root.innerHTML = '';
489    entries.forEach(entry => {
490      const element = createNewsEntryNode(entry);
491      root.appendChild(element);
492    });
493    document.querySelector('[data-news-no_hit]').style.display = entries.length > 0 ? 'none' : 'block';
494  }
495  // 記事数
496  const counter = document.querySelector('[data-news-counter]');
497  if (counter)
498    counter.textContent = `${newsEntryClient.count}`;
499  // ページネーション
500  const pagination = document.querySelector('[data-news-pagination]');
501  if (pagination) {
502    pagination.innerHTML = '';
503    const paginationElement = createPaginationNode(newsEntryClient.count, condition.page);
504    pagination.appendChild(paginationElement);
505  }
506});

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.