1const formularioBusca = document.querySelector("[data-aulas-busca]"); 2const campoBusca = document.querySelector("[data-aulas-campo]"); 3const barraFiltros = document.querySelector(".aulas-categorias"); 4const botoesFiltro = document.querySelectorAll("[data-aulas-filtro]"); 5const cardsAula = document.querySelectorAll("[data-aula-card]"); 6const avisoVazio = document.querySelector("[data-aulas-vazio]"); 7const botaoCarregarAulas = document.querySelector("[data-aulas-carregar]"); 8const botaoMenuAulas = document.querySelector(".aulas-topo__marca .aulas-topo__icone"); 9const blocoDescricaoAula = document.querySelector("[data-aula-descricao]"); 10const conteudoDescricaoAula = document.querySelector("[data-aula-descricao-conteudo]"); 11const botaoDescricaoAula = document.querySelector("[data-aula-descricao-toggle]"); 12 13let filtroAtual = ""; 14let limiteAulas = window.matchMedia("(max-width: 620px)").matches ? 8 : 12; 15const loteAulas = window.matchMedia("(max-width: 620px)").matches ? 6 : 8; 16let observadorCarregarAulas = null; 17 18if (barraFiltros) { 19 filtroAtual = barraFiltros.dataset.aulasCategoriaInicial ?? ""; 20} 21 22function limparBusca(valor) { 23 return String(valor) 24 .replace(/[\u0000-\u001f\u007f<>`"']/g, " ") 25 .replace(/\s+/g, " ") 26 .slice(0, 80) 27 .trim(); 28} 29 30function normalizarTexto(texto) { 31 return limparBusca(texto) 32 .normalize("NFD") 33 .replace(/[\u0300-\u036f]/g, "") 34 .toLowerCase() 35 .trim(); 36} 37 38function filtrarAulas() { 39 if (campoBusca && campoBusca.value.length > 80) { 40 campoBusca.value = campoBusca.value.slice(0, 80); 41 } 42 43 const termo = normalizarTexto(campoBusca?.value ?? ""); 44 const filtro = normalizarTexto(filtroAtual); 45 let visiveis = 0; 46 let encontrados = 0; 47 48 cardsAula.forEach((card) => { 49 const texto = normalizarTexto(card.dataset.aulaText ?? ""); 50 const categoria = normalizarTexto(card.dataset.aulaCategory ?? ""); 51 const combinaBusca = !termo || texto.includes(termo); 52 const combinaFiltro = !filtro || categoria === filtro; 53 const combina = combinaBusca && combinaFiltro; 54 const mostrar = combina && encontrados < limiteAulas; 55 56 card.hidden = !mostrar; 57 card.style.display = mostrar ? "" : "none"; 58 59 if (combina) { 60 encontrados += 1; 61 } 62 63 if (mostrar) { 64 visiveis += 1; 65 } 66 }); 67 68 avisoVazio?.classList.toggle("ativo", encontrados === 0); 69 70 if (botaoCarregarAulas) { 71 const temMais = encontrados > visiveis; 72 botaoCarregarAulas.hidden = !temMais; 73 botaoCarregarAulas.textContent = temMais ? "Carregar mais aulas" : "Tudo carregado"; 74 } 75} 76 77function reiniciarCarregamento() { 78 limiteAulas = window.matchMedia("(max-width: 620px)").matches ? 8 : 12; 79 filtrarAulas(); 80} 81 82function carregarMaisAulas() { 83 limiteAulas += loteAulas; 84 filtrarAulas(); 85} 86 87function carregarMaisQuandoPerto() { 88 if (!botaoCarregarAulas || botaoCarregarAulas.hidden) { 89 return; 90 } 91 92 const distanciaAteFim = document.documentElement.scrollHeight - (window.scrollY + window.innerHeight); 93 94 if (distanciaAteFim < 900) { 95 carregarMaisAulas(); 96 } 97} 98 99if (campoBusca) { 100 const buscaUrl = limparBusca(new URLSearchParams(window.location.search).get("q") ?? ""); 101 102 if (buscaUrl) { 103 campoBusca.value = buscaUrl; 104 } 105} 106 107formularioBusca?.addEventListener("submit", (evento) => { 108 evento.preventDefault(); 109 reiniciarCarregamento(); 110}); 111 112campoBusca?.addEventListener("input", reiniciarCarregamento); 113campoBusca?.addEventListener("search", reiniciarCarregamento); 114 115barraFiltros?.addEventListener("click", (evento) => { 116 const botao = evento.target.closest("[data-aulas-filtro]"); 117 118 if (!botao || !barraFiltros.contains(botao)) { 119 return; 120 } 121 122 filtroAtual = botao.dataset.aulasFiltro ?? ""; 123 barraFiltros.querySelectorAll("[data-aulas-filtro]").forEach((item) => { 124 const ativo = item === botao; 125 item.classList.toggle("ativo", ativo); 126 item.setAttribute("aria-pressed", ativo ? "true" : "false"); 127 }); 128 129 if (botao.dataset.aulasUrl && window.location.pathname !== botao.dataset.aulasUrl) { 130 window.history.pushState({ categoria: filtroAtual }, "", botao.dataset.aulasUrl); 131 } 132 133 reiniciarCarregamento(); 134}); 135 136window.addEventListener("popstate", () => { 137 const botao = Array.from(barraFiltros?.querySelectorAll("[data-aulas-filtro]") ?? []) 138 .find((item) => item.dataset.aulasUrl === window.location.pathname); 139 140 if (!botao) { 141 return; 142 } 143 144 filtroAtual = botao.dataset.aulasFiltro ?? ""; 145 barraFiltros?.querySelectorAll("[data-aulas-filtro]").forEach((item) => { 146 const ativo = item === botao; 147 item.classList.toggle("ativo", ativo); 148 item.setAttribute("aria-pressed", ativo ? "true" : "false"); 149 }); 150 reiniciarCarregamento(); 151}); 152 153botaoCarregarAulas?.addEventListener("click", carregarMaisAulas); 154 155if (botaoCarregarAulas && "IntersectionObserver" in window) { 156 observadorCarregarAulas = new IntersectionObserver((entradas) => { 157 if (entradas.some((entrada) => entrada.isIntersecting) && !botaoCarregarAulas.hidden) { 158 carregarMaisAulas(); 159 } 160 }, { rootMargin: "900px 0px" }); 161 observadorCarregarAulas.observe(botaoCarregarAulas); 162} else if (botaoCarregarAulas) { 163 botaoCarregarAulas.hidden = false;
164} 165 166window.addEventListener("scroll", carregarMaisQuandoPerto, { passive: true }); 167window.addEventListener("resize", carregarMaisQuandoPerto); 168 169botaoMenuAulas?.addEventListener("click", () => { 170 document.body.classList.toggle("aulas-sidebar-recolhida"); 171}); 172 173reiniciarCarregamento(); 174carregarMaisQuandoPerto(); 175 176function prepararDescricaoAula() { 177 if (!blocoDescricaoAula || !conteudoDescricaoAula || !botaoDescricaoAula) { 178 return; 179 } 180 181 const precisaRecolher = conteudoDescricaoAula.scrollHeight > 150; 182 blocoDescricaoAula.classList.toggle("aula-descricao--recolhivel", precisaRecolher); 183 botaoDescricaoAula.hidden = !precisaRecolher; 184 185 if (!precisaRecolher) { 186 botaoDescricaoAula.setAttribute("aria-expanded", "true"); 187 } 188} 189 190botaoDescricaoAula?.addEventListener("click", () => { 191 const expandida = blocoDescricaoAula?.classList.toggle("aula-descricao--expandida") ?? false; 192 botaoDescricaoAula.textContent = expandida ? "Ver menos" : "Ver mais"; 193 botaoDescricaoAula.setAttribute("aria-expanded", expandida ? "true" : "false"); 194}); 195 196prepararDescricaoAula();
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.