برنامه نویسی

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

چند هفته پیش، آخر هفته را صرف ساختن دیگری کردم CFP کمک کننده ارسال در قالب پسوند فایرفاکس. پیاده روی در پارک نبود. برای کمک به دیگرانی که ممکن است علاقه مند به انجام همین کار (و خود آینده من) باشند، این سفر من است.

متن نوشته

من چندین پست در مورد گردش کار ارسال کنفرانس خود نوشته ام. برای جمع بندی:

  • همه چیز بر اساس یک برد Trello است
  • من یک برنامه ایجاد کردم که یک وب هوک را روی برد ثبت کرد
  • وقتی کنفرانسی را از یک خط به خط دیگر منتقل می‌کنم، یک جریان کاری را در سمت برنامه شروع یا ادامه می‌دهد

من تابلو را با نگاه کردن به وب‌سایت‌ها، عمدتاً Papercall و Sessionize، و کپی دستی داده‌های کنفرانس روی کارت‌ها، منبع می‌کنم. دو گزینه اتوماسیون موجود است:

  1. خودکارسازی منابع کنفرانس
  2. ایجاد خودکار کارت

در مورد قسمت اول خیلی فکر کردم. اگر آن را خودکار کنم، یک لیست طولانی از کارت‌های 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
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. دکمه را در نوار ناوبری تنظیم کنید. برای جزئیات بیشتر در مورد مکان دکمه، لطفاً اسناد را بررسی کنید
  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
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. ثبت نام کنید foo به عنوان شنونده رویداد به دکمه عمل کنید. وقتی فردی روی دکمه افزونه کلیک می کند، آن را فرا می خواند foo تابع

اشکال زدایی افزونه

بیایید یک لحظه در مورد اشکال زدایی صحبت کنیم. چند ساعت از دست دادم چون نمی دانستم چه اتفاقی افتاده است. وقتی ۲۰ سال پیش شروع به توسعه جاوا اسکریپت کردم، با آن “اشکال زدایی” کردیم alert(). این بهترین تجربه توسعه دهنده ای نبود که می توانید به آن امیدوار باشید. شیوه های مدرن تر عبارتند از چوب بری و اشکال زدایی. اسپویلر: من موفق به رفع اشکال نشدم، بنابراین روی ورود به سیستم تمرکز خواهم کرد.

اول از همه، اسکریپت های محتوا در زمینه صفحه کار می کنند. از این رو، دستورات ورود به سیستم در کنسول معمولی کار می کنند. اسکریپت های پس زمینه در زمینه دیگری کار می کنند. برای تماشای بیانیه های گزارش آنها، باید داشته باشیم یکی دیگر کنسول توسعه دهنده فایرفاکس. با کلیک بر روی دکمه “Inspect” می توانید آن را در پنل افزونه باز کنید.

Developer Console برای پسوند اسکریپت پس زمینه

ارتباط بین اسکریپت ها

اکنون که می دانیم چگونه وارد سیستم شویم، می توان بیشتر پیش رفت و ارتباطات را در میان اسکریپت ها توصیف کرد. در اینجا یک مرور کلی از جریان کلی است:

بررسی اجمالی جریان ارتباط بین اسکریپت ها

بیایید کد را کمی تغییر دهیم تا 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"
  ]
}]
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. سایت های مختلف را مطابقت دهید
  2. اسکریپت هایی برای Sessionize
  3. اسکریپت برای تماس کاغذی
  4. کد به اشتراک گذاشته شده در هر دو سایت

در این مرحله، ما موفق شدیم داده های لازم را به دست آوریم و آن را به سایت بازگردانیم background اسکریپت آخرین مرحله تماس با Trello با داده است.

مدیریت اعتبار احراز هویت

استفاده از Trello’s REST به اعتبارنامه احراز هویت نیاز دارد. من می‌خواهم کد را در GitHub به اشتراک بگذارم، بنابراین نمی‌توانم اعتبارنامه‌ها را کد سخت کنم: به پیکربندی نیاز دارم.

ما می توانیم یک افزونه فایرفاکس را از طریق یک برنامه اختصاصی پیکربندی کنیم گزینه ها صفحه برای انجام این کار، آشکار اختصاصی ارائه می دهد options_ui بخشی که می توانیم مسیر صفحه HTML را ارائه دهیم:

  "options_ui": {
    "page": "settings/options.html"
  }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

صفحه می تواند مستقیماً به اسکریپت ها و شیوه نامه مورد نیاز خود ارجاع دهد. اسکریپت باید:

  1. ذخیره اطلاعات در ذخیره سازی مرورگر در ذخیره
  2. بارگذاری اعتبار از ذخیره سازی مرورگر وقتی صفحه تنظیمات باز می شود

با مثال ارائه شده بسیار ساده است.

کد من کاملا مشابه است. فقط به سه فیلد به جای یک فیلد نیاز دارد:

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
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. از فایرفاکس استفاده می کند storage API
  2. هنگامی که صفحه بارگیری می شود، از فضای ذخیره سازی بخوانید
  3. هنگامی که کاربر HTML را ارسال می کند در فضای ذخیره سازی ذخیره شود form

ما همچنین باید از آن بپرسیم storage مجوز در مانیفست:

  "permissions": [ "storage" ]
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون می‌توانیم اعتبارنامه Trello (و همچنین شناسه لیست Trello مورد نیاز) را در صفحه تنظیمات ذخیره کنیم:

صفحه تنظیمات افزونه فایرفاکس

ما می توانیم از همان استفاده کنیم storage API در کد فراخوانی Trello برای خواندن اعتبار.

در این مرحله، من از راه اندازی خود راضی بودم. من به تازگی یک سفر رفت و برگشت دیگر از آن اضافه کردم background به content برای نمایش یک alert با نام و آدرس کارت Trello.

نتیجه نهایی

نتیجه

این اولین پسوندی بود که نوشتم، و اگرچه شروع چالش برانگیز بود، اما به آنچه می خواستم رسیدم. اکنون، می‌توانم به یک صفحه Papercall و Sessionize بروید، روی دکمه افزونه کلیک کرده و کنفرانس را روی برد Trello خود دریافت کنم. چند روز طول کشید و سرگرم کننده بود. ارزشش را داشت. من به کار روی آن ادامه می دهم تا ذره ذره آن را بهبود بخشم.

کد منبع کامل این پست را می توانید در GitHub بیابید:

فراتر رفتن:

در ابتدا در A Java Geek در 2 آوریل منتشر شدnd، 2023

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا