Código HTML do Conteúdo

Post: Delivery of €13 million in submarine cables for the Shanhaiguan offshore project


<div> <div data-elementor-id="27685" data-elementor-post-type="elementor_library" data-elementor-type="single-post"> <section data-element_type="section" data-id="597ed679"> <div> <p> document.addEventListener(&lsquo;DOMContentLoaded&rsquo;, function() {<br /> const buttons = document.querySelectorAll(&lsquo;.wpcode-tts-button&rsquo;);<br /> if (!buttons.length || !(&lsquo;speechSynthesis&rsquo; in window)) return;</p> <p> const ajaxUrl = &lsquo;https://www.redhotcyber.com/wp-admin/admin-ajax.php&rsquo;;</p> <p> function recordAudioView(postId) {<br /> fetch(ajaxUrl, {<br /> method: &lsquo;POST&rsquo;,<br /> headers: {<br /> &lsquo;Content-Type&rsquo;: &lsquo;application/x-www-form-urlencoded&rsquo;<br /> },<br /> body: &lsquo;action=wpcode_tts_view&amp;post_id=&rsquo; + encodeURIComponent(postId)<br /> })<br /> .then(response =&gt; response.json())<br /> .then(data =&gt; {<br /> if (!data.success) {<br /> console.error(&lsquo;Errore logico AJAX:&rsquo;, data.data);<br /> }<br /> })<br /> .catch(error =&gt; console.error(&lsquo;Errore di rete AJAX:&rsquo;, error));<br /> }</p> <p> let voices = [];<br /> let voicesLoaded = false;</p> <p> function loadVoices() {<br /> voices = speechSynthesis.getVoices();<br /> if (voices.length &gt; 0) {<br /> voicesLoaded = true;<br /> }<br /> }</p> <p> // Tentativo di caricamento iniziale<br /> loadVoices();</p> <p> // Assicurati che le voci vengano ricaricate quando l&rsquo;elenco cambia (evento cruciale)<br /> if (speechSynthesis.onvoiceschanged !== undefined) {<br /> speechSynthesis.onvoiceschanged = loadVoices;<br /> }</p> <p> /**<br /> * Funzione principale per avviare la sintesi vocale, con logica di retry.<br /> * @param {HTMLElement} button L&rsquo;elemento del pulsante.<br /> * @param {number} attempt Contatore dei tentativi (max 2).<br /> */<br /> function startSpeaking(button, attempt = 1) {<br /> const text = button.getAttribute(&lsquo;data-article&rsquo;);<br /> const lang = button.getAttribute(&lsquo;data-lang&rsquo;) || &lsquo;it-IT&rsquo;;<br /> const pref = button.getAttribute(&lsquo;data-voice-pref&rsquo;) || &rdquo;;<br /> const rate = parseFloat(button.getAttribute(&lsquo;data-rate&rsquo;)) || 1;<br /> const pitch = parseFloat(button.getAttribute(&lsquo;data-pitch&rsquo;)) || 1;</p> <p> if (!text) { console.error(&lsquo;Testo mancante o vuoto.&rsquo;); return; }</p> <p> // *** LOGICA DI RETRY PER IL CARICAMENTO DELLE VOCI ***<br /> if (!voicesLoaded &amp;&amp; attempt === 1) {<br /> loadVoices(); // Riprova a caricare<br /> if (!voicesLoaded) {<br /> console.warn(&ldquo;Voci non caricate al 1&deg; tentativo. Riprovo in 500ms.&rdquo;);<br /> button.textContent = &ldquo;&#9203; Caricamento vocale&hellip; (Riprovo)&rdquo;;</p> <p> // Riprova dopo 500ms<br /> setTimeout(() =&gt; startSpeaking(button, 2), 500);<br /> return;<br /> }<br /> } else if (!voicesLoaded &amp;&amp; attempt === 2) {<br /> console.error(&ldquo;Voci non caricate al 2&deg; tentativo. L&rsquo;API TTS non &egrave; disponibile.&rdquo;);<br /> button.textContent = &ldquo;&#128266; API vocale non disponibile &#10060;&rdquo;;<br /> setTimeout(() =&gt; {<br /> if (button.getAttribute(&lsquo;data-speaking&rsquo;) !== &lsquo;true&rsquo;) {<br /> button.textContent=&rdquo;&#128266; Ascolta l&rsquo;articolo&rdquo;;<br /> }<br /> }, 3000);<br /> return;<br /> }<br /> // *** FINE LOGICA DI RETRY ***</p> <p> // Cancella eventuali letture precedenti e setta lo stato<br /> speechSynthesis.cancel();<br /> document.querySelectorAll(&lsquo;.wpcode-tts-button&rsquo;).forEach(b =&gt; {<br /> if (b !== button) {<br /> b.setAttribute(&lsquo;data-speaking&rsquo;, &lsquo;false&rsquo;);<br /> b.textContent = &ldquo;&#128266; Ascolta l&rsquo;articolo&rdquo;;<br /> }<br /> });</p> <p> const utter = new SpeechSynthesisUtterance(text);<br /> utter.lang = lang;<br /> utter.rate = rate;<br /> utter.pitch = pitch;</p> <p> // Selezione voce migliorata<br /> let selectedVoice = null;<br /> if (voices.length) {<br /> const italianVoices = voices.filter(v =&gt; v.lang.startsWith(&ldquo;it&rdquo;));</p> <p> // Priorit&agrave; 1: Voci di alta qualit&agrave;<br /> if (pref === &lsquo;female&rsquo;) {<br /> selectedVoice = italianVoices.find(v =&gt; v.name.includes(&ldquo;Google&rdquo;) &amp;&amp; /(it-IT|Italian)/i.test(v.lang) &amp;&amp; /(female|femmina|alessia|lucia|carla)/i.test(v.name)) ||<br /> italianVoices.find(v =&gt; v.name.includes(&ldquo;Microsoft&rdquo;) &amp;&amp; /(female|femmina)/i.test(v.name));<br /> } else if (pref === &lsquo;male&rsquo;) {<br /> selectedVoice = italianVoices.find(v =&gt; v.name.includes(&ldquo;Google&rdquo;) &amp;&amp; /(it-IT|Italian)/i.test(v.lang) &amp;&amp; /(male|maschio|luca|paolo)/i.test(v.name)) ||<br /> italianVoices.find(v =&gt; v.name.includes(&ldquo;Microsoft&rdquo;) &amp;&amp; /(male|maschio)/i.test(v.name));<br /> }</p> <p> // Priorit&agrave; 2 &amp; 3: Fallback<br /> if (!selectedVoice) {<br /> if (pref === &lsquo;female&rsquo;) selectedVoice = italianVoices.find(v =&gt; /(female|femmina|alessia|lucia|carla)/i.test(v.name));<br /> else if (pref === &lsquo;male&rsquo;) selectedVoice = italianVoices.find(v =&gt; /(male|maschio|luca|paolo|giorgio)/i.test(v.name));<br /> }<br /> if (!selectedVoice &amp;&amp; italianVoices.length) selectedVoice = italianVoices[0];<br /> }<br /> if (selectedVoice) utter.voice = selectedVoice;</p> <p> // Handlers<br /> utter.onstart = function(){ button.setAttribute(&lsquo;data-speaking&rsquo;,&rsquo;true&rsquo;); button.textContent=&rdquo;&#9209;&#65039; Ferma la lettura&rdquo;; };<br /> utter.onend = function(){ button.setAttribute(&lsquo;data-speaking&rsquo;,&rsquo;false&rsquo;); button.textContent=&rdquo;&#128266; Ascolta l&rsquo;articolo&rdquo;; };<br /> utter.onerror = function(e){<br /> console.error(&lsquo;TTS error &ndash; Codice:&rsquo;, e.error, &lsquo;dettaglio:&rsquo;, e);<br /> button.setAttribute(&lsquo;data-speaking&rsquo;,&rsquo;false&rsquo;);<br /> //button.textContent=&rdquo;&#128266; Errore di lettura &#128542;&rdquo;;<br /> setTimeout(() =&gt; {<br /> if (button.getAttribute(&lsquo;data-speaking&rsquo;) !== &lsquo;true&rsquo;) {<br /> button.textContent=&rdquo;&#128266; Ascolta l&rsquo;articolo&rdquo;;<br /> }<br /> }, 3000);<br /> };</p> <p> speechSynthesis.speak(utter);<br /> button.setAttribute(&lsquo;data-speaking&rsquo;,&rsquo;true&rsquo;); // Setta lo stato qui per evitare click multipli<br /> }</p> <p> buttons.forEach(function(button) {<br /> button.addEventListener(&lsquo;click&rsquo;, function() {<br /> const speaking = button.getAttribute(&lsquo;data-speaking&rsquo;) === &lsquo;true&rsquo;;</p> <p> // Se stiamo parlando, ferma e resetta. Non contare il click di stop.<br /> if (speaking) {<br /> speechSynthesis.cancel();<br /> button.setAttribute(&lsquo;data-speaking&rsquo;,&rsquo;false&rsquo;);<br /> button.textContent=&rdquo;&#128266; Ascolta l&rsquo;articolo&rdquo;;<br /> return;<br /> }</p> <p> // *** LOGICA DI CONTEGGIO E AVVIO ***</p> <p> // 1. Registra la vista (se non stiamo gi&agrave; parlando)<br /> const postId = button.getAttribute(&lsquo;data-post-id&rsquo;);<br /> if (postId) {<br /> recordAudioView(postId);<br /> }</p> <p> // 2. Avvia la sintesi vocale con logica di retry<br /> startSpeaking(button);</p> <p> // **********************************<br /> });<br /> });<br /> });</p> <p> const lazyloadRunObserver = () =&gt; {<br /> const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` );<br /> const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) =&gt; {<br /> entries.forEach( ( entry ) =&gt; {<br /> if ( entry.isIntersecting ) {<br /> let lazyloadBackground = entry.target;<br /> if( lazyloadBackground ) {<br /> lazyloadBackground.classList.add( &lsquo;e-lazyloaded&rsquo; );<br /> }<br /> lazyloadBackgroundObserver.unobserve( entry.target );<br /> }<br /> });<br /> }, { rootMargin: &lsquo;200px 0px 200px 0px&rsquo; } );<br /> lazyloadBackgrounds.forEach( ( lazyloadBackground ) =&gt; {<br /> lazyloadBackgroundObserver.observe( lazyloadBackground );<br /> } );<br /> };<br /> const events = [<br /> &lsquo;DOMContentLoaded&rsquo;,<br /> &lsquo;elementor/lazyload/observe&rsquo;,<br /> ];<br /> events.forEach( ( event ) =&gt; {<br /> document.addEventListener( event, lazyloadRunObserver );<br /> } ); </p> </div> </section> </div></div>