اولین افزونه فایرفاکس من – انجمن DEV

چند هفته پیش، آخر هفته را صرف ساختن دیگری کردم CFP کمک کننده ارسال در قالب پسوند فایرفاکس. پیاده روی در پارک نبود. برای کمک به دیگرانی که ممکن است علاقه مند به انجام همین کار (و خود آینده من) باشند، این سفر من است.
متن نوشته
من چندین پست در مورد گردش کار ارسال کنفرانس خود نوشته ام. برای جمع بندی:
- همه چیز بر اساس یک برد Trello است
- من یک برنامه ایجاد کردم که یک وب هوک را روی برد ثبت کرد
- وقتی کنفرانسی را از یک خط به خط دیگر منتقل میکنم، یک جریان کاری را در سمت برنامه شروع یا ادامه میدهد
من تابلو را با نگاه کردن به وبسایتها، عمدتاً Papercall و Sessionize، و کپی دستی دادههای کنفرانس روی کارتها، منبع میکنم. دو گزینه اتوماسیون موجود است:
- خودکارسازی منابع کنفرانس
- ایجاد خودکار کارت
در مورد قسمت اول خیلی فکر کردم. اگر آن را خودکار کنم، یک لیست طولانی از کارتهای Trello ایجاد میکند که به هر حال باید آنها را فیلتر کنم. من به این نتیجه رسیدم که بهتر است آنها را قبلاً فیلتر کنم.
با این حال، من کارت را به صورت دستی با کپی کردن اطلاعات مربوطه ایجاد کردم: نام، تاریخ، تاریخ سررسید، پیوند CFP و وب سایت. این دقیقاً همان چیزی است که یک افزونه فایرفاکس می تواند به شما کمک کند.
الزامات و طراحی
داستان کاربر بسیار ساده است:
AS A: توسعه دهنده تنبل
من می خواهم: به طور خودکار داده های CFP را در Trello هنگام مرور یک صفحه وب در Papercall یا Sessionize اضافه کنید
SO AS: اینکه وقتم را صرف انجام کارهای سرگرم کننده تر از کپی پیست کنم— داستان تک کاربر من
تنها نیاز من این است که باید با فایرفاکس کار کند.
ایده اول من دکمه ای است که ایجاد را فعال می کند، اما برای من اهمیتی ندارد که کجا باشد: داخل صفحه به عنوان یک پوشش یا جایی در مرورگر. در حالت اول، باید یک جاوا اسکریپت تزریق شده در سمت مشتری باشد. از سوی دیگر، یک افزونه فایرفاکس. من گزینه دوم را انتخاب کردم زیرا باید چگونگی دستیابی به اولین را بیابم.
همچنین می خواستم ابتدا افزونه خود را در Rust با WebAssembly ایجاد کنم. اسپویلر: نداشتم.
یک افزونه ساده فایرفاکس
من هیچ سرنخی در مورد نوشتن افزونه فایرفاکس نداشتم، زیرا این اولین باری بود که یک افزونه می نوشتم. اولین قدم من دنبال کردن آموزش بود. مبانی ساختار توسعه را توضیح می دهد. سپس، آموزش دوم را دنبال کردم. نحوه ایجاد یک منوی پاپ آپ برای برنامه افزودنی را توضیح می دهد، اما نحوه تعامل با صفحه وب را توضیح نمی دهد. در این مرحله تصمیم گرفتم از طریق انجام دادن یاد بگیرم، تکنیکی که برای من خوب عمل می کند.
پسوند فایرفاکس با مانیفست شروع می شود. در اینجا یکی از آموزش اول، ساده شده است:
{
"manifest_version": 2,
"name": "Borderify",
"version": "1.0",
"content_scripts": [
{
"js": ["borderify.js"]
}
]
}
document.body.style.border = '5px solid red';
من حلقه بازخورد توسعه را خوب یافتم. تصور کنید که آموزش را دنبال کرده اید و تمام فایل های لازم را در بالا ایجاد کرده اید. می توانید به about:debugging#/runtime/this-firefox و روی دکمه “Load Temporary Add-on” کلیک کنید.
سپس به فایل مانیفست خود اشاره کنید. فایرفاکس افزونه را بارگیری می کند: اکنون فعال است.
در مثال بالا، جاوا اسکریپت از آموزش یک حاشیه قرمز در اطراف هر صفحه وب اضافه می کند. این بی فایده است، ما می توانیم بهتر انجام دهیم، اما نشان می دهد که چگونه کار می کند. ما می توانیم اسکریپت را برای تغییر رنگ تغییر دهیم، به عنوان مثال، از جانب red
به green
. برای بارگذاری مجدد فایرفاکس هر تغییری، از جمله تغییرات در مانیفست، روی دکمه “بارگذاری مجدد” در پانل برنامه افزودنی موقت کلیک کنید.
تعامل با افزونه
همانطور که در بالا ذکر کردم، من دکمه ای می خواهم که ایجاد Trello Card را آغاز کند. فایرفاکس چندین گزینه تعامل را امکان پذیر می کند: راه اندازی مستقیم یا باز کردن یک پنجره پاپ آپ. من نیازی به وارد کردن هیچ پارامتری ندارم، بنابراین اولی در مورد من کافی است.
فایرفاکس به چندین مکان اجازه می دهد تا دکمه ها را اضافه کنند: نوار ابزار مرورگر، نوار کناری یا داخل نوار URL مرورگر. من از نوار ابزار بدون دلیل استفاده کردم، زیرا این همان چیزی بود که در آموزش دوم نمایش داده شد. در نهایت، فقط کمی تغییر می کند و حرکت از یکی به دیگری آسان است.
افزودن دکمه در مانیفست انجام می شود:
"browser_action": {
"default_area": "navbar", #1
"default_icon": "icons/trello-tile.svg" #2
}
- دکمه را در نوار ناوبری تنظیم کنید. برای جزئیات بیشتر در مورد مکان دکمه، لطفاً اسناد را بررسی کنید
- نماد را پیکربندی کنید. می توان از بیت مپ در فرمت های مختلف استفاده کرد، اما تنظیم SVG بسیار ساده تر است
در این مرحله همه چیز خوب و شیک بود. پس از آن، ساعت های زیادی را در تلاش برای درک انواع مختلف فیلمنامه ها و نحوه تعامل آنها از دست دادم. من آن را یک بخش اختصاصی می کنم.
اسکریپت، اسکریپت در همه جا
زبان پیشفرض اسکریپتها در برنامههای افزودنی جاوا اسکریپت است. با این حال، بسته به مکان آنها، نقش های متفاوتی را ایفا می کنند. بدتر از آن، آنها نیاز به “گفتگو” با یکدیگر دارند.
بیایید با شروع کنیم content-script
من در بالا استفاده کردم manifest.json
. اسکریپت های محتوا به یک صفحه وب متصل می شوند. به این ترتیب، آنها می توانند به DOM آن دسترسی داشته باشند. زمانی که فایرفاکس صفحه را بارگذاری می کند، اجرا می شوند. اسکریپت یک حاشیه قرمز در اطراف صفحه وب اضافه می کند body
در آموزش
با این حال، ما به نوع دیگری از اسکریپت نیاز داریم: زمانی که روی دکمه کلیک میکنیم، یک اسکریپت فعال شود. چنین اسکریپت هایی باید همراه با برنامه افزودنی اجرا شوند اما می توانند به رویدادها گوش دهند. به عنوان شناخته می شوند background
اسکریپت ها
اسکریپتهای پسزمینه مکانی برای قرار دادن کدهایی هستند که نیاز به حفظ حالت طولانیمدت، یا انجام عملیات طولانیمدت، مستقل از طول عمر صفحات وب خاص یا پنجرههای مرورگر دارند.
اسکریپتهای پسزمینه بهمحض بارگیری برنامه افزودنی بارگیری میشوند و تا زمانی که برنامه افزودنی غیرفعال یا حذف شود، بارگذاری میشوند، مگر اینکه دائمی بهعنوان نادرست مشخص شود. تا زمانی که مجوزهای لازم را درخواست کرده باشید، می توانید از هر یک از API های WebExtension در اسکریپت استفاده کنید.
— اسکریپت های پس زمینه
بیایید چنین اسکریپتی بسازیم. با شروع می شود manifest
– مثل همیشه:
"background": {
"scripts": [ "background.js" ]
}
اکنون می توانیم خود اسکریپت را ایجاد کنیم:
function foo() {
console.log('Hello from background')
}
browser.browserAction.onClicked.addListener(foo) //1
- ثبت نام کنید
foo
به عنوان شنونده رویداد به دکمه عمل کنید. وقتی فردی روی دکمه افزونه کلیک می کند، آن را فرا می خواندfoo
تابع
اشکال زدایی افزونه
بیایید یک لحظه در مورد اشکال زدایی صحبت کنیم. چند ساعت از دست دادم چون نمی دانستم چه اتفاقی افتاده است. وقتی ۲۰ سال پیش شروع به توسعه جاوا اسکریپت کردم، با آن “اشکال زدایی” کردیم alert()
. این بهترین تجربه توسعه دهنده ای نبود که می توانید به آن امیدوار باشید. شیوه های مدرن تر عبارتند از چوب بری و اشکال زدایی. اسپویلر: من موفق به رفع اشکال نشدم، بنابراین روی ورود به سیستم تمرکز خواهم کرد.
اول از همه، اسکریپت های محتوا در زمینه صفحه کار می کنند. از این رو، دستورات ورود به سیستم در کنسول معمولی کار می کنند. اسکریپت های پس زمینه در زمینه دیگری کار می کنند. برای تماشای بیانیه های گزارش آنها، باید داشته باشیم یکی دیگر کنسول توسعه دهنده فایرفاکس. با کلیک بر روی دکمه “Inspect” می توانید آن را در پنل افزونه باز کنید.
ارتباط بین اسکریپت ها
اکنون که می دانیم چگونه وارد سیستم شویم، می توان بیشتر پیش رفت و ارتباطات را در میان اسکریپت ها توصیف کرد. در اینجا یک مرور کلی از جریان کلی است:
بیایید کد را کمی تغییر دهیم تا background.js
پیام می فرستد:
function sendMessage(tab) {
browser.tabs
.sendMessage(tab.id, 'message in from background')
.then(response => {
console.log(response)
})
.catch(error => {
console.error(`Error: ${error}`)
})
}
browser.browserAction.onClicked.addListener(sendMessage)
حالا کد را تغییر می دهیم content.js
:
browser.runtime.onMessage.addListener((message, sender) => {
return Promise.resolve('message back from content')
});
دریافت محتوا
تا کنون، ما یک جریان رفت و برگشت بین background
و content
اسکریپت ها گوشت برای دریافت محتوا از صفحه در content
اسکریپت و ارسال آن به background
از طریق یک پیام به یاد داشته باشید که فقط content
اسکریپت می تواند به صفحه دسترسی پیدا کند! خود کد از Document API استفاده می کند، به عنوان مثال، document.querySelector()
، document.getElementsByClassName()
و غیره. مشخصات بی اهمیت هستند.
موضوع بعدی این است که ساختار Sessionize و Papercall متفاوت است. از این رو، برای هر سایت به کدهای خراش متفاوتی نیاز داریم. ما میتوانیم یک اسکریپت واحد ایجاد کنیم که URL را بررسی کند، اما برنامههای افزودنی میتوانند از آن برای ما مراقبت کنند. بیایید مانیفست را تغییر دهیم:
"content_scripts" : [{
"matches": [ "https://sessionize.com/*" ], #1
"js": [ #2
"content/common.js", #4
"content/sessionize.js"
]
},
{
"matches": [ "https://www.papercall.io/*" ], #1
"js": [ #3
"content/common.js", #4
"content/papercall.js"
]
}]
- سایت های مختلف را مطابقت دهید
- اسکریپت هایی برای Sessionize
- اسکریپت برای تماس کاغذی
- کد به اشتراک گذاشته شده در هر دو سایت
در این مرحله، ما موفق شدیم داده های لازم را به دست آوریم و آن را به سایت بازگردانیم background
اسکریپت آخرین مرحله تماس با Trello با داده است.
مدیریت اعتبار احراز هویت
استفاده از Trello’s REST به اعتبارنامه احراز هویت نیاز دارد. من میخواهم کد را در GitHub به اشتراک بگذارم، بنابراین نمیتوانم اعتبارنامهها را کد سخت کنم: به پیکربندی نیاز دارم.
ما می توانیم یک افزونه فایرفاکس را از طریق یک برنامه اختصاصی پیکربندی کنیم گزینه ها صفحه برای انجام این کار، آشکار اختصاصی ارائه می دهد options_ui
بخشی که می توانیم مسیر صفحه HTML را ارائه دهیم:
"options_ui": {
"page": "settings/options.html"
}
صفحه می تواند مستقیماً به اسکریپت ها و شیوه نامه مورد نیاز خود ارجاع دهد. اسکریپت باید:
- ذخیره اطلاعات در ذخیره سازی مرورگر در ذخیره
- بارگذاری اعتبار از ذخیره سازی مرورگر وقتی صفحه تنظیمات باز می شود
با مثال ارائه شده بسیار ساده است.
کد من کاملا مشابه است. فقط به سه فیلد به جای یک فیلد نیاز دارد:
function saveOptions(e) {
browser.storage.sync.set({ //1
listId: document.querySelector('#list-id').value,
key: document.querySelector('#key').value,
token: document.querySelector('#token').value,
})
}
function restoreOptions() {
browser.storage.sync.get() //1
.then(data => {
document.querySelector('#list-id').value = data.listId || ''
document.querySelector('#key').value = data.key || ''
document.querySelector('#token').value = data.token || ''
}, error => {
console.error(`Error: ${error}`)
})
}
document.addEventListener('DOMContentLoaded', restoreOptions) //2
document.querySelector('form').addEventListener('submit', saveOptions) //3
- از فایرفاکس استفاده می کند
storage
API - هنگامی که صفحه بارگیری می شود، از فضای ذخیره سازی بخوانید
- هنگامی که کاربر HTML را ارسال می کند در فضای ذخیره سازی ذخیره شود
form
ما همچنین باید از آن بپرسیم storage
مجوز در مانیفست:
"permissions": [ "storage" ]
اکنون میتوانیم اعتبارنامه Trello (و همچنین شناسه لیست Trello مورد نیاز) را در صفحه تنظیمات ذخیره کنیم:
ما می توانیم از همان استفاده کنیم storage
API در کد فراخوانی Trello برای خواندن اعتبار.
در این مرحله، من از راه اندازی خود راضی بودم. من به تازگی یک سفر رفت و برگشت دیگر از آن اضافه کردم background
به content
برای نمایش یک alert
با نام و آدرس کارت Trello.
نتیجه
این اولین پسوندی بود که نوشتم، و اگرچه شروع چالش برانگیز بود، اما به آنچه می خواستم رسیدم. اکنون، میتوانم به یک صفحه Papercall و Sessionize بروید، روی دکمه افزونه کلیک کرده و کنفرانس را روی برد Trello خود دریافت کنم. چند روز طول کشید و سرگرم کننده بود. ارزشش را داشت. من به کار روی آن ادامه می دهم تا ذره ذره آن را بهبود بخشم.
کد منبع کامل این پست را می توانید در GitHub بیابید:
فراتر رفتن:
در ابتدا در A Java Geek در 2 آوریل منتشر شدnd، 2023