From 1109132f09d75da9a28b649c7677bb6ce07c40c0 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:41:45 -0500 Subject: initial commit --- .../mozilla/add-ons/add-on_guidelines/index.html | 116 ++++++ files/fa/mozilla/add-ons/index.html | 117 ++++++ files/fa/mozilla/add-ons/sdk/index.html | 81 ++++ .../mozilla/add-ons/themes/background/index.html | 104 +++++ files/fa/mozilla/add-ons/themes/index.html | 61 +++ .../add-ons/themes/theme_concepts/index.html | 232 +++++++++++ .../mozilla/add-ons/webextensions/api/index.html | 61 +++ .../add-ons/webextensions/api/runtime/index.html | 168 ++++++++ .../webextensions/api/runtime/onmessage/index.html | 317 ++++++++++++++ files/fa/mozilla/add-ons/webextensions/index.html | 97 +++++ .../your_first_webextension/index.html | 152 +++++++ .../your_second_webextension/index.html | 458 +++++++++++++++++++++ 12 files changed, 1964 insertions(+) create mode 100644 files/fa/mozilla/add-ons/add-on_guidelines/index.html create mode 100644 files/fa/mozilla/add-ons/index.html create mode 100644 files/fa/mozilla/add-ons/sdk/index.html create mode 100644 files/fa/mozilla/add-ons/themes/background/index.html create mode 100644 files/fa/mozilla/add-ons/themes/index.html create mode 100644 files/fa/mozilla/add-ons/themes/theme_concepts/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/api/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/api/runtime/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/api/runtime/onmessage/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/your_first_webextension/index.html create mode 100644 files/fa/mozilla/add-ons/webextensions/your_second_webextension/index.html (limited to 'files/fa/mozilla/add-ons') diff --git a/files/fa/mozilla/add-ons/add-on_guidelines/index.html b/files/fa/mozilla/add-ons/add-on_guidelines/index.html new file mode 100644 index 0000000000..a2ceecab7b --- /dev/null +++ b/files/fa/mozilla/add-ons/add-on_guidelines/index.html @@ -0,0 +1,116 @@ +--- +title: Add-on guidelines +slug: Mozilla/Add-ons/Add-on_guidelines +translation_of: 'https://extensionworkshop.com/documentation/publish/add-on-policies/' +--- +

These add-on guidelines were created to foster an open and diverse add-on developer community while ensuring an excellent user experience. They apply to all add-ons and add-on updates regardless of where they are hosted, and also apply to customizations performed by installers that configure Firefox without using an add-on. Add-ons hosted on AMO are subject to additional policies.

+

Be Transparent

+ +

Be Respectful to Users

+ +

Be Safe

+ +

Be Stable

+ +

Exceptions

+ +

Other exceptions may apply.

+

Enforcement

+

Add-ons that do not follow these guidelines may qualify for blocklisting, depending on the extent of the violations. Guidelines qualified with the word + + must + are especially important, and violations thereof will most likely result in a blocklisting nomination.

+

The Add-ons Team will do their best to contact the add-on's developers and provide a reasonable time frame for the problems to be corrected before a block is put in place. If an add-on is considered malicious or its developers have proven unreachable or unresponsive, or in case of repeat violations, blocklisting may be immediate.

+

Guideline violations should be reported via Bugzilla, under Tech Evangelism > Add-ons. Questions can be posted in the #addons IRC channel.

+

These guidelines may change in the future. All updates will be announced in the Add-ons Blog.

diff --git a/files/fa/mozilla/add-ons/index.html b/files/fa/mozilla/add-ons/index.html new file mode 100644 index 0000000000..ac0a1e3aa6 --- /dev/null +++ b/files/fa/mozilla/add-ons/index.html @@ -0,0 +1,117 @@ +--- +title: افزونه‌ها +slug: Mozilla/Add-ons +tags: + - Add-ons + - NeedsTranslation + - TopicStub +translation_of: Mozilla/Add-ons +--- +
تغییر و توسعه برنامه‌های موزیلا
+ +

افزونه‌ها قابلیت‌های جدیدی به برنامه‌های مبتنی بر Gecko مانند فایرفاکس، سی‌مانکی و تاندربیرد اضافه می‌کنند. دو نوع اصلی از افزونه‌ها وجود دارد: الحاقی‌ها که قابلیت‌های جدیدی به برنامه اضافه می‌کنند، تم‌ها که رابط کاربری برنامه را تغییر می‌دهند.

+ +

موزیلا برای هر دو نوع الحاقی‌ها و تم‌ها، یک مخزن در addons.mozilla.org راه‌اندازی کرده‌است، که به عنوان AMO شناخته می‌شود. وقتی شما افزونه‌ها را به AMO ارسال می‌کنید افزونه‌ها بازبینی شده، و افزونه‌ها بعد از گذراندن مرحله بازبینی برای کاربران قابل دسترس خواهد بود. شما مجبور نیستید که افزونه‌ها را به AMO ارسال کنید، اما اگر این‌کار را انجام دهید، کاربران اطمینان پیدا می‌کنند که در عمل افزونه‌ها بازبینی شده‌، و شما به عنوان یک منبع مفید افزونه‌ها از دید AMO سود خواهید برد.

+ +

افرونه‌ها تاثیر زیادی بر برنامه‌هایی که آن‌ها را میزبانی می‌کنند می‌گذارند. ما برای اطمینان از فراهم کردن یک تجربه خوب برای کاربران باید مجموعه‌ای از راهنمایی‌ها را توسعه دهیم. این راهنمایی‌ها بر روی تمام انواع افزونه‌ها اعمال می‌شود، چه آن‌ها در addons.mozilla.org میزبانی بشوند یا نشوند.

+ +
+

الحاقی‌ها

+ +

الحاقی‌ها قابلیت جدیدی به برنامه‌های موزیلا مانند فایرفاکس و تاندربیرد اضافه می‌کنند. الحاقی‌ها ویژگی‌های جدیدی به مرورگر، مانند روش متفاوتی برای مدیریت تب‌ها اضافه می‌کنند، و آن‌ها می توانند محتوای وب را به‌منظور استفاده از وب‌سایت‌ها یا امنیت وب‌سایت‌های خاص بهبود بخشند.

+ +

سه تکنیک مختلف وجود دارد که شما می‌توانید برای ساختن الحاقی‌ها استفاده کنید: الحاقی‌های افزودنی مبتنی بر SDK، الحاقی‌های خود راه‌انداز بدون نیاز به راه‌اندازی مجدد، الحاقی‌های روی هم قرار داده شده.

+ + + +

اگر امکان دارد، توصیه می‌شود تا از افزونه SDK استفاده کنید، که از مکانیزم توسعه بدون نیاز به راه اندازی مجدد استفاده می‌کند ولی وظایف خاص را ساده کرده و بعد از اجرا پاک‌سازی را انجام می‌دهد . اگر افزونه SDK مناسب نیازهای شما نیست، به‌جای آن یک الحاقی بدون نیاز به راه اندازی مجدد را توسعه دهید. درحال حاضر الحاقی‌های روی هم قرار گرفته منسوخ شده‌اند، اگر چه خیلی از آن‌ها که بسیار مورد علاقه هستند هنوز وجود دارند.

+ +

برای اطلاعات بیشتر در مورد انتخاب تکنیک مناسب برای استفاده، این مقایسه را بخوانید.

+ +
+
+

تمرین‌های مفید

+ +

مهم نیست که شما چطور یک الحاق را توسعه می‌دهید، راهنمایی‌های زیادی وجود دارد که می توانید دنبال کنید و مطمئن شوید که الحاقی شما تا آنجایی که امکان دارد تجربه خوبی برای کاربران مهیا کرده‌است یا نه.

+ +
+
کارائی
+
اطمینان از این‌که الحاقی شما سریع، جواب‌گو و از نظرحافظه کارآمد است.
+
امنیت
+
اطمینان از این‌که الحاقی شما کاربر را در معرض وب سایت‌های بداندیش قرار نمی‌دهد.
+
رسوم
+
اطمینان از این‌که الحاقی شما به درستی با دیگر الحاقی‌ها کار می‌کند.
+
+
+ +
+

برنامه ویژه

+ +

اغلب مستندات فرض می‌کنند که توسعه شما برای میزکار فایرفاکس است. اگر شما بعضی دیگر برنامه‌های مبتنی بر Gecko را توسعه می‌دهید، تفاوت‌های اصلی وجود دارد که شما باید در مورد آن بدانید.

+ +
+
تاندربیرد
+
توسعه الحاقی‌ها برای سرویس گیرنده پست الکترونیک تاندربیرد.
+
فایرفاکس برای اندروید
+
توسعه الحاقی‌ها برای فایرفاکس برای اندروید.
+
سی‌مانکی
+
توسعه الحاقی‌ها برای مجموعه برنامه سی‌مانکی.
+
+
+
+ +
+

تم‌ها

+ +

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

+ +
+
+

تم‌های سبک وزن از تم‌های کامل برای پیاده سازی ساده‌تر هستند، اما سفارشی سازی محدودی را فراهم می‌کنند.

+
+ +
+

با تم‌های کامل می توانید تغییرات بیشتری به ظاهر برنامه بدهید. مستندات برای تم‌های کامل به‌روز نیستند، اما به عنوان پایه‌ای برای مستندات به‌روز شده به اینجا لینک شده است.

+
+
+ +
+

انواع دیگر افزونه‌ها

+ +

متصّل شونده‌های موتور جستجو نوع ساده و خیلی خاص از افزونه هستند: آن‌ها موتور‌های جستجوی جدید را به نوار جستجوی مرورگر اضافه می کنند.

+ +

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

+ + + +
    +
  1. Overlay extensions
  2. +
  3. Restartless extensions
  4. +
  5. Add-on SDK
  6. +
  7. Extension good practices +
      +
    1. Performance
    2. +
    3. Security
    4. +
    5. Etiquette
    6. +
    +
  8. +
  9. Themes +
      +
    1. Lightweight themes
    2. +
    3. Complete themes
    4. +
    +
  10. +
  11. Publishing add-ons +
      +
    1. addons.mozilla.org
    2. +
    3. Add-on guidelines
    4. +
    +
  12. +
diff --git a/files/fa/mozilla/add-ons/sdk/index.html b/files/fa/mozilla/add-ons/sdk/index.html new file mode 100644 index 0000000000..135dca5a25 --- /dev/null +++ b/files/fa/mozilla/add-ons/sdk/index.html @@ -0,0 +1,81 @@ +--- +title: کیت توسعه افزونه +slug: Mozilla/Add-ons/SDK +translation_of: Archive/Add-ons/Add-on_SDK +--- +

شما می توانید افزونه های فایرفاکس را با استفاده از تکنولوژی های وب و کیت توسعه فایرفاکس بسازید: جاوااسکریپت ، HTML، و CSS. کیت توسعه شامل API های جاوااسکریپت برای توسعه افزونه و ابزارهایی برای توسعه و آزمایش و انتشار افزونه است.

+ +
+

آموزش ها

+ +
+
+
+
شروع
+
چگونه کیت توسعه را نصب کنیم و از ابزار cfx  برای توسعه ، تست و انتشار افزونه استفاده کنیم.
+
ارتباط با مرورگر
+
باز کردن صفحات, بارگزاری صفحات, و لیست صفحات باز.
+
تکنیک های توسعه
+
یاد گرفتن تکنیک های توسعه معمولی , مانند یونیت تست, logging, ایجاد ماژوله های قابل استفاده مجدد, محلی کردن, and توسعه برای موبایل.
+
+
+ +
+
+
ایجاد اجزای رابط کاربری
+
ساخت اجزای رابط کاربری مانند دکمه های تولبار, منوهای بازشونده, منوها, و دیالوگ ها.
+
ویرایش صفحات
+
ویرایش صفحات  مطابق یک الگوی آدرس یا به صورت پویا یک تب را ویرایش کنیم.
+
قرار دادن همه چیز کنار هم
+
مشاهده افزونه ها نمونه .
+
+
+
+ +
+

راهنما ها

+ +
+
+
+
راهنمای نویسندگان
+
یاد گرفتن چگونگی شرکت کردن در توسعه کیت توسعه, و یاد گرفتن مهمترین اصطلاحات کیت توسعه , مانند ماژول, کلاس ها و وراثت, تنظیمات خصوصی, و  فرایند های محتوا.
+
زیر ساخت های کیت توسعه
+
جنبه های تکنولوژی زیر بنایی کیت توسعه: ماژول ها , شماره برنامه , و تعریف قوانین سازگاری فایرفاکس.
+
اسکریپت های محتوا
+
یک راهنمای دقیق برای کار با اسکریپت های محتوا.
+
+
+ +
+
+
اصطلاحات کیت توسعه
+
چارچوب رویداد های کیت توسعه  ، تمایز بین اسکریپت های محتوا و اسکریپت های افزونه ها.
+
XUL مهاجرت
+
یک راهنما یرای انتقال افزونه های XUL به کیت توسعه. این راهنما شامل مقایسه دو مجموعه ابزار و نمونه های کاری انتقال افزونه های XUL.
+
فایرفاکس چند پروسه ای و کیت توسعه
+
چگونگی چک کردن سازگاری افزونه شما با فایرفاکس چند پروسه ای و درست کردن ان در صورت نبودن
+
+
+
+ +
+

ارجاع

+ +
+
+
+
رابط های برنامه کاربردی سطح بالا
+
مستندات مرجع برای رابط های برنامه کاربردی  کیت توسعه سطح بالا.
+
ابزراهای مرجع
+
مستندات ارجاع برای ابزار cfx برای توسعه , تست, و انتشار افزونه, استفاده های کلی از ابزار کنسول برای Logging, و فایل pachage,json.
+
+
+ +
+
+
رابط های برنامه کاربردی سطح پایین
+
مستندات مرجع برای رابط های برنامه کاربری کیت توسعه سطح پایین.
+
+
+
diff --git a/files/fa/mozilla/add-ons/themes/background/index.html b/files/fa/mozilla/add-ons/themes/background/index.html new file mode 100644 index 0000000000..3ad47ca2be --- /dev/null +++ b/files/fa/mozilla/add-ons/themes/background/index.html @@ -0,0 +1,104 @@ +--- +title: Background Themes +slug: Mozilla/Add-ons/Themes/Background +translation_of: Mozilla/Add-ons/Themes/Lightweight_themes +--- +

{{AddonSidebar}}

+ +

How to Create Your Own Background Theme

+ +
+

Themes are made up of a "header" graphic image file, which skins the default Firefox UI background.

+ +

Finished Your Design? You can submit it right now!

+ +

Creating a Theme Header Image

+ +

The header image is displayed as the background of the top of the browser window, nestling in behind the toolbars, address bar, search bar and the tab strip. It will be anchored to the top-right corner of the browser window.

+ +

+ + + +

Image Requirements

+ + + +

Tips

+ + + +

Online Image Editor Resources

+ + + + + +

In older versions of Firefox, or newer versions with certain add-ons installed, the footer image is displayed as the background of the bottom of the browser window, behind the add-on and find bars. It will be anchored to the bottom-left corner of the browser window. Footer images are optional.

+ +

+ + + +

Image Requirements

+ + + +

Tips

+ + + +

Submitting your Theme Images

+ +

To get started submitting your images, go to the Theme Submission page:

+ +
    +
  1. Name your theme — pick a unique name for your theme. Duplicate names are not allowed, so you may need to try a few times to find a unique name.
  2. +
  3. Pick a category and tags — select a category and enter some tags that best describe your theme. Keep in mind that a reviewer may reject your theme if it is obvious that your category and/or tags are unrelated to your theme.
  4. +
  5. Describe your theme — write a short description of your theme. Keep in mind that a reviewer may reject your theme if your description is not an accurate representation of your theme.
  6. +
  7. Select a license for your theme — decide on a copyright license for your work. Read more about the types of Creative Common licenses. +
      +
    • Important: Please be sure you have the rights to use the image in your theme!
    • +
    +
  8. +
  9. Upload your images — make sure they are under 300 KB in size and JPG or PNG format!
  10. +
  11. Select text and tab colors — you can choose the tab ("background") color and foreground text color that work best with your header image.
  12. +
  13. Preview your theme — you're ready to preview your theme! Simply mouse over the image above the Submit Theme button, and see how it looks instantly.
  14. +
  15. Submit your theme — if everything looks right, click the Submit Theme button and you're done! You can see all the themes you've authored on your profile page. +
      +
    • Tip: to ensure that your theme is approved for the gallery, be sure it complies with the content guidelines and terms of service!
    • +
    +
  16. +
+ +

+ +

Submit Your Theme Now

+ +

More Tutorials

+ +

Mozilla Themes Focal Point on Sizing - A tutorial on theming with a focus on sizing, by VanillaOrchids.

+
diff --git a/files/fa/mozilla/add-ons/themes/index.html b/files/fa/mozilla/add-ons/themes/index.html new file mode 100644 index 0000000000..86dd860fa7 --- /dev/null +++ b/files/fa/mozilla/add-ons/themes/index.html @@ -0,0 +1,61 @@ +--- +title: Themes +slug: Mozilla/Add-ons/Themes +tags: + - Add-ons + - Look & Feel + - NeedsTranslation + - Themes + - TopicStub +translation_of: Mozilla/Add-ons/Themes +--- +{{AddonSidebar}} + +
+

The Theme documentation here is out of date.

+
+ +

Themes are skins for different Mozilla applications. They allow you to change the look and feel of the user interface and personalize it to your tastes. A theme can simply change the colors of the UI or it can change every piece of its appearance.

+ +
+
+

Documentation

+ +
+
Building a Theme
+
A tutorial for building a simple theme in Firefox.
+
Common Theme Issues and Their Solutions
+
Common issues seen when AMO editors review themes and how to fix them.
+
Lightweight themes
+
Building lightweight themes for Firefox
+
Creating a Skin for SeaMonkey 2
+
An introduction to creating new themes for SeaMonkey 2.
+
Making Sure Your Theme Works with RTL Locales
+
How to make sure your theme will look right with Hebrew, Arabic, Persian and Urdu locales.
+
Theme Packaging
+
How to package themes for Firefox and Thunderbird.
+
Yet Another Theme Tutorial
+
Another tutorial in Mozilla theme construction.
+
Obsolete docs
+
These docs are very old and will never be updated, but we've kept them in case the are useful source material for people updating the Theme documentation.
+
+
+ +
+

Getting help

+ + + +

Tools

+ + +
+
+ +

 

diff --git a/files/fa/mozilla/add-ons/themes/theme_concepts/index.html b/files/fa/mozilla/add-ons/themes/theme_concepts/index.html new file mode 100644 index 0000000000..dda28c91fe --- /dev/null +++ b/files/fa/mozilla/add-ons/themes/theme_concepts/index.html @@ -0,0 +1,232 @@ +--- +title: Theme concepts +slug: Mozilla/Add-ons/Themes/Theme_concepts +translation_of: Mozilla/Add-ons/Themes/Theme_concepts +--- +
{{AddonSidebar()}}
+ +

Themes developed using the WebExtensions API in Firefox enable you to change the look of the browser by adding images to the header area of the Firefox browser; this is the area behind the menu bar, toolbars, address bar, search bar, and tab strip.

+ +

These theme options can be implemented as static themes (although the theme images themselves may be animated) or as dynamic themes created in a browser extension.

+ +
+

If you have a lightweight theme it will be converted to this new theme format automatically before lightweight themes are deprecated. You do not need to port your th eme. However, please feel free to update your themes to use any of the new features described here.

+
+ +

Static themes

+ +

Static themes are specified using the same resources as a browser extension: a manifest.json file to define the theme components with those components stored in the same folder as the manifest.json file or a sub folder. These resources are then packed in a zip for publication on addons.mozilla.org (AMO) or for self-distribution. For more information on self-distribution, visit Signing and distributing your add-on.

+ +

You can also use the theme generator on AMO to create a static theme. Additionally, Firefox Color can be used to preview customizations to the browser's theme with options to share and export a theme.

+ +
+

A theme and browser extension functionality cannot be defined in one package, such as including a theme to complement an extension. You can, however, programmatically include a theme in an extension using the Theme API. See Dynamic themes.

+
+ +

Defining a theme

+ +

To create a theme (in this example a simple, single image theme):

+ + + +

Static theme approaches

+ +

There are two approaches you can take to theming the header area of Firefox: using a single image or using multiple images. You could combine the two, but it’s easier to treat them separately.

+ +

Single image themes

+ +

This is the basic or minimal theming option, where you define:

+ + + +

The area your header image needs to fill is a maximum of 200 pixels high. The maximum image width is determined by the resolution of the monitor Firefox is displaying on and how much of the monitor Firefox is using. Practically, this means you would need to allow for a width of up to 5120 pixels wide (for the next generation of 5k monitors). However, rather than creating a very wide image, a better approach is to use a narrower image with a transparent left edge so that it fades to the background color. For example, we could use this image
+ An image of a weta (the common name for a group of about 70 insect species in the families Anostostomatidae and Rhaphidophoridae, endemic to New Zealand) with the left edge fading to total transparency.
+ combined with a complementary background color, to create this effect in the header
+ A single image theme using the weta.png image

+ +

See details about this theme in the themes example weta_fade.

+ +

Obviously, you can still provide a single wide image if you prefer.

+ +

Multiple image themes

+ +

As an alternative to creating a single image theme, you have the option to use multiple images. These images can be individually anchored to locations within the header, with the option to apply tiling to each image.

+ +

Depending on the effect you want to create you may need to suppress the mandatory "theme_frame": image with an empty or transparent image. You would use an empty or transparent image if, for example, you wanted to tile a centrally justified image, such as
+ An image of a weta (the common name for a group of about 70 insect species in the families Anostostomatidae and Rhaphidophoridae, endemic to New Zealand) with the left and right edges fading to total transparency.
+ to create this effect
+ A single image theme using the additional images option to align an image to the center of the heading and tile it.
+ Here you specify the weta image like this:

+ +
"images": {
+  "theme_frame": "empty.png",
+  "additional_backgrounds": [ "weta_for_tiling.png"]
+},
+ +

and the images tiling with:

+ +
"properties": {
+  "additional_backgrounds_alignment": [ "top" ],
+  "additional_backgrounds_tiling": [ "repeat"  ]
+},
+ +

Full details of how to setup this theme can be found in the themes example weta_tiled. Full detais of the alignment and tiling options can be found in the "theme" key description.

+ +

Alternatively, you can use multiple images, say combining the original weta image with this one anchored to the left of the header
+ An image of a weta (the common name for a group of about 70 insect species in the families Anostostomatidae and Rhaphidophoridae, endemic to New Zealand) with the right edge fading to total transparency.
+ to create this effect
+ A theme using the additional images option to place two mirrored image to the left and right of the browser header.

+ +

Where the images are specified with:

+ +
"images": {
+  "theme_frame": "empty.png",
+  "additional_backgrounds": [ "weta.png", "weta-left.png"]
+},
+ +

and their alignment by:

+ +
"properties": {
+  "additional_backgrounds_alignment": [ "right top" , "left top" ]
+},
+ +

Full details of how to setup this theme can be found in the themes example weta_mirror. Full details of the alignment options can be found in the "theme" key description.

+ +

Static animated themes

+ +

It is possible to create an animated theme using an APNG format image, as in the themes example animated. However, remember that rapid animations, such as the one in the example might be too distracting for a practical theme.

+ +

You can also animate themes programmatically, which we discuss in Dynamic themes.

+ +

Updating static themes

+ +

If your static theme is hosted on AMO, you can upload a new version using the Developer Hub with the following steps:

+ +
    +
  1. Visit the product page for your theme through the Developer Hub
  2. +
  3. Select "Upload New Version" on the left
  4. +
  5. Upload your packaged file for validation or modify it using the theme generator
  6. +
+ +

For self-hosted static themes, a new version can be updated through AMO by following the above steps or be handled by you through an updateURL or external application updates. A new version will need to be signed through the Developer Hub.

+ +
+

 If you are uploading a packaged file, the version number must be higher than the current version number

+
+ +

Dynamic themes

+ +

As an alternative to defining a static theme, you can use the {{WebExtAPIRef("theme")}} API to control the theme used in Firefox from within a browser extension. There are a couple of use cases for this option:

+ + + +

And, obviously, you can combine the two and bundle a programmatically controlled theme with your extension.

+ +

Using the {{WebExtAPIRef("theme")}} API is straightforward. First, request "theme" permission in the extension's manifest.json file. Next, you build a JSON object containing the same information you would use in a static theme’s manifest.json, Finally, pass the JSON object in a {{WebExtAPIRef("theme.update()")}} call.

+ +

For example, the following code, from the dynamic theme example defines the content for the day and night elements of the dynamic theme:

+ +
const themes = {
+  'day': {
+    images: {
+     theme_frame: 'sun.jpg',
+    },
+    colors: {
+     frame: '#CF723F',
+     tab_background_text: '#111',
+    }
+  },
+  'night': {
+    images: {
+     theme_frame: 'moon.jpg',
+    },
+    colors: {
+     frame: '#000',
+     tab_background_text: '#fff',
+    }
+  }
+};
+ +

The theme.Theme object is then passed to {{WebExtAPIRef("theme.update()")}} to change the header theme, as in this code snippet from the same example:

+ +
function setTheme(theme) {
+  if (currentTheme === theme) {
+    // No point in changing the theme if it has already been set.
+    return;
+  }
+  currentTheme = theme;
+  browser.theme.update(themes[theme]);
+}
+ +

Learn more about dynamic themes and see an additional example in the following video:

+ +

{{EmbedYouTube("ycckyrUN0AY")}}

+ +

+ +

If you have not built a browser extension before, check out Your first extension for a step-by-step guide.

+ +

Cross-browser compatibility

+ +

There is currently limited compatibility between themes in the major browsers. Opera takes an entirely different approach, and Microsoft Edge themes are not yet open to developers.

+ +

There is good compatibility between Firefox static themes and Chrome themes, providing the ability to port a single header image theme from Firefox to Chrome. However, noting that "frame": and "tab_background_text": only support RGB color array definition on Chrome.

+ +

So, in the single image theme example (weta_fade) could be supported in Chrome using the following manifest.json file:

+ +
{
+  "manifest_version": 2,
+  "version": "1.0",
+  "name": "<your_theme_name>",
+  "theme": {
+    "images": {
+      "theme_frame": "weta.png"
+    },
+    "colors": {
+      "frame": [ 173 , 176 , 159 ],
+      "tab_background_text": [ 0 , 0 , 0 ]
+    }
+  }
+}
+ +

Also, note that Chrome tiles the “theme_frame”: image from the left of the header area.

+ +

The basic theme example using the Chrome compatible manifest.json keys, showing the differences in how those keys are implemented.

+ +

For more information, see the notes on Chrome compatibility.

diff --git a/files/fa/mozilla/add-ons/webextensions/api/index.html b/files/fa/mozilla/add-ons/webextensions/api/index.html new file mode 100644 index 0000000000..724bf34516 --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/api/index.html @@ -0,0 +1,61 @@ +--- +title: JavaScript APIs +slug: Mozilla/Add-ons/WebExtensions/API +tags: + - NeedsTranslation + - TopicStub + - WebExtensions +translation_of: Mozilla/Add-ons/WebExtensions/API +--- +
{{AddonSidebar}}
+ +
+

JavaScript APIs for WebExtensions can be used inside the extension's background scripts and in any other documents bundled with the extension, including browser action or page action popups, sidebars, options pages, or new tab pages. A few of these APIs can also be accessed by an extension's content scripts (see the list in the content script guide).

+ +

To use the more powerful APIs you need to request permission in your extension's manifest.json.

+ +

You can access the APIs using the browser namespace:

+ +
function logTabs(tabs) {
+  console.log(tabs)
+}
+
+browser.tabs.query({currentWindow: true}, logTabs)
+
+ +
+

Many of the APIs are asynchronous, returning a {{JSxRef("Promise")}}:

+ +
function logCookie(c) {
+  console.log(c)
+}
+
+function logError(e) {
+  console.error(e)
+}
+
+let setCookie = browser.cookies.set(
+  {url: "https://developer.mozilla.org/"}
+);
+setCookie.then(logCookie, logError)
+
+ +
+

Note that this is different from Google Chrome's extension system, which uses the chrome namespace instead of browser, and which uses callbacks instead of promises for asynchronous functions. As a porting aid, the Firefox implementation of WebExtensions APIs supports chrome and callbacks as well as browser and promises. Mozilla has also written a polyfill which enables code that uses browser and promises to work unchanged in Chrome: https://github.com/mozilla/webextension-polyfill.

+ +

Firefox also implements these APIs under the chrome namespace using callbacks. This allows code written for Chrome to run largely unchanged in Firefox for the APIs documented here.

+ +

Microsoft Edge uses the browser namespace, but doesn't yet support promise-based asynchronous APIs. In Edge, for the time being, asynchronous APIs must use callbacks.

+ +

Not all browsers support all the APIs: for the details, see Browser support for JavaScript APIs.

+ +

Tip: Throughout the JavaScript API listings you will find short code examples that illustrate how the API is used. You can exercise these examples, without needing to create a web extension, using the console in the Toolbox. For example, here is the first code example on this page running in the Toolbox console in Firefox Developer Edition:

+ +

Illustration of a snippet of web extension code run from the console in the Toolbox

+ +

JavaScript API listing

+ +

See below for a complete list of JavaScript APIs:

+
+ +
{{LandingPageListSubpages}}
diff --git a/files/fa/mozilla/add-ons/webextensions/api/runtime/index.html b/files/fa/mozilla/add-ons/webextensions/api/runtime/index.html new file mode 100644 index 0000000000..62478e3457 --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/api/runtime/index.html @@ -0,0 +1,168 @@ +--- +title: runtime +slug: Mozilla/Add-ons/WebExtensions/API/runtime +tags: + - API + - Add-ons + - Extensions + - Interface + - NeedsTranslation + - Reference + - TopicStub + - WebExtensions + - runtime +translation_of: Mozilla/Add-ons/WebExtensions/API/runtime +--- +
{{AddonSidebar}}
+ +

This module provides information about your extension and the environment it's running in.

+ +

It also provides messaging APIs enabling you to:

+ + + +

Types

+ +
+
{{WebExtAPIRef("runtime.Port")}}
+
Represents one end of a connection between two specific contexts, which can be used to exchange messages.
+
{{WebExtAPIRef("runtime.MessageSender")}}
+
+

Contains information about the sender of a message or connection request.

+
+
{{WebExtAPIRef("runtime.PlatformOs")}}
+
Identifies the browser's operating system.
+
{{WebExtAPIRef("runtime.PlatformArch")}}
+
Identifies the browser's processor architecture.
+
{{WebExtAPIRef("runtime.PlatformInfo")}}
+
Contains information about the platform the browser is running on.
+
{{WebExtAPIRef("runtime.RequestUpdateCheckStatus")}}
+
Result of a call to {{WebExtAPIRef("runtime.requestUpdateCheck()")}}.
+
{{WebExtAPIRef("runtime.OnInstalledReason")}}
+
The reason that the {{WebExtAPIRef("runtime.onInstalled")}} event is being dispatched.
+
{{WebExtAPIRef("runtime.OnRestartRequiredReason")}}
+
The reason that the {{WebExtAPIRef("runtime.onRestartRequired")}} event is being dispatched.
+
+ +

Properties

+ +
+
{{WebExtAPIRef("runtime.lastError")}}
+
This value is set when an asynchronous function has an error condition that it needs to report to its caller.
+
{{WebExtAPIRef("runtime.id")}}
+
The ID of the extension.
+
+ +

Functions

+ +
+
{{WebExtAPIRef("runtime.getBackgroundPage()")}}
+
Retrieves the Window object for the background page running inside the current extension.
+
{{WebExtAPIRef("runtime.openOptionsPage()")}}
+
+

Opens your extension's options page.

+
+
{{WebExtAPIRef("runtime.getManifest()")}}
+
Gets the complete manifest.json file, serialized as an object.
+
{{WebExtAPIRef("runtime.getURL()")}}
+
Given a relative path from the manifest.json to a resource packaged with the extension, returns a fully-qualified URL.
+
{{WebExtAPIRef("runtime.setUninstallURL()")}}
+
Sets a URL to be visited when the extension is uninstalled.
+
{{WebExtAPIRef("runtime.reload()")}}
+
Reloads the extension.
+
{{WebExtAPIRef("runtime.requestUpdateCheck()")}}
+
Checks for updates to this extension.
+
{{WebExtAPIRef("runtime.connect()")}}
+
Establishes a connection from a content script to the main extension process, or from one extension to a different extension.
+
{{WebExtAPIRef("runtime.connectNative()")}}
+
+
Connects the extension to a native application on the user's computer.
+
+
{{WebExtAPIRef("runtime.sendMessage()")}}
+
Sends a single message to event listeners within your extension or a different extension. Similar to {{WebExtAPIRef('runtime.connect')}} but only sends a single message, with an optional response.
+
{{WebExtAPIRef("runtime.sendNativeMessage()")}}
+
Sends a single message from an extension to a native application.
+
{{WebExtAPIRef("runtime.getPlatformInfo()")}}
+
Returns information about the current platform.
+
{{WebExtAPIRef("runtime.getBrowserInfo()")}}
+
Returns information about the browser in which this extension is installed.
+
{{WebExtAPIRef("runtime.getPackageDirectoryEntry()")}}
+
Returns a DirectoryEntry for the package directory.
+
+ +

Events

+ +
+
{{WebExtAPIRef("runtime.onStartup")}}
+
Fired when a profile that has this extension installed first starts up. This event is not fired when an incognito profile is started.
+
{{WebExtAPIRef("runtime.onInstalled")}}
+
Fired when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.
+
{{WebExtAPIRef("runtime.onSuspend")}}
+
Sent to the event page just before the extension is unloaded. This gives the extension an opportunity to do some cleanup.
+
{{WebExtAPIRef("runtime.onSuspendCanceled")}}
+
Sent after {{WebExtAPIRef("runtime.onSuspend")}} to indicate that the extension won't be unloaded after all.
+
{{WebExtAPIRef("runtime.onUpdateAvailable")}}
+
Fired when an update is available, but isn't installed immediately because the extension is currently running.
+
{{WebExtAPIRef("runtime.onBrowserUpdateAvailable")}} {{deprecated_inline}}
+
Fired when an update for the browser is available, but isn't installed immediately because a browser restart is required.
+
{{WebExtAPIRef("runtime.onConnect")}}
+
Fired when a connection is made with either an extension process or a content script.
+
{{WebExtAPIRef("runtime.onConnectExternal")}}
+
Fired when a connection is made with another extension.
+
{{WebExtAPIRef("runtime.onMessage")}}
+
Fired when a message is sent from either an extension process or a content script.
+
{{WebExtAPIRef("runtime.onMessageExternal")}}
+
Fired when a message is sent from another extension. Cannot be used in a content script.
+
{{WebExtAPIRef("runtime.onRestartRequired")}}
+
Fired when the device needs to be restarted.
+
+ +

Browser compatibility

+ + + +

{{Compat("webextensions.api.runtime")}}

+ +
{{WebExtExamples("h2")}}
+ +
Acknowledgements + +

This API is based on Chromium's chrome.runtime API. This documentation is derived from runtime.json in the Chromium code.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git a/files/fa/mozilla/add-ons/webextensions/api/runtime/onmessage/index.html b/files/fa/mozilla/add-ons/webextensions/api/runtime/onmessage/index.html new file mode 100644 index 0000000000..f58f2a5f8c --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/api/runtime/onmessage/index.html @@ -0,0 +1,317 @@ +--- +title: runtime.onMessage +slug: Mozilla/Add-ons/WebExtensions/API/runtime/onMessage +translation_of: Mozilla/Add-ons/WebExtensions/API/runtime/onMessage +--- + + +

برخی از موارد مورد استفاده برای مثال:

+ + + +

برای ارسال پیام که توسط onMessage() listener, از {{WebExtAPIRef("runtime.sendMessage()")}} یا (برای ارسال پیام به یک content script) {{WebExtAPIRef("tabs.sendMessage()")}}.

+ +
+

از ایجاد چندین  onMessage() listeners برای همان نوع پیام خودداری کنید, زیرا نظم چندین listeners will fire تضمین نمی شود.

+ +

اگر می خواهید تحویل پیام به یک نقطه پایان خاص را تضمین کنید, از روش مبتنی بر اتصال برای پیام استفاده کنید.

+
+ +

همراه با message خود, به listener منتقل می شود:

+ + + +

شما می توانید با فراخوانی تابع ()sendResponse در listener خود. مثالی را ببینید.

+ +

برای ارسال  response ناهمزمان, دو گزینه وجود دارد:

+ + + +
+

بازگشت یک Promise در حال حاضر ترجیح داده می شود, زیرا sendResponse() از مشخصات W3C حذف می شود.

+ +

کتابخانه محبوب webextension-polyfill قبلا تابع ()sendResponse را از اجزای آن حذف کرده است.

+
+ +
+

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

+
+ +

Syntax

+ +
browser.runtime.onMessage.addListener(listener)
+browser.runtime.onMessage.removeListener(listener)
+browser.runtime.onMessage.hasListener(listener)
+
+ +

رویکردها سه تابع دارند:

+ +
+
addListener(listener)
+
به این رویداد یک listener اضلفه می کند.
+
removeListener(listener)
+
listening به این رویداد را متوقف می کند. یک listener دلیلی است برای حذف listener.
+
hasListener(listener)
+
بررسی می کند که حداقل یک listener برای این رویداد ثبت شده باشد. اگر listening وجود داشت true برمیگرداند, در غیر این صورت false را بر میگرداند.
+
+ +

addListener syntax

+ +

پارامترها

+ +
+
listener
+
+

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

+ +
+
message
+
object. خود پیام است. این یک شیء با قابلیت JSON-ifiable است.
+
sender
+
یک {{WebExtAPIRef('runtime.MessageSender')}} شیء به نمایندگی از فرستنده پیام.
+
sendResponse
+
+

یک تابع برای صدا زدن, حداکثر یک بار, برای ارسال پاسخ به پیام. این تابع یک آرگومان واحد را شامل می شود, که ممکن است هر شیء با قابلیت JSON باشد. این آرگومان به فرستنده پیام ارسال می شود.

+ +

اگر بیش از یک شنونده  onMessage() در همان سند دارید, پس فقط ممکن است یک نفر پاسخی ارسال کند.

+ +

برای ارسال پاسخ همزمان, قبل از بازگشت تابع listener با  sendResponse() تماس بگیرید.

+ +

برای ارسال پاسخ به صورت ناهمزمان:

+ +
    +
  • یا یک رفرنس برای آرگومان ()sendResponse نگه دارید و  مقدار true را برای تابع listener برگردانید. شما می توانید پس از بازگشت تابع listener، با  ()sendResponse تماس بگیرید.
  • +
  • یا یک {{jsxref("Promise")}} را از تابع listener برگردانید و  promise  را در صورت آماده بودن پاسخ حل کنید.  این یک روش ترجیحی است.
  • +
+
+
+ +

تابع  listener می تواند مقدار Boolean یا  {{jsxref("Promise")}} را برگرداند.

+ +
+

مهم: با استفاده از تابع async  با  ()addListener تماس نگیرید:

+ +
// don't do this
+browser.runtime.onMessage.addListener(
+  async (data, sender) => {
+    if (data.type === 'handle_me') { return 'done'; }
+  }
+);
+
+ +

این امر باعث می شود شنونده هر پیامی را که دریافت می کند, به طور موثر همه شنوندگان دیگر را از دریافت و پردازش پیام مسدود می کند.

+ +

اگر می خواهید رویکردی ناهمزمان داشته باشید, به جای این کار از یک  Promise استفاده کنید, مانند مثال زیر:

+ +
browser.runtime.onMessage.addListener(
+  (data, sender) => {
+    if (data.type === 'handle_me') {
+      return Promise.resolve('done');
+    }
+  }
+);
+
+
+
+
+ +

سازگاری مرورگر

+ + + +

{{Compat("webextensions.api.runtime.onMessage()")}}

+ +

Examples

+ +

Simple example

+ +

This content script listens for click events on the web page. If the click was on a link, it messages the background page with the target URL:

+ +
// content-script.js
+
+window.addEventListener("click", notifyExtension);
+
+function notifyExtension(e) {
+  if (e.target.tagName != "A") {
+    return;
+  }
+  browser.runtime.sendMessage({"url": e.target.href});
+}
+
+ +

The background script listens for these messages and displays a notification using the notifications API:

+ +
// background-script.js
+
+browser.runtime.onMessage.addListener(notify);
+
+function notify(message) {
+  browser.notifications.create({
+    "type": "basic",
+    "iconUrl": browser.extension.getURL("link.png"),
+    "title": "You clicked a link!",
+    "message": message.url
+  });
+}
+
+ +

Sending a synchronous response

+ +

This content script sends a message to the background script when the user clicks on the page. It also logs any response sent by the background script:

+ +
// content-script.js
+
+function handleResponse(message) {
+  console.log(`background script sent a response: ${message.response}`);
+}
+
+function handleError(error) {
+  console.log(`Error: ${error}`);
+}
+
+function sendMessage(e) {
+  const sending = browser.runtime.sendMessage({content: "message from the content script"});
+  sending.then(handleResponse, handleError);
+}
+
+window.addEventListener("click", sendMessage);
+ +

Here is a version of the corresponding background script, that sends a response synchronously, from inside in the listener:

+ +
// background-script.js
+
+function handleMessage(request, sender, sendResponse) {
+  console.log(`content script sent a message: ${request.content}`);
+  sendResponse({response: "response from background script"});
+}
+
+browser.runtime.onMessage.addListener(handleMessage);
+ +

And here is another version which uses {{jsxref("Promise.resolve()")}}:

+ +
// background-script.js
+
+function handleMessage(request, sender, sendResponse) {
+  console.log(`content script sent a message: ${request.content}`);
+  return Promise.resolve({response: "response from background script"});
+}
+
+browser.runtime.onMessage.addListener(handleMessage);
+ +

Sending an asynchronous response using sendResponse

+ +

Here is an alternative version of the background script from the previous example. It sends a response asynchronously after the listener has returned. Note return true; in the listener: this tells the browser that you intend to use the sendResponse argument after the listener has returned.

+ +
// background-script.js
+
+function handleMessage(request, sender, sendResponse) {
+  console.log(`content script sent a message: ${request.content}`);
+  setTimeout(() => {
+    sendResponse({response: "async response from background script"});
+  }, 1000);
+  return true;
+}
+
+browser.runtime.onMessage.addListener(handleMessage);
+
+ +

Sending an asynchronous response using a Promise

+ +

This content script gets the first <a> link on the page and sends a message asking if the link's location is bookmarked. It expects to get a Boolean response (true if the location is bookmarked, false otherwise):

+ +
// content-script.js
+
+const firstLink = document.querySelector("a");
+
+function handleResponse(isBookmarked) {
+  if (isBookmarked) {
+    firstLink.classList.add("bookmarked");
+  }
+}
+
+browser.runtime.sendMessage({
+  url: firstLink.href
+}).then(handleResponse);
+ +

Here is the background script. It uses {{WebExtAPIRef("bookmarks.search()")}} to see if the link is bookmarked, which returns a {{jsxref("Promise")}}:

+ +
// background-script.js
+
+function isBookmarked(message, sender, response) {
+  return browser.bookmarks.search({
+    url: message.url
+  }).then(function(results) {
+    return results.length > 0;
+  });
+}
+
+browser.runtime.onMessage.addListener(isBookmarked);
+ +

If the asynchronous handler doesn't return a Promise, you can explicitly construct a promise. This rather contrived example sends a response after a 1-second delay, using Window.setTimeout():

+ +
// background-script.js
+
+function handleMessage(request, sender, sendResponse) {
+  return new Promise(resolve => {
+    setTimeout( () => {
+      resolve({response: "async response from background script"});
+    }, 1000);
+  });
+}
+
+browser.runtime.onMessage.addListener(handleMessage);
+ +

{{WebExtExamples}}

+ +
Acknowledgements + +

This API is based on Chromium's chrome.runtime API. This documentation is derived from runtime.json in the Chromium code.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git a/files/fa/mozilla/add-ons/webextensions/index.html b/files/fa/mozilla/add-ons/webextensions/index.html new file mode 100644 index 0000000000..49530e6d87 --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/index.html @@ -0,0 +1,97 @@ +--- +title: WebExtensions +slug: Mozilla/Add-ons/WebExtensions +tags: + - افزونه + - افزونه_فایرفاکس + - برنامه_نویسی + - توسعه +translation_of: Mozilla/Add-ons/WebExtensions +--- +
{{AddonSidebar}}
+ +
افزونه ها قادر به بسط و تغییر قابلیت یک مرورگر می باشند. افزونه ها، برای فایرفاکس، با به کارگیری 
+ +
وب-گستر API، که یک سیستم مرورگر-متقابل جهت توسعه افزونه هاست، ساخته می شود. برای یک گسترش بزرگ، سیستم با افزونه API یا  extension API مورد پشتیبانی گوگل و اوپرا و  W3C Draft Community Group سازگار می باشد. افزونه های نوشته شده برای این مرورگرها، اغلب بیشتر مواقع در فایرفاکس یا Microsoft Edge ، تنها با اندکی تغییر، اجرا خواهند شد. همچنین این API دارای سازگاری کامل با multiprocess Firefox است.
+ +
اگر شما ایده ها یا پرسش هایی داشته، یا برای رها شدن از افزونه های وراثتی، جهت به کارگیری وب-افزونه ها، نیازمند کمک باشید،می توانید در dev-addons mailing list  یا #webextensions در IRC به تنیجه برسید.
+ +

 

+ +
+ + +
+

منابع

+ + + +

JavaScript APIs

+ +
{{ ListSubpages ("/en-US/Add-ons/WebExtensions/API") }}
+ +

Manifest keys

+ +
{{ ListSubpages ("/en-US/Add-ons/WebExtensions/manifest.json") }}
+
+
diff --git a/files/fa/mozilla/add-ons/webextensions/your_first_webextension/index.html b/files/fa/mozilla/add-ons/webextensions/your_first_webextension/index.html new file mode 100644 index 0000000000..b3fcdaaa40 --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/your_first_webextension/index.html @@ -0,0 +1,152 @@ +--- +title: اولین extension شما +slug: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension +translation_of: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension +--- +
{{AddonSidebar}}
+ +

در این مقاله ما از ابتدا تا انتهای ساخت یک افزونه برای فایر فاکس را با هم مرور میکنیم. این افزونه فقط یک border قرمز را به هر صفحه ای که از «mozilla.org» یا هر کدام از زیر دامنه های آن فراخوانی شده باشد را اضافه میکند .

+ +

منبع کد این مثال بر روی گیت هاب: https://github.com/mdn/webextensions-examples/tree/master/borderify.

+ +

در ابتدا شما به فایرفاکس نسخه 45 یا بالاتر نیاز دارید.

+ +

نوشتن extension

+ +

یک فولدر جدید ایجاد کنید و به آن بروید. به عنوان مثال ، در خط فرمان / ترمینال خود را اینگونه انجام می دهید:

+ +
mkdir borderify
+cd borderify
+ +

manifest.json

+ +

اکنون یک فایل جدید با نام "manifest.json" را مستقیماً در فولدر "borderify" ایجاد کنید. مطالب زیر را به آن بدهید:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Borderify",
+  "version": "1.0",
+
+  "description": "Adds a red border to all webpages matching mozilla.org.",
+
+  "icons": {
+    "48": "icons/border-48.png"
+  },
+
+  "content_scripts": [
+    {
+      "matches": ["*://*.mozilla.org/*"],
+      "js": ["borderify.js"]
+    }
+  ]
+
+}
+ + + +

جالب ترین نکته اینجاست که content_scripts  به Firefox می گوید یک اسکریپت را در صفحات وب بارگذاری کنید که URL آن با الگوی خاصی مطابقت دارد. در این حالت ، ما از Firefox می خواهیم یک اسکریپت با نام "borderify.js" را در تمام صفحات HTTP یا HTTPS که از "mozilla.org" یا هر یک از زیر دامنه های آن استفاده می شود بارگیری کند.

+ + + +
+

در بعضی مواقع باید یک ID برای extension خود تعیین کنید . اگر نیاز به add-on ID دارید , کلید  برنامه ها را در manifest.json قرار دهید و ویژگی gecko.id آن را تنظیم کنید:

+ +
"applications": {
+  "gecko": {
+    "id": "borderify@example.com"
+  }
+}
+
+ +

icons/border-48.png

+ +

extension باید یک نماد داشته باشد. تا در کنار لیست  extension ها در  Add-ons Manager  نمایش داده شود. manifest.json ما قول داده است كه ما در " icons/border-48.png" نماد داشته باشيم.

+ +

فولدر "icons" را مستقیماً در فولدر "borderify" ایجاد کنید. نمادی را در آنجا با نام "border-48.png" ذخیره کنید. می توانید از نمونه این مورد که از نماد Google Material Design طراحی شده است و تحت شرایط مجوز Creative Commons Attribution-ShareAlike استفاده می شود استفاده کنید.

+ +

اگر می خواهید نماد خود را تهیه کنید ، باید 48x48 پیکسل باشد. شما همچنین می توانید یک نماد پیکسل 96x96 را برای نمایشگرهای با وضوح بالا تهیه کنید ، و اگر این کار را انجام دهید به عنوان 96خاصیت icons object در manifest.json مشخص می شود:

+ +
"icons": {
+  "48": "icons/border-48.png",
+  "96": "icons/border-96.png"
+}
+ +

روش دیگر ، شما می توانید یک فایل SVG را در اینجا تهیه کنید ، و به درستی اندازه گیری می شود. (اگرچه: اگر از SVG استفاده می کنید و نماد شما متن را شامل می شود ، ممکن است بخواهید از ابزار "تبدیل به مسیر" ویرایشگر SVG خود برای صاف کردن متن استفاده کنید ، به طوری که با اندازه / موقعیت ثابت سازگار باشد.

+ + + +

borderify.js

+ +

سرانجام ، فایلی به نام "borderify.js" را مستقیماً در فولدر "borderify" ایجاد کنید. این محتوا را به آن بدهید:

+ +
document.body.style.border = "5px solid red";
+ +

این اسکریپت در صفحات مطابقت با الگوی ارائه شده در content_scriptsکلید manifest.json بارگذاری می شود . درست مانند اسکریپت هایی که توسط خود صفحه بارگذاری شده است ، اسکریپت دسترسی مستقیم به اسناد دارد.

+ + + +

امتحان کردن

+ +

ابتدا بررسی کنید که فایل های مناسب را در فولدرهای مناسب دارید:

+ +
borderify/
+    icons/
+        border-48.png
+    borderify.js
+    manifest.json
+ +

نصب

+ +

 در فایرفاکس : صفحه about:debugging را باز کنید، روی "This Firefox" (در نسخه های جدیدتر فایرفاکس) کلیک کنید، روی "Load Temporary Add-on" کلیک کنید و یکی از فایل ها را از آدرس اصلی extension خود انتخاب کنید

+ +

{{EmbedYouTube("cer9EUKegG4")}}

+ +

extension اکنون نصب شده است و تا زمانی که فایرفاکس را مجدداً راه اندازی کنید ، باقی خواهد ماند.

+ +

روش دیگر ، می توانید با استفاده از ابزار web-ext ، پسوند را از خط فرمان اجرا کنید.

+ +

آزمایش کردن

+ +

اکنون سعی کنید از صفحهای تحت "mozilla.org" بازدید کنید،  و باید border قرمز را در صفحه مشاهده کنید:

+ +

{{EmbedYouTube("rxBQl2Z9IBQ")}}

+ +
+

هر چند آن را در addons.mozilla.org امتحان نکنید! اسکریپت های محتوا در حال حاضر در آن دامنه مسدود شده اند .

+
+ +

کمی آزمایش کنید. اسکریپت محتوا را تغییر دهید تا رنگ حاشیه تغییر کند ، یا کاری دیگر روی محتوای صفحه انجام دهید. اسکریپت محتوا را ذخیره کنید ، سپس فایل های extension  را با کلیک کردن روی دکمه "Reload" در about:debugging بارگیری مجدد کنید. می توانید تغییرات را بلافاصله مشاهده کنید:

+ +

{{EmbedYouTube("NuajE60jfGY")}}

+ + + +

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

+ +

برای استفاده افراد دیگر از extension شما ، باید آن را بسته بندی کرده و برای امضا به موزیلا ارسال کنید. برای کسب اطلاعات بیشتر در مورد آن ، به  "Publishing your extension" مراجعه کنید.

+ +

بعدی چیست؟

+ +

اکنون شما یک ایده از روند توسعه یک WebExtension برای Firefox دارید ، سعی کنید:

+ + diff --git a/files/fa/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/fa/mozilla/add-ons/webextensions/your_second_webextension/index.html new file mode 100644 index 0000000000..aff7ba0259 --- /dev/null +++ b/files/fa/mozilla/add-ons/webextensions/your_second_webextension/index.html @@ -0,0 +1,458 @@ +--- +title: اکستنشن دوم شما +slug: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +--- +
+

{{AddonSidebar}}

+ +

اگر شما مقاله اولین اکستنشن خود را خوانده اید، حالا ایده ای از چگونگی نوشتن یک اکستنشن به شما داده می شود. در این مقاله ما اکستنشن کمی پیچیده تری را که در ان از تعدادی از API ها استفاده شده، می نویسیم.

+ +

The extension adds a new button to the Firefox toolbar. When the user clicks the button, we display a popup enabling them to choose an animal. Once they choose an animal, we'll replace the current page's content with a picture of the chosen animal.

+ +

To implement this, we will:

+ + + +

You could visualise the overall structure of the extension like this:

+ +

+ +

It's a simple extension, but shows many of the basic concepts of the WebExtensions API:

+ + + +

You can find complete source code for the extension on GitHub.

+ +

To write this extension, you'll need Firefox 45 or newer.

+ +

Writing the extension

+ +

Create a new directory and navigate to it:

+ +
mkdir beastify
+cd beastify
+ +

manifest.json

+ +

Now create a new file called "manifest.json", and give it the following contents:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Beastify",
+  "version": "1.0",
+
+  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
+  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
+  "icons": {
+    "48": "icons/beasts-48.png"
+  },
+
+  "permissions": [
+    "activeTab"
+  ],
+
+  "browser_action": {
+    "default_icon": "icons/beasts-32.png",
+    "default_title": "Beastify",
+    "default_popup": "popup/choose_beast.html"
+  },
+
+  "web_accessible_resources": [
+    "beasts/frog.jpg",
+    "beasts/turtle.jpg",
+    "beasts/snake.jpg"
+  ]
+
+}
+
+ + + +

Note that all paths given are relative to manifest.json itself.

+ +

The icon

+ +

The extension should have an icon. This will be shown next to the extension's listing in the Add-ons Manager (you can open this by visiting the URL "about:addons"). Our manifest.json promised that we would have an icon for the toolbar at "icons/beasts-48.png".

+ +

Create the "icons" directory and save an icon there named "beasts-48.png".  You could use the one from our example, which is taken from the Aha-Soft’s Free Retina iconset, and used under the terms of its license.

+ +

If you choose to supply your own icon, It should be 48x48 pixels. You could also supply a 96x96 pixel icon, for high-resolution displays, and if you do this it will be specified as the 96 property of the icons object in manifest.json:

+ +
"icons": {
+  "48": "icons/beasts-48.png",
+  "96": "icons/beasts-96.png"
+}
+ +

The toolbar button

+ +

The toolbar button also needs an icon, and our manifest.json promised that we would have an icon for the toolbar at "icons/beasts-32.png".

+ +

Save an icon named "beasts-32.png" in the "icons" directory. You could use the one from our example, which is taken from the IconBeast Lite icon set and used under the terms of its license.

+ +

If you don't supply a popup, then a click event is dispatched to your extension when the user clicks the button. If you do supply a popup, the click event is not dispatched, but instead, the popup is opened. We want a popup, so let's create that next.

+ +

The popup

+ +

The function of the popup is to enable the user to choose one of three beasts.

+ +

Create a new directory called "popup" under the extension root. This is where we'll keep the code for the popup. The popup will consist of three files:

+ + + +
mkdir popup
+cd popup
+touch choose_beast.html choose_beast.css choose_beast.js
+
+ +

choose_beast.html

+ +

The HTML file looks like this:

+ +
<!DOCTYPE html>
+
+<html>
+  <head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" href="choose_beast.css"/>
+  </head>
+
+<body>
+  <div id="popup-content">
+    <div class="button beast">Frog</div>
+    <div class="button beast">Turtle</div>
+    <div class="button beast">Snake</div>
+    <div class="button reset">Reset</div>
+  </div>
+  <div id="error-content" class="hidden">
+    <p>Can't beastify this web page.</p><p>Try a different page.</p>
+  </div>
+  <script src="choose_beast.js"></script>
+</body>
+
+</html>
+
+ +

We have a <div> element with an ID of "popup-content" that contains an element for each animal choice. We have another <div> with an ID of "error-content" and a class "hidden". We'll use that in case there's a problem initializing the popup.

+ +

Note that we include the CSS and JS files from this file, just like a web page.

+ +

choose_beast.css

+ +

The CSS fixes the size of the popup, ensures that the three choices fill the space, and gives them some basic styling. It also hides elements with class="hidden": this means that our "error-content" <div> will be hidden by default.

+ +
html, body {
+  width: 100px;
+}
+
+.hidden {
+  display: none;
+}
+
+.button {
+  margin: 3% auto;
+  padding: 4px;
+  text-align: center;
+  font-size: 1.5em;
+  cursor: pointer;
+}
+
+.beast:hover {
+  background-color: #CFF2F2;
+}
+
+.beast {
+  background-color: #E5F2F2;
+}
+
+.reset {
+  background-color: #FBFBC9;
+}
+
+.reset:hover {
+  background-color: #EAEA9D;
+}
+
+
+ +

choose_beast.js

+ +

Here's the JavaScript for the popup:

+ +
/**
+ * CSS to hide everything on the page,
+ * except for elements that have the "beastify-image" class.
+ */
+const hidePage = `body > :not(.beastify-image) {
+                    display: none;
+                  }`;
+
+/**
+ * Listen for clicks on the buttons, and send the appropriate message to
+ * the content script in the page.
+ */
+function listenForClicks() {
+  document.addEventListener("click", (e) => {
+
+    /**
+     * Given the name of a beast, get the URL to the corresponding image.
+     */
+    function beastNameToURL(beastName) {
+      switch (beastName) {
+        case "Frog":
+          return browser.extension.getURL("beasts/frog.jpg");
+        case "Snake":
+          return browser.extension.getURL("beasts/snake.jpg");
+        case "Turtle":
+          return browser.extension.getURL("beasts/turtle.jpg");
+      }
+    }
+
+    /**
+     * Insert the page-hiding CSS into the active tab,
+     * then get the beast URL and
+     * send a "beastify" message to the content script in the active tab.
+     */
+    function beastify(tabs) {
+      browser.tabs.insertCSS({code: hidePage}).then(() => {
+        let url = beastNameToURL(e.target.textContent);
+        browser.tabs.sendMessage(tabs[0].id, {
+          command: "beastify",
+          beastURL: url
+        });
+      });
+    }
+
+    /**
+     * Remove the page-hiding CSS from the active tab,
+     * send a "reset" message to the content script in the active tab.
+     */
+    function reset(tabs) {
+      browser.tabs.removeCSS({code: hidePage}).then(() => {
+        browser.tabs.sendMessage(tabs[0].id, {
+          command: "reset",
+        });
+      });
+    }
+
+    /**
+     * Just log the error to the console.
+     */
+    function reportError(error) {
+      console.error(`Could not beastify: ${error}`);
+    }
+
+    /**
+     * Get the active tab,
+     * then call "beastify()" or "reset()" as appropriate.
+     */
+    if (e.target.classList.contains("beast")) {
+      browser.tabs.query({active: true, currentWindow: true})
+        .then(beastify)
+        .catch(reportError);
+    }
+    else if (e.target.classList.contains("reset")) {
+      browser.tabs.query({active: true, currentWindow: true})
+        .then(reset)
+        .catch(reportError);
+    }
+  });
+}
+
+/**
+ * There was an error executing the script.
+ * Display the popup's error message, and hide the normal UI.
+ */
+function reportExecuteScriptError(error) {
+  document.querySelector("#popup-content").classList.add("hidden");
+  document.querySelector("#error-content").classList.remove("hidden");
+  console.error(`Failed to execute beastify content script: ${error.message}`);
+}
+
+/**
+ * When the popup loads, inject a content script into the active tab,
+ * and add a click handler.
+ * If we couldn't inject the script, handle the error.
+ */
+browser.tabs.executeScript({file: "/content_scripts/beastify.js"})
+.then(listenForClicks)
+.catch(reportExecuteScriptError);
+
+
+ +

The place to start here is line 96. The popup script executes a content script in the active tab as soon as the popup is loaded, using the browser.tabs.executeScript() API. If executing the content script is successful, then the content script will stay loaded in the page until the tab is closed or the user navigates to a different page.

+ +

A common reason the browser.tabs.executeScript() call might fail is that you can't execute content scripts in all pages. For example, you can't execute them in privileged browser pages like about:debugging, and you can't execute them on pages in the addons.mozilla.org domain. If it does fail, reportExecuteScriptError() will hide the "popup-content" <div>, show the "error-content" <div>, and log an error to the console.

+ +

If executing the content script is successful, we call listenForClicks(). This listens for clicks on the popup.

+ + + +

The beastify() function does three things:

+ + + +

The reset() function essentially undoes a beastify:

+ + + +

The content script

+ +

Create a new directory, under the extension root, called "content_scripts" and create a new file in it called "beastify.js", with the following contents:

+ +
(function() {
+  /**
+   * Check and set a global guard variable.
+   * If this content script is injected into the same page again,
+   * it will do nothing next time.
+   */
+  if (window.hasRun) {
+    return;
+  }
+  window.hasRun = true;
+
+  /**
+   * Given a URL to a beast image, remove all existing beasts, then
+   * create and style an IMG node pointing to
+   * that image, then insert the node into the document.
+   */
+  function insertBeast(beastURL) {
+    removeExistingBeasts();
+    let beastImage = document.createElement("img");
+    beastImage.setAttribute("src", beastURL);
+    beastImage.style.height = "100vh";
+    beastImage.className = "beastify-image";
+    document.body.appendChild(beastImage);
+  }
+
+  /**
+   * Remove every beast from the page.
+   */
+  function removeExistingBeasts() {
+    let existingBeasts = document.querySelectorAll(".beastify-image");
+    for (let beast of existingBeasts) {
+      beast.remove();
+    }
+  }
+
+  /**
+   * Listen for messages from the background script.
+   * Call "beastify()" or "reset()".
+  */
+  browser.runtime.onMessage.addListener((message) => {
+    if (message.command === "beastify") {
+      insertBeast(message.beastURL);
+    } else if (message.command === "reset") {
+      removeExistingBeasts();
+    }
+  });
+
+})();
+
+ +

The first thing the content script does is to check for a global variable window.hasRun: if it's set the script returns early, otherwise it sets window.hasRun and continues. The reason we do this is that every time the user opens the popup, the popup executes a content script in the active tab, so we could have multiple instances of the script running in a single tab. If this happens, we need to make sure that only the first instance is actually going to do anything.

+ +

After that, the place to start is line 40, where the content script listens for messages from the popup, using the browser.runtime.onMessage API. We saw above that the popup script can send two different sorts of messages: "beastify" and "reset".

+ + + +

The beasts

+ +

Finally, we need to include the images of the beasts.

+ +

Create a new directory called "beasts", and add the three images in that directory, with the appropriate names. You can get the images from the GitHub repository, or from here:

+ +

+ +

Testing it out

+ +

First, double check that you have the right files in the right places:

+ +
beastify/
+
+    beasts/
+        frog.jpg
+        snake.jpg
+        turtle.jpg
+
+    content_scripts/
+        beastify.js
+
+    icons/
+        beasts-32.png
+        beasts-48.png
+
+    popup/
+        choose_beast.css
+        choose_beast.html
+        choose_beast.js
+
+    manifest.json
+ +

Starting in Firefox 45, you can install extensions temporarily from disk.

+ +

Open "about:debugging" in Firefox, click "Load Temporary Add-on", and select your manifest.json file. You should then see the extension's icon appear in the Firefox toolbar:

+ +

{{EmbedYouTube("sAM78GU4P34")}}

+ +

Open a web page, then click the icon, select a beast, and see the web page change:

+ +

{{EmbedYouTube("YMQXyAQSiE8")}}

+ +

Developing from the command line

+ +

You can automate the temporary installation step by using the web-ext tool. Try this:

+ +
cd beastify
+web-ext run
+
-- cgit v1.2.3-54-g00ecf