1(() => { 2 const chaveEstado = '__portaisRolagem'; 3 const chaveArmazenamento = 'portais:rolagem'; 4 let posicoes = {}; 5 let identificadorAtual; 6 let retornoHistorico = false; 7 let restauracaoPendente = false; 8 let limiteRestauracao = 0; 9 let quadroPendente = 0; 10 const inserirEstadoOriginal = history.pushState.bind(history); 11 const substituirEstadoOriginal = history.replaceState.bind(history); 12 13 try { 14 posicoes = JSON.parse(sessionStorage.getItem(chaveArmazenamento) || '{}') || {}; 15 } catch { 16 // a navegação continua quando o armazenamento está indisponÃvel. 17 } 18 19 /// <summary> 20 /// Método para identificar a entrada atual sem remover o estado de outros componentes. 21 /// </summary> 22 function identificarEntrada() { 23 identificadorAtual = history.state?.[chaveEstado] || crypto.randomUUID(); 24 substituirEstadoOriginal({ ...history.state, [chaveEstado]: identificadorAtual }, ''); 25 } 26 27 /// <summary> 28 /// Método para registrar a posição da entrada atual do histórico. 29 /// </summary> 30 function registrarPosicao() { 31 if (!restauracaoPendente) { 32 posicoes[identificadorAtual] = { x: window.scrollX, y: window.scrollY }; 33 } 34 } 35 36 /// <summary> 37 /// Método para encerrar uma restauração quando o usuário assume a rolagem. 38 /// </summary> 39 function encerrarRestauracao() { 40 restauracaoPendente = false; 41 cancelAnimationFrame(quadroPendente); 42 } 43 44 /// <summary> 45 /// Método para restaurar a posição enquanto o conteúdo da página termina de carregar. 46 /// </summary> 47 function restaurarPosicao() { 48 cancelAnimationFrame(quadroPendente); 49 if (!restauracaoPendente) return; 50 const posicao = posicoes[identificadorAtual]; 51 if (!posicao || performance.now() > limiteRestauracao) { 52 encerrarRestauracao(); 53 return; 54 } 55 window.scrollTo({ left: posicao.x, top: posicao.y, behavior: 'instant' }); 56 quadroPendente = requestAnimationFrame(restaurarPosicao); 57 } 58 59 /// <summary> 60 /// Método para inserir uma nova entrada e preservar a posição da página de origem. 61 /// </summary> 62 history.pushState = function (estado, titulo, endereco) { 63 registrarPosicao(); 64 const identificador = crypto.randomUUID(); 65 inserirEstadoOriginal({ ...estado, [chaveEstado]: identificador }, titulo, endereco); 66 encerrarRestauracao(); 67 identificadorAtual = identificador; 68 retornoHistorico = false; 69 }; 70 71 /// <summary> 72 /// Método para preservar a identificação da entrada em atualizações e redirecionamentos. 73 /// </summary> 74 history.replaceState = function (estado, titulo, endereco) { 75 substituirEstadoOriginal({ ...estado, [chaveEstado]: identificadorAtual }, titulo, endereco); 76 }; 77 78 /// <summary> 79 /// Método para preparar o retorno ou avanço para uma entrada existente. 80 /// </summary> 81 function tratarHistorico() { 82 encerrarRestauracao(); 83 identificarEntrada(); 84 retornoHistorico = true; 85 restauracaoPendente = !!posicoes[identificadorAtual]; 86 limiteRestauracao = performance.now() + 10000; 87 quadroPendente = requestAnimationFrame(restaurarPosicao); 88 } 89 90 /// <summary> 91 /// Método para aplicar a rolagem adequada após a atualização da página. 92 /// </summary> 93 window.atualizarRolagemNavegacao = function () { 94 if (retornoHistorico) { 95 restaurarPosicao(); 96 return; 97 } 98 if (location.hash) { 99 rolarAte(location.hash, 120); 100 } else if (new URLSearchParams(location.search).get('nr') !== '1') { 101 window.scrollTo({ top: 0, left: 0, behavior: 'instant' }); 102 } 103 }; 104 105 /// <summary> 106 /// Método para guardar as posições da aba antes de sair do documento. 107 /// </summary> 108 function guardarPosicoes() { 109 registrarPosicao(); 110 try { 111 sessionStorage.setItem(chaveArmazenamento, JSON.stringify(posicoes)); 112 } catch { 113 // mantém a restauração em memória quando o armazenamento está indisponÃvel. 114 } 115 } 116 117 /// <summary> 118 /// Método para restaurar o histórico após uma navegação com recarga completa. 119 /// </summary> 120 function tratarExibicao(evento) { 121 if (evento.persisted || performance.getEntriesByType('navigation')[0]?.type === 'back_forward') { 122 tratarHistorico(); 123 } 124 } 125 126 identificarEntrada(); 127 window.addEventListener('pageshow', tratarExibicao); 128 window.addEventListener('scroll', registrarPosicao, { passive: true }); 129 window.addEventListener('popstate', tratarHistorico); 130 window.addEventListener('pagehide', guardarPosicoes); 131 window.addEventListener('wheel', encerrarRestauracao, { passive: true }); 132 window.addEventListener('touchstart', encerrarRestauracao, { passive: true }); 133 window.addEventListener('pointerdown', encerrarRestauracao, { passive: true }); 134 window.addEventListener('keydown', encerrarRestauracao); 135})();
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.