PageSourceSearch

https://www.hankyu-hanshin.co.jp/assets/js/entries_posts.js

js hankyu-hanshin.co.jp collected 2026-10-02 03:08:16 UTC 12,452 bytes, 389 lines download raw bytes

1; (function () {
2    const html = $('html'),
3        cfg = {
4            _json_path: '',
5            _release_json: '../../release/json/all_entries.json',
6            _ir_topics_json: '../../ir/topics/json/all_entries.json',
7            _per_page: 30,
8            _current_page: 1,
9            _total_page: 0,
10            _all_category: [],
11            _all_type: [],
12            _all_year: [],
13            _entries: [],
14            _entries_filters: [],
15            _is_page: 'release',
16        },
17        filters = {
18            _year: '',
19            _category: '',
20            _type: ''
21        },
22        entries_category = $('#entries_category'),
23        entries_type = $('#entries_type'),
24        entries_year = $('#entries_year'),
25        entries_posts = $('#entries_posts'),
26        entries_form = $('#entries_form'),
27        inname = $('#inname');
28
29    // MULTI CATEGORY
30    const split_multi = (str) => (str || '').split(',').map(_ => _.trim()).filter(_ => _ !== '');
31
32    // SUB TITLE
33    const render_subtitle = () => {
34
35        let _li = "";
36        if (entries_category.val() !== "all") {
37            const txt = entries_category.find('option:selected').text();
38            _li += `<li>${txt}</li>`;
39        }
40        if (entries_type.val() !== "all") {
41            const txt = entries_type.find('option:selected').text();
42            _li += `<li>${txt}</li>`;
43        }
44        if (entries_year.val() !== "all") {
45            const txt = entries_year.find('option:selected').text();
46            _li += `<li>${txt}</li>`;
47        }
48        if (_li != "") {
49            inname.html(`<ul class="bulleted_list">${_li}</ul>`);
50        } else {
51            inname.html('');
52        }
53    }
54
55    //  FILTER
56    const filter_init = () => {
57        const years = new Set(),
58            categories = new Map(),
59            types = new Map();
60
61        cfg._entries.forEach(_post => {
62            const from = `${_post.date.substring(0, 4)}-04-01`;
63            const to = `${+_post.date.substring(0, 4) + 1}-03-31`;
64
65            if (_post.date >= from && _post.date <= to) {
66                years.add(_post.date.substring(0, 4));
67            }
68
69            const basenames = split_multi(_post.category_basename),
70                labels = split_multi(_post.category);
71            basenames.forEach((_basename, _i) => {
72                categories.set(_basename, labels[_i]);
73            });
74            types.set(_post.type_basename, _post.type);
75        });
76
77        cfg._all_year = [...years].sort((a, b) => b - a);
78        cfg._all_category = [...categories].map(([value, label]) => ({
79            value,
80            label
81        }));
82        cfg._all_type = [...types].map(([value, label]) => ({
83            value,
84            label
85        }));
86    };
87
88
89    filter_apply = () => {
90        cfg._entries_filters = cfg._entries.filter(_ => {
91            if (filters._category && filters._category != 'all') {
92                if (!split_multi(_.category_basename).includes(filters._category)) {
93                    return false;
94                }
95            }
96            if (filters._type && filters._type != 'all') {
97                if (_.type_basename !== filters._type) {
98                    return false;
99                }
100            }
101            if (filters._year && filters._year != 'all') {
102                const from = `${filters._year}-04-01`;
103                const to = `${+filters._year + 1}-03-31`;
104
105                if (_.date < from || _.date > to) {
106                    return false;
107                }
108            }
109
110            return true;
111        });
112
113        cfg._total_page = Math.ceil(cfg._entries_filters.length / cfg._per_page);
114    }
115
116    const filter_submit = () => {
117        entries_category.on('change', function () {
118            entries_form.submit();
119        });
120        entries_type.on('change', function () {
121            entries_form.submit();
122        });
123        entries_year.on('change', function () {
124            entries_form.submit();
125        });
126        entries_form.on('submit', function (e) {
127
128            e.preventDefault();
129
130            filters._category = $('#entries_category').val();
131            filters._type = $('#entries_type').val();
132            filters._year = $('#entries_year').val();
133
134            cfg._current_page = 1;
135
136            filter_apply();
137            update_url();
138            render_post();
139
140            html.animate({
141                scrollTop: 0
142            }, 0)
143        });
144    }
145
146    // SELECT OPTION
147    const selection_set = () => {
148        if (filters._category === "" || !filters._category) {
149            filters._category = "all";
150        }
151        if (filters._type === "" || !filters._type) {
152            filters._type = "all";
153        }
154
155        if (filters._year === "" || !filters._year) {
156            filters._year = "all";
157        }
158        entries_category.val(filters._category);
159        entries_type.val(filters._type);
160        entries_year.val(filters._year);
161    }
162
163    // RENDER
164    const create_post = ({ permalink, date, category_basename, category, title, type }) => {
165        category_basename = split_multi(category_basename)[0] || '';
166        category = split_multi(category)[0] || '';
167        if (cfg._is_page == "release") {
168            if (permalink !== "") {
169                return `<li>
170                        <a href="${permalink}" target="_blank" rel="noopener noreferrer">
171                            <time datetime="${date}">${date.replaceAll('-', '.')}</time>
172                            <span class="category ${category_basename}">${category == "阪急阪神ホールディングス" ? "阪急阪神HD" : category}</span>
173                            <p>${title}</p>
174                        </a>
175                    </li>`;
176            } else {
177                return `<li>
178                        <span class="no-link">
179                            <time datetime="${date}">${date.replaceAll('-', '.')}</time>
180                            <span class="category ${category_basename}">${category == "阪急阪神ホールディングス" ? "阪急阪神HD" : category}</span>
181                            <p>${type} ${title}</p>
182                        </span>
183                    </li>`;
184            }
185        }
186        if (cfg._is_page == "ir_topics") {
187            if (permalink !== "") {
188                return `<li>
189                        <a href="${permalink}" target="_blank" rel="noopener noreferrer">
190                            <time datetime="${date}">${date.replaceAll('-', '.')}</time>
191                            <span class="category ${category_basename}">${category == "阪急阪神ホールディングス" ? "阪急阪神HD" : category}</span>
192                            <p>【${type}】 ${title}</p>
193                        </a>
194                    </li>`;
195            } else {
196                return `<li>
197                        <span class="no-link">
198                            <time datetime="${date}">${date.replaceAll('-', '.')}</time>
199                            <span class="category ${category_basename}">${category == "阪急阪神ホールディングス" ? "阪急阪神HD" : category}</span>
200                            <p>【${type}】 ${title}</p>
201                        </span>
202                    </li>`;
203            }
204        }
205        return
206    }
207    const render_post = () => {
208        let _from = (cfg._current_page - 1) * cfg._per_page,
209            _to = _from + cfg._per_page,
210            _data = cfg._entries_filters.slice(_from, _to);
211
212        // render HTML...
213        entries_posts.empty();
214        $.each(_data, function (_, _i) {
215            entries_posts.append(create_post(_i));
216        });
217
218        if (entries_posts.children().length == 0) {
219            entries_posts.append(`<p>該当の記事がありません。条件を変更して検索してください。</p>`);
220        }
221
222
223        render_pagination();
224        render_subtitle();
225    }
226
227    // PAGINATION
228    const get_pagination = (current, total) => {
229        if (total <= 7) {
230            return Array.from({ length: total }, (_, i) => i + 1);
231        }
232        if (current <= 3) {
233            return [1, 2, 3, 4, '...', total];
234        }
235        if (current >= total - 2) {
236            return [1, '...', total - 3, total - 2, total - 1, total];
237        }
238        return [
239            1,
240            '...',
241            current - 1,
242            current,
243            current + 1,
244            '...',
245            total
246        ];
247    };
248
249    const render_pagination = () => {
250        const pages = get_pagination(cfg._current_page, cfg._total_page);
251
252        const pagination = $('#entries_pagination');
253        let _html = '';
254
255        if (cfg._current_page != 1) {
256            _html += `<div class="prev" data-pagi="prev"></div>`;
257        }
258
259        pages.forEach(_page => {
260            if (_page === '...') {
261                _html += `<span class="dots">...</span>`;
262            } else {
263                if (_page === cfg._current_page) {
264                    _html += `<span class="current">${_page}</span>`;
265                } else {
266                    _html += `<div class="" data-pagi="${_page}">${_page}</div>`;
267                }
268            }
269        });
270
271        if (cfg._current_page != cfg._total_page && pages.length > 1) {
272            _html += `<div class="next" data-pagi="next"></div>`;
273        }
274
275        pagination.html(_html);
276    }
277
278    const goto_page = (_page) => {
279        if (_page < 1 || _page > cfg._total_page) return;
280
281        cfg._current_page = _page;
282
283        update_url();
284
285        render_post();
286    }
287
288    // URL
289    const read_url = () => {
290        const params = new URLSearchParams(location.search);
291
292        filters._category = params.get('category') || "";
293        filters._type = params.get('type') || "";
294        filters._year = params.get('year');
295
296        cfg._current_page =
297            Number(params.get('page')) || 1;
298    }
299
300    const update_url = () => {
301        const params = new URLSearchParams();
302
303        if (cfg._all_category.some(item => item.value === filters._category)) {
304            params.set('category', filters._category);
305        }
306        if (cfg._all_type.some(item => item.value === filters._type)) {
307            params.set('type', filters._type);
308        }
309        if (cfg._all_year.includes(filters._year)) {
310            params.set('year', filters._year);
311        }
312
313        if (cfg._current_page > 1) {
314            params.set('page', cfg._current_page);
315        }
316
317        history.pushState(
318            {},
319            '',
320            params.toString()
321                ? `${location.pathname}?${params}`
322                : location.pathname
323        );
324    }
325
326    // INIT
327    async function init() {
328        const page_release = $('#entries_release'),
329            page_ir_topics = $('#entries_ir');
330        if (page_release.length == 0 && page_ir_topics.length == 0) {
331            return;
332        }
333
334        if (page_release.length > 0) {
335            cfg._is_page = "release";
336            cfg._json_path = cfg._release_json;
337        }
338        if (page_ir_topics.length > 0) {
339            cfg._is_page = "ir_topics";
340            cfg._json_path = cfg._ir_topics_json;
341        }
342
343        // 
344        read_url();
345
346        const script = document.currentScript;
347        const path = new URL(cfg._json_path, script.src);
348
349        //
350        const res = await fetch(path),
351            entries = await res.json();
352        cfg._entries = entries?.posts;
353        cfg._total_page = Math.ceil(cfg._entries.length / cfg._per_page);
354
355        filter_init();
356        filter_apply();
357        selection_set();
358        render_post();
359        filter_submit();
360
361        $(document).on('click', '[data-pagi]', function () {
362            const _ = $(this),
363                target = _.attr('data-pagi');
364            if (target == "prev") {
365                if (cfg._current_page > 1) {
366                    goto_page(cfg._current_page - 1);
367                }
368            } else if (target == "next") {
369                if (cfg._current_page < cfg._total_page) {
370                    goto_page(cfg._current_page + 1);
371                }
372            } else {
373                goto_page(+target);
374            }
375            html.animate({
376                scrollTop: 0
377            }, 0)
378        });
379
380        window.addEventListener('popstate', function () {
381            read_url();
382            selection_set();
383            filter_apply();
384            render_post();
385        });
386    }
387
388    init();
389})();

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.