Questo tutorial crea il prototipo più piccolo e utile di Chrome Manifest V3: un'area di testo privata montata sulle pagine dei Pin di Pinterest, digitata dall'ID numerico del Pin e salvata in chrome.storage.local. È intenzionalmente un prototipo, non un clone pronto per la produzione delle precedenti note di Pinterest.
Il DOM di Pinterest può cambiare senza preavviso. Mantieni i selettori isolati, evita di imitare il marchio protetto di Pinterest ed esegui test sui tipi di pagina e sulle impostazioni locali che supporti.
1. Crea l'estensione Manifest V3
Crea una cartella con manifest.json e content.js. Quello di Chrome riferimento manifesto è la fonte della verità per le chiavi disponibili.
{
"versione_manifest": 3,
"name": "Prototipo contesto pin",
"versione": "0.1.0",
"description": "Salva una nota locale privata per un Pin Pinterest.",
"autorizzazioni": ["archiviazione"],
"content_script": [{
"corrispondenze": ["https://*.pinterest.com/*"],
"js": ["content.js"],
"run_at": "document_idle"
}]
}
La corrispondenza dell'host è ampia perché Pinterest utilizza la navigazione lato client. Se la tua funzionalità supporta meno percorsi o domini nazionali, restringi e documenta tale ambito.
2. Deriva una chiave stabile dall'URL del Pin
Non inserire note chiave in base alla posizione della carta o al titolo visibile. Estrarre l'ID numerico da un canonico /spillo/…/ percorso e ritorno nullo ovunque altro.
funzione getPinId(url = posizione.href) {
prova {
const {nome percorso} = nuovo URL(url);
const corrispondenza = percorso.corrispondenza(//pin/(d+)/?/);
partita di ritorno? corrispondenza[1]: nullo;
} prendi {
restituire null;
}
}
Testa URL di dettaglio validi, stringhe di query, pagine non Pin, URL non validi e qualsiasi modello locale che affermi di supportare. Non allegare mai silenziosamente una nota quando l'ID non è sicuro.
3. Archiviare un record con versione
Mantieni lo schema esplicito in modo che siano possibili migrazioni future:
funzione asincrona readNote(pinId) {
chiave const = 'nota-pin:' + pinId;
const risultato = attendono chrome.storage.local.get(chiave);
risultato restituito[chiave] ?? { versione: 1, pinId, testo: '', aggiornatoAt: null };
}
funzione asincrona writeNote(pinId, testo) {
chiave const = 'nota-pin:' + pinId;
record costante = {
versione: 1,
ID pin,
testo,
aggiornatoAt: nuova data().toISOString()
};
attendono chrome.storage.local.set({ [chiave]: record });
registrazione del reso;
}
Chrome documenta un limite predefinito di 10 MB per storage.local, con un separato Spazio di archiviazione illimitato permesso di aumentarlo. Chrome documenta inoltre che la memoria dell'estensione locale viene cancellata quando l'estensione viene rimossa. Leggi la corrente Documentazione dell'API di archiviazione e progettare l'esportazione prima di invitare dati importanti.
4. Montare un editor isolato e accessibile
Uno Shadow DOM riduce le collisioni accidentali di stile. L'esempio viene aggiunto al corpo della pagina in modo che non dipenda da un fragile nome della classe Pinterest:
funzione asincrona mountEditor(pinId) {
if (document.querySelector('[data-pin-context-root]')) return;
const host = document.createElement('aside');
host.dataset.pinContextRoot = '';
host.setAttribute('aria-label', 'Nota Pin privata');
document.body.append(host);
const root = host.attachShadow({ modalità: 'open' });
const etichetta = document.createElement('etichetta');
label.textContent = 'Nota privata';
editor const = document.createElement('textarea');
editor.setAttribute('aria-label', 'Nota privata per questo Pin');
stato const = document.createElement('span');
status.setAttribute('ruolo', 'stato');
const salvato = attendi readNote(pinId);
editor.valore = salvato.testo;
root.append(etichetta, editor, stato);
bindAutosave(editor, stato, pinId);
}
Crea testo dell'interfaccia con testoContenuto, non inaffidabile innerHTML. Aggiungi stili di messa a fuoco visibili, contrasto sufficiente, un'etichetta reale, accesso da tastiera e testo di stato che non distolga la messa a fuoco.
5. Salva senza scrivere su ogni sequenza di tasti
funzione bindAutosave(editor, stato, pinId) {
lascia salvareTimer;
editor.addEventListener('input', () => {
status.textContent = 'Non salvato';
clearTimeout(saveTimer);
saveTimer = setTimeout(asincrono () => {
prova {
attendono writeNote(pinId, editor.value);
status.textContent = 'Salvato localmente';
} cattura (errore) {
console.error('Salvataggio nota pin non riuscito', errore);
status.textContent = 'Impossibile salvare';
}
}, 400);
});
}
Per la produzione, elimina anche gli input in sospeso nella transizione di pagina, proteggi contro la sovrascrittura reciproca di due schede, definisci una dimensione massima delle note e gli errori di quota di superficie.
6. Gestisci la navigazione lato client di Pinterest
Un gestore del caricamento della pagina una tantum non riesce a spostarsi tra il feed e le visualizzazioni dei dettagli. Utilizza una funzione di riconciliazione idempotente e osserva le modifiche senza rimontare su ogni mutazione:
lascia programmato = falso;
funzione asincrona riconcilia() {
programmato = falso;
const pinId = getPinId();
const esistente = document.querySelector('[data-pin-context-root]');
if (!pinId) {
esistente?.remove();
ritorno;
}
if (esistente?.dataset.pinId === pinId) return;
esistente?.remove();
attendono mountEditor(pinId);
const montato = document.querySelector('[data-pin-context-root]');
se (montato) montato.dataset.pinId = pinId;
}
nuovo MutationObserver(() => {
se rientro (programmato);
programmato = vero;
requestAnimationFrame(riconciliare);
}).observe(document.documentElement, {childList: true, subtree: true });
conciliare();
Una versione di produzione dovrebbe anche monitorare direttamente lo stato della navigazione, ove possibile, e disconnettere gli osservatori di cui non ha più bisogno. Profilare il codice su feed lunghi; una funzionalità corretta che riduce le prestazioni della pagina è comunque un'estensione errata.
7. Rispettare i vincoli di sicurezza di Manifest V3
Manifest V3 vieta il codice eseguibile ospitato in remoto. Raggruppa JavaScript eseguibile con l'estensione, mantieni la politica di sicurezza del contenuto predefinita a meno che non si disponga di una modifica giustificata, evita l'esecuzione di codice dinamico e richiedi solo le autorizzazioni richieste dalla funzionalità. Quello di Chrome Panoramica di Manifest V3 spiega il modello della piattaforma.
8. Aggiungi le funzionalità di cui un prodotto reale ha bisogno
- Esportazione/importazione JSON con convalida dello schema e gestione dei conflitti;
- esportazione leggibile dall'uomo per il recupero;
- ricerca e tag opzionali;
- reporting sull'utilizzo dello spazio di archiviazione e sulle quote;
- cancellazione per nota e per tutti i dati;
- una politica sulla privacy che corrisponda al comportamento osservabile;
- test di migrazione tra versioni dello schema;
- avvisi chiari di disinstallazione e mancata sincronizzazione;
- telemetria degli errori solo con un'attenta minimizzazione e divulgazione.
9. Testare i percorsi di errore
- Carica l'estensione decompressa da
chrome://estensioni. - Visita un feed, una bacheca, una pagina dei dettagli del Pin e un percorso senza Pin.
- Naviga tra due Pin senza ricaricare e conferma l'isolamento delle note.
- Apri lo stesso Pin in due schede e testa il comportamento in conflitto.
- Disabilitare l'archiviazione o simulare un errore di quota e verificare l'avviso.
- Esporta, rimuovi un record di prova e ripristinalo.
- Testa la navigazione tramite tastiera, lo zoom, le etichette dello screen reader e le condizioni della pagina scura/chiara.
La lezione di ingegneria
La textarea è la parte facile. Un'estensione Pinterest affidabile dipende da identità stabile, gestione resiliente del ciclo di vita, interfaccia utente accessibile, autorizzazioni limitate, archiviazione documentata e un percorso di uscita testato. Costruisci quelle qualità prima di espandere l'elenco delle funzionalità.
Continua a costruire il tuo sistema Pinterest
Continua con la guida che corrisponde al passaggio successivo:
Ottieni l'estensione Notestopin Chrome
Aggiungi note private a qualsiasi Pin, taggalo e cerca i tuoi salvataggi in un secondo momento.
Aggiungi a Chrome