PageSourceSearch

https://vestnikkui.ru/bundles/journals/js/publication-detail/issue.js?v=20260929-journal-bar

js vestnikkui.ru collected 2026-10-02 20:02:54 UTC 8,793 bytes, 260 lines download raw bytes

1(function (window, document) {
2    var modules = window.EditorumPublicationDetailModules = window.EditorumPublicationDetailModules || {};
3    var shared = modules.shared || {};
4    var issue = modules.issue = modules.issue || {};
5
6    var queryAll = shared.queryAll;
7    var getQueryParam = shared.getQueryParam;
8    var updateUrlState = shared.updateUrlState;
9
10    function initIssueTabs(options) {
11        var settings = options || {};
12        var tabRoot = document.querySelector(settings.rootSelector || '.issue-page .issue-tabs');
13        var tabs = tabRoot ? queryAll(settings.tabSelector || '.issue-tab[data-tab-target]', tabRoot) : [];
14        var panels = queryAll(settings.panelSelector || '.issue-page .issue-panel');
15        var initialTab = settings.defaultTab || 'issue-contents';
16        var queryParam = settings.queryParam || 'tab';
17        var legacyHashes = settings.legacyHashes || {};
18        var requestedTab = getQueryParam(queryParam);
19        var normalizedFromHash = null;
20
21        function getPanelById(targetId) {
22            var match = null;
23
24            panels.some(function (panel) {
25                if (panel.id === targetId) {
26                    match = panel;
27                    return true;
28                }
29
30                return false;
31            });
32
33            return match;
34        }
35
36        function panelHasRenderedContent(targetId) {
37            var panel = getPanelById(targetId);
38
39            if (!panel) {
40                return false;
41            }
42
43            return Array.prototype.some.call(panel.childNodes, function (node) {
44                if (node.nodeType === 1) {
45                    return true;
46                }
47
48                return node.nodeType === 3 && node.textContent.trim().length > 0;
49            });
50        }
51
52        function activateTab(targetId, writeUrl) {
53            var targetTab = null;
54            var targetPanel = document.getElementById(targetId);
55
56            tabs.some(function (tab) {
57                if (tab.getAttribute('data-tab-target') === targetId) {
58                    targetTab = tab;
59                    return true;
60                }
61
62                return false;
63            });
64
65            if (!targetTab || !targetPanel) {
66                return false;
67            }
68
69            tabs.forEach(function (tab) {
70                tab.classList.remove('active');
71                tab.setAttribute('aria-selected', 'false');
72            });
73            targetTab.classList.add('active');
74            targetTab.setAttribute('aria-selected', 'true');
75
76            panels.forEach(function (panel) {
77                panel.classList.remove('active');
78                panel.setAttribute('aria-hidden', 'true');
79            });
80            targetPanel.classList.add('active');
81            targetPanel.setAttribute('aria-hidden', 'false');
82
83            if (writeUrl) {
84                updateUrlState((function () {
85                    var state = {};
86
87                    state[queryParam] = targetId;
88
89                    return state;
90                })(), '#' + targetId, false);
91            }
92
93            return true;
94        }
95
96        if (!tabs.length || !panels.length) {
97            return false;
98        }
99
100        if (requestedTab && tabs.some(function (tab) { return tab.getAttribute('data-tab-target') === requestedTab; })) {
101            initialTab = requestedTab;
102        } else if (!requestedTab && window.location.hash && legacyHashes[window.location.hash]) {
103            normalizedFromHash = legacyHashes[window.location.hash];
104            initialTab = normalizedFromHash;
105            updateUrlState((function () {
106                var state = {};
107
108                state[queryParam] = normalizedFromHash;
109
110                return state;
111            })(), window.location.hash, true);
112        }
113
114        if (!panelHasRenderedContent(initialTab) && panels.length) {
115            initialTab = panels.reduce(function (resolvedTargetId, panel) {
116                if (resolvedTargetId) {
117                    return resolvedTargetId;
118                }
119
120                return panelHasRenderedContent(panel.id) ? panel.id : '';
121            }, '') || initialTab;
122        }
123
124        activateTab(initialTab, false);
125
126        if ((requestedTab || normalizedFromHash) && window.location.hash !== '#' + initialTab) {
127            updateUrlState((function () {
128                var state = {};
129
130                state[queryParam] = initialTab;
131
132                return state;
133            })(), '#' + initialTab, true);
134        }
135
136        tabs.forEach(function (tab) {
137            tab.addEventListener('click', function () {
138                var targetId = tab.getAttribute('data-tab-target');
139
140                activateTab(targetId, true);
141            });
142        });
143
144        window.addEventListener('popstate', function () {
145            var restoredTab = getQueryParam(queryParam);
146            var restoredHash = window.location.hash;
147
148            if (restoredTab && tabs.some(function (tab) { return tab.getAttribute('data-tab-target') === restoredTab; })) {
149                activateTab(restoredTab, false);
150                return;
151            }
152
153            if (restoredHash && legacyHashes[restoredHash]) {
154                activateTab(legacyHashes[restoredHash], false);
155            }
156        });
157
158        return true;
159    }
160
161    function initRubricToggles(options) {
162        var settings = options || {};
163        var toggleSelector = settings.toggleSelector || '.issue-page .rubric-toggle';
164        var initializedToggles = queryAll(toggleSelector);
165
166        function setRubricExpanded(toggle, expanded) {
167            var targetId = toggle.getAttribute('data-rubric-target');
168            var body = targetId ? document.getElementById(targetId) : null;
169
170            toggle.setAttribute('aria-expanded', expanded ? 'true' : 'false');
171            toggle.classList.toggle('is-collapsed', !expanded);
172            if (body) {
173                body.classList.toggle('is-collapsed', !expanded);
174            }
175        }
176
177        function expandHashTarget() {
178            var hashId = '';
179            var hashTarget;
180            var targetToggle;
181
182            if (!window.location.hash || window.location.hash.charAt(0) !== '#') {
183                return;
184            }
185
186            try {
187                hashId = decodeURIComponent(window.location.hash.slice(1));
188            } catch (error) {
189                return;
190            }
191
192            if (!hashId) {
193                return;
194            }
195
196            targetToggle = initializedToggles.filter(function (toggle) {
197                return toggle.getAttribute('data-rubric-target') === hashId;
198            })[0] || null;
199
200            if (!targetToggle) {
201                hashTarget = document.getElementById(hashId);
202                targetToggle = hashTarget
203                    ? initializedToggles.filter(function (toggle) {
204                        return toggle.getAttribute('data-rubric-target') === hashTarget.id;
205                    })[0] || null
206                    : null;
207            }
208
209            if (targetToggle) {
210                setRubricExpanded(targetToggle, true);
211            }
212        }
213
214        initializedToggles.forEach(function (toggle) {
215            toggle.addEventListener('click', function () {
216                var isExpanded = toggle.getAttribute('aria-expanded') === 'true';
217
218                setRubricExpanded(toggle, !isExpanded);
219            });
220        });
221
222        expandHashTarget();
223        window.addEventListener('hashchange', expandHashTarget);
224    }
225
226    function initIssueTitleNoWrap(options) {
227        var settings = options || {};
228        var titleSelector = settings.titleSelector || '.issue-page .issue-journal-link';
229        var triplePattern = /([А-ЯЁA-Z]\.\s+[А-ЯЁA-Z]\.\s+[А-ЯЁA-Z][а-яёa-z-]+[.,;:]?)/gu;
230
231        queryAll(titleSelector).forEach(function (title) {
232            var html = title.innerHTML || '';
233            var normalizedHtml;
234
235            if (!html || html.indexOf('issue-journal-link__nowrap') !== -1) {
236                return;
237            }
238
239            normalizedHtml = html
240                .replace(triplePattern, '<span class="issue-journal-link__nowrap" style="white-space: nowrap;">$1</span>');
241
242            if (normalizedHtml !== html) {
243                title.innerHTML = normalizedHtml;
244            }
245        });
246    }
247
248    function initIssuePage(options) {
249        var settings = options || {};
250
251        initIssueTabs(settings.issueTabs || {});
252        initRubricToggles(settings.rubrics || {});
253        initIssueTitleNoWrap(settings.typography || {});
254    }
255
256    issue.initIssueTabs = initIssueTabs;
257    issue.initRubricToggles = initRubricToggles;
258    issue.initIssueTitleNoWrap = initIssueTitleNoWrap;
259    issue.initIssuePage = initIssuePage;
260})(window, document);

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.