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.