1(function() { 2 "use strict"; 3 var CONTENEDOR = "tvo-contenido"; 4 var main = document.getElementById(CONTENEDOR); 5 if (!main || !window.fetch || !window.DOMParser || !history.pushState) return; 6 if (document.body.classList.contains("admin-bar")) return; 7 var origen = location.origin; 8 var suave = window.matchMedia("(prefers-reduced-motion: no-preference)"); 9 var cache = {}; 10 var enCurso = null; 11 var aviso = document.createElement("div"); 12 aviso.className = "tvo-oculto"; 13 aviso.setAttribute("aria-live", "polite"); 14 document.body.appendChild(aviso); 15 var barra = document.createElement("div"); 16 barra.className = "tvo-navegando"; 17 document.body.appendChild(barra); 18 history.replaceState({ 19 tvo: true, 20 y: window.scrollY 21 }, "", location.href); 22 if ("scrollRestoration" in history) history.scrollRestoration = "manual"; 23 function valida(url) { 24 if (url.origin !== origen) return false; 25 var p = url.pathname; 26 if (/^\/wp-(admin|login|json|content|includes)/.test(p)) return false; 27 if (/\.(xml|txt|jpe?g|png|gif|webp|svg|pdf|zip|mp4|mp3)$/i.test(p)) return false; 28 if (/\/feed\/?$/.test(p)) return false; 29 return true; 30 } 31 function traer(url) { 32 if (cache[url]) return cache[url]; 33 cache[url] = fetch(url, { 34 credentials: "same-origin", 35 headers: { 36 "X-TVO-Navegacion": "1" 37 } 38 }).then(function(r) { 39 var tipo = r.headers.get("content-type") || ""; 40 if (!r.ok || tipo.indexOf("text/html") === -1) throw new Error("respuesta"); 41 return r.text().then(function(html) { 42 return { 43 html: html, 44 url: r.url 45 }; 46 }); 47 }).catch(function(e) { 48 delete cache[url]; 49 throw e; 50 }); 51 return cache[url]; 52 } 53 function ejecutarScripts(raiz) { 54 [].forEach.call(raiz.querySelectorAll("script"), function(viejo) { 55 if (viejo.type && viejo.type !== "text/javascript" && viejo.type !== "module") return; 56 var nuevo = document.createElement("script"); 57 [].forEach.call(viejo.attributes, function(a) { 58 nuevo.setAttribute(a.name, a.value); 59 }); 60 if (viejo.src) nuevo.async = false; else nuevo.textContent = viejo.textContent; 61 viejo.parentNode.replaceChild(nuevo, viejo); 62 }); 63 } 64 function aplicar(dato, destino, historial) { 65 var doc = (new DOMParser).parseFromString(dato.html, "text/html"); 66 var nuevo = doc.getElementById(CONTENEDOR); 67 if (!nuevo || nuevo.hasAttribute("data-recarga")) { 68 location.href = dato.url; 69 return; 70 } 71 function cambiar() { 72 if (window.TVO && window.TVO.limpiarPortada) { 73 window.TVO.limpiarPortada(); 74 window.TVO.limpiarPortada = null; 75 } 76 document.title = doc.title; 77 document.body.className = doc.body.className; 78 var descripcion = doc.querySelector('meta[name="description"]'); 79 var actual = document.querySelector('meta[name="description"]'); 80 if (actual && descripcion) actual.setAttribute("content", descripcion.getAttribute("content")); 81 main.innerHTML = nuevo.innerHTML; 82 if (nuevo.hasAttribute("data-recarga")) main.setAttribute("data-recarga", "1"); else main.removeAttribute("data-recarga"); 83 if (historial === "nuevo") history.pushState({ 84 tvo: true, 85 y: 0 86 }, "", dato.url); 87 ejecutarScripts(main); 88 if (window.TVO && window.TVO.escanear) window.TVO.escanear(main); 89 var ancla = destino.hash ? document.getElementById(decodeURIComponent(destino.hash.slice(1))) : null; 90 if (typeof historial === "number") window.scrollTo(0, historial); else if (ancla) ancla.scrollIntoView(); else window.scrollTo(0, 0); 91 if (window.TVO && window.TVO.prepararAparicion) window.TVO.prepararAparicion(main); 92 window.dispatchEvent(new Event("scroll")); 93 } 94 if (document.startViewTransition && suave.matches) document.startViewTransition(cambiar); else cambiar(); 95 main.focus({ 96 preventScroll: true 97 }); 98 aviso.textContent = doc.title; 99 document.dispatchEvent(new CustomEvent("tvo:pagina", { 100 detail: { 101 url: dato.url, 102 titulo: doc.title 103 } 104 })); 105 if (typeof window.gtag === "function") { 106 window.gtag("event", "page_view", { 107 page_location: dato.url, 108 page_title: doc.title 109 }); 110 } 111 } 112 function ir(url, historial) { 113 var destino = new URL(url, location.href); 114 var clave = destino.href.split("#")[0]; 115 var id = {}; 116 enCurso = id; 117 barra.classList.add("tvo-navegando-activo"); 118 traer(clave).then(function(dato) { 119 if (enCurso !== id) return; 120 delete cache[clave]; 121 aplicar(dato, destino, historial); 122 }).catch(function() { 123 location.href = destino.href; 124 }).then(function() { 125 if (enCurso === id) barra.classList.remove("tvo-navegando-activo"); 126 }); 127 } 128 function guardarPosicion() { 129 var estado = history.state || {}; 130 estado.tvo = true; 131 estado.y = window.scrollY; 132 history.replaceState(estado, "", location.href); 133 } 134 document.addEventListener("click", function(e) { 135 if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; 136 var a = e.target.closest("a"); 137 if (!a || !a.href || a.hasAttribute("download") || a.target && a.target !== "_self") return; 138 if (a.getAttribute("href").charAt(0) === "#") return; 139 var url = new URL(a.href, location.href); 140 if (!valida(url)) return; 141 if (url.pathname === location.pathname && url.search === location.search && url.hash) return; 142 e.preventDefault(); 143 guardarPosicion(); 144 ir(url.href, "nuevo"); 145 }); 146 document.addEventListener("submit", function(e) { 147 var form = e.target; 148 if (e.defaultPrevented || (form.method || "get").toLowerCase() !== "get") return; 149 var url = new URL(form.action || location.href, location.href); 150 if (!valida(url)) return; 151 e.preventDefault(); 152 url.search = new URLSearchParams(new FormData(form)).toString(); 153 guardarPosicion(); 154 ir(url.href, "nuevo"); 155 }); 156 function precargar(e) { 157 var a = e.target.closest && e.target.closest("a"); 158 if (!a || !a.href || a.target && a.target !== "_self") return; 159 var url = new URL(a.href, location.href); 160 if (!valida(url) || url.href.split("#")[0] === location.href.split("#")[0]) return; 161 traer(url.href.split("#")[0]).catch(function() {}); 162 } 163 document.addEventListener("mouseover", function(e) { 164 var a = e.target.closest && e.target.closest("a"); 165 if (!a || a.dataset.tvoPre) return; 166 a.dataset.tvoPre = "1"; 167 setTimeout(function() { 168 if (a.matches(":hover")) precargar(e); 169 }, 80); 170 }, { 171 passive: true 172 }); 173 document.addEventListener("touchstart", precargar, { 174 passive: true 175 }); 176 window.addEventListener("popstate", function(e) { 177 if (!e.state || !e.state.tvo) { 178 location.reload(); 179 return; 180 } 181 ir(location.href, e.state.y || 0); 182 }); 183})();
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.