1/** 2 * Arena B3 v2 â Faixa azul + colchete pontilhado no topo das paginas internas. 3 * Substitui o titulo-texto solto por page hero full-bleed (pedido cliente 05/08). 4 */ 5(function () { 6 'use strict'; 7 8 var HERO_ID = 'ab3-v2-page-hero'; 9 var BODY_CLASS = 'ab3-v2-has-page-hero'; 10 11 var TITLES = { 12 'quemSomos': { 13 pt: 'Quem Somos', 14 en: 'About Us', 15 es: 'Quiénes Somos', 16 }, 17 programacao: { 18 pt: 'Programação', 19 en: 'Program', 20 es: 'Programación', 21 }, 22 galeria: { 23 pt: 'Galeria de Fotos', 24 en: 'Photo Gallery', 25 es: 'GalerÃa de Fotos', 26 }, 27 imprensa: { 28 pt: 'Imprensa', 29 en: 'Press', 30 es: 'Prensa', 31 }, 32 comoChegar: { 33 pt: 'Como Chegar', 34 en: 'Getting Here', 35 es: 'Cómo Llegar', 36 }, 37 faq: { 38 pt: 'FAQ', 39 en: 'FAQ', 40 es: 'FAQ', 41 }, 42 }; 43 44 var renderedKey = ''; 45 var lastScrollHash = ''; 46 47 /* Arte cliente: colchetes [ ] solidos (nao pontilhados). Branco via CSS color. */ 48 var BRACKET_SVG = 49 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150" fill="currentColor" aria-hidden="true">' + 50 '<path d="M0 0 H34 V11 H11 V139 H34 V150 H0 Z"/>' + 51 '<path d="M116 0 H150 V150 H116 V139 H139 V11 H116 Z"/>' + 52 '</svg>'; 53 54 function parseHash() { 55 var hash = location.hash || ''; 56 var route = location.pathname.replace(/\/$/, '') || '/'; 57 var fragment = ''; 58 if (hash.charAt(0) === '#') { 59 var raw = hash.slice(1); 60 var qIndex = raw.indexOf('?'); 61 if (qIndex >= 0) raw = raw.slice(0, qIndex); 62 var fragIndex = raw.indexOf('#'); 63 if (fragIndex >= 0) { 64 fragment = raw.slice(fragIndex + 1); 65 raw = raw.slice(0, fragIndex); 66 } 67 if (raw && raw.charAt(0) === '/') { 68 route = raw.replace(/\/$/, '') || '/'; 69 } 70 } 71 return { route: route, fragment: fragment }; 72 } 73 74 function getLang() { 75 var lang = ''; 76 try { 77 lang = localStorage.getItem('currentLanguage') || ''; 78 } catch (e) { /* storage indisponivel */ } 79 return ['pt', 'en', 'es'].indexOf(lang) >= 0 ? lang : 'pt'; 80 } 81 82 function resolveHeroKey(parsed) { 83 if (parsed.route === '/programacao') return 'programacao'; 84 if (parsed.route === '/a-arena') { 85 if (parsed.fragment === 'galeria') return 'galeria'; 86 if (!parsed.fragment || parsed.fragment === 'institucional') return 'quemSomos'; 87 return null; 88 } 89 if (parsed.route === '/contato') { 90 if (parsed.fragment === 'imprensa') return 'imprensa'; 91 if (parsed.fragment === 'como-chegar') return 'comoChegar'; 92 if (parsed.fragment === 'faq') return 'faq'; 93 return null; 94 } 95 return null; 96 } 97 98 function ensureHeroElement() { 99 var existing = document.getElementById(HERO_ID); 100 if (existing) return existing; 101 102 var navbar = document.querySelector('app-navbar'); 103 if (!navbar || !navbar.parentNode) return null; 104 105 var hero = document.createElement('header'); 106 hero.id = HERO_ID; 107 hero.className = 'ab3-v2-page-hero'; 108 hero.hidden = true; 109 110 var inner = document.createElement('div'); 111 inner.className = 'ab3-v2-page-hero__inner'; 112 113 var heading = document.createElement('div'); 114 heading.className = 'ab3-v2-page-hero__heading'; 115 116 var title = document.createElement('h1'); 117 title.className = 'ab3-v2-page-hero__title'; 118 119 var bracket = document.createElement('span'); 120 bracket.className = 'ab3-v2-page-hero__bracket'; 121 bracket.setAttribute('aria-hidden', 'true'); 122 bracket.innerHTML = BRACKET_SVG; 123 124 heading.appendChild(title); 125 heading.appendChild(bracket); 126 inner.appendChild(heading); 127 hero.appendChild(inner); 128 129 navbar.parentNode.insertBefore(hero, navbar.nextSibling); 130 return hero; 131 } 132 133 /** 134 * Cliente 06/08: ao mudar de pagina o browser/Angular ancora no fragment 135 * (#institucional, #galeria, #faqâ¦) e o banner azul fica fora da viewport 136 * ("entra no meio da pagina"). Corrige rolando o page-hero para logo 137 * abaixo do navbar sticky â com retries pq o Angular ainda re-rola. 138 */ 139 function scrollBannerIntoView() { 140 var hero = document.getElementById(HERO_ID); 141 if (!hero || hero.hidden) return; 142 143 var tries = 0; 144 function go() { 145 hero = document.getElementById(HERO_ID); 146 if (!hero || hero.hidden) return; 147 148 var navbar = document.querySelector('app-navbar'); 149 var navH = navbar ? navbar.getBoundingClientRect().height : 0;
150 var heroTop = hero.getBoundingClientRect().top; 151 // Ideal: topo do banner colado sob o navbar (±28px). 152 if (Math.abs(heroTop - navH) > 28) { 153 var absoluteTop = hero.getBoundingClientRect().top + window.pageYOffset - navH; 154 window.scrollTo({ 155 top: Math.max(0, Math.round(absoluteTop)), 156 behavior: tries === 0 ? 'smooth' : 'auto', 157 }); 158 } 159 160 tries += 1; 161 if (tries < 7) { 162 setTimeout(go, tries === 1 ? 180 : 420); 163 } 164 } 165 setTimeout(go, 60); 166 } 167 168 function updateHero() { 169 if ((location.hash || '').indexOf('/admin') === 1) return; 170 171 var parsed = parseHash(); 172 var lang = getLang(); 173 var heroKey = resolveHeroKey(parsed); 174 var hero = ensureHeroElement(); 175 if (!hero) return; 176 177 if (!heroKey) { 178 hero.hidden = true; 179 document.body.classList.remove(BODY_CLASS); 180 renderedKey = ''; 181 lastScrollHash = ''; 182 return; 183 } 184 185 var copy = TITLES[heroKey]; 186 var titleText = (copy && copy[lang]) || (copy && copy.pt) || ''; 187 var nextKey = heroKey + '|' + lang + '|' + titleText; 188 var hashNow = location.hash || ''; 189 var hashChanged = hashNow !== lastScrollHash; 190 191 hero.hidden = false; 192 document.body.classList.add(BODY_CLASS); 193 194 if (renderedKey !== nextKey) { 195 var titleEl = hero.querySelector('.ab3-v2-page-hero__title'); 196 if (titleEl) titleEl.textContent = titleText; 197 198 var bracketEl = hero.querySelector('.ab3-v2-page-hero__bracket'); 199 if (bracketEl) { 200 bracketEl.innerHTML = BRACKET_SVG; 201 } 202 203 renderedKey = nextKey; 204 } 205 206 // Corrige ancora ao trocar hash (browser/Angular apontam pro fragment e 207 // escondem o banner). MutationObserver nao deve re-disparar o scroll. 208 if (hashChanged) { 209 lastScrollHash = hashNow; 210 scrollBannerIntoView(); 211 } 212 } 213 214 function watchSpaNavigation() { 215 window.addEventListener('hashchange', updateHero); 216 window.addEventListener('popstate', updateHero); 217 218 ['pushState', 'replaceState'].forEach(function (method) { 219 var original = history[method]; 220 history[method] = function () { 221 var result = original.apply(this, arguments); 222 updateHero(); 223 return result; 224 }; 225 }); 226 227 var appRoot = document.querySelector('app-root'); 228 if (appRoot && window.MutationObserver) { 229 var observer = new MutationObserver(function () { 230 updateHero(); 231 }); 232 observer.observe(appRoot, { childList: true, subtree: true }); 233 } 234 } 235 236 function init() { 237 updateHero(); 238 watchSpaNavigation(); 239 } 240 241 if (document.readyState === 'loading') { 242 document.addEventListener('DOMContentLoaded', init); 243 } else { 244 init(); 245 } 246})();
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.