پیش از اینکه وارد دنیای کدنویسی شویم، باید بدانیم اکستنشنهای کروم چگونه کار میکنند. یک اکستنشن کروم مانند یک برنامه وب کوچک است، اما با این تفاوت که به کامپوننتها و APIهای خاص مرورگر دسترسی دارد. اکستنشنها از اجزای مجزایی تشکیل شدهاند که در محیطهای (Environments) کاملاً متفاوتی اجرا میشوند و از طریق یک سیستم پیامرسانی (Messaging API) با یکدیگر ارتباط برقرار میکنند.
۱. فایل Manifest.json (قلب پپشرفته اکستنشن)
این فایل در واقع شناسنامه و مانیفست پروژه شماست. تمام تنظیمات، مجوزها (Permissions)، اسکریپتهای پسزمینه، آیکونها و ساختار اکستنشن در این فایل فرمت JSON تعریف میشوند. در Manifest V3، امنیت و بهینهسازی عملکرد (Performance) به شدت ارتقا یافته است.
۲. اسکریپتهای پسزمینه (Service Workers)
در Manifest V3، صفحات پسزمینه (Background Pages) جای خود را به Service Workers دادهاند. این اسکریپتها رویداد-محور (Event-driven) هستند؛ یعنی همیشه در حافظه رم مرورگر مقیم نیستند. زمانی که رویدادی (مانند کلیک روی آیکون، باز شدن یک تب جدید یا دریافت یک پیام) رخ میدهد، Service Worker بیدار میشود، کارش را انجام میدهد و دوباره برای بهینهسازی مصرف رم غیرفعال میشود. این بخش دسترسی کامل به Chrome APIs دارد اما به DOM صفحات وب دسترسی مستقیم ندارد.
۳. اسکریپتهای محتوا (Content Scripts)
این اسکریپتها مستقیماً در متن و اتمسفر صفحه وبی که کاربر در حال مشاهده آن است تزریق (Inject) میشوند. آنها به DOM صفحه دسترسی کامل دارند و میتوانند ظاهر سایتها را تغییر دهند، دادهها را استخراج کنند یا دکمههای جدیدی به صفحات اضافه کنند. با این حال، اسکریپتهای محتوا به اکثر Chrome APIs دسترسی مستقیم ندارند و محدودیتهای امنیتی شدیدی دارند.
۴. عناصر رابط کاربری (Popup & Options Pages)
Popup: پنجره کوچکی است که وقتی کاربر روی آیکون اکستنشن در نوار ابزار کروم کلیک میکند، ظاهر میشود. این پنجره یک فایل HTML استاندارد همراه با CSS و JavaScript اختصاصی خود است.
Options Page: صفحهای است که به کاربر اجازه میدهد تنظیمات اکستنشن را شخصیسازی کند (مثلاً تم تاریک/روشن، وارد کردن توکن API و غیره).
برای حفظ اصول تمیزنویسی (Clean Code) و معماری منظم، ساختار پوشههای پروژه خود را به شکل زیر پیادهسازی میکنیم. یک پوشه به نام custom-chrome-extension ایجاد کنید و ساختار زیر را در آن بچینید:
custom-chrome-extension/
│
├── manifest.json
│
├── icons/
│ ├── icon16.png
│ ├── icon48.png
│ └── icon128.png
│
├── popup/
│ ├── popup.html
│ ├── popup.css
│ └── popup.js
│
├── background/
│ └── service-worker.js
│
└── content-scripts/
└── content.js
در این پروژه، ما یک اکستنشن هوشمند خواهیم ساخت که:
یک پنل Popup زیبا برای تعامل با کاربر دارد.
متنهای انتخاب شده توسط کاربر در صفحات وب را به کمک Content Script شناسایی میکند.
اطلاعات را به Service Worker فرستاده و در chrome.storage ذخیره میکند.
گام اول: پیکربندی manifest.json
فایل مانیفست زیر را با دقت و بر اساس استانداردهای مدرن V3 تنظیم میکنیم:
{
"manifest_version": 3,
"name": "دستیار توسعهدهنده هوشمند",
"version": "1.0.0",
"description": "یک اکستنشن کاربردی برای ذخیره متون و مدیریت وظایف روزانه توسعهدهندگان.",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"action": {
"default_popup": "popup/popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"background": {
"service_worker": "background/service-worker.js"
},
"content_scripts": [
{
"matches": [""],
"js": ["content-scripts/content.js"]
}
],
"permissions": [
"storage",
"activeTab",
"contextMenus"
]
}
نکته مهندسی: استفاده از "matches": [""] به این معنی است که اسکریپت محتوای ما روی همه سایتها اجرا میشود. در پروژههای بزرگ، بهتر است دامنهها را محدود کنید تا پرفورمنس مرورگر کاربر افت نکند.
گام دوم: طراحی رابط کاربری (popup/popup.html)
یک UI مینیمال و مدرن با استفاده از HTML5 برای بخش پاپآپ طراحی میکنیم:
دستیار هوشمند کرومذخیره گام سوم: استایلدهی مدرن (popup/popup.css)
برای اینکه پاپآپ ظاهر جذابی داشته باشد، از اصول فرانتاند مدرن کمک میگیریم:
body {
width: 320px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 12px;
background-color: #f8f9fa;
color: #333;
}
.container {
display: flex;
flex-direction: column;
}
h3 {
margin: 0 0 10px 0;
color: #2c3e50;
font-size: 16px;
text-align: center;
}
hr {
border: 0;
height: 1px;
background: #ddd;
margin-bottom: 12px;
}
.form-group {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
input {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
outline: none;
}
input:focus {
border-color: #3498db;
}
button {
padding: 8px 16px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background-color: #2980b9;
}
ul {
list-style: none;
padding: 0;
margin: 0;
max-height: 200px;
overflow-y: auto;
}
li {
padding: 8px;
background: white;
margin-bottom: 6px;
border-radius: 4px;
border-right: 4px solid #3498db;
font-size: 13px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.footer {
margin-top: 10px;
font-size: 11px;
color: #7f8c8d;
text-align: center;
}
گام چهارم: منطق جاوااسکریپت پاپآپ (popup/popup.js)
در این بخش از chrome.storage.local برای ذخیره و بازیابی دادهها استفاده میکنیم. این API به صورت غیرهمزمان (Asynchronous) کار میکند.
document.addEventListener('DOMContentLoaded', () => {
const taskInput = document.getElementById('task-input');
const saveBtn = document.getElementById('save-btn');
const taskList = document.getElementById('task-list');
const statusText = document.getElementById('status-text');
// بارگذاری دادههای ذخیره شده از قبل
chrome.storage.local.get(['tasks'], (result) => {
const tasks = result.tasks || [];
tasks.forEach(task => appendTaskToList(task));
});
// رویداد کلیک دکمه ذخیره
saveBtn.addEventListener('click', () => {
const taskText = taskInput.value.trim();
if (taskText) {
chrome.storage.local.get(['tasks'], (result) => {
const tasks = result.tasks || [];
tasks.push(taskText);
chrome.storage.local.set({ tasks: tasks }, () => {
appendTaskToList(taskText);
taskInput.value = '';
statusText.textContent = 'با موفقیت ذخیره شد.';
setTimeout(() => statusText.textContent = 'آماده به کار', 2000);
});
});
}
});
function appendTaskToList(text) {
const li = document.createElement('li');
li.textContent = text;
taskList.appendChild(li);
}
});
گام پنجم: پیادهسازی اسکریپت محتوا (content-scripts/content.js)
حالا میخواهیم قابلیتی بسازیم که اگر کاربر در هر وبسایتی متنی را انتخاب (Select) کرد، اسکریپت محتوا آن متن را شنود کرده و به اکستنشن ارسال کند.
// شنود رویداد رها کردن کلیک موس برای تشخیص متن انتخاب شده
document.addEventListener('mouseup', () => {
const selectedText = window.getSelection().toString().trim();
if (selectedText.length > 0) {
// ارسال متن انتخاب شده به Service Worker پسزمینه
chrome.runtime.sendMessage({
action: "TEXT_SELECTED",
payload: selectedText
});
}
});
گام ششم: مدیریت رویدادها در پسزمینه (background/service-worker.js)
در نهایت، اسکریپت پسزمینه پیام فرستاده شده از Content Script را دریافت کرده و یک منوی راستکلیک (Context Menu) برای کاربر ایجاد میکند تا بتواند متن را مستقیماً ذخیره کند.
// ایجاد منوی راست کلیک هنگام نصب اکستنشن
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "saveSelectedText",
title: "ذخیره متن انتخاب شده در دستیار",
contexts: ["selection"]
});
});
// شنود کلیک روی منوی راست کلیک
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "saveSelectedText" && info.selectionText) {
saveToStorage(info.selectionText);
}
});
// شنود پیامهای دریافتی از Content Script
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "TEXT_SELECTED") {
console.log("متن دریافت شده در پسزمینه: ", message.payload);
// در صورت تمایل میتوانید پردازشهای بیشتری اینجا انجام دهید
}
});
// تابع کمکی برای ذخیره در Storage
function saveToStorage(text) {
chrome.storage.local.get(['tasks'], (result) => {
const tasks = result.tasks || [];
tasks.push(`کپی شده: ${text}`);
chrome.storage.local.set({ tasks: tasks }, () => {
console.log("متن با موفقیت در Storage ذخیره شد.");
});
});
}
اکنون کدنویسی ابزار تخصصی شما به پایان رسیده است. برای تست و اجرای آن روی مرورگر خود، مراحل زیر را به ترتیب دنبال کنید:
تبریک میگوییم! اکستنشن شما با موفقیت بارگذاری شد. اکنون میتوانید آیکون آن را در نوار ابزار کروم Pin کنید، روی آن کلیک کنید تا پاپآپ باز شود، یا در یک سایت متنی را انتخاب کرده و با راستکلیک کردن، آن را در حافظه اکستنشن خود ذخیره کنید.
به عنوان یک مهندس نرمافزار ارشد، رعایت نکات زیر برای ارتقای کیفیت و امنیت اکستنشن الزامی است:
مبدا محدودیت (Principle of Least Privilege): در فایل manifest.json هرگز مجوزهایی که نیاز ندارید را درخواست نکنید. برای مثال اگر به تبها نیاز ندارید، مجوز tabs را حذف کنید. این کار شانس تایید اکستنشن شما را در Chrome Web Store افزایش میدهد.
جلوگیری از حملات XSS: هنگام کار با اسکریپتهای محتوا و پاپآپ، هرگز دادههای ورودی کاربر یا متون سایتها را مستقیماً با innerHTML رندر نکنید. همیشه از textContent یا innerText استفاده کنید تا جلو تزریق کدهای مخرب جاوااسکریپت گرفته شود.
مدیریت حافظه در Service Workers: به یاد داشته باشید که متغیرهای سراسری (Global Variables) در service-worker.js با غیرفعال شدن اسکریپت از بین میروند. اگر نیاز به حفظ پایداری دادهها دارید، حتماً از chrome.storage.local استفاده کنید.
با به کارگیری این معماری ماژولار و رعایت استانداردهای مانیفست نسخه ۳، شما اکنون یک ساختار پایه بسیار قدرتمند در اختیار دارید که میتوانید آن را با اتصال به APIهای هوش مصنوعی یا پایگاههای داده ابری، به یک محصول تجاری کامل تبدیل کنید.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.