(() => { 'use strict'; // Doppia sicurezza: attivo solo sul dominio richiesto if (window.location.hostname !== 's170-ar.ogame.gameforge.com') { return; } const STORAGE_KEY = 'ogame_notepad_text'; const COLLAPSED_KEY = 'ogame_notepad_collapsed'; const POS_KEY = 'ogame_notepad_pos'; const SIZE_KEY = 'ogame_notepad_size'; // ---- Creazione elementi ---- const container = document.createElement('div'); container.id = 'ogame-notepad'; const header = document.createElement('div'); header.className = 'onp-header'; header.innerHTML = 'Notepad' + '' + '' + ''; const textarea = document.createElement('textarea'); textarea.placeholder = 'Scrivi le tue note qui...'; textarea.spellcheck = false; const footer = document.createElement('div'); footer.className = 'onp-footer'; footer.innerHTML = '0 caratteri' + '● Salvato'; const resizer = document.createElement('div'); resizer.className = 'onp-resizer'; resizer.title = 'Trascina per ridimensionare'; container.appendChild(header); container.appendChild(textarea); container.appendChild(footer); container.appendChild(resizer); document.body.appendChild(container); // Pulsante per riaprire quando chiuso const toggleBtn = document.createElement('button'); toggleBtn.id = 'ogame-notepad-toggle'; toggleBtn.innerHTML = '▶'; toggleBtn.title = 'Apri notepad'; document.body.appendChild(toggleBtn); const countEl = footer.querySelector('#onp-count'); const statusEl = footer.querySelector('.onp-status'); // ---- Persistenza ---- let saveTimer = null; let dirty = false; // true se ci sono modifiche non ancora salvate let syncing = false; // evita loop quando aggiorniamo da un'altra tab function loadNote() { try { const saved = localStorage.getItem(STORAGE_KEY); if (saved !== null) { textarea.value = saved; } } catch (e) { /* storage non disponibile */ } updateCount(); } function saveNote() { dirty = false; try { localStorage.setItem(STORAGE_KEY, textarea.value); statusEl.textContent = '\u25CF Salvato'; statusEl.style.color = '#6fbf6f'; } catch (e) { statusEl.textContent = '\u26A0 Errore salvataggio'; statusEl.style.color = '#e0a050'; } } function updateCount() { const n = textarea.value.length; countEl.textContent = n + (n === 1 ? ' carattere' : ' caratteri'); } // Salvataggio automatico con debounce textarea.addEventListener('input', () => { dirty = true; updateCount(); statusEl.textContent = '\u25CF Salvataggio...'; statusEl.style.color = '#d8d8a0'; clearTimeout(saveTimer); saveTimer = setTimeout(saveNote, 400); }); // Sincronizzazione in tempo reale tra le tab dello stesso dominio. // Quando un'altra tab salva, questa riceve l'evento 'storage' e aggiorna // la textarea, così premendo F5 qui trovi sempre i dati più recenti. window.addEventListener('storage', (e) => { if (e.key !== STORAGE_KEY) return; // Non sovrascrivere mentre l'utente sta digitando in questa tab if (document.activeElement === textarea && dirty) return; syncing = true; textarea.value = e.newValue !== null ? e.newValue : ''; updateCount(); statusEl.textContent = '\u25CF Salvato'; statusEl.style.color = '#6fbf6f'; syncing = false; }); // ---- Trascinamento finestra ---- function restorePosition() { try { const saved = localStorage.getItem(POS_KEY); if (saved) { const pos = JSON.parse(saved); if (typeof pos.left === 'number' && typeof pos.top === 'number') { container.style.left = pos.left + 'px'; container.style.top = pos.top + 'px'; } } } catch (e) {} } function restoreSize() { try { const saved = localStorage.getItem(SIZE_KEY); if (saved) { const size = JSON.parse(saved); if (typeof size.w === 'number') container.style.width = size.w + 'px'; if (typeof size.h === 'number') container.style.height = size.h + 'px'; } } catch (e) {} } function makeResizable() { let startX = 0, startY = 0, startW = 0, startH = 0, resizing = false; resizer.addEventListener('mousedown', (e) => { resizing = true; startX = e.clientX; startY = e.clientY; startW = container.offsetWidth; startH = container.offsetHeight; e.preventDefault(); e.stopPropagation(); }); window.addEventListener('mousemove', (e) => { if (!resizing) return; const newW = Math.max(200, startW + (e.clientX - startX)); const newH = Math.max(160, startH + (e.clientY - startY)); container.style.width = newW + 'px'; container.style.height = newH + 'px'; }); window.addEventListener('mouseup', () => { if (!resizing) return; resizing = false; try { localStorage.setItem(SIZE_KEY, JSON.stringify({ w: container.offsetWidth, h: container.offsetHeight })); } catch (e) {} }); } function makeDraggable() { let dragStartX = 0, dragStartY = 0, origLeft = 0, origTop = 0, dragging = false; header.addEventListener('mousedown', (e) => { if (e.target.closest('.onp-btn')) return; // non trascinare quando clicchi i bottoni dragging = true; dragStartX = e.clientX; dragStartY = e.clientY; const rect = container.getBoundingClientRect(); origLeft = rect.left; origTop = rect.top; e.preventDefault(); }); window.addEventListener('mousemove', (e) => { if (!dragging) return; const dx = e.clientX - dragStartX; const dy = e.clientY - dragStartY; container.style.left = (origLeft + dx) + 'px'; container.style.top = (origTop + dy) + 'px'; }); window.addEventListener('mouseup', () => { if (!dragging) return; dragging = false; try { localStorage.setItem(POS_KEY, JSON.stringify({ left: container.getBoundingClientRect().left, top: container.getBoundingClientRect().top })); } catch (e) {} }); } // ---- Collapse / expand ---- function setCollapsed(collapsed) { container.classList.toggle('collapsed', collapsed); toggleBtn.style.display = collapsed ? 'block' : 'none'; try { localStorage.setItem(COLLAPSED_KEY, collapsed ? '1' : '0'); } catch (e) {} } header.querySelector('#onp-collapse').addEventListener('click', () => { setCollapsed(true); }); toggleBtn.addEventListener('click', () => { setCollapsed(false); textarea.focus(); }); // ---- Blocca le scorciatoie di OGame quando il focus è sul notepad ---- // Intercetta in fase di cattura così gli handler globali di OGame // (frecce, spazio, invio, ecc.) non reagiscono mentre scrivi. function blockKeysWhileTyping(e) { if (document.activeElement === textarea) { // Blocca SOLO la propagazione verso gli handler globali di OGame, // ma NON chiama preventDefault: così la textarea continua a inserire // caratteri, spostare il cursore, creare nuove righe, ecc. e.stopImmediatePropagation(); return false; } } window.addEventListener('keydown', blockKeysWhileTyping, true); window.addEventListener('keyup', blockKeysWhileTyping, true); window.addEventListener('keypress', blockKeysWhileTyping, true); // ---- Init ---- restorePosition(); restoreSize(); makeDraggable(); makeResizable(); loadNote(); let collapsed = false; try { collapsed = localStorage.getItem(COLLAPSED_KEY) === '1'; } catch (e) {} setCollapsed(collapsed); // Salva al cambio pagina SOLO se ci sono modifiche non ancora salvate. // In questo modo una tab "stantia" non sovrascrive i dati più recenti // scritti da un'altra tab quando premi F5. window.addEventListener('beforeunload', () => { if (dirty) { clearTimeout(saveTimer); saveNote(); } }); })();