Bu eğitimde işe yarayan en küçük Chrome Manifest V3 prototipini geliştireceğiz: Pinterest Pin sayfalarına eklenen, sayısal Pin kimliğini anahtar olarak kullanan ve chrome.storage.local içinde saklanan özel bir metin alanı. Bu örnek özellikle prototip olarak sınırlandırılmıştır; Pinterest'in eski not özelliğinin kullanıma hazır bir kopyası değildir.
Pinterest'in DOM yapısı bildirim yapılmadan değişebilir. Seçicileri tek bir yerde yalıtın, Pinterest'in korunan marka öğelerini taklit etmeyin ve desteklediğiniz bütün sayfa türleri ile dil sürümlerinde test yapın.
1. Manifest V3 uzantısını oluşturun
Şu dosyaları içeren bir klasör oluşturun: manifest.json ve content.js. Kullanılabilen anahtarlar için Chrome'un manifest başvuru belgesini kesin kaynak olarak kullanın.
{
"manifest_version": 3,
"name": "Pin Bağlamı Prototipi",
"version": "0.1.0",
"description": "Bir Pinterest Pini için özel yerel not kaydedin.",
"permissions": ["storage"],
"content_scripts": [{
"matches": ["https://*.pinterest.com/*"],
"js": ["content.js"],
"run_at": "document_idle"
}]
}
Pinterest istemci taraflı gezinme kullandığından eşleşen sunucu kapsamı geniş tutulmuştur. Özelliğiniz daha az yolu veya ülke alan adını destekliyorsa kapsamı daraltın ve belgeleyin.
2. Pin adresinden kararlı bir anahtar türetin
Notları kartın konumuna veya görünen başlığına göre anahtarlamayın. Standart /pin/…/ yolundan sayısal kimliği çıkarın; diğer bütün durumlarda null döndürün.
function getPinId(url = location.href) {
try {
const { pathname } = new URL(url);
const match = pathname.match(/\/pin\/(\d+)\/?/);
return match ? match[1] : null;
} catch {
return null;
}
}
Geçerli ayrıntı adreslerini, sorgu dizelerini, Pin olmayan sayfaları, hatalı adresleri ve desteklediğinizi belirttiğiniz bütün dil kalıplarını test edin. Kimlik kesin değilken bir notu asla sessizce bağlamayın.
3. Sürümlendirilmiş kayıt saklayın
Gelecekte veri geçişi yapabilmek için şemayı açıkça tanımlayın:
async function readNote(pinId) {
const key = 'pin-note:' + pinId;
const result = await chrome.storage.local.get(key);
return result[key] ?? { version: 1, pinId, text: '', updatedAt: null };
}
async function writeNote(pinId, text) {
const key = 'pin-note:' + pinId;
const record = {
version: 1,
pinId,
text,
updatedAt: new Date().toISOString()
};
await chrome.storage.local.set({ [key]: record });
return record;
}
Chrome belgelerine göre storage.local için varsayılan sınır 10 MB'dir. Bu sınırı artırmak için ayrı bir unlimitedStorage izni kullanılabilir. Chrome ayrıca uzantı kaldırıldığında yerel uzantı depolamasının silindiğini belirtir. Güncel Storage API belgesini okuyun ve kullanıcıların önemli verilerini kaydetmesine izin vermeden önce dışa aktarma özelliğini tasarlayın.
4. Yalıtılmış ve erişilebilir bir düzenleyici ekleyin
Shadow DOM istenmeyen stil çakışmalarını azaltır. Örnek, kolayca değişebilen bir Pinterest sınıf adına bağımlı olmamak için öğeyi sayfanın body bölümüne ekler:
async function mountEditor(pinId) {
if (document.querySelector('[data-pin-context-root]')) return;
const host = document.createElement('aside');
host.dataset.pinContextRoot = '';
host.setAttribute('aria-label', 'Özel Pin notu');
document.body.append(host);
const root = host.attachShadow({ mode: 'open' });
const label = document.createElement('label');
label.textContent = 'Özel not';
const editor = document.createElement('textarea');
editor.id = 'pin-note-editor';
label.htmlFor = editor.id;
editor.setAttribute('aria-label', 'Bu Pin için özel not');
const status = document.createElement('span');
status.setAttribute('role', 'status');
const saved = await readNote(pinId);
editor.value = saved.text;
root.append(label, editor, status);
bindAutosave(editor, status, pinId);
}
Arayüz metnini textContent ile oluşturun; güvenilmeyen değerleri innerHTML ile eklemeyin. Görünür odak stilleri, yeterli karşıtlık, gerçek bir etiket, klavye erişimi ve odağı üzerine almayan durum metni de ekleyin.
5. Her tuş vuruşunda yazmadan kaydedin
function bindAutosave(editor, status, pinId) {
let saveTimer;
editor.addEventListener('input', () => {
status.textContent = 'Kaydedilmedi';
clearTimeout(saveTimer);
saveTimer = setTimeout(async () => {
try {
await writeNote(pinId, editor.value);
status.textContent = 'Yerel olarak kaydedildi';
} catch (error) {
console.error('Pin notu kaydedilemedi', error);
status.textContent = 'Kaydedilemedi';
}
}, 400);
});
}
Üretim sürümünde sayfa geçişi sırasında bekleyen girdiyi de kaydedin, iki sekmenin birbirinin değişikliklerini ezmesini önleyin, en büyük not boyutunu belirleyin ve depolama kotası hatalarını kullanıcıya gösterin.
6. Pinterest'in istemci taraflı gezinmesini yönetin
Sayfa yüklenirken yalnızca bir kez çalışan işleyici, akış ile ayrıntı görünümü arasındaki geçişleri kaçırır. Tekrar çalıştırıldığında aynı sonucu veren bir uzlaştırma işlevi kullanın ve her DOM değişikliğinde arayüzü yeniden eklemeden değişiklikleri izleyin:
let scheduled = false;
async function reconcile() {
scheduled = false;
const pinId = getPinId();
const existing = document.querySelector('[data-pin-context-root]');
if (!pinId) {
existing?.remove();
return;
}
if (existing?.dataset.pinId === pinId) return;
existing?.remove();
await mountEditor(pinId);
const mounted = document.querySelector('[data-pin-context-root]');
if (mounted) mounted.dataset.pinId = pinId;
}
new MutationObserver(() => {
if (scheduled) return;
scheduled = true;
requestAnimationFrame(reconcile);
}).observe(document.documentElement, { childList: true, subtree: true });
reconcile();
Üretim sürümü mümkün olduğunda gezinme durumunu doğrudan izlemeli ve artık gerek duymadığı gözlemcileri devre dışı bırakmalıdır. Kodu uzun akışlarda profilleyin; doğru çalışan bir özellik sayfa performansını düşürüyorsa yine kötü bir uzantıdır.
7. Manifest V3 güvenlik kısıtlarına uyun
Manifest V3, uzakta barındırılan çalıştırılabilir kodu yasaklar. Çalıştırılabilir JavaScript'i uzantıyla paketleyin, değiştirmek için geçerli bir nedeniniz yoksa varsayılan içerik güvenliği politikasını koruyun, dinamik kod çalıştırmaktan kaçının ve yalnızca özelliğin gerektirdiği izinleri isteyin. Chrome'un Manifest V3 genel bakış belgesi platform modelini açıklar.
8. Gerçek bir ürünün gerektirdiği özellikleri ekleyin
- şema doğrulaması ve çakışma yönetimiyle JSON dışa ve içe aktarma
- kurtarma için insanların okuyabileceği dışa aktarma biçimi
- arama ve isteğe bağlı etiketler
- depolama kullanımı ve kota bilgileri
- tek tek notları ve bütün verileri silme seçenekleri
- gözlemlenebilen davranışla uyuşan gizlilik politikası
- şema sürümleri arasında veri geçişi testleri
- kaldırma ve senkronizasyon olmaması hakkında açık uyarılar
- yalnızca dikkatle en aza indirilmiş ve açıkça bildirilmiş hata telemetrisi
9. Hata yollarını test edin
- Paketlenmemiş uzantıyı şu sayfadan yükleyin:
chrome://extensions. - Bir akışı, panoyu, Pin ayrıntı sayfasını ve Pin olmayan bir yolu ziyaret edin.
- Sayfayı yenilemeden iki Pin arasında geçiş yapın ve notların birbirinden ayrı kaldığını doğrulayın.
- Aynı Pini iki sekmede açın ve çakışma davranışını test edin.
- Depolamayı devre dışı bırakın veya kota hatasını taklit edin ve uyarının gösterildiğini doğrulayın.
- Verileri dışa aktarın, bir test kaydını silin ve geri yükleyin.
- Klavye ile gezinmeyi, yakınlaştırmayı, ekran okuyucu etiketlerini ve koyu ya da açık sayfa koşullarını test edin.
Mühendislik açısından çıkarılacak ders
Metin alanı işin kolay kısmıdır. Güvenilir bir Pinterest uzantısı; kararlı kimliğe, dayanıklı yaşam döngüsü yönetimine, erişilebilir arayüze, sınırlı izinlere, belgelenmiş depolamaya ve test edilmiş bir çıkış yoluna bağlıdır. Özellik listesini genişletmeden önce bu temelleri kurun.
Pinterest düzeninizi geliştirmeye devam edin
Sıradaki adımınıza uygun rehberle devam edin:
Notestopin Chrome uzantısını deneyin
Pinlere özel notlar ve etiketler ekleyin, kaydettiklerinizi daha sonra kolayca bulun.
Chrome'a ekle