PageSourceSearch

https://radiometromix.net/assets_v2/js/spa-v2.js?v=20260820-horoscopo-spa-v1

js radiometromix.net collected 2026-10-02 02:02:03 UTC 4,299 bytes, 134 lines download raw bytes

1(function(){
2  'use strict';
3
4  const ROOT='/';
5  const allowed=new Set([
6    '', 'index.php', 'categoria.php', 'noticia.php',
7    'quem-somos.php', 'contato.php', 'envie-sua-musica.php',
8    'horoscopo.php'
9  ]);
10
11  let navigationId=0;
12  let activeController=null;
13
14  function cleanVisibleUrl(){
15    if(location.pathname!==ROOT || location.search || location.hash){
16      try{history.replaceState({rmmx:true},'',ROOT);}catch(_){ }
17    }
18  }
19
20  const legacyFiles=new Map([
21    ['index_v2.php','index.php'],
22    ['categoria_v2.php','categoria.php'],
23    ['noticia_v2.php','noticia.php'],
24    ['quem-somos_v2.php','quem-somos.php'],
25    ['contato_v2.php','contato.php']
26  ]);
27
28  function normalizeLegacyUrl(url){
29    const file=(url.pathname.split('/').pop()||'').toLowerCase();
30    const replacement=legacyFiles.get(file);
31    if(!replacement) return url;
32    const clean=new URL(url.href);
33    clean.pathname='/'+replacement;
34    return clean;
35  }
36
37  function isNavigable(url){
38    if(url.origin!==location.origin) return false;
39    const file=(url.pathname.split('/').pop()||'').toLowerCase();
40    return allowed.has(file);
41  }
42
43  function closeTransientUi(){
44    document.querySelector('.side-menu')?.classList.remove('open');
45    document.querySelector('.menu-overlay')?.classList.remove('open');
46    document.body.classList.remove('no-scroll');
47  }
48
49  async function load(url,options={}){
50    const current=document.getElementById('rmmxPageContent');
51    if(!current){location.href=url;return;}
52
53    const id=++navigationId;
54    if(activeController) activeController.abort();
55    activeController=new AbortController();
56
57    current.classList.add('rmmx-loading');
58
59    try{
60      const fetchOptions=Object.assign({},options,{
61        headers:Object.assign({'X-RMMX-SPA':'1'},options.headers||{}),
62        credentials:'same-origin',
63        signal:activeController.signal
64      });
65
66      const response=await fetch(url,fetchOptions);
67      if(!response.ok) throw new Error('HTTP '+response.status);
68      const html=await response.text();
69      if(id!==navigationId) return;
70
71      const doc=new DOMParser().parseFromString(html,'text/html');
72      const incoming=doc.getElementById('rmmxPageContent');
73      if(!incoming) throw new Error('Conteúdo inválido');
74
75      current.innerHTML=incoming.innerHTML;
76      current.className=incoming.className;
77      document.title=doc.title||document.title;
78
79      const pageClasses=[...doc.body.classList].filter(c=>c!=='no-scroll');
80      document.body.className=[...new Set(['home-v2',...pageClasses])].join(' ');
81
82      closeTransientUi();
83      cleanVisibleUrl();
84      window.scrollTo({top:0,left:0,behavior:'auto'});
85      document.dispatchEvent(new CustomEvent('rmmx:pagechange',{detail:{url:String(url)}}));
86    }catch(error){
87      if(error&&error.name==='AbortError') return;
88      console.error('[RMMX SPA]',error);
89      location.href=url;
90    }finally{
91      if(id===navigationId){
92        current.classList.remove('rmmx-loading');
93        activeController=null;
94      }
95    }
96  }
97
98  document.addEventListener('click',event=>{
99    const link=event.target.closest('a[href]');
100    if(!link||event.defaultPrevented||event.button!==0||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey) return;
101    if(link.target==='_blank'||link.hasAttribute('download')) return;
102
103    const raw=link.getAttribute('href')||'';
104    if(!raw||raw.startsWith('#')||raw.startsWith('mailto:')||raw.startsWith('tel:')||raw.startsWith('javascript:')) return;
105
106    const url=normalizeLegacyUrl(new URL(raw,location.href));
107    if(!isNavigable(url)) return;
108
109    event.preventDefault();
110    load(url.href);
111  },true);
112
113  document.addEventListener('submit',event=>{
114    const form=event.target;
115    if(!(form instanceof HTMLFormElement)) return;
116
117    const url=normalizeLegacyUrl(new URL(form.action||location.href,location.href));
118    if(!isNavigable(url)) return;
119
120    event.preventDefault();
121    const method=(form.method||'get').toUpperCase();
122    const data=new FormData(form);
123
124    if(method==='GET'){
125      for(const [key,value] of data.entries()) url.searchParams.set(key,value);
126      load(url.href);
127    }else{
128      load(url.href,{method:method,body:data});
129    }
130  },true);
131
132  cleanVisibleUrl();
133  addEventListener('popstate',cleanVisibleUrl);
134})();

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.