NaviRestauro Italia
Home
Servizi
Catalogo
Prezzi
Blog
Chi Siamo
FAQ
Contatti
Preferiti
Carrello
Menu
Cerca
Accedi
Registrati
Tema
Blog
Più recenti
Azzera
Carica altri
Link copiato
🔗
✕
') ]); document.querySelector('header').innerHTML=h; document.querySelector('footer').innerHTML=f; const savedTheme=localStorage.getItem('theme')||'light'; document.documentElement.classList.toggle('dark', savedTheme==='dark'); initEvents(); } function initEvents(){ document.body.addEventListener('click',(e)=>{ const t=e.target; if(t.matches('[data-open]')) document.querySelector(t.getAttribute('data-open'))?.showModal(); if(t.matches('[data-close]')) { const dlg = document.querySelector(t.getAttribute('data-close')); dlg?.close(); if(dlg?.id==='post-modal') clearPostUrl(); } if(t.id==='theme-toggle-apply'){ const v=document.querySelector('input[name="theme-choice"]:checked')?.value||'light'; localStorage.setItem('theme',v); document.documentElement.classList.toggle('dark', v==='dark'); document.querySelector('#modal-theme')?.close(); } }); const banner=document.querySelector('#cookie-banner'); if(banner && !localStorage.getItem('cookie-ok')) banner.classList.remove('hidden'); document.querySelector('#cookie-accept')?.addEventListener('click', ()=>{ localStorage.setItem('cookie-ok','1'); banner?.classList.add('hidden'); }); } function createSkeletonCards(count=4){ const wrap = document.getElementById('posts'); wrap.innerHTML = ''; for(let i=0;i
r.json()); sessionStorage.setItem(cacheKey, JSON.stringify(data)); } state.posts = Array.isArray(data) ? data.slice() : []; restorePreferences(); buildFilters(); render(); handleInitialOpen(); attachInteractions(); }catch(e){ const wrap = document.getElementById('posts'); wrap.innerHTML = '
Errore nel caricamento degli articoli. Riprova più tardi.
'; } } function restorePreferences(){ const p = JSON.parse(localStorage.getItem('nr-blog-prefs')||'{}'); if(typeof p.sortDesc==='boolean') state.sortDesc = p.sortDesc; if(p.tag) state.tag = p.tag; const sortBtn = document.getElementById('sort-toggle'); sortBtn.textContent = state.sortDesc ? 'Più recenti' : 'Meno recenti'; } function savePreferences(){ localStorage.setItem('nr-blog-prefs', JSON.stringify({ sortDesc: state.sortDesc, tag: state.tag })); } function buildFilters(){ const tagSet = new Set(); state.posts.forEach(p => (Array.isArray(p.tags)?p.tags:[]).forEach(t=>tagSet.add(t))); const tags = ['Tutti', ...Array.from(tagSet).sort((a,b)=>a.localeCompare(b,'it'))]; const box = document.getElementById('tag-filters'); box.innerHTML=''; tags.forEach(tag=>{ const b=document.createElement('button'); const active = (state.tag===null && tag==='Tutti') || (state.tag===tag); b.className = `px-3 py-1.5 rounded-full text-sm border ${active?'g4s0p':'t1w8z'} xk9h7`; b.textContent = tag; b.dataset.tag = tag==='Tutti' ? '' : tag; box.appendChild(b); }); } function getFilteredSorted(){ let list = state.posts.slice(); if(state.tag) list = list.filter(p=>Array.isArray(p.tags) && p.tags.includes(state.tag)); list.sort((a,b)=> state.sortDesc ? new Date(b.date)-new Date(a.date) : new Date(a.date)-new Date(b.date)); return list; } function render(){ const wrap = document.getElementById('posts'); const info = document.getElementById('info'); const btnMore = document.getElementById('load-more'); const list = getFilteredSorted(); const total = list.length; const upto = Math.min(state.page*state.perPage, total); const view = list.slice(0, upto); wrap.innerHTML=''; if(view.length===0){ wrap.innerHTML = '
Nessun articolo trovato.
'; } else { view.forEach(p=>{ const card = document.createElement('article'); card.className = 'xk9h7 border border-gray-200 dark:border-slate-800 rounded-xl p-5 bg-white dark:bg-slate-900'; const tags = (p.tags||[]).map(t=>`
${t}
`).join(' '); const dateStr = new Date(p.date).toLocaleDateString('it-IT'); card.innerHTML = `
${escapeHTML(p.title)}
${dateStr}
${escapeHTML(p.excerpt)}
${tags}
Leggi
Anteprima
`; wrap.appendChild(card); }); } info.textContent = total>0 ? `Visualizzati ${view.length} di ${total} articoli${state.tag?` — filtro: ${state.tag}`:''}` : ''; if(upto < total){ btnMore.classList.remove('hidden'); } else { btnMore.classList.add('hidden'); } } function attachInteractions(){ if(state.mounted) return; state.mounted = true; document.getElementById('tag-filters').addEventListener('click', (e)=>{ const btn = e.target.closest('button[data-tag]'); if(!btn) return; const tag = btn.dataset.tag || null; state.tag = tag; state.page = 1; savePreferences(); buildFilters(); render(); }); document.getElementById('sort-toggle').addEventListener('click', ()=>{ state.sortDesc = !state.sortDesc; document.getElementById('sort-toggle').textContent = state.sortDesc ? 'Più recenti' : 'Meno recenti'; savePreferences(); state.page = 1; render(); }); document.getElementById('reset-filters').addEventListener('click', ()=>{ state.tag = null; state.page = 1; state.sortDesc = true; savePreferences(); buildFilters(); render(); }); document.getElementById('load-more').addEventListener('click', ()=>{ state.page += 1; render(); }); const wrap = document.getElementById('posts'); wrap.addEventListener('click', (e)=>{ const btn = e.target.closest('button[data-id]'); const prev = e.target.closest('button[data-preview]'); if(btn){ const id = Number(btn.getAttribute('data-id')); const post = state.posts.find(x=>x.id===id); if(post) openPost(post, true); } if(prev){ const id = Number(prev.getAttribute('data-preview')); const post = state.posts.find(x=>x.id===id); if(post) openPost(post, false); } }); document.getElementById('post-modal').addEventListener('click', (e)=>{ const dlg = e.currentTarget; const rect = dlg.getBoundingClientRect(); const inDialog = (e.clientX>=rect.left && e.clientX<=rect.right && e.clientY>=rect.top && e.clientY<=rect.bottom); if(!inDialog){ dlg.close(); clearPostUrl(); } }); document.getElementById('share-btn').addEventListener('click', async ()=>{ const title = document.getElementById('post-title').textContent.trim(); const url = new URL(location.href); const slug = url.searchParams.get('post'); const shareUrl = slug ? url.href : url.origin + url.pathname; try{ if(navigator.share){ await navigator.share({ title, url: shareUrl }); } else { await navigator.clipboard.writeText(shareUrl); showCopyTip(); } }catch(e){ /* ignore */ } }); window.addEventListener('popstate', ()=>{ const slug = new URL(location.href).searchParams.get('post'); if(slug){ const post = state.posts.find(p=>p.slug===slug); if(post) openPost(post, false, false); } else { document.getElementById('post-modal').close(); } }); } function computeReadingTimeFromHTML(html){ const div = document.createElement('div'); div.innerHTML = html; const text = div.textContent || ''; const words = text.trim().split(/\s+/).filter(Boolean).length; const wpm = 220; const mins = Math.max(1, Math.round(words / wpm)); return { mins, words }; } function openPost(post, push=true, focusDialog=true){ const dlg = document.getElementById('post-modal'); const titleEl = document.getElementById('post-title'); const metaEl = document.getElementById('post-meta'); const contentEl = document.getElementById('post-content'); titleEl.textContent = post.title; const dateStr = new Date(post.date).toLocaleDateString('it-IT'); const rt = computeReadingTimeFromHTML(post.content); const tags = (post.tags||[]).map(t=>`
${t}
`).join(' '); metaEl.innerHTML = `
${dateStr}
•
${rt.mins} min lettura
${tags?`•
${tags}
`:''}`; contentEl.innerHTML = sanitizeHTML(post.content); enhancePostContentLinks(contentEl); if(!dlg.open) dlg.showModal(); if(focusDialog) titleEl.focus({preventScroll:true}); if(push){ const url = new URL(location.href); url.searchParams.set('post', post.slug); history.pushState({ post: post.slug }, '', url.toString()); } } function clearPostUrl(){ const url = new URL(location.href); if(url.searchParams.has('post')){ url.searchParams.delete('post'); history.pushState({}, '', url.toString()); } } function handleInitialOpen(){ const slug = new URL(location.href).searchParams.get('post'); if(slug){ const post = state.posts.find(p=>p.slug===slug); if(post) openPost(post, false); } } function enhancePostContentLinks(container){ container.querySelectorAll('a[href]').forEach(a=>{ const href = a.getAttribute('href')||''; if(/^https?:\/\//i.test(href)){ a.setAttribute('target','_blank'); a.setAttribute('rel','noopener noreferrer'); } }); } function escapeHTML(str){ return String(str).replace(/[&<>"']/g, s=>({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[s])); } function sanitizeHTML(html){ const template = document.createElement('template'); template.innerHTML = html; const allowed = ['P','UL','OL','LI','A','STRONG','EM','B','I','H1','H2','H3','H4','H5','BLOCKQUOTE','IMG','BR','HR','PRE','CODE','SPAN','FIGURE','FIGCAPTION']; const walker = (node)=>{ [...node.children].forEach(child=>{ if(!allowed.includes(child.tagName)){ const span = document.createElement('span'); span.innerHTML = child.innerHTML; child.replaceWith(span); walker(span); }else{ if(child.tagName==='A'){ const href = child.getAttribute('href')||'#'; if(href.startsWith('javascript:')) child.setAttribute('href','#'); } if(child.tagName==='IMG'){ const src = child.getAttribute('src')||''; if(/^javascript:/i.test(src)) child.remove(); child.setAttribute('loading','lazy'); child.setAttribute('decoding','async'); child.setAttribute('alt', child.getAttribute('alt')||'Immagine'); child.style.maxWidth='100%'; child.style.height='auto'; } walker(child); } }); }; walker(template.content); return template.innerHTML; } function showCopyTip(){ const tip = document.getElementById('copy-tip'); tip.classList.add('show'); setTimeout(()=>tip.classList.remove('show'), 1600); } mountLayout().then(loadPosts); document.addEventListener('keydown',(e)=>{ if(e.key==='Escape'){ document.querySelectorAll('dialog[open]').forEach(d=>d.close()); clearPostUrl(); } if(e.key==='ArrowRight' || e.key==='ArrowLeft'){ const slug = new URL(location.href).searchParams.get('post'); if(!slug) return; const list = getFilteredSorted(); const idx = list.findIndex(p=>p.slug===slug); if(idx<0) return; const next = e.key==='ArrowRight' ? list[idx+1] : list[idx-1]; if(next) openPost(next, true); } });