From 75690ba775bdb676a5a8ba5d0c5f5bf31d57307e Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Thu, 24 Sep 2026 11:17:20 +0200 Subject: [PATCH] primo commit --- README.md | 3 - content.css | 144 +++++++++++++++++++++++++ content.js | 263 ++++++++++++++++++++++++++++++++++++++++++++++ icons/icon128.png | Bin 0 -> 1503 bytes icons/icon16.png | Bin 0 -> 195 bytes icons/icon32.png | Bin 0 -> 291 bytes icons/icon48.png | Bin 0 -> 464 bytes make_icon.py | 38 +++++++ manifest.json | 22 ++++ 9 files changed, 467 insertions(+), 3 deletions(-) delete mode 100644 README.md create mode 100644 content.css create mode 100644 content.js create mode 100644 icons/icon128.png create mode 100644 icons/icon16.png create mode 100644 icons/icon32.png create mode 100644 icons/icon48.png create mode 100644 make_icon.py create mode 100644 manifest.json diff --git a/README.md b/README.md deleted file mode 100644 index de545f3..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ogame_notepad - -Estensione per browser derivati da Chrome che mette un piccolo blocco note a sinistra della pagina web ogame \ No newline at end of file diff --git a/content.css b/content.css new file mode 100644 index 0000000..cb4499d --- /dev/null +++ b/content.css @@ -0,0 +1,144 @@ +/* ===== OGame Notepad - finestra flottante ===== */ +#ogame-notepad { + position: fixed; + left: 20px; + top: 20px; + width: 280px; + height: 360px; + z-index: 999999; + display: flex; + flex-direction: column; + font-family: Verdana, Arial, Helvetica, sans-serif; + background: #0b1220; + border: 1px solid #2a4a6b; + border-radius: 6px; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.65), inset 0 0 0 1px rgba(255, 255, 255, 0.03); + overflow: hidden; +} + +/* Barra del titolo (trascinabile) */ +#ogame-notepad .onp-header { + display: flex; + align-items: center; + justify-content: space-between; + background: linear-gradient(180deg, #1b2f4d, #14243c); + color: #d9b45a; + padding: 8px 10px; + border-bottom: 1px solid #2a4a6b; + font-size: 13px; + font-weight: bold; + letter-spacing: 1px; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + user-select: none; + cursor: move; +} + +#ogame-notepad .onp-title { + display: flex; + align-items: center; + gap: 7px; +} + +#ogame-notepad .onp-title .onp-dot { + width: 10px; + height: 10px; + background: radial-gradient(circle at 35% 35%, #7fd0ff, #2a6bb0); + border-radius: 50%; + box-shadow: 0 0 8px #2a6bb0; +} + +#ogame-notepad .onp-actions { + display: flex; + gap: 4px; +} + +#ogame-notepad .onp-btn { + background: transparent; + border: 1px solid transparent; + color: #9db8d6; + font-size: 14px; + cursor: pointer; + padding: 1px 6px; + line-height: 1; + border-radius: 3px; +} +#ogame-notepad .onp-btn:hover { + background: #2a4a6b; + color: #ffffff; + border-color: #3a6a9b; +} + +#ogame-notepad textarea { + flex: 1; + resize: none; + border: none; + background: #0b1220; + color: #dce6f2; + padding: 10px; + font-size: 13px; + line-height: 1.55; + font-family: inherit; + outline: none; +} +#ogame-notepad textarea::placeholder { + color: #4a5f7a; +} + +#ogame-notepad .onp-footer { + display: flex; + align-items: center; + justify-content: space-between; + background: #101a2c; + color: #6f87a3; + padding: 5px 10px; + border-top: 1px solid #2a4a6b; + font-size: 11px; +} + +#ogame-notepad .onp-footer .onp-status { + color: #6fbf6f; +} + +/* Impugnatura per il ridimensionamento (angolo in basso a destra) */ +#ogame-notepad .onp-resizer { + position: absolute; + right: 0; + bottom: 0; + width: 18px; + height: 18px; + cursor: nwse-resize; + z-index: 3; +} +#ogame-notepad .onp-resizer::after { + content: ''; + position: absolute; + right: 3px; + bottom: 3px; + width: 8px; + height: 8px; + border-right: 2px solid #3a6a9b; + border-bottom: 2px solid #3a6a9b; + border-radius: 0 0 3px 0; +} +#ogame-notepad .onp-resizer:hover::after { + border-color: #d9b45a; +} + +/* Pulsante per riaprire il notepad quando è chiuso */ +#ogame-notepad-toggle { + position: fixed; + left: 10px; + top: 20px; + z-index: 999999; + background: linear-gradient(180deg, #1b2f4d, #14243c); + color: #d9b45a; + border: 1px solid #2a4a6b; + border-radius: 6px; + padding: 10px 8px; + cursor: pointer; + font-size: 15px; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5); +} +#ogame-notepad-toggle:hover { + background: linear-gradient(180deg, #2a4a6b, #1b2f4d); +} diff --git a/content.js b/content.js new file mode 100644 index 0000000..cc01fc8 --- /dev/null +++ b/content.js @@ -0,0 +1,263 @@ +(() => { + '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(); + } + }); +})(); diff --git a/icons/icon128.png b/icons/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea8fb527bc102a06e569d186cb0d020be3c7727 GIT binary patch literal 1503 zcmV<51t9u~P) zuX0r}5XKjV84S9z5`ihAjtXXKm_7!gf|@#>0fzyB;4wNi%ph8K1sDVpS&gYG>I`X` zSy-#@FbxA**@_%kD!VVI8Q2;U-fDLKX%!3d^1XifAOBb&iw zr`CkGAbN~7Ggvc%sm`Q?w=8;$lo_lT!9*vB;^L1eyid#s7EGYtfh`N~W6=nz1_+72 zMd5uyM$j^W%0*`t-p7Iwx*LE?e0T7;HhMJL(KbO>1Nh?C4tQwLT1}+gj^9Qv6Lh%< zXUI=2ty*WEW;?OAq>b=cvT-8h`w~LqB7NW`>aLoQzq`6j{{7_b`{>^;zJAE;nQl9W zM{ic!?UfS5B0#D5yQ|Ap@wYLG-6=~uT;pAB0Ob8LZg;0_;xBO2162k<-p^wZ-4~wQ z2n#j3JZZfsX8%K^1P*cY`)AeLOAEyj0HHrjY_|8HB^4AI0HL1`Nu!kLR9ysO_TT5} z;TP5G*Xog71N5H#7vF#Myc`S1&$N5+pBE=*cR6PTRS^KQp9jfhVJ=w)K<>}u+uwKE zUARY%ZpF*MUbFw?^~)~T;pTRyd;QX7q4-n5AdSYd(Ph;DSofEqy&51Y+ZR9tn4F{m zQ2f`&KuX8#2!QZE7P)#M1x!xV00{qWSSSWvVtQsp0EB;eBQr-Bn`ws1ehEcpaYgy0}l*<<6nKQKkl=(mpUFs1n7j-C;$UY4h&!v?lces z2Iz>zGynrk4h&$J9%%pu=!~^AV0J5bE2n`j7Pq$%0gNM^24DaMETsXnDZpa5+#-ko z10b0OU;rhoqyZRUavm7KeQ2=d>&E~uEolG`g&M^|8h`;N2L@24Bnn8Z24H~6fdM8b zXaKAP`XX5jrd9w%hPQ%o8W@KA#Sx@{$;mPR(ttb?X&^_p+r_H}z@|`NTGGI>N03we zEg%96j62(F4~mKnfG8kOX%tw*_h)|&Sq4BcXct#}AF&^eLKLt`jV{>+KosapNgAk~ z{X`9?fqTynM887_r-AFZ!q-OSq7;BAV1rlZf07ZRM5p2!0Q&;{@I{UZU$XA^X?`F? zDiz?}!2hIXd+Q{uS_L2#^rNI0tkI=g;PKn96%WitTk0a-Znz6)yvfC*%f5}!yQ1;7Nn zNQzG+R0HIg;PB{;#HEKNG#=986A3;Oh)B>z5AlgsUJc_Q^sCkG;SpXDyFdFw6Gd{b zMf|DYQ0Lv7oIMq2ici!b0=W3mVD?Cm62I3DYxiwjqy+t0@1nAgzh;72&=#La$p8zp z8o`3_3+g9%Arla7(+IJpu;z)Xx&aopYy^wKFQ|9GC1wJmF^!Pg{IVcEkud`-q>Mmh z+YDqikFx45KH6sw&FhkBZw>9AxOm-@SH8YGXx{LV^`s5hFr^OgGhgc&Bzc5Tk zL)4f-ijhQj8M4zcdKzL>!F@Jy6Kk{>V=F=f0000U{{X&Q+A$aiL)`!X002ovPDHLk FV1jNzpThtE literal 0 HcmV?d00001 diff --git a/icons/icon16.png b/icons/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..7a5bb6dc13517cdb05e1a9e6ec5bc3227f5c45c3 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`U7jwEAr*6yQw}h>gyj577OpRT z&Y`?ZLU`k>!jp!I-d!th{IM@iVQ-!>%Z{t9bFSqk=5>6lxzEYmY&=~wCre`DT(=%Z z9w1ONlLL|y3=$7LPj_-~Ir_}rO<@w38*f5F!l7w4oviuqWD--F3{PA&CaC$p7vAgnzEuTDTE~Dl%vy8VlKJ)-x#o+1c=d#Wzp$P!;ctxZD literal 0 HcmV?d00001 diff --git a/icons/icon32.png b/icons/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..02a86d7a9ecf71f9dc8d9280ac5c8781543db656 GIT binary patch literal 291 zcmV+;0o?wHP))ib#y#hw%Xb28*>! zT2{5C{#m0*Ije(nroX@x16qtJAQy@`7ZSLT5PmDgzMzzJ{y30WbcEP)X3z*K+{lGX7b$%jBdrI>3>m;}#?YlqkupWxr0@t{!Y*>)!3f`kOhTux zqK}}2pCEW=KuQVciSuFW;cyMH`yG#L@6CP?cKUKY1+8hjUXOFdBrgWXL!Gt(Vp4@f zFXD2Xk}4$1cs(4h+>TS)u8$HCWa!)Vw(D8vVxr+SFzx#H*M}YtFRyw$zQ5hs#m;Sa z`#YPEXsmLa=Y~G}az1&lW~+cu=VABg4yVq=if~3C6qAFwbD1Zs?_sJVoWVj@bw6s5hyJpq`?v0VwyUU zx4S)WiwOg_(^MkBdG;nBMs%AMBeu~^5&Nlui4q@si01|)I|pZx(}idN0000