diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/xul_school | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/xul_school')
11 files changed, 1623 insertions, 0 deletions
diff --git a/files/ru/xul_school/appendix_a_colon__add-on_performance/index.html b/files/ru/xul_school/appendix_a_colon__add-on_performance/index.html new file mode 100644 index 0000000000..1364929357 --- /dev/null +++ b/files/ru/xul_school/appendix_a_colon__add-on_performance/index.html @@ -0,0 +1,43 @@ +--- +title: 'Приложение A: Производительность дополнений' +slug: 'XUL_School/Appendix_A:_Add-on_Performance' +tags: + - Дополнения + - Производительность + - Расширения +translation_of: 'Archive/Add-ons/Overlay_Extensions/XUL_School/Appendix_A:_Add-on_Performance' +--- +<div class="note"> + <strong>Внимание:</strong> Смотрите новую статью <a href="/en/Extensions/Performance_best_practices_in_extensions" title="en/Extensions/Performance best practices in extensions">Performance best practices in extensions</a> для получения более свежей информации по оптимизации производительности ваших дополнений.</div> +<p>Add-ons can have a noticeable performance impact on Firefox. This is evident when opening a Firefox profile that has many add-ons installed; some profiles can take minutes to load, which is a serious inconvenience for users that gives them a negative view of Firefox. Add-on developers need to make sure that they minimize their add-ons' performance impact, and here are a few simple guidelines that should be followed to achieve that.</p> +<h2 id="Запуск">Запуск</h2> +<p>This is the area where add-ons have the most noticeable impact. Most add-ons use the load event handler in the main overlay to initialize their objects and sometimes read files or even fetch remote data. The problem with the <em>onload</em> event is that it runs before the main window becomes visible, so all handlers need to complete before the user can see the window. An add-on can normally add a few hundred milliseconds to startup time because of the load handler, and it's not hard to figure out what having several add-ons will do.</p> +<p>Luckily, minimizing your startup time is easy, if you follow these guidelines:</p> +<ol> + <li>Do not load or run code before it’s needed. Add-ons can have extra features that are only available depending on user preferences. Other add-ons have most of their features depend on a user being logged in to a service. Don’t load at startup something you won’t need at the time.</li> + <li><a href="/../../../../en/Using_JavaScript_code_modules" title="../../../../en/Using_JavaScript_code_modules">JavaScript Code Modules</a>. Use them. JSM provide the cleanest way to separate JS into modules that can be loaded on request, unlike chrome scripts which are generally loaded with the overlay at startup. Keep as much of your code in JSM, make it as modular as you can, and only load modules as you require them. If your add-on is too simple for JSM, don’t worry about it. There’s still one more thing you can do.</li> + <li>Do as little as possible in your load handler. Ask yourself: is there anything I can’t run 100 ms or even 500 ms later? If there is, just use an <a href="/../../../../En/nsITimer" title="../../../../En/nsITimer">nsITimer</a> or the <a href="/../../../../en/DOM/window.setTimeout" title="../../../../en/DOM/window.setTimeout">setTimeout</a> function to delay running this code . The Firefox window will be able to load sooner and your startup code will run almost instantaneously afterward, in parallel with the loading of the homepage or the saved tab session. The browser will now load faster, and your code will still load at startup for all practical purposes. The code is simple enough:</li> +</ol> +<pre class="brush: js">// this is the function that is called in the load event handler. +init : function() { + let that = this; + // run this later and let the window load. + window.setTimeout(function() { that.postInit(); }, 500); +}, + +postInit: function() { + // actual init code goes here. +}, +</pre> +<p>How can you tell it works? The <a class="link-https" href="https://wiki.mozilla.org/Firefox/Projects/StartupPerformance/MeasuringStartup" title="https://wiki.mozilla.org/Firefox/Projects/StartupPerformance/MeasuringStartup">Measuring Startup</a> wiki page includes a relatively simple test you can use to compare a clean Firefox profile vs that profile with your add-on installed.</p> +<h2 id="Загрузка_страницы">Загрузка страницы</h2> +<p>This is another critical route that many add-ons tap into. The <a href="/en/XUL_School/Intercepting_Page_Loads" title="en/XUL School/Intercepting Page Loads">Intercepting Page Loads</a> section details several techniques to do this, and you should read all of them carefully to figure out which one you need. Some of these events are fired multiple times during a single page load, and having inefficient code in the event handlers can cause a noticeable delay that users may have hard time figuring out.</p> +<p>Look at the source samples in the article and notice how they mostly consist of nested <em>if</em> statements. This is what you should do <strong>first</strong> to make sure that you filter out all cases that don't interest you so that your add-on doesn't slow down other requests. A very common filter is the URL of the page, since most add-ons are limited to one or a few domains. Use regular expressions if you need to. Make sure your comparison code is as efficient as possible.</p> +<p>Finally, make sure all of your page load code is as efficient as possible. This can be tricky for some add-ons, like ad or script blockers that need to check a whitelist or blacklist. Nevertheless, loading pages is pretty important in Firefox, and users expect it to be fast. Try your best to keep it that way.</p> +<h2 id="Другие_рекомендации">Другие рекомендации</h2> +<ul> + <li>Always clean up after yourself. Event listeners, observers and other handlers normally have both an add and a remove function. Don't forget to remove what you don't need anymore! Even if you need something during the whole existence of the window, you should clean everything up in the unload event handler.</li> + <li>Even the unload event should be handled efficiently. Even if it is not as important as other areas, Firefox shutdown can also be slowed down because of add-ons. If there's anything you can unload before shutdown, or if there's anything you can do to unload things more efficiently, then it's important that you do.</li> + <li><strong>Никогда</strong> не используйте XMLHttpRequest в синхронном режиме.</li> + <li>If your add-on needs to perform a heavy operation like sorting or a complex mathematical calculation, you should use <a href="/En/Using_web_workers" title="En/Using web workers">DOM Workers</a> to offload the work to other threads.</li> +</ul> diff --git a/files/ru/xul_school/getting_started_with_firefox_extensions/index.html b/files/ru/xul_school/getting_started_with_firefox_extensions/index.html new file mode 100644 index 0000000000..2d436a73b9 --- /dev/null +++ b/files/ru/xul_school/getting_started_with_firefox_extensions/index.html @@ -0,0 +1,107 @@ +--- +title: Приступая к работе с расширениями Firefox. +slug: XUL_School/Getting_Started_with_Firefox_Extensions +translation_of: >- + Archive/Add-ons/Overlay_Extensions/XUL_School/Getting_Started_with_Firefox_Extensions +--- +<p>{{ PreviousNext("XUL_School/Introduction", "XUL_School/The_Essentials_of_an_Extension") }}</p> + +<h2 id="Что_такое_расширение_Firefox">Что такое расширение Firefox?</h2> + +<blockquote> +<p>Расширения — это небольшие дополнения (<span>add-on</span>), добавляющие новые функциональные возможности приложениям <span>Mozilla</span>, таким как <span>Firefox</span> и <span>Thunderbird</span>. С их помощью в приложение можно добавить что угодно, от кнопки на панели инструментов до совершенно новой возможности. Они позволяют настраивать приложения с учётом личных потребностей каждого пользователя, которому могут понадобиться дополнительные функциональные возможности, сохраняя при этом приложения небольшими для скачивания.</p> +</blockquote> + +<p>Взято со <a href="/ru/Extensions" title="ru/Extensions">страницы о расширениях</a>.</p> + +<p>Как говорится в приведенной цитате, расширения - это маленькие приложения добавляющие что-нибудь новое к тому или иному приложению Mozilla. Этот учебник посвящён расширениям для Firefox, но те же самые (или схожие) принципы применимы для создания расширений для других приложений, таких как Thunderbird, Seamonkey и Flock.</p> + +<p>Стоит также отметить, что определения <em>расширение</em> (extension) и <em>дополнение</em> (add-on) различаются. Все расширения - это дополнения, но дополнения также могут быть темами, плагинами, или языковыми пакетами. Данный учебник - о разработке расширений, но темы и языковые пакеты разрабатываются очень похожим образом. Плагины (plugins) полностью отличаются, поэтому здесь мы их рассматривать не будем. Вы можете прочитать больше о плагинах и их разработке на <a href="/en/Plugins" title="en/Plugins">странице о плагинах</a>.</p> + +<p>Firefox предоставляет очень богатую и гибкую архитектуру, позволяющую разработчикам расширений добавлять дополнительные возможности, настраивать деятельность пользователей, а также полностью заменять и удалять части браузера. Склад дополнений (репозитарий)<span class="link-https"> Mozilla</span> - <a href="https://addons.mozilla.org" title="https://addons.mozilla.org">Mozilla Add-on repository (AMO)</a> - содержит множество расширений с разнообразной функциональностью. Например: фильтрация контента (<a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/1865" title="https://addons.mozilla.org/en-US/firefox/addon/1865">AdBlock Plus</a>, <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/722" title="https://addons.mozilla.org/en-US/firefox/addon/722">NoScript</a>), взаимодействие с web-приложениями (<a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/3615" title="https://addons.mozilla.org/en-US/firefox/addon/3615">Delicious Bookmarks</a>, <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/5202" title="https://addons.mozilla.org/en-US/firefox/addon/5202">eBay Companion</a>), web-разработка (<a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/6622" title="https://addons.mozilla.org/en-US/firefox/addon/6622">DOM Inspector</a>, <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/1843" title="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a>), защита детей (<a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/5881" title="https://addons.mozilla.org/en-US/firefox/addon/5881">Glubble For Families</a>). Существуют современные, достаточно функциональные и сложные расширения. Вы познакомитесь со многим, что может понадобится для разработки таких приложений. Фирма Glaxstar работал над тремя дополнениями из перечисленных выше.</p> + +<p>Расширения сейчас существуют в трёх формах:</p> + +<ol> + <li>Дополнения расширений SDK (также известны как "Jetpacks" - "реактивные ранцы"). <a href="http://ru.wikipedia.org/wiki/SDK" title="http://ru.wikipedia.org/wiki/SDK">SDK - software development kit - (англ.) комплект средств разработки.</a></li> + <li>Расширения начальной загрузки.</li> + <li>Традиционные расширения.</li> +</ol> + +<p>Если вы новичок в разработке дополнений, то комплект разработки SDK - предоставляет хороший способ быстро создать простые расширения. Этот учебник посвящён традиционным расширениям, которые создаются по-другому. Загрузочные расширения по сложности на ступеньку выше обычных, поэтому стоит изучить этот материал, прежде чем пытаться их делать.</p> + +<p>Начнём обучение с анализа очень простого расширения.</p> + +<h2 id="Расширение_Привет_мир!">Расширение "Привет, мир!"</h2> + +<p>Примеры расширений и этот учебник в целом предназначаются для современных версий Firefox, но большинство из всего этого работает и на устаревших версиях.</p> + +<p>Мы начнем с традиционного расширения "Привет, мир!" (Hello World). И начнём мы с его установки. Щёлкните по ссылке ниже.</p> + +<p><a href="/@api/deki/files/5139/=xulschoolhello1.xpi" title="https://developer.mozilla.org/@api/deki/files/5139/=xulschoolhello1.xpi">Установить "Hello World"</a></p> + +<p>Это запустит либо установку, либо загрузку файлов - в зависимости от типа содержимого ("content type"), которое для этого файла использует веб-сервер. Тип содержимого, соответствующий запуску установки - <strong>"application/x-<strong>xpinstall"</strong></strong>. В данном случае тип содержимого установлен правильно и должно появлятся окно установки расширения.</p> + +<p>Если тип содержимого установлен правильно, то вы, вероятно, получите уведомление о том, что сайту не позволено устанавливать дополнения в ваш браузер Firefox. Это защитный барьер, предотвращающий установку сайтами расширений без согласия пользователя. Он необходим из-за того, что вредоносное расширение может причинить вред такого же уровня, как и любая другая вредоносная программа: совершить кражу данных, удаление или замену файлов и вообще, вызвать нежелательное поведение. Все дополнения , опубликованные в <a class="link-https" href="https://addons.mozilla.org/" title="https://addons.mozilla.org/">AMO</a>, прошли через процесс предварительного рассмотрения, включающий проверку безопасности.</p> + +<p>После загрузки файла, вы можете перенести ("drag and drop") его в область содержимого Firefox - и должна начаться установка.</p> + +<p>Вы увидите окно с сообщением, что вы собираетесь установить расширение и с какой-нибудь дополнительной информацией, вроде имени автора. Вы увидите сообщение о том, что автор не может быть проверен. Проверить авторство возможно только у расширений, подписанных с помощью цифрового сертификата. Подписанные расширения редки, но позже мы рассмотрим, как их подписывать.</p> + +<p>Нажмите на кнопку "Установить сейчас" ("Install Now"). После установки расширения, вам будет предложено перезапустить Firefox. Установка, удаление, включение и выключение расширения требуют перезагрузки для завершения операции . Исключение составляют плагины NPAPI, дополнения SDK расширений и загрузочные расширения. Имейте это в виду, если вы создаете расширение, манипулирующее другими расширениями или темами.</p> + +<p>После установки, взгляните на главное окно Firefox и посмотрите не изменилось ли что-нибудь.</p> + +<p>Вы это видели? В главном меню появилось новое подменю с надписью "Hello World!" ("Привет, мир!"). Если вы откроете меню, а затем в меню пункт ниже, вы увидите замечательное сообщение. Нажмите на кнопку ОК, чтобы его закрыть.</p> + +<p><img alt="" class="internal" src="https://developer.mozilla.org/@api/deki/files/4138/=helloworldalert.png" style="height: 126px; width: 326px;"></p> + +<p>Это всё, что делает это расширение. Теперь давайте посмотрим на него внимательнее.</p> + +<h2 id="Содержимое_Расширения">Содержимое Расширения</h2> + +<p>Возможно, вы заметили, что файл установки расширения называется xulschoolhello1.xpi. <a href="/en/XPI" title="en/XPI">XPI</a> (произносится как "зиппи". "zippy" - с англ: живой, быстрый, энергичный, яркий) выступает в качестве кроссплатформенного установщика, потому что один файл установки может быть обработан на всех платформах, поддерживаемых браузером Firefox. Файлы XPI - это просто данные, сжатые архиватором ZIP, однако Firefox распознает расширение XPI и запускает процесс установки при попытке загрузить такой файл.</p> + +<p>Чтобы заглянуть в файл XPI вам нужно сперва скачать его - не устанавливая. Если сервер запускает установку при нажатии на ссылку или кнопку - откажитесь, а затем нажмите правой кнопкой мыши на <a href="/@api/deki/files/5139/=xulschoolhello1.xpi" title="/@api/deki/files/5139/=xulschoolhello1.xpi">ссылке установки</a> и выберите вариант "Сохранить ссылку как..." ("Save Link As...").</p> + +<p>Далее распакуем файл XPI. Один из способов сделать это: переименовать расширение файла из <em>"xpi"</em> в <em>"zip"</em>. (в Линуксе это не требуется, т.к. расширения нужны только в декоративных целях, а программы распознают тип файла сами) Другой способ - открыть файл с помощью архиватора, поддерживающего стандарт ZIP. Выберите и распакуйте архив в удобное место. Вы увидите структуру каталогов вроде этой:</p> + +<ul> + <li>xulschoolhello1 + <ul> + <li>chrome.manifest</li> + <li>install.rdf</li> + <li>content + <ul> + <li>browserOverlay.xul</li> + <li>browserOverlay.js</li> + </ul> + </li> + <li>skin + <ul> + <li>browserOverlay.css</li> + </ul> + </li> + <li>locale + <ul> + <li>en-US + <ul> + <li>browserOverlay.dtd</li> + <li>browserOverlay.properties</li> + </ul> + </li> + </ul> + </li> + </ul> + </li> +</ul> + +<p>Так много файлов для такой ерунды! Не волнуйтесь, мы скоро увидим назначение всех этих файлов и вы поймёте, что всё довольно просто. В следующем разделе мы изучим эти файлы и посмотрим, что же они делают.</p> + +<p>{{ PreviousNext("XUL_School/Introduction", "XUL_School/The_Essentials_of_an_Extension") }}</p> + +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> + +<p>{{ languages( { "fr": "fr/Vulgarisation_XUL/Premiers_pas_avec_les_extensions_Firefox" } ) }}</p> + +<div id="cke_pastebin" style="position: absolute; top: 1090.5px; width: 1px; height: 1px; overflow: hidden; left: -1000px;"> </div> diff --git a/files/ru/xul_school/index.html b/files/ru/xul_school/index.html new file mode 100644 index 0000000000..df9ea3174e --- /dev/null +++ b/files/ru/xul_school/index.html @@ -0,0 +1,79 @@ +--- +title: Школьный учебник по XUL +slug: XUL_School +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School +--- +<p>Школа XUL - это содержательное руководство по разработке дополнений, в котором акцент сделан на разработке расширений Firefox. Рекомендуется прочитать его полностью хотя бы один раз. Поскольку Firefox быстро развивается, содержание данного руководства должно обновляться и быть актуальным.</p> +<dl> + <dt> + Введение</dt> + <dd> + <ul> + <li><a href="/ru/XUL_School/Introduction" title="ru/XUL School/Introduction">Введение</a></li> + <li><a href="/ru/XUL_School/Getting_Started_with_Firefox_Extensions" title="/ru/XUL_School/Getting_Started_with_Firefox_Extensions">Приступая к работе с расширениями Firefox</a></li> + <li><a href="/ru/XUL_School/The_Essentials_of_an_Extension" title="/ru/XUL_School/The_Essentials_of_an_Extension">Основы расширения</a></li> + <li><a href="/ru/docs/XUL_School/Настройка_среды_разработки" title="/ru/docs/XUL_School/Настройка_среды_разработки">Настройка среды разработки</a></li> + <li><a href="/en/XUL_School/JavaScript_Object_Management" title="en/XUL School/JavaScript Object Management">Менеджер объектов JavaScript</a></li> + </ul> + </dd> + <dt> + Основной набор возможностей</dt> + <dd> + <ul> + <li><a href="/ru/XUL_School/Добавление_меню_и_подменю" title="ru/XUL School/Добавление меню и подменю">Добавление меню и подменю</a></li> + <li><a href="/en/XUL_School/Adding_Toolbars_and_Toolbar_Buttons" title="en/XUL School/Adding Toolbars and Toolbar Buttons">Добавление панели инструментов и кнопок на панели инструментов</a></li> + <li><a href="/en/XUL_School/Adding_Events_and_Commands" title="en/XUL School/Adding Events and Commands">Добавление событий и команд</a></li> + <li><a href="/en/XUL_School/Adding_windows_and_dialogs" title="en/XUL School/Adding windows and dialogs">Добавление окон и диалогов</a></li> + <li><a href="/en/XUL_School/Adding_sidebars" title="en/XUL School/Adding sidebars">Добавление боковых панелей</a></li> + <li><a href="/en/XUL_School/User_Notifications_and_Alerts" title="en/XUL School/User Notifications and Alerts">Уведомление и оповещение пользователей</a></li> + </ul> + </dd> + <dt> + Intermediate functionality</dt> + <dd> + <ul> + <li><a href="/en/XUL_School/Intercepting_Page_Loads" title="en/XUL School/Intercepting Page Loads">Intercepting page loads</a></li> + <li><a href="/en/XUL_School/Connecting_to_Remote_Content" title="en/XUL School/Connecting to Remote Content">Connecting to Remote Content</a></li> + <li><a href="/en/XUL_School/Handling_Preferences" title="en/XUL School/Handling Preferences">Handling preferences</a></li> + <li><a href="/en/XUL_School/Local_Storage" title="en/XUL School/Local Storage">Local Storage</a></li> + </ul> + </dd> + <dt> + Advanced topics</dt> + <dd> + <ul> + <li><a href="/en/XUL_School/The_Box_Model" title="en/XUL School/The Box Model">The Box Model</a></li> + <li><a href="/en/XUL_School/XPCOM_Objects" title="en/XUL School/XPCOM Objects">XPCOM Objects</a></li> + <li><a href="/en/XUL_School/Observer_Notifications" title="en/XUL School/Observer Notifications">Observer Notifications</a></li> + <li><a href="/en/XUL_School/Custom_XUL_Elements_with_XBL" title="en/XUL School/Custom XUL Elements with XBL">Custom XUL Elements with XBL</a></li> + <li><a href="/en/XUL_School/Mozilla_Documentation_Roadmap" title="en/XUL School/Mozilla Documentation Roadmap">Mozilla Documentation Roadmap</a></li> + <li><a href="/en/XUL_School/Useful_Mozilla_Community_Sites" title="en/XUL School/Useful Mozilla Community Sites">Useful Mozilla Community Sites</a></li> + </ul> + </dd> + <dt> + Приложения</dt> + <dd> + <ul> + <li><a href="/en/XUL_School/Appendix_A:_Add-on_Performance" title="en/XUL School/Appendix A: Add-on Performance">Приложение A: Производительность дополнений</a></li> + <li><a href="/en/XUL_School/Appendix_B:_Install_and_Uninstall_Scripts" title="en/XUL School/Appendix B: Install and Uninstall Scripts">Приложение B: Установка и удаление скриптов</a></li> + <li><a href="/en/XUL_School/Appendix_C:_Avoid_using_eval_in_Add-ons" title="en/XUL School/Appendix C: Avoid using eval in Add-ons">Приложение C: Как избежать использования eval в дополнениях</a></li> + <li><a href="/en/XUL_School/Appendix_D:_Loading_Scripts" title="en/XUL School/Appendix D: Loading Scripts">Приложение D: Загрузка скриптов</a></li> + <li><a href="/en/XUL_School/DOM_Building_and_HTML_Insertion" title="en/XUL School/Appendix E: DOM Building and HTML Insertion">Приложение E: Построение DOM и внедрение HTML</a></li> + <li><a href="/en/XUL_School/Appendix_F:_Monitoring_DOM_changes" title="en/XUL School/Appendix F: Monitoring DOM changes">Приложение F: Отслеживание изменений в DOM</a></li> + </ul> + </dd> +</dl> +<p>The XUL School project was developed by <a class="external" href="http://appcoast.com/" title="http://appcoast.com/">Appcoast</a> (formerly Glaxstar). The project is now published here following its <a href="/Project:Copyrights" title="https://developer.mozilla.org/Project:Copyrights">sharing licenses</a>. Its contents have been modified from the original source as necessary.</p> +<div class="noinclude"> + <p>{{ languages( { "ja": "ja/XUL_School", "fr": "fr/Vulgarisation_XUL", "es": "es/Escuela_XUL" } ) }}</p> +</div> +<p> </p> +<div style="position: fixed; display: none; background-color: rgb(51, 204, 255); padding: 7px; color: rgb(0, 0, 0); border-radius: 7px 7px 7px 7px; font-size: 14px; max-width: 400px; font-family: Arial,Helvetica,sans-serif; line-height: 100%; text-align: left; border-style: dashed; border-width: 2px; border-color: rgb(0, 0, 153); opacity: 1; top: 190.317px; left: 64px;"> + Настройка среды разработки</div> +<div style="display: none; position: fixed; width: 450px; padding: 3px; border-width: 0px 0px 2px 2px; border-style: dashed; border-color: grey; border-radius: 0px 0px 0px 5px; background-color: rgb(255, 255, 255); overflow: auto; min-height: 200px; text-align: center; color: rgb(0, 0, 0); right: 0px; top: 0px;"> + <textarea></textarea><select><option value="af">Afrikaans</option><option value="sq">Albanian</option><option value="ar">Arabic</option><option value="hy">Armenian</option><option value="az">Azerbaijani</option><option value="eu">Basque</option><option value="be">Belarusian</option><option value="bg">Bulgarian</option><option value="ca">Catalan</option><option value="zh-CN">Chinese (Simplified)</option><option value="zh-TW">Chinese (Traditional)</option><option value="hr">Croatian</option><option value="cs">Czech</option><option value="da">Danish</option><option selected value="auto">Detect language</option><option value="nl">Dutch</option><option value="en">English</option><option value="et">Estonian</option><option value="tl">Filipino</option><option value="fi">Finnish</option><option value="fr">French</option><option value="gl">Galician</option><option value="ka">Georgian</option><option value="de">German</option><option value="el">Greek</option><option value="ht">Haitian Creole</option><option value="iw">Hebrew</option><option value="hi">Hindi</option><option value="hu">Hungarian</option><option value="is">Icelandic</option><option value="id">Indonesian</option><option value="ga">Irish</option><option value="it">Italian</option><option value="ja">Japanese</option><option value="ko">Korean</option><option value="la">Latin</option><option value="lv">Latvian</option><option value="lt">Lithuanian</option><option value="mk">Macedonian</option><option value="ms">Malay</option><option value="mt">Maltese</option><option value="no">Norwegian</option><option value="fa">Persian</option><option value="pl">Polish</option><option value="pt">Portuguese</option><option value="ro">Romanian</option><option value="ru">Russian</option><option value="sr">Serbian</option><option value="sk">Slovak</option><option value="sl">Slovenian</option><option value="es">Spanish</option><option value="sw">Swahili</option><option value="sv">Swedish</option><option value="th">Thai</option><option value="tr">Turkish</option><option value="uk">Ukrainian</option><option value="ur">Urdu</option><option value="vi">Vietnamese</option><option value="cy">Welsh</option><option value="yi">Yiddish</option></select><span style="font-weight: bold; cursor: pointer; color: lightgrey;">⇄</span><select><option value="af">Afrikaans</option><option value="sq">Albanian</option><option value="ar">Arabic</option><option value="hy">Armenian</option><option value="az">Azerbaijani</option><option value="eu">Basque</option><option value="be">Belarusian</option><option value="bg">Bulgarian</option><option value="ca">Catalan</option><option value="zh-CN">Chinese (Simplified)</option><option value="zh-TW">Chinese (Traditional)</option><option value="hr">Croatian</option><option value="cs">Czech</option><option value="da">Danish</option><option value="nl">Dutch</option><option value="en">English</option><option value="et">Estonian</option><option value="tl">Filipino</option><option value="fi">Finnish</option><option value="fr">French</option><option value="gl">Galician</option><option value="ka">Georgian</option><option value="de">German</option><option value="el">Greek</option><option value="ht">Haitian Creole</option><option value="iw">Hebrew</option><option value="hi">Hindi</option><option value="hu">Hungarian</option><option value="is">Icelandic</option><option value="id">Indonesian</option><option value="ga">Irish</option><option value="it">Italian</option><option value="ja">Japanese</option><option value="ko">Korean</option><option value="la">Latin</option><option value="lv">Latvian</option><option value="lt">Lithuanian</option><option value="mk">Macedonian</option><option value="ms">Malay</option><option value="mt">Maltese</option><option value="no">Norwegian</option><option value="fa">Persian</option><option value="pl">Polish</option><option value="pt">Portuguese</option><option value="ro">Romanian</option><option selected value="ru">Russian</option><option value="sr">Serbian</option><option value="sk">Slovak</option><option value="sl">Slovenian</option><option value="es">Spanish</option><option value="sw">Swahili</option><option value="sv">Swedish</option><option value="th">Thai</option><option value="tr">Turkish</option><option value="uk">Ukrainian</option><option value="ur">Urdu</option><option value="vi">Vietnamese</option><option value="cy">Welsh</option><option value="yi">Yiddish</option></select> + <div style="text-align: left; background-color: rgb(235, 239, 249);"> + Detect language » Russian</div> + <div style="width: 444px; max-width: 444px; padding: 2px; min-height: 80px; border-width: 1px; border-style: solid; border-color: grey; background-color: rgb(255, 255, 255); text-align: justify;"> + </div> +</div> diff --git a/files/ru/xul_school/introduction/index.html b/files/ru/xul_school/introduction/index.html new file mode 100644 index 0000000000..0057c15f7d --- /dev/null +++ b/files/ru/xul_school/introduction/index.html @@ -0,0 +1,33 @@ +--- +title: Введение +slug: XUL_School/Introduction +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/Introduction +--- +<p>{{ Next("XUL_School/Getting_Started_with_Firefox_Extensions") }}</p> +<p>Добро пожаловать в Школьный Учебник по XUL!</p> +<p>Этот учебник предназначен стать трамплином, который в мгновение ока вознесёт вас до уровня профессионального разработчика расширений Firefox. Мы вложили в него годы опыта работы с XUL, предоставив множество решений проблем, с которыми обычно сталкиваются разработчики расширений.</p> +<p>Школа XUL была создана <a class="external" href="http://appcoast.com/" title="http://appcoast.com/">Appcoast</a> (прежде Glaxstar) - одной из немногих компаний, предназначенных для разработки высококачественных расширений к Firefox-у. В то время, когда был создан этот учебник, Glaxstar собрала команду из более, чем дюжины разработчиков XUL, и здесь отражён их общий многолетний опыт создания расширений для Firefox.</p> +<p>В этом учебнике вы узнаете как разрабатывать расширения к Firefox. Вы научитесь быстро выполнять наиболее распространённые задачи в разработке расширений, сравнивая несколько разных подходов к их решению. В большинстве случаев мы предоставим образцы кода, (которые вы сможете просто скопировать и приспособить под свои нужды), а также некоторые работающие примеры расширений. Учебник предназначен быть как можно более кратким, часто ссылаясь к документации Mozilla на более подробную информацию. Вы можете думать об этом как о кратком путеводителе по огромному миру платформы Mozilla. Большинство ссылок в этой документации даны для того, чтобы по ним щёлкнули и прочитали.</p> +<p>Мы начнём с краткого введения в некоторые ключевые понятия, на случай, если вы не знакомы с Mozilla и Firefox.</p> +<h2 id="Mozilla_и_Firefox">Mozilla и Firefox</h2> +<p>Термин <a class="external" href="http://en.wikipedia.org/wiki/Mozilla" title="http://en.wikipedia.org/wiki/Mozilla">Mozilla</a> используется для обозначения нескольких понятий: проект Mozilla, фонд <a class="external" href="http://en.wikipedia.org/wiki/Mozilla_Foundation" title="http://en.wikipedia.org/wiki/Mozilla_Foundation">Mozilla Foundation</a>, корпорация <a class="external" href="http://en.wikipedia.org/wiki/Mozilla_Corporation" title="http://en.wikipedia.org/wiki/Mozilla_Corporation">Mozilla Corporation</a> старый <a href="http://en.wikipedia.org/wiki/Mozilla_Application_Suite" title="http://en.wikipedia.org/wiki/Mozilla_Application_Suite">браузер Mozilla</a>. Даже Firefox иногда упоминается как "Mozilla". Если вы не знакомы с этими терминами, хорошо, что вы уделили время чтобы узнать немного о Mozilla. Это поможет вам понять культуру вокруг сообщества.</p> +<p>Сообщество Mozilla породило несколько <a href="http://www.mozilla.org/projects/" title="http://www.mozilla.org/projects/">продуктов и проектов</a>, самым известным из которых является веб-браузер Mozilla Firefox. Firefox - один из самых успешных проектов с открытым кодом в истории, сочетающий в себе открытость, соответствие стандартам и изощрённость открытого кода с сосредоточением на пользовательском опыте и мощной программе поддержки, чаще присущим менее открытым компаниям.</p> +<p>Версия Firefox номер 1.0 была выпущена в ноябре 2004 года, версия 2.0 - в октябре 2006 года, а версия 3.0 - в июне 2008 года. Этот учебник был написан после выпуска Firefox 3 и со временем был обновлён. В то время как большая его часть должна работать для создания расширений Firefox 3 (и даже Firefox 2), настоятельно рекомендуется, чтоб вы стремились поддерживать современные версии Firefox, чтобы поощрять пользователей придерживаться всех актуальных исправлений, касающихся безопасности. Выпуск, старее 6 месяцев, скорее всего, уязвим к опубликованным "ошибкам безопасности".</p> +<h2 id="XUL">XUL</h2> +<p>XUL - the XML User interface Language - язык разметки пользовательского интерфейса на основе XML (расширенного языка разметки).</p> +<p><a href="/en/XUL" title="en/XUL">XUL</a> (произносится "зул") - это одна из многих технологий, используемых при создании продуктов и расширений на основе Mozilla. Это только одна часть панорамы разработки, но, учитывая, что это практически исключительно для Mozilla, это, как правило, используется для отождествления всех разработок, связанных с Мозиллой. Вы порой будете встречать такие термины, как "XUL-приложения" и "XUL-расширения", но редко они будут относиться к проектам, построенным исключительно с XUL. Обычно это означает проекты, построенные с использованием технологий Mozilla. Даже этот проект, названный Школой XUL, охватывает ряд других технологий, таких как JavaScript, CSS, XBL и XPCOM.</p> +<h2 id="Gecko_(Геккон)">Gecko (Геккон)</h2> +<p><a href="/en/Gecko" title="/en/Gecko">Движок Gecko</a> - это часть Firefox, используемая для отрисовки его пользовательского интерфейса и веб-страниц. Вы можете определить уровень совместимости веб-стандартов в <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80%D0%BE%D0%B2#.D0.91.D1.80.D0.B0.D1.83.D0.B7.D0.B5.D1.80.D1.8B_.D0.BD.D0.B0_.D0.B4.D0.B2.D0.B8.D0.B6.D0.BA.D0.B5_Gecko" title="http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80%D0%BE%D0%B2#.D0.91.D1.80.D0.B0.D1.83.D0.B7.D0.B5.D1.80.D1.8B_.D0.BD.D0.B0_.D0.B4.D0.B2.D0.B8.D0.B6.D0.BA.D0.B5_Gecko">браузерах на основе Gecko</a>, глядя на их строку <a href="http://ru.wikipedia.org/wiki/User_Agent" title="http://ru.wikipedia.org/wiki/User_Agent">"Агент Пользователя" (User Agent, UA)</a>, которая должна включать версию Gecko. Версии Gecko несколько независимы от версий Firefox, и вы можете увидеть карту версий Firefox и версий Gecko на <a href="/en/Gecko" title="/en/Gecko">странице Gecko</a>. Строка UA для Firefox на момент написания этой статьи (в американском английском, Mac OS X):</p> +<p>Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:<strong>7.0.1</strong>) Gecko/20100101 Firefox/7.0.1</p> +<p>Выделенный фрагмент - это версия Gecko: 7.0.1. Вы можете прочесть и скопировать строку UA, любого окна Firefox, выбрав в главном меню: "Справка" > "Информация о поиске и устранении неисправностей.".</p> +<h2 id="XULRunner_(Пускатель_XUL)">XULRunner (Пускатель XUL)</h2> +<p>Firefox и другие приложения Mozilla, можно рассматривать как состоящие из двух разных частей: слой пользовательского интерфейса, отличающийся в каждом проекте, и общую платформу, поверх которой построен слой интерфейса. Эта платформа известна как <a href="/en/XULRunner" title="/en/XULRunner">"XULRunner"</a>. XULRunner включает в себя отрисовывающий движок Gecko, <a href="/en/Necko" title="/en/Necko">сетевую библиотеку Necko</a> и несколько других компонентов, обеспечивающих независимый от операционной системы: файл управления, "доступность", "локализацию" - среди прочих. Именно эта очень мощная платформа позволила обеспечить такой быстрый рост сообщества разработки вокруг Mozilla и Firefox.</p> +<p>XULRunner доступен и в двоичной форме, на <a href="/en/XULRunner" title="/en/XULRunner">странице XULRunner</a>, и он является основой для нескольких проектов, таких, как Songbird (Певчая птичка), Миро и Eudora. В <a href="/en/XULRunner_Hall_of_Fame" title="/en/XULRunner_Hall_of_Fame">Зале Славы XULRunner</a> довольно обстоятельный список приложений, работающих на XULRunner-е.</p> +<h2 id="К_учебнику">К учебнику</h2> +<p>С основными понятиями на нашем пути разобрались, теперь мы вправе разрабатывать расширения.</p> +<p>Вероятно, вам, всёж-таки интересно, что же именно такое эти расширения, что они могут делать, и как вы можете делать их. Собственно, весь этот учебник и посвящён объяснению этого.</p> +<p>Добро пожаловать в мир разработки расширений!</p> +<p>Пожалуй, начнём.</p> +<p>{{ Next("XUL_School/Getting_Started_with_Firefox_Extensions") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> +<p>{{ languages( { "fr": "fr/Vulgarisation_XUL/Introduction" } ) }}ведение</p> diff --git a/files/ru/xul_school/the_essentials_of_an_extension/index.html b/files/ru/xul_school/the_essentials_of_an_extension/index.html new file mode 100644 index 0000000000..e4dcdba9d5 --- /dev/null +++ b/files/ru/xul_school/the_essentials_of_an_extension/index.html @@ -0,0 +1,456 @@ +--- +title: Устройство расширения +slug: XUL_School/The_Essentials_of_an_Extension +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/The_Essentials_of_an_Extension +--- +<p> </p> + +<div class="blockIndicator warning"> +<p dir="ltr" id="docs-internal-guid-dff3a9fe-7fff-750b-9799-0456f08af0f4">Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.</p> +</div> + +<p> </p> + +<p>{{LegacyAddonsNotice}}{{AddonSidebar}}</p> + +<p>{{ PreviousNext("XUL_School/Getting_Started_with_Firefox_Extensions", "XUL_School/Setting_Up_a_Development_Environment") }}</p> + +<h2 id="Файл_install.rdf">Файл install.rdf</h2> + +<p>В предыдущем разделе мы начали рассматривать содержимое расширения "Hello World". Теперь мы рассмотрим его файлы и код, начиная с файла <em>"install.rdf"</em>. Вы можете его открыть любым текстовым редактором.</p> + +<p>Файл подготовлен с применением специальной разновидности XML, под названием <a href="http://ru.wikipedia.org/wiki/Resource_Description_Framework" title="http://ru.wikipedia.org/wiki/Resource_Description_Framework"><span class="external">RDF</span></a>. RDF использовался как основной механизм хранения для Firefox, но сейчас заменяется упрощённой системой баз данных. Далее в учебнике мы рассмотрим обе эти системы хранения данных.</p> + +<p>Теперь давайте взглянем на важные части этого файла.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><em:id>helloworld@xulschool.com</em:id></pre> +</div> +</div> + +<p>Это уникальный идентификатор расширения. Firefox-у он нужен, чтобы отличать ваши расширения от других расширений, поэтому надо, чтобы у вас был уникальный ID.</p> + +<p>Есть два принятых стандарта для идентификаторов дополнений. Одним из них является формат адреса электронной почты, как в примере "Hello World", в котором должно быть что-то вроде <em><span style="color: #0000ff;"><название-программы>@<ваш-домен></span></em>. Другой обычной практикой является использование порождённой строки <a href="http://ru.wikipedia.org/wiki/UUID" title="http://ru.wikipedia.org/wiki/UUID">UUID</a>, повторение которой крайне маловероятно. В Unix-системах, в командной строке есть инструмент под названием <em>uuidgen</em>, порождающий новые UUID-строки. Для всех других платформ также есть такие загружаемые инструменты, порождающие UUID. Окружающие скобки - это просто обозначение и это обычная практика. Пока ваш идентификатор сколь-нибудь уникален, то можно выбрать любую форму.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><em:name>XUL School Hello World</em:name> +<em:description>Welcome to XUL School!</em:description> +<em:version>0.1</em:version> +<em:creator>Appcoast</em:creator> +<span class="code-comment"><em:homepageURL>https://developer.Mozilla.org/en/XUL_School</em:homepageURL></span></pre> +</div> +</div> + +<p>Это данные, отображаемые до и после установки расширения и которые можно увидеть в панели управления дополнениями. Помощники и переводчики могут добавить много других тегов. Все подробности смотрите в <a href="/en/Install_Manifests" title="/en/Install_Manifests">полной спецификации</a> файла <strong>install.rdf</strong>.</p> + +<p>Так как расширения могут быть переведены на несколько языков, часто необходимо перевести описание расширения или, даже, его название. Локализованные описание и название могут быть вписаны с помощью следующего кода:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><em:localized> + <Description> + <em:locale>ru-RU</em:locale> + <em:name>Школа XUL Привет мир</em:name> + <em:description>Добро пожаловать в школу XUL!</em:description> + </Description> +</em:localized></pre> +</div> +</div> + +<p>Строчка локали <em>ru-RU</em> указывает, что это русская (ru) локализация для России (RU). Вы можете добавить столько разделов <<em>em:localized</em>>, сколько вам нужно. Для Firefox 2, локализация этого файла <a href="/en/Localizing_extension_descriptions#Localizing_before_Gecko_1.9" title="/en/Localizing_extension_descriptions#Localizing_before_Gecko_1.9">немного сложнее</a>. Мы позже в этом разделе ещё обсудим локализацию.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><em:type>2</em:type></pre> +</div> +</div> + +<p>Это указывает, что устанавливаемое добавление является расширением. Вы можете прочитать о различных возможных типах в <a href="https://developer.Mozilla.org/en/Install_Manifests#type" title="https://developer.Mozilla.org/en/Install_Manifests#type">соответствующем разделе спецификации файла install.rdf</a>.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><em:targetApplication> + <Description> + <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> + <em:minVersion>4.0</em:minVersion> + <em:maxVersion>10.*</em:maxVersion> + </Description> +</em:targetApplication> +</pre> +</div> +</div> + +<p>Этот узел определяет целевое приложение и его целевые версии. В частности здесь указан интернет-обозреватель Firefox, начиная с 4-й и до 10-ых версий. Указанный UUID является уникальным идентификатором Firefox. Другие Mozilla и основанные на Mozilla приложения, такие как Thunderbird и Seamonkey имеют свои собственные UUID. У вас может быть расширение, работающее в нескольких приложениях и версиях. Например, если вы создаёте расширение к Firefox, то, как правило, достаточно минимума усилий, чтобы перенести его в SeaMonkey, имеющее сходные характеристики и пользовательский интерфейс.</p> + +<p>Минимум и максимум определяют диапазон версий, дозволительный для установки расширения. Вот ещё <a href="/en/Toolkit_version_format" title="/en/Toolkit_version_format">ссылка о формате указания версий</a>. Если приложение или диапазон версий не совпадают, то пользователю не будет разрешено установить расширение или расширение будет установлено в отключённом состоянии. Пользователи могут отключить проверку версий в настройках интернет-обозревателя или путём установки дополнений через <a href="https://addons.Mozilla.org/en-US/Firefox/addon/15003" title="https://addons.Mozilla.org/en-US/Firefox/addon/15003">Докладчик о совместимости дополнений (Add-on Compatibility Reporter)</a>. Начиная с Firefox 11, дополнения по умолчанию будут совместимы, и Firefox в основном будет игнорировать диапазон версий. Всё-же рекомендуется всегда проверять дополнения с каждой новой версией Firefox.</p> + +<p>Это информация, нужная Firefox и другим приложениям Mozilla для установки дополнения. Любые ошибки или отсутствие информации приведут к сбою процесса установки или установке расширения в выключённом состоянии.</p> + +<h2 id="Файл_chrome.manifest">Файл chrome.manifest</h2> + +<blockquote> +<p><span style="color: #0000ff;">Хром (Chrome) - это набор элементов пользовательского интерфейса окна приложения, находящихся за пределами области содержимого окна.</span> Панели инструментов, строки меню, индикаторы прогресса выполнения и заголовки окон - всё это примеры элементов, обычно являющихся частью Хрома.</p> +</blockquote> + +<p>Взято из <a href="/en/Chrome_Registration" title="en/Chrome Registration">Регистрации Хрома</a>.</p> + +<p>В двух словах, хром - это всё, что вы видите в Firefox. Все окна Firefox можно рассматривать как состоящие из двух частей: (1) хром, (2) область возможного содержимого (то, что показывают веб-страницы во вкладках Firefox). Такие окна как "окно загрузок" - это чистый Хром. Большая часть кода расширения находится в папке "хром", как и в примере "Hello World".</p> + +<p>Как мы видели в структуре каталогов распакованного расширения, Хром состоит из 3 разделов: <span style="color: #0000ff;">content (содержание)</span>, <span style="color: #0000ff;">locale (локаль, язык)</span> и <span style="color: #0000ff;">skin (тема)</span>. Эта троица необходима для большинства расширений. Если мы откроем файл <em>chrome.manifest</em> (опять же, сгодится любой текстовый редактор), то увидим, что указаны эти 3 секции:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">content xulschoolhello content/ +skin xulschoolhello classic/1.0 skin/ +locale xulschoolhello en-US locale/en-US/ +</pre> +</div> +</div> + +<p><span style="color: #0000ff;">Файл <em>chrome.manifest</em> говорит Firefox, где искать файлы Хрома.</span> Текст расположен вразрядку, чтобы выглядел как таблица, но это не обязательно. Синтаксический анализатор (парсер, parser) игнорирует повторение пробелов.</p> + +<p>Первое слово в строке говорит Firefox, что именно объявляется (содержание, скин, локаль языка или другое, о чём будет рассказано позже). Второе - это название пакета, о котором мы скоро расскажем.</p> + +<p>У скина и языков есть третье значение для указания, какой именно язык или какой именно скин они расширяют. Может быть несколько скинов и языков, касающихся различных других скинов и языков. Обычно указывают одну запись для глобального скина (<em>classic/1.0</em>) и несколько записей для языковых пакетов, по одному для каждого перевода. Наконец, последним указано расположение в файловой системе.</p> + +<p>В файл <em>chrome.manifest</em> могут быть внесены некоторые дополнительные параметры. Они описаны на <a href="/en/Chrome_Registration" title="/en/Chrome_Registration">странице Регистрации Chrome</a>. Примечательно, мы может включить записи, особенные для операционных систем. Это важно, потому что внешний вид браузера отличается в разных операционных системах., Если наше расширение должно выглядеть по-разному в разных ОС, то мы можем изменить файл манифеста, например, таким образом:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">content xulschoolhello content/ +skin xulschoolhello classic/1.0 skin/unix/ +skin xulschoolhello classic/1.0 skin/mac/ os=Darwin +skin xulschoolhello classic/1.0 skin/win/ os=WinNT +locale xulschoolhello en-US locale/en-US/ +</pre> +</div> +</div> + +<p>Так, мы можем задать отдельные темы оформления для Windows, Mac OS X, и Linux (а также других Unix-систем), каждая из которых определена в отдельный каталог. Так как большинство других систем на основе Unix, то тема "Unix" указывается по умолчанию, без флагов.</p> + +<h2 id="Хром">Хром</h2> + +<p>Как сказано выше, Хром состоит из 3 разделов: содержание (контент), язык (локаль) и тема (скин). <em>Содержание </em>- это важнейший раздел, содержащий в себе пользовательский интерфейс (XUL) и скрипты (JS - JavaScript). Раздел <em>Скин </em>содержит файлы, определяющие большую часть внешнего вида пользовательского интерфейса (с помощью CSS и изображений, как у веб-страниц). Раздел <em>Язык</em> содержит все тексты, используемые в расширении, в DTD и в файлах свойств. Такое разделение позволяет другим разработчикам создавать темы, заменяющие скины, а переводчикам - создавать локализации на разных языках. И всё это - без необходимости изменения кода вашего расширения. Это даёт расширениям Firefox хорошую гибкость.</p> + +<p>Файлы Хрома доступны через <code>chrome</code>-протокол. Пример того, как выглядят URI Хрома:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">chrome:<span class="code-comment">//packagename/section/path/to/file</span></pre> +</div> +</div> + +<p>Так, например, если бы надо было получить доступ к файлу <em><strong>browserOverlay.xul</strong></em> в расширении, Хром-URI был бы:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">c<span class="external">hrome://xulschoolhello/content/browserOverlay.xul</span></pre> +</div> +</div> + +<p>Если у вас слишком много файлов в Содержании, и вы хотите организовать их в подкаталогах, не нужно ничего менять в <strong><em>chrome.manifest</em></strong>, а нужно, лишь добавить в URI правильный путь после <em><strong>content</strong></em>.</p> + +<p>Адресация к файлам Скина и Языка работает точно также, и вам не нужно указывать названий Скина или Языка. Так что, для получения доступа к файлу DTD в расширении "Привет мир", <code>chrome</code>-путь выглядит так: <code><em>chrome://xulschoolhello/locale/browserOverlay.dtd</em>. </code>Firefox сам знает какой язык нужно искать.</p> + +<p>Вот интересный эксперимент. Откройте новую вкладку Firefox, вбейте в адресной строке: <em><code>chrome://mozapps/content/downloads/downloads.xul</code></em> и нажмите клавишу Enter. Удивлены? Вы только что открыли окно загрузок во вкладке Firefox! Вы можете получить доступ к любому файлу Хрома, просто введя его URI в адресной строке. Это может пригодиться, если вы захотите проверить файлы скриптов, являющихся частью Firefox, в своих или других расширениях. Большинство этих файлов открываются как текстовые, за исключением файлов XUL, которые выполняются и отображаются точно так как вы обычно видите их в окне.</p> + +<h3 id="Content_(Содержание)">Content (Содержание)</h3> + +<p>В каталоге "content" есть 2 файла. Давайте сначала посмотрим на файл XUL.</p> + +<p><a href="/en/XUL" title="/en/XUL">XUL</a> файлы - это XML-файлы, определяющие элементы пользовательского интерфейса в Firefox и его расширениях. Создание XUL был вдохновлено языком HTML, так что вы увидите много общего между ними. Однако, XUL по сравнению с HTML улучшен - в нём исправлены ошибки, допущенные в ходе эволюции HTML. XUL позволяет создавать интерфейсы намного богаче и интерактивнее, чем те, что можно создать с помощью HTML. Или, по крайней мере, XUL облегчает работу.</p> + +<p>Файлы XUL обычно определяют одно из двух: окна или наложения (оверлейные программы, накладки, слои). В файле <strong><em>downloads.xul</em></strong>, который вы до этого открывали, был код, определявший окно загрузок (Downloads). Файл XUL включён в расширение Hello World в качестве наложения. Наложение расширяет существующие окна, заменяя некоторые их элементы или добавляя новые. Строка, которую мы пропустили в файле <strong><em>chrome.manifest</em></strong> говорится, что этот файл XUL - наложение к главному окну интернет-обозревателя:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">overlay chrome:<span class="code-comment">//browser/content/browser.xul chrome://xulschoolhello/content/browserOverlay.xul</span></pre> +</div> +</div> + +<p>С помощью этой строки, Firefox, узнаёт, что ему надо взять содержание <strong><em>browserOverlay.xul</em></strong> и наложить его на главное окно браузера - <strong><em>browser.xul</em></strong>. Вы можете объявлять наложения для любого окна или диалогового окна в Firefox, но наложение на основное окно браузера - самый распространённый случай на сегодняшний день.</p> + +<p>Теперь давайте посмотрим на содержимое нашего файла XUL. Мы пропустим первые несколько строк, потому что они связаны с Темой и Языком, и мы их рассмотрим позже.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><overlay id="xulschoolhello-browser-overlay" + xmlns="http://www.Mozilla.org/keymaster/gatekeeper/there.is.only.xul"></pre> +</div> +</div> + +<p>Ключевой элемент в файле - наложение (оверлей) - <em>overlay</em>. Другие документы XUL используют тег <em>window</em> (окно) или <em>dialog</em> (диалог). У этого элемента есть уникальный идентификатор (id), который вы должны иметь в большинстве элементов в вашем XUL. Второй атрибут - это пространство имён, которое является тем, что вы всегда должны определять в корневом элементе своего XUL. Он говорит, что этот узел и все дочерние узлы являются XUL. Когда вы в одном документе смешиваете разные типы содержания, такие как XUL с HTML или SVG, вам надо только изменить объявления пространства имён.</p> + +<div class="panel" style="border-width: 1px;"> +<div class="panelContent"> +<div class="note">Вы могли заметить, что мы используем именование в нескольких местах, таких как идентификатор <strong><em>xulschoolhello-browser-overlay</em></strong>. Это стандартные пространства имён, которые мы используем, чтобы избежать конфликтов с Firefox и другими расширениями, а также упростить некоторые задачи разработки. Мы задаём пространство имён для всех идентификаторов и классов стилей в элементах этого наложения, потому что они будут смешаны с другими элементами в главном окне интернет-обозревателя. Если бы мы использовали общие идентификаторы, как <strong>container</strong> (<em>"контейнер"</em>) или <strong>input</strong> (<em>"ввод"</em>), то они, скорее всего, конфликтовали бы с идентификаторами использующимися в Firefox, или идентификаторами из других наложений расширений. Использование пространства имён позволяет минимизировать проблемы совместимости с другими расширениями. Мы используем <a href="http://ru.wikipedia.org/wiki/CamelCase" title="http://ru.wikipedia.org/wiki/CamelCase">ВерблюжийРегистр (CamelCase)</a> для имён файлов, и пишем всё в нижнем регистре с тире для элементов идентификаторов и для имён класса стиля CSS, но вы можете использовать свою собственную систему.</div> +</div> +</div> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><script type=<span class="code-quote">"application/x-javascript"</span> + src=<span class="code-quote">"chrome:<span class="code-comment">//xulschoolhello/content/browserOverlay.js"</span> /></span></pre> +</div> +</div> + +<p>Как и в HTML, он включает в себя файл сценария на языке JavaScript. Вы можете вставить столько элементов <strong><em>script</em></strong> (сценарий) в документ XUL, сколько вам нужно. Мы позже рассмотрим его код.</p> + +<div class="panel" style="border-width: 1px;"> +<div class="panelContent"> +<div class="note">Возможно вы заметили как сформатирован наш код, и удивились правилам, которым мы следуем. Наше главное правило - длина строки не более 80 символов. Это кажется чрезмерно строгим, особенно с XML-файлами, но это число было выбрано, чтобы позволить почти любому текстовому редактору легко обрабатывать эти файлы. Даже старые редакторы для командной строки работают с файлами, в которых строки сокращены до 80 символов. Табуляция проста: 2 пробельных отступа. Мы никогда не используем настоящие символы табуляции, за исключением файлов <strong><em>Makefile</em></strong>, которые будут рассмотрены позже. Большинство наших стандартов кодирования основаны на стандартах Mozilla или других известных и используемых стандартах.</div> +</div> +</div> + +<p>Мы пропустим код, который рассматривается в разделе Языка (локали), перейдя к наиболее важной части содержания:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><menubar id="main-menubar"> + <menu id="xulschoolhello-hello-menu" label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloMenu.accesskey;" insertafter="helpMenu"> + <menupopup> + <menuitem id="xulschoolhello-hello-menu-item" + label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloItem.accesskey;" + oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" /> + </menupopup> + </menu> +</menubar> + +<vbox id="appmenuSecondaryPane"> + <menu id="xulschoolhello-hello-menu-2" label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloMenu.accesskey;" + insertafter="appmenu_addons"> + <menupopup> + <menuitem id="xulschoolhello-hello-menu-item-2" + label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloItem.accesskey;" + oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" /> + </menupopup> + </menu> +</vbox> +</pre> +</div> +</div> + +<p>Это код, добавляющий меню "Привет, Мир!" в окно интернет-обозревателя. Тут два почти одинаковых блока кода из-за того, как Firefox сейчас обрабатывает меню. Раньше было так, что на всех платформах была панель с обширным меню. Это изменилось в последней версии Firefox, в частности, в Windows, где видна одна кнопка Firefox, с единым и упрощённым меню опций. Нажатие на кнопку ALT в Windows переключает между кнопкой меню и классическим меню. Второй блок кода применяется в случае, кнопки меню, а первый блок кода охватывает все остальные случаи. Так как кнопка меню теперь наиболее распространена, мы сосредоточимся на ней.</p> + +<p>Для того, чтобы написать этот код, нам нужны некоторые знания кода XUL в файле <strong><em>browser.xul</em></strong>. Нам нужно знать, что идентификатор (id) правой панели в едином меню - это <strong><em>appmenuSecondaryPane</em></strong>. Мы добавляем собственное меню, и говорим Firefox, добавить его в ту панель, сразу после пункта "Add-ons" ("Дополнения"). Пример:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">insertafter=<span class="code-quote">"appmenu_addons"</span> +</pre> +</div> +</div> + +<p><strong><em>appmenu_addons</em></strong> - это идентификатор (id) элемента меню, который соответствует пункту "Дополнения" ("Add-ons") в главном меню. Позже мы увидим, как можно узнать такие штуки, типа идентификаторов элементов браузера, но сейчас давайте посмотрим на те элементы, которые составляют меню "Hello World".</p> + +<p>Для классического меню мы добавили меню "Привет мир" прямо в "корень" этого меню, так, чтоб вам было легче его заметить, но так поступать не рекомендуется. Представьте себе, что все расширения станут добавлять пункты меню в главное меню; тогда при установке нескольких расширений этот подход сделает его похожим на приборную панель самолёта, полную ручек и переключателей. В случае единого меню, всё немного сложнее в связи с отсутствием вариантов., Если пункт меню помещается в раздел "Web Developer" ("Веб-разработчик"), то рекомендуется добавить его туда. В противном случае, "Главное меню" может быть единственным выходом.</p> + +<p>Одно рекомендуемое место для пунктов меню в классической нише меню - под меню "Инструменты" ("Tools"), так что на самом деле код должен выглядеть так:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><menupopup id=<span class="code-quote">"menu_ToolsPopup"</span>> + <menu id=<span class="code-quote">"xulschoolhello-hello-menu"</span> label=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.hello.label;"</span> + accesskey=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.helloMenu.accesskey;"</span> + insertbefore=<span class="code-quote">"</span>devToolsEndSeparator<span class="code-quote">"</span>> + <menupopup> + <menuitem id=<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">-hello-menu-item" + </span> label=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.hello.label;"</span> + accesskey=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.helloItem.accesskey;"</span> + oncommand=<span class="code-quote">"XULSchoolChrome.BrowserOverlay.sayHello(event);"</span> /> + </menupopup> + </menu> +</menupopup> +</pre> +</div> +</div> + +<p>Мы накладываем меню, которое глубже в дереве XUL, но это не важно, потому что всё, что нам нужно - это идентификатор (id) элемента, на который мы хотим наложить свой код. В данном случае это элемент <strong><a href="/en/XUL/menupopup" title="/en/XUL/menupopup">menupopup</a></strong>, находящийся внутри элемента "Инструменты" (<strong>"Tools"</strong>) в <a href="/en/XUL/menu" title="/en/XUL/menu">menu</a> ("меню"). Атрибут <strong><em>"InsertBefore"</em></strong> диктует Firefox добавить меню в нижнюю часть раздела инструментов разработчика, над его конечным разделителем. Далее в учебнике мы поговорим о меню подробнее.</p> + +<p>Теперь давайте посмотрим на действительный код:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">oncommand=<span class="code-quote">"XULSchoolChrome.BrowserOverlay.sayHello(event);"</span> +</pre> +</div> +</div> + +<p>Этот атрибут определяет обработчик события. Команда <strong><em>"event"</em></strong> (<em>"событие"</em>) - наиболее часто используется в Firefox, так как она соответствует главному действию для большинства элементов пользовательского интерфейса. значение этого атрибута - код на JavaScript, вызывающий функцию. Эта функция определена в JS-файле, включенном ранее тегом <strong><em>"script"</em></strong>. JS-функция будет вызвана, когда пользователь нажмёт на пункт меню <strong><em>"Привет Мир"</em></strong> (<em>"Hello World"</em>). Все обработчики событий, назначают специальный объект под названием <strong><em>"event"</em></strong> (<em>"событие"</em>), который обычно передаётся в качестве аргумента функции. Более подробно обработчики событий описаны ниже.</p> + +<p>Теперь давайте взглянем на файл JavaScript и посмотрим, что происходит, когда срабатывает событие.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="brush: js">/** + * XULSchoolChrome namespace. + */ +if ("undefined" == typeof(XULSchoolChrome)) { + var XULSchoolChrome = {}; +};</pre> +</div> +</div> + +<p>Определяется пространство имён <strong><em>"XULSchoolChrome"</em></strong>. Все объекты и переменные, которые мы определяем в этом JavaScript носят всеобъемлющий характер, это означает, что скрипты в Firefox и других расширениях могут увидеть их и взаимодействовать с ними. Это также значит, что, если мы определим объект под названием <strong><em>"MenuHandler"</em></strong> (<em>"ОбработчикСобытияМеню"</em>) или с иным типичным названием, то он, скорее всего, будет конфликтовать с существующим объектом. Так что, нам остаётся здесь сделать - это определить единый всеобъемлющий объект: <strong><em>"XULSchoolChrome"</em></strong>. Теперь мы знаем, что все наши объекты находятся внутри этого объекта, который вряд ли будет продублирован или переписан другими расширениями.</p> + +<p>Вы можете прочитать больше об <a href="/en/JavaScript/Reference/Operators/typeof" title="/en/JavaScript/Reference/Operators/typeof">операторе "typeof"</a>. Если вы не знакомы с JavaScript или с этим синтаксисом, то вам будет интересно узнать, что инициализация объекта сочетанием фигурных скобок <strong><em>"{}"</em></strong> эквивалентна его инициализации строкой <strong><em>"new Object()"</em></strong>.</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="brush: js">/** + * Controls the browser overlay <span class="code-keyword">for</span> the Hello World extension. + */ +XULSchoolChrome.BrowserOverlay = {</pre> +</div> +</div> + +<p>Наконец, <strong><em>BrowserOverlay</em></strong> - это наш объект. Именование и обращение к объектам таким длинным и подробным образом могут показаться поначалу некомфортными, но это оправдано.</p> + +<div class="panel" style="border-width: 1px;"> +<div class="panelContent"> +<div class="note">Мы используем стиль описания <a href="http://java.sun.com/j2se/javadoc/writingdoccomments/index.html" title="http://java.sun.com/j2se/javadoc/writingdoccomments/index.html">Javadoc</a> во всех пространствах имён, объектах, а также членах объекта. Это такой же стандарт, как используется в коде Mozilla и некоторых инструментах, могущих автоматически порождать документацию из Javadoc.</div> +</div> +</div> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="brush: js">sayHello : function(aEvent) { + let stringBundle = document.getElementById("xulschoolhello-string-bundle"); + let message = stringBundle.getString("xulschoolhello.greeting.label"); + + window.alert(message); +}</pre> +</div> +</div> + +<p>Объявление нашей функции. Три строки кода - это всё, что нужно для её работы. Первая строка в теле функции объявляет переменную <strong><em>"stringBundle"</em></strong>, которая будет содержать элемент <strong><a href="/en/XUL/stringbundle" title="/en/XUL/stringbundle">stringbundle</a></strong>, определённый в наложении. Переменная объявляется с помощью оператора <strong><em>"let"</em></strong> ("пусть"), похожего на <strong><em>var</em></strong>, но с более ограниченной областью. <a href="/en/JavaScript/Reference/Statements/let" title="/en/JavaScript/Reference/Statements/let">здесь</a> вы можете подробнее прочитать об <strong>объявлении let</strong>.</p> + +<p>Для управления документом XUL, как и в обычном JS, мы можем использовать <a href="/en/DOM" title="/en/DOM"><strong>DOM</strong> <em>(Document Object Model)</em></a>. Сначала мы получаем ссылку на <strong><em><a href="/en/XUL/stringbundle" title="/en/XUL/stringbundle">элемент stringbundle</a></em></strong> в документе. Это специальный элемент, позволяющий динамически получать переведённые на нужный язык (локализованные) строки по предоставлении ему лишь "ключа", идентифицирующего текст. Это как-раз то, что мы делаем во второй строке кода. Мы вызываем <strong><em><a href="/en/XUL/stringbundle#m-getString" title="/en/XUL/stringbundle#m-getString">метод getString</a></em></strong> элемента связки и получаем переведённое на нужный язык сообщение для показа. Затем мы вызываем функцию <a href="/en/DOM/window.alert" title="/en/DOM/window.alert"><strong><em>"window.alert"</em></strong></a> с сообщением - так же, как мы могли бы это сделать в HTML-документе.</p> + +<h3 id="Локаль">Локаль</h3> + +<p>Есть два типа файлов перевода интерфейса (далее - локализации, на правах устоявшегося термина) на нужные языки: DTD и свойства. В этом примере мы используем оба типа. DTD - наиболее эффективный способ показа текста в XUL, поэтому вы должны по возможности использовать именно его. Он весьма негибкий и поэтому он не может быть использован для динамически создаваемого текста, поэтому нужен альтернативный способ получения локализованных строк.</p> + +<p>Оглядываясь на код меню, вы, вероятно, заметили, некоторые атрибуты, вроде этих:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">label=<span class="code-quote">"&xulschoolhello.hello.label;"</span> accesskey=<span class="code-quote">"&xulschoolhello.helloItem.accesskey;"</span></pre> +</div> +</div> + +<p>Эти атрибуты определяют текст, который вы видите в меню, и они являются строковыми ключами, определёнными в нашем DTD файле <strong><em>"browserOverlay.dtd"</em></strong>. Файл DTD был вовлечён в файле XUL таким кодом:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><!DOCTYPE overlay SYSTEM "chrome://xulschoolhello/locale/browserOverlay.dtd" ></pre> +</div> +</div> + +<p>И в файле DTD можно увидеть связь между ключами и локализованными строками:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><!ENTITY xulschoolhello.hello.label <span class="code-quote">"Hello World!"</span>> +<!ENTITY xulschoolhello.helloMenu.accesskey <span class="code-quote">"l"</span>> +<!ENTITY xulschoolhello.helloItem.accesskey <span class="code-quote">"H"</span>></pre> +</div> +</div> + +<p>Обратите внимание, что в файле XUL вы накладываете строковый ключ между амперсандом "<span style="color: #0000ff;"><strong>&</strong></span>" и точкой с запятой "<span style="color: #0000ff;"><strong>;</strong></span>", в то время как в файле DTD вы только указываете ключ. Вы можете получить непредсказуемые ошибки синтаксического разбора (парсинга) или неправильную локализацию, если не укажете это правильно.</p> + +<p>Клавиши быстрого доступа (также известны как "горячие клавиши". прим. пер.) - это ссылки, позволяющие вам быстро перемещаться по меню, используя только клавиатуру. Они также являются единственным способом навигации по меню для людей с ограниченными возможностями, такими, как частичная или полная слепота, или физическими недостатками, с которыми трудно или невозможно пользоваться мышью. Вы можете легко узнать горячую клавишу быстрого доступа в Windows, так как буква, соответствующая горячей клавише указывается, как на рисунке ниже (буква подчеркнута):</p> + +<div> +<p><img alt="" class="internal" src="https://developer.mozilla.org/@api/deki/files/4226/=accesskeys.png" style="height: 58px; width: 167px;"></p> +</div> + +<p>У большинства средств управления пользовательским интерфейсом есть атрибут <strong><em>"accesskey"</em></strong> ("клавиша быстрого доступа"), и его надо использовать. Значение клавиши доступа локализовано - привязано к языковому набору, потому что оно должно соответствовать букве в тексте названия пункта меню. Вам надо также делать всё возможное, чтобы избежать повторения горячей клавиши. Например, они не должны повторяться в пределах меню или подменю. В окне нужно особенно осторожно выбирать клавиши доступа, потому что там обычно ещё больше других средств управления. И особенно внимательно выбирайте клавиши доступа для наложения (Overlay). В нашем случае (в английской версии - прим. пер.) мы не можем использовать английскую букву "H" в качестве горячей клавиши в главном пункте меню, потому что это было бы то же самое как клавиша доступа в Меню "Help" ("помощь"). То же самое с буквой "W" и меню "Window" ("Окно") в Операционной системе "Mac OS". Так что мы остановились на букве "l".</p> + +<p>Значения для строк DTD проставляются тогда, когда документ загружается. Если вы запросите значение атрибута <strong><em>"label"</em></strong> у меню "Привет мир!", используя DOM, то вы получите локализованную строку, а не строку ключа. Вы не можете динамически изменять значение атрибута с новым DTD ключом, но можете установить новое значение:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="brush: js">let helloItem = document.getElementById(<span class="code-quote">"xulschoolhello-hello-menu-item"</span>); + +<span class="code-comment">// The alert will say <span class="code-quote">"Hello World!"</span> +</span>alert(helloItem.getAttribute(<span class="code-quote">"label"</span>)); +<span class="code-comment">// Wrong +</span>helloItem.setAttribute(<span class="code-quote">"label"</span>, <span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.hello2.label;"</span>); +<span class="code-comment">// Better +</span>helloItem.setAttribute(<span class="code-quote">"label"</span>, <span class="code-quote">"Alternate message"</span>); +<span class="code-comment">// Right! +</span>helloItem.setAttribute(<span class="code-quote">"label"</span>, someStringBundle.getString(<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.hello2.label"</span>));</pre> +</div> +</div> + +<p>По этой причине строки DTD - не универсальное решение на все случаи локализации, и по этой причине часто нам нужно включать связки строк в файлы XUL:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><stringbundleset id="stringbundleset"> + <stringbundle id="xulschoolhello-string-bundle" + src="chrome://xulschoolhello/locale/browserOverlay.properties" /> +</stringbundleset></pre> +</div> +</div> + +<p>Элемент <strong><em><a href="/en/XUL/stringbundleset" title="/en/XUL/stringbundleset">"stringbundleset"</a></em></strong> (<em>"строкСвязкаНабор"</em>) - это просто вместилище для элементов <strong><em><a href="/en/XUL/stringbundle" title="/en/XUL/stringbundle">"stringbundle"</a></em></strong> (строкСвязка). В документе должна быть только одна причина, по которой мы накладываем <strong><em>"stringbundleset"</em></strong>, находящийся в <strong><em>"browser.xul"</em></strong>, отсюда очень общий идентификатор (<strong><em>"id"</em></strong>). Мы не включили атрибуты <strong><em>"insertbefore"</em></strong> ("вставитьПеред") или <strong><em>"insertafter"</em></strong> ("вставитьПосле"), потому что порядок следования связок строк не имеет значения. Элемент абсолютно невидим. Если вы не включите ни одного из атрибутов, задающих очерёдность в элементе накладки, то Firefox просто приложит ваш элемент в качестве последнего потомка родительского элемента.</p> + +<p>Всё, что нужно для "связки строк" (string bundle) - это идентификатор (чтобы иметь возможность получить элемент позже) и <code>chrome</code>-путь к файлу свойств. И, конечно, нужен сам файл свойств:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">xulshoolhello.greeting.label = Hi! How are you?</pre> +</div> +</div> + +<p>Пробелы около знака равенства игнорируются. Так же, как в <strong><em>install.rdf</em></strong>, комментарии могут быть добавлены с помощью символа "<span style="color: #0000ff;"><strong>#</strong></span>" в начале строки с комментарием. Пустые строки тоже игнорируются.</p> + +<p>Вам пригодится уметь включать динамическое содержание как часть локализованных (переведённых на язык пользователя) строк. например, когда вы захотите информировать пользователя о некотором состоянии, связанном с расширением. Например: "Найдено 5 слов по поисковому запросу". Первой мыслью, вероятно, будет просто объединять строки, и держать отдельно свойство "Найдено" и отдельно свойство "слов по ...". Это плохая идея. Это значительно усложняет работу переводчиков ("локализаторов"), кроме того, в разных языках правила грамматики могут полностью менять порядок слов в предложении. Поэтому в свойствах лучше использовать параметры:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">xulshoolhello.search.label = Found %S words matching the search query!</pre> +</div> +</div> + +<p>Затем используйте <strong><em><a href="/en/XUL/stringbundle#m-getFormattedString" title="/en/XUL/stringbundle#m-getFormattedString">"getFormattedString"</a></em></strong> вместо <span id="cke_bm_225S" style="display: none;"> </span><strong><em>"getString"</em></strong><span id="cke_bm_225E" style="display: none;"> </span>, чтобы получить локализованную строку. Благодаря этому нам не нужно держать несколько свойств, и это облегчает жизнь переводчикам. Вы можете прочитать больше об этом в <strong><em><a href="/en/XUL_Tutorial/Property_Files#Text_Formatting" title="/en/XUL_Tutorial/Property_Files#Text_Formatting">разделе "Форматирование текста"</a></em></strong><span id="cke_bm_226E" style="display: none;"> </span> в Учебнике XUL ("XUL Tutorial"). Также обратите внимание на <strong><em><a href="/en/Localization_and_Plurals" title="/en/Localization_and_Plurals">статью "Множественное число и локализация"</a></em></strong>, охватывающую функцию "локализации" в Firefox, которая позволит дополнительно уточнить этот последний пример для обработки различных типов формы множественного числа, также зависящих от языков.</p> + +<h3 id="Тема_(скин)">Тема (скин)</h3> + +<p>Отделка (styling. создание дизайна, стилизация) XUL очень похожа на отделку HTML. Мы рассмотрим некоторые различия, когда мы коснёмся коробочной модели XUL-а (XUL Box Model), и других более сложных тем. Есть не так много стилей, которые вы можете сделать для минимального меню и простейшего аварийного предупреждения (alert message), так что расширение "Привет, мир!" только включает пустой файл CSS и обязательный глобальный файл Скина:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"><?xml-stylesheet type=<span class="code-quote">"text/css"</span> href=<span class="code-quote">"chrome:<span class="code-comment">//global/skin/"</span>?> +</span><?xml-stylesheet type=<span class="code-quote">"text/css"</span> + href=<span class="code-quote">"chrome:<span class="code-comment">//xulschoolhello/skin/browserOverlay.css"</span>?></span></pre> +</div> +</div> + +<p>Файл CSS всеобщей темы содержит стили по умолчанию для всех элементов XUL и окон. Когда забывают вовлечь этот файл в окно XUL, то обычно это приводит к интересным и часто к нежелательным результатам. В нашем случае нам действительно не нужно его вовлекать, так как мы накладываем основной файл XUL нашего браузера, а этот файл уже вовлекает в себя эту всеобщую таблицу стилей CSS. Вообще, лучше бы его всегда вовлекать. Так труднее сделать ошибку, не включив его. Если вам интересно, вы можете ввести <code>chrome</code>-путь в адресную строку и посмотреть файл.</p> + +<p>Мы коснулись всех файлов в расширении "Привет мир". Теперь вы должны иметь представление об основах участия в разработке расширений, так что теперь нам придется перейти прямо к настройке среды разработки. Но сначала небольшое упражнение.</p> + +<h2 id="Упражнение">Упражнение</h2> + +<p>Измените приветственное сообщение, которое отображается в окне предупреждения, и переместите меню "Привет мир" в меню "Инструменты", которому оно принадлежит. Заново упакуйте XPI и переустановите его. Вы можете просто перетащить файл XPI в браузер, и он будет установлен локально. Проверьте его и убедитесь, что изменения работают. Если у вас возникли проблемы при установке, вполне вероятно, что вы не воспроизвели структуру XPI правильно, возможно, добавив ненужные папки.</p> + +<div class="note"><strong>Примечание:</strong> упаковка расширения действительно состоит только в создании ZIP архива содержимого главного каталога (папки) и последующем изменении расширения файла на ".XPI". <strong>Не пакуйте</strong> содержащий нужные данные каталог, а строго только его содержимое. Содержимое каталога, файлы <strong><em>chrome.manifest</em></strong>, <strong><em>install.rdf</em></strong> и другие файлы и каталоги должны быть в корневом каталоге архива. Если сжать ещё и содержащий каталог (имеется в виду ещё один уровень вложенности), то ваше расширение не будет загружаться.</div> + +<p>Имейте в виду, что в Firefox 4 и выше, в Windows и некоторых дистрибутивах Линукса, меню "Инструменты" по умолчанию скрыто. Оно может быть включено с помощью клавиши <ALT>.</p> + +<p>Когда закончите, можете посмотреть по этой ссылке решение: <a href="/@api/deki/files/5141/=xulschoolhello2.xpi" title="https://developer.Mozilla.org/@api/deki/files/5141/=xulschoolhello2.xpi">Hello World 2</a>.</p> + +<p>{{ PreviousNext("XUL_School/Getting_Started_with_Firefox_Extensions", "XUL_School/Setting_Up_a_Development_Environment") }}</p> + +<p><span style="font-size: small;">Этот учебник сообществу Mozilla был любезно пожертвован фирмой Appcoast.</span></p> + +<div id="cke_pastebin" style="position: absolute; top: 2144.83px; width: 1px; height: 1px; overflow: hidden; left: -1000px;"> </div> diff --git a/files/ru/xul_school/добавление_меню_и_подменю/index.html b/files/ru/xul_school/добавление_меню_и_подменю/index.html new file mode 100644 index 0000000000..8c2b96e4a9 --- /dev/null +++ b/files/ru/xul_school/добавление_меню_и_подменю/index.html @@ -0,0 +1,99 @@ +--- +title: Добавление меню и подменю +slug: XUL_School/Добавление_меню_и_подменю +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/Adding_menus_and_submenus +--- +<p>{{ PreviousNext("XUL_School/Setting_Up_a_Development_Environment", "XUL_School/Adding_Toolbars_and_Toolbar_Buttons") }}</p> +<p>The Hello World example in the previous sections shows the two most common ways to add menus. In this section we'll look into more specialized menus and what you can do with them.</p> +<h2 id="Adding_a_New_Menu">Adding a New Menu</h2> +<p>We already saw how to add menus in overlays and, as you may have imagined, you can nest submenus as deep as you want. You should avoid having deep menus or too many options, since they are confusing for most users.</p> +<p>If your extension requires custom XUL windows, you may also need to have menus on those windows. You can do this with a <a href="/en/XUL/menubar" title="en/XUL/menubar">menubar</a>. The <em>menubar</em> element should be a child of a <a href="/en/XUL/toolbox" title="en/XUL/toolbox">toolbox</a> element because it is treated like another toolbar on systems other than Mac OS X.</p> +<div class="note"> + <p>Mac OS X treats menus in a very different way than other systems. If your extension involves menus in any way, you should test it on Mac OS X to make sure everything works adequately.</p> +</div> +<p>The toolbox should be positioned near the top of the XUL document, and the code should be similar to this:</p> +<pre><code><toolbox> + <menubar id="</code><code>xulschoolhello</code><code>-menubar"> + <menu id="</code><code>xulschoolhello</code><code>-greeting-menu" label="&</code><code>xulschoolhello</code><code>.greeting.label;"> + <menupopup> + <menuitem label="&xulschoolhello.greet.short.label;" + oncommand="XULSchoolChrome.GreetingDialog.greetingShort(event);" /> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.medium.label;" + oncommand="XULSchoolChrome.GreetingDialog.greetingMedium(event);" /> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.long.label;" + oncommand="XULSchoolChrome.GreetingDialog.greetingLong(event);" /> + <menuseparator /> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.custom.label;" + oncommand="XULSchoolChrome.GreetingDialog.greetingCustom(event);" /> + </menupopup> + </menu> + </menubar> +</toolbox> </code></pre> +<p>This code displays a simple <a href="/en/XUL/menu" title="en/XUL/menu">menu</a> with options for 3 different types of greetings, a <a href="/en/XUL/menuseparator" title="en/XUL/menuseparator">menuseparator</a>, and finally an option to show a custom greeting. The separator is usually displayed as a horizontal line that creates a logical division between different types of <a href="/en/XUL/menuitem" title="en/XUL/menuitem">menuitem</a> elements, keeping everything more organized.</p> +<p>A <em>menubar</em> can hold one or more <em>menu</em> elements. Menus require a <a href="/en/XUL/menupopup" title="en/XUL/menupopup">menupopup</a> element as a container for its children, which are usually <em>menuitem</em> elements, but can also be <em>menuseparator,</em> or <em>menu</em> in order to have multiple nesting levels:</p> +<pre><code><toolbox> + <menubar id="</code><code>xulschoolhello</code><code>-menubar"> + <menu id="</code><code>xulschoolhello</code><code>-greeting-menu" label="&</code><code>xulschoolhello</code><code>.greeting.label;"> + <menupopup> + <menu id="</code><code>xulschoolhello</code><code>-greeting-sizes-menu" label="&</code><code>xulschoolhello</code><code>.greetingSizes.label;"> + <menupopup> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.short.label;" + oncommand="</code><code>XULSchoolChrome</code><code>.GreetingDialog.greetingShort(event);" /> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.medium.label;" + oncommand="</code><code>XULSchoolChrome</code><code>.GreetingDialog.greetingMedium(event);" /> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.long.label;" + oncommand="</code><code>XULSchoolChrome</code><code>.GreetingDialog.greetingLong(event);" /> + </menupopup> + </menu> + <menuitem label="&</code><code>xulschoolhello</code><code>.greet.custom.label;" + oncommand="</code><code>XULSchoolChrome</code><code>.GreetingDialog.greetingCustom(event);" /> + </menupopup> + </menu> + </menubar> +</toolbox> </code></pre> +<p>In this case we grouped the 3 greeting items into a submenu. It doesn't make much sense to do that in this case because we end up with only two menu items, one of them being a menu with 3 child items.</p> +<p>You can also have menus that are filled dynamically. Instead of setting the menupopup directly in the XUL, you can use the <a href="/en/XUL/Attribute/onpopupshowing" title="en/XUL/Attribute/onpopupshowing">onpopupshowing</a> event to fill the children when the popup is about to be displayed. DOM functions like <a href="/en/DOM/document.createElement" title="en/DOM/document.createElement">createElement</a> and <a href="/En/DOM/Node.appendChild" title="En/DOM/Node.appendChild">appendChild</a> can be used to accomplish this.</p> +<div class="note"> + <p>If you have nothing to show on a menu, you should follow the standard used in Firefox: show a single disabled item with an "(Empty)" label.</p> + <p>If filling your menu takes a noticeable amount of time, you should not make Firefox (and your users) wait for it to fill up before displaying anything. It's best to show an item with a throbber image (see <a class="external" rel="freelink">chrome://global/skin/icons/loading_16.png</a>) so the user knows there's something going on, and asynchronously fill its contents. We'll look into some asynchronous techniques further ahead in the tutorial.</p> +</div> +<h2 id="Adding_Elements_to_Existing_Menus">Adding Elements to Existing Menus</h2> +<p>Just as explained in the previous sections, the best place to overlay your extension menu is inside the <em>Tools</em> menu. That is, unless there's a place inside the menu structure where your extension menus make more sense. If you're overlaying the Tools menu, your overlay code should have something like this:</p> +<pre><code><menupopup id="menu_ToolsPopup"> + <menu id="</code><code>xulschoolhello</code><code>-hello-menu" label="&</code><code>xulschoolhello</code><code>.hello.label;" + accesskey="&</code><code>xulschoolhello</code><code>.helloMenu.accesskey;" + insertafter="javascriptConsole,devToolsSeparator"> + <menupopup> + <!-- Your menuitem goes here. --> + </menupopup> + </menu> +</menupopup> </code></pre> +<p>Now let's look at some specialized types of menu items.</p> +<h2 id="Menu_types">Menu types</h2> +<h3 id="Checkbox_Menu_Items">Checkbox Menu Items</h3> +<p>You can make a <em>menuitem</em> "checkable" to allow the user to enable/disable options using the menu. We use two attributes for this: <a href="/en/XUL/menuitem#a-menuitem.type" title="en/XUL/menuitem#a-menuitem.type">type</a> and <a href="/en/XUL/menuitem#a-checked" title="en/XUL/menuitem#a-checked">checked</a>. The <em>type</em> attribute must be set to "checkbox". You can set the <em>checked</em> attribute to "true" to check it by default.</p> +<p>The item's checked state changes when the user clicks on it. An example of one such item is the View > Status Bar item in the main Firefox menu.</p> +<h3 id="Radio_Menu_Items">Radio Menu Items</h3> +<p>If you need to have a set of <em>menuitem</em> elements where only one of them has to be checked at any given moment, you should set the <em>type</em> to "radio". The <em>name</em> attribute is used to identify the items that belong to the radio group.</p> +<pre><code><menupopup oncommand="XULSchoolChrome.HW.GreetingDialog.greeting(event);"> + <menuitem type="radio" name="</code><code>xulschoolhello</code><code>-greeting-radio" + label="&</code><code>xulschoolhello</code><code>.greet.short.label;" checked="true" /> + <menuitem type="radio" name="</code><code>xulschoolhello</code><code>-greeting-radio" + label="&</code><code>xulschoolhello</code><code>.greet.medium.label;" /> + <menuitem type="radio" name="</code><code>xulschoolhello</code><code>-greeting-radio" + label="&</code><code>xulschoolhello</code><code>.greet.long.label;" /> +</menupopup> </code></pre> +<p>This is a modified version of the 3 greeting menus. It is now implemented as a radio menu where you pick one of the 3 available choices. The first one is checked by default. The <em>oncommand</em> attribute is set on the <em>menupopup</em> to avoid code duplication, since now the 3 items call the same function.</p> +<p>Another example of a menu like this is the View > Sidebars menu. Only one sidebar is visible at any given moment, and you can pick from several.</p> +<h3 id="Menus_with_Images">Menus with Images</h3> +<p>To add an icon to a <em>menu</em> or <em>menuitem</em>, set its class to "menu-iconic" or "menuitem-iconic" respectively, and set the <a href="/en/XUL/Attribute/image" title="en/XUL/Attribute/image">image</a> attribute or the <a href="/en/CSS/list-style-image" title="en/CSS/list-style-image">list-style-image</a> CSS property. Menu icons are typically 16px by 16px.</p> +<h2 id="Menus_on_Mac_OS_X">Menus on Mac OS X</h2> +<p>As mentioned earlier, menus are very different on Mac OS X. This is because menus on Mac are located in a single menu bar which is controlled by the operating system, as opposed to menus in other systems, which are entirely controlled by Firefox. Mac OS X also has menu standards, such as the positioning of certain items that are not used in other systems. Here's a list of the known issues we've run into when handling menus on Mac:</p> +<ul> + <li>The About, Preferences and Quit menu items are located under the "Firefox" menu, not the usual places you would find them. You can access these items by id through the DOM, but their parent menu is not easily accessible.</li> + <li>We've run into bugs when adding, removing, enabling and disabling menu items dynamically, specially the root menu items (File, Edit, View, etc). You should carefully test this behavior to make sure it works properly in your extension.</li> + <li>Images in menu items may not appear, showing only a narrow segment of the image instead. This seems to happen when remote images are used.</li> + <li>Menu items are not dynamically updated while they are open. For example, you could have a <em>menuitem</em> that tells you the current time and is updated every second. On other systems you would be able to see the item update itself without having to close the menu and then reopen. This is not the case on Mac OS.</li> +</ul> +<p>{{ PreviousNext("XUL_School/Setting_Up_a_Development_Environment", "XUL_School/Adding_Toolbars_and_Toolbar_Buttons") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> diff --git a/files/ru/xul_school/добавление_окон_и_диалогов/index.html b/files/ru/xul_school/добавление_окон_и_диалогов/index.html new file mode 100644 index 0000000000..1d77564aac --- /dev/null +++ b/files/ru/xul_school/добавление_окон_и_диалогов/index.html @@ -0,0 +1,138 @@ +--- +title: Добавление окон и диалогов +slug: XUL_School/Добавление_окон_и_диалогов +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/Adding_windows_and_dialogs +--- +<p>PreviousNext("XUL_School/The_Box_Model", "XUL_School/Adding_sidebars") }}</p> +<h2 id="Opening_windows_and_dialogs">Opening windows and dialogs</h2> +<p>To open a new window, use the Javascript <a href="/en/DOM/window.open" title="en/DOM/window.open">window.open</a> function just like with HTML windows.</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">window.open( + "chrome://xulschoolhello/content/someWindow.xul", + "xulschoolhello-some-window", + "chrome,centerscreen");</pre> + </div> +</div> +<p>The first argument is the URL to open, the second is an id to identify the window, and the last is an optional comma-separated list of features, which describe the behavior and appearance of the window. If this value is null or empty, the default toolbars of the main window will be added to the new one, which is rarely what you want. The <a href="/en/DOM/window.open" title="en/DOM/window.open">window.open</a> page has a detailed description of the features you can use and their values. The following features are very important and you should always keep them in mind:</p> +<ul> + <li>chrome. This can only be used from the chrome, not from regular HTML JavaScript. It indicates that a chrome document is being opened, not a web page. This means that the document defines the whole window, and not only the inner content area. You should always include it when opening a XUL window or dialog.</li> + <li>modal. Modal windows block their parent window until action is taken on them. An alert window is an example of this. Modal windows should be avoided when possible because they interrupt the user's browsing and can become annoying very quickly. This feature should only be used when there's no way to continue without having the user do something. <strong>Never open modal windows at startup.</strong></li> + <li>resizable. Indicates the user can resize the window or not. In general, windows should not be resizable unless they display dynamically generated content from a datasource, such as lists or trees that may need resizing to have a better view of the content.</li> +</ul> +<p>To open a new dialog, use the function <a href="/en/DOM/window.openDialog" title="en/DOM/window.openDialog">window.openDialog</a>, an extension of the <em>open</em> function. It allows you to send a set of optional parameters that can be used to communicate with the dialog.</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">let someValue = 2; +let returnValue = { accepted : false , result : "" }; + +window.openDialog( + "<a class="external" rel="freelink">chrome://xulschoolhello/content/someDialog.xul</a>", + "xulschoolhello-some-dialog", "chrome,centerscreen", + someValue, returnValue); // you can send as many extra parameters as you need. + +// if (returnValue.accepted) { do stuff }</pre> + </div> +</div> +<p>The optional parameters are available in the dialog code through the <em>window.arguments</em> property:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">let someValue = window.arguments[0]; +let returnValue = window.arguments[1]; + +// returnValue.accepted = true; +// returnValue.result = "something"; +</pre> + </div> +</div> +<p>The parameter named <em>returnValue</em> is an object that the dialog will modify to reflect what the user did in it. This is the simplest way to have the dialog return something to its opener. Note that the opener will wait until the dialog is closed. This means the <em>openDialog</em> function call will not return until the dialog has been closed by the user.</p> +<h2 id="Common_Dialogs_and_the_Prompt_Service">Common Dialogs and the Prompt Service</h2> +<p>There are several types of dialogs that are fairly common, so there are ways to create them easily without having to reinvent the wheel and write all their XUL and JS code all over again. Whenever you need a new dialog, you should ask yourself if it can be implemented using these common dialogs, and use them whenever it is possible. They have been thoroughly tested for OS integration, accessbility and localization, so you save yourself a lot of work and favor them.</p> +<p>Using the <a href="/en/XPCOM_Interface_Reference/nsIPromptService" title="en/NsIPromptService">Prompt Service</a> is the recommended way to create common dialogs in an extension. Read the article and its examples carefully, because there are many useful functions to use in the Prompt Service. There are some equivalent, simpler functions that are available in the <em>window</em> object, but those are meant for unprivileged HTML JavaScript code.</p> +<h3 id="Alert">Alert</h3> +<p>The alert is the simplest form of dialog. All it does is display a text message that the user can read and then click the OK button to dismiss it. We have been using the <a href="/en/DOM/window.alert" title="en/DOM/window.alert">window.alert</a> function to open alert messages in our examples so far, but that's not the right way to do it. It's OK to use this function if you're just debugging some problem and want to see if the program reaches a specific line of code, or to inspect the value of a variable, but your final extension should not have <em>alert</em> calls anywhere.</p> +<p>If you use <em>window.alert</em>, the alert window will have the title [JavaScript Application], indicating that the source of the message is not well defined. The Prompt Service allows better alerts to be displayed. Here's an example of displaying an alert using the Prompt Service:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">let prompts = + Cc["@mozilla.org/embedcomp/prompt-service;1"]. + getService(Ci.nsIPromptService); + +prompts.alert(window, "Alert Title", "Hello!");</pre> + </div> +</div> +<p>You should of course use localized strings instead of hard-coded ones.</p> +<p>The Prompt Service allows you to set the title of the dialog however you want it, and also lets you specify the window you want to use as a parent for the alert. This normally should be set to the current window. You can pass a null value and the service will pick the currently active window.</p> +<h3 id="Confirm">Confirm</h3> +<p>Confirmation dialogs display a text with a Yes / No question, and prompts the user to choose an answer. In HTML you can use the <a href="/en/DOM/window.confirm" title="en/DOM/window.confirm">window.confirm</a> function for this. The Prompt Service has a <em>confirm</em> method with similar behavior:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">let prompts = + Cc["@mozilla.org/embedcomp/prompt-service;1"]. + getService(Ci.nsIPromptService); + +if (prompts.confirm(window, "Confirm Title", "Would you like to continue?")) { + // do something. +} else { + // do something else +}</pre> + </div> +</div> +<p>The method returns a boolean value indicating the user's response.</p> +<h3 id="Others">Others</h3> +<p>Unprivileged Javascript can also use the <a href="/en/DOM/window.prompt" title="en/DOM/window.prompt">window.prompt</a> function to receive text input from the user. The Prompt Service has a very rich set of functions that allow different kinds of inputs, such as text, passwords, usernames and passwords, and checkboxes that can be used for "Never ask this again"-type dialogs. The <a href="/en/XPCOM_Interface_Reference/nsIPromptService#confirmEx" title="en/nsIPromptService#confirmEx">confirmEx</a> and <a href="/en/XPCOM_Interface_Reference/nsIPromptService#prompt" title="en/nsIPromptService#prompt">prompt</a> methods are the most customizable, allowing a great deal of options that cover most common dialog cases.</p> +<p>Using the Prompt Service will save you a lot of XUL coding, and you'll be at ease knowing that you're using Mozilla's tried and tested code.</p> +<h2 id="The_Dialog_Element">The Dialog Element</h2> +<p>When the Prompt Service is not enough, you'll have to create you own XUL dialogs. Luckily, you still get a great deal of help from the platform if you use the <a href="/en/XUL/dialog" title="en/XUL/dialog">dialog</a> element as the document root instead of the more generic <em>window</em> element.</p> +<p>You may be asking yourself what's the big deal about defining a simple XUL window with an OK and maybe a Cancel button. The dialogs we have covered in this section are very simple and shouldn't be too hard to implement manually using XUL. Well, it's more complicated than that. Different operating systems order and position their buttons differently in their dialogs. There are also subtle aspects about window size, margins and paddings that are not the same for all systems, so you should avoid making dialogs from scratch or overriding the default dialog CSS styles.</p> +<p>The <em>dialog</em> element handles all of this transparently. All you need to do is define which buttons you'll need and the actions associated with them.</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><dialog id=<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">-hello-dialog"</span> + title=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.helloDialog.title;"</span> + buttons=<span class="code-quote">"accept,cancel"</span> + ondialogaccept=<span class="code-quote">"<span class="code-keyword">return</span> XULSchoolChrome.HelloDialog.accept();"</span> + ondialogcancel=<span class="code-quote">"<span class="code-keyword">return</span> XULSchoolChrome.HelloDialog.cancel();"</span> + xmlns=<span class="code-quote">"http:<span class="code-comment">//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</span>></span></pre> + </div> +</div> +<p>Carefully read the specification of the <a href="/en/XUL/dialog" title="en/XUL/dialog">dialog</a> element. You'll see that you can choose from a wide variety of buttons, associate any action you need to them, override their labels, and even add completely customized extra buttons. All of this without having to worry about your dialog looking odd in some operating systems. The only constant rule is that clicking on OK and Cancel will close the dialog unless your associated function returns false. You should avoid returning false, though, specially with the Cancel button. Dialogs in general should be easy to dismiss.</p> +<div class="panel" style="border-width: 1px;"> + <div class="panelContent"> + <p>Your dialogs shouldn't have fixed dimensions because of potential localization problems. Dialogs are sized to their contents and will generally work fine. However, there are cases where the dialog contents are generated or expanded dynamically by your code, and you'll need to resize them appropriately. The <a href="/en/DOM/window.sizeToContent" title="en/DOM/window.sizeToContent">window.sizeToContent</a> function is what you need in this case.</p> + </div> +</div> +<h2 id="Input_Controls">Input Controls</h2> +<p>Most additional XUL windows and dialogs in extensions are some kind of input form. Let's look into the most commonly used form elements and how to use them in your XUL windows. There isn't much we need to add from what the XUL Tutorial explains, so go ahead and read the following sections:</p> +<ul> + <li><a href="/en/XUL_Tutorial/Input_Controls" title="en/XUL Tutorial/Input Controls">Input controls</a></li> + <li><a href="/en/XUL_Tutorial/Numeric_Controls" title="en/XUL Tutorial/Numeric Controls">Numeric controls</a></li> + <li><a href="/en/XUL_Tutorial/List_Controls" title="en/XUL Tutorial/List Controls">List controls</a></li> +</ul> +<p>There are some other aspects to take into account when handling input controls, which we cover in the following sections.</p> +<h3 id="Groupboxes">Groupboxes</h3> +<p>The <a href="/en/XUL/groupbox" title="en/XUL/groupbox">groupbox</a> element should be easy to understand: it groups a series of XUL controls together. It's a box container with styling that is usually a visible border around its contents, so that it's clear what is being grouped together. It is frequently used with the <a href="/en/XUL/caption" title="en/XUL/caption">caption</a> element to associate the grouped elements with a title.</p> +<p>The <em>groupbox</em> shouldn't be seen as an aesthetic device, but a logical one. If all you need is a border, use CSS. The <em>groupbox</em> element should be used when enclosed elements share some function which is separate from other elements or groups in the same window. It's also a useful accessibility feature, because screen readers will read the caption right before reading any text in its contents. You can change its style using CSS in case you don't want the borders to appear. See the Firefox Preferences window for an example of this: sections are defined using <em>groupbox</em> elements, but their style is quite different from the default.</p> +<h3 id="Attribute_Persistence">Attribute Persistence</h3> +<p>User actions can change the state of your windows, such as selecting an option in a listbox, or entering text in a textbox. If the user closes and then reopens your window, all the controls are reset to their defaults, which may not be what you want. You need some way of remembering the user-manipulated attribute values so that the window reloads it last state when opened.</p> +<p>Most XUL elements support the <a href="/en/XUL/Attribute/persist" title="en/XUL/Attribute/persist">persist</a> attribute, which has this exact function. You set the <em>persist</em> attribute with a space-separated list of attribute names, indicating which attribute values must be persisted across window "sessions".</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><checkbox id=<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">-some-checkbox"</span> + label=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.someText.label;" + </span> checked=<span class="code-quote">"<span class="code-keyword">false</span>"</span> persist=<span class="code-quote">"checked"</span> /></pre> + </div> +</div> +<p>Setting the <em>id</em> attribute of the element is mandatory if you want the <em>persist</em> attribute to work. You can also set persistence programatically using the <em>document.persist</em> function:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="brush: js">document.persist("xulschoolhello-some-checkbox", "checked");</pre> + </div> +</div> +<p>Persistent data is stored in the user profile, in the file <em>localstore.rdf</em>. You may need to modify or delete this file often when testing persistent data in your extension.</p> +<h3 id="Focus_and_Tabbing">Focus and Tabbing</h3> +<p>Moving through all input controls in a window using only the keyboard is an accessibility requirement. You can do this in most Firefox windows by pressing the Tab key. Each Tab key press moves you to the next control in the window, giving it focus.</p> +<p>In general, there's nothing you need to do in order to have good keyboard focus management. Firefox will automatically focus the first input control in your window, and tab focus advances in the order the items are found in the XUL document. If you have a very complex layout, or need customized tabbing behavior, you can set the <a href="/en/XUL/Property/tabIndex" title="en/XUL/Property/tabIndex">tabindex</a> attribute in the controls. You can also use the <a href="/en/XUL/Method/focus" title="en/XUL/Method/focus">focus</a> function to focus an element depending on events such as window load. You should do this carefully, to avoid having inaccessible controls.</p> +<p>You can also use the <a href="/en/CSS/-moz-user-focus" title="en/CSS/-moz-user-focus">-moz-user-focus</a> CSS property to enable focusing of elements that typically wouldn't receive focus. Again, this should be used sparingly.</p> +<p>{{ PreviousNext("XUL_School/The_Box_Model", "XUL_School/Adding_sidebars") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> diff --git a/files/ru/xul_school/добавление_панелей_инструментов_и_кнопок/index.html b/files/ru/xul_school/добавление_панелей_инструментов_и_кнопок/index.html new file mode 100644 index 0000000000..60ec952087 --- /dev/null +++ b/files/ru/xul_school/добавление_панелей_инструментов_и_кнопок/index.html @@ -0,0 +1,214 @@ +--- +title: Добавление панелей инструментов и кнопок +slug: XUL_School/Добавление_панелей_инструментов_и_кнопок +translation_of: >- + Archive/Add-ons/Overlay_Extensions/XUL_School/Adding_Toolbars_and_Toolbar_Buttons +--- +<p>{{ PreviousNext("XUL_School/Adding_Menus_and_Submenus", "XUL_School/Adding_events_and_commands") }}</p> +<h2 id="Панели_инструментов">Панели инструментов</h2> +<p>Adding new toolbars to Firefox is easy, but adding them the wrong way is very easy as well.</p> +<p>Toolbars in Firefox are very customizable. Some users don't like extra toolbars, or they want to rearrange toolbar buttons to their liking, possibly merging multiple toolbars in the process. Firefox allows all of this by default, and if you don't pay attention to the details we describe here, your toolbar may not be as easy to customize as the rest.</p> +<p>The first thing you need to do is add your buttons to the toolbar palette. The <a href="/en/XUL/toolbarpalette" title="en/XUL/toolbarpalette">toolbarpalette</a> is a collection of all toolbar buttons and toolbar items in Firefox, including those added by extensions. To add your buttons, all you need to do is overlay the palette in your main browser overlay.</p> +<pre><overlay id="xulschoolhello-browser-overlay" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <toolbarpalette id="BrowserToolbarPalette"> + <toolbarbutton id="xulschoolhello-hello-world-button" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&xulschoolhello.helloWorld.label;" + tooltiptext="&xulschoolhello.helloWorld.tooltip;" + oncommand="XULSchoolChrome.BrowserOverlay.doSomething(event);" /> + <!-- More buttons here. --> + </toolbarpalette> + <!-- More overlay stuff. --> +</overlay> +</pre> +<p>One detail that is easy to overlook is the fact that the <em>toolbarpalette</em> element is outside of the <em>window</em> element. If you put the <em>toolbarpalette</em> element inside the <em>window</em> element in your overlay, some weird errors will begin to happen.</p> +<div class="note"> + <p>Always set the <em>label</em> and <em>tooltiptext</em> attributes of a <a href="/en/XUL/toolbarbutton" title="en/XUL/toolbarbutton">toolbarbutton</a>. In the case of a <a href="/en/XUL/toolbaritem" title="en/XUL/toolbaritem">toolbaritem</a> element (discussed later), use the <em>title</em> attribute instead of <em>label</em>. Tooltips are very important for users that want to know what a button does before clicking it.</p> +</div> +<p>Setting the image for a toolbar button is done with CSS:</p> +<pre>#xulschoolhello-hello-world-button { + list-style-image: url("chrome://xulschoolhello/skin/hello-world.png"); +} +</pre> +<p>It's not really that simple to set the image for a toolbar button, because we need to consider the appearance of the button on different systems, and also consider the different button states, but we'll get into that further ahead.</p> +<p>The CSS file with your toolbar styles needs to be included in the overlay file, as you would expect, but also in the chrome.manifest file. This is very important because the toolbar customization dialog won't work correctly without this. The way to include the file in the manifest is to add this line:</p> +<pre>style chrome://global/content/customizeToolbar.xul chrome://xulschoolhello/skin/toolbar.css +</pre> +<p>If you are using XBL bindings (explained way ahead) for your toolbar items, you'll have to include the CSS files for those as well, each in a new line like the one above.</p> +<p>We now have code that adds one or more buttons to the toolbar palette. The user can now use the Customize Dialog to add the buttons to the current Firefox toolbars. In most cases this is not what you want as default behavior, because it would be very hard for the user to discover your buttons. Keep in mind most users don't know how to customize toolbars in Firefox.</p> +<p>Теперь давайте создадим свою панель инструментов - <a href="/en/XUL/toolbar" title="en/XUL/toolbar">toolbar</a>. Это также делается в в оверлее.</p> +<pre class="brush: xml"><overlay ...> + ... + <window id="main-window"> + <toolbox id="navigator-toolbox"> + <toolbar id="xulschoolhello-toolbar" + <!-- toolbarname="&xulschoolhello.toolbarName.label;" + accesskey="&xulschoolhello.toolbar.accesskey;" + customizable="true" mode="icons" + context="toolbar-context-menu" + defaultset="xulschoolhello-hello-world-button" + insertbefore="PersonalToolbar" --> /> + </toolbox> + </window> + ... +</overlay></pre> +<p>Our toolbar is added as a child of the <a href="/en/XUL/toolbox" title="en/XUL/toolbox">toolbox</a> element in the main browser window. The toolbox is the collection of toolbars in Firefox, including the main menu bar. Let's look at the attributes we used:</p> +<ul> + <li>The <em>toolbarname</em> is the name that will appear on the View > Toolbars menulist. This menu allows hiding and showing any toolbar.</li> + <li>The <em>customizable</em> attribute determines if the user can customize the toolbar. You should normally set this to <em>true</em>, unless you have strong reasons not to want users changing your toolbar.</li> + <li>The <em>mode</em> attribute is set to <em>icons</em>, which is the usual value. This can be changed in the Customize dialog by the user.</li> + <li>The <em>context</em> attribute should also be set if you want a customizable toolbar. It points to the id of a popup element that holds the customization options that are displayed when the user right-clicks on the toolbar. This popup is already part of the main window, so it doesn't need to be implemented again.</li> + <li>The <em>defaultset</em> attribute lists the ids of the icons you want to include on your toolbar by default. It's a comma-separated list of ids, and it can also include other special values: <em>spacer</em>, <em>separator</em> and <em>spring</em>. <em>spacer</em> represents an empty button space, <em>separator</em> a vertical separation line and <em>spring</em> a flexible empty area that stretches.</li> + <li>Finally, the <em>insertbefore</em> attribute places our toolbar above the Bookmarks Toolbar. This is a matter of personal preference, but the Mac OS theme seems to be designed so that the Bookmarks Toolbar is always the last one (it has a lighter color than the rest). It also makes sense from a usability perspective, since bookmarks should be very easy to access for the user.</li> +</ul> +<p>That's it for the basics. With this knowledge you should be able to create simple toolbars and toolbar buttons you can add to Firefox. Now we'll look deeper into the details of toolbars so that you can make <strong>great</strong> toolbars.</p> +<h2 id="Кнопки_на_панели_инструментов">Кнопки на панели инструментов</h2> +<p>There are several types of buttons and elements you can add to a toolbar depending on your needs. The <a href="/en/XUL/toolbarbutton" title="en/XUL/toolbarbutton">toolbarbutton</a> element has the <em>type</em> attribute that allows you to change the behavior of the button in many ways. The <em>menu</em> and <em>menu-button</em> types allow you to create buttons that open popup menus beneath them. See the Back/Forward buttons in the main Firefox toolbar for an example. Menu toolbar buttons are handy when you want to include many options in your toolbar and you don't want it to be too cluttered. The other types, <em>checkbox</em> and <em>radio</em> are useful when you have buttons that change state when the user clicks on them. Read more about this in the <a href="/en/XUL/Attribute/toolbarbutton.type" title="en/XUL/Attribute/toolbarbutton.type">type attribute</a> specification.</p> +<div class="note"> + <p>Keep in mind some users have small screens with low resolution. If you shrink the Firefox window, you'll notice that the content resizes until it reaches its minimum size and begin to be cropped (cut), making UI elements disappear. You should test that your toolbar resizes gracefully and doesn't force Firefox to crop content before it's strictly necessary.</p> +</div> +<p>Добавим кнопку на нашу панель инструментов.</p> +<pre class="brush: xml"><overlay ...> + ... + <window id="main-window"> + <toolbox id="navigator-toolbox"> + <toolbar id="xulschoolhello-toolbar"> + <toolbarbutton id="xulschoolhello-btn" label="Hello" /> + </toolbar> + </toolbox> + </window> + ... +</overlay></pre> +<div> + </div> +<p>When you need something more elaborate than a button in your toolbar, you can use the <a href="/en/XUL/toolbaritem" title="en/XUL/toolbaritem">toolbaritem</a> element instead. This element is nothing more than a wrapper, so you can have whatever XUL content you want in it. However, you should keep in mind that odd-looking toolbars are likely to confuse and annoy users. Use custom toolbar items sparingly.</p> +<h3 id="Иконки_кнопок_на_панели_инструментов">Иконки кнопок на панели инструментов</h3> +<p>Создание иконок для панели инструментов является одной из наиболее трудных задач при разработке расширения. Придумать рисунки для кнопок не трудно, сложнее заставить их гармонировать с Firefox в разных операционных системах. Внимание к иконкам значительно изменилось после Firefox 4, поэтому о старых версиях здесь не будет упоминаться однако, можете проверить более ранние ревизии этого документа).</p> +<p>Наборы иконок для Firefox:</p> +<p><strong>Windows</strong></p> +<p><img alt="Toolbar-win.png" class="internal default" src="/@api/deki/files/5960/=Toolbar-win.png"></p> +<p><strong>Mac OS X (Lion и старше)</strong></p> +<p><img alt="Toolbar-mac-lion.png" class="internal default" src="/@api/deki/files/5958/=Toolbar-mac-lion.png"></p> +<p><strong>Mac OS X</strong></p> +<p><img alt="Toolbar-mac.png" class="internal default" src="/@api/deki/files/5959/=Toolbar-mac.png"></p> +<p><strong>Linux (Gnome)</strong></p> +<p><img alt="Toolbar-gnome.png" class="internal default" src="/@api/deki/files/5957/=Toolbar-gnome.png"></p> +<p><img alt="Toolbar-gnome-small.png" class="internal default" src="/@api/deki/files/5956/=Toolbar-gnome-small.png"></p> +<div class="note"> + <p>Примечание: изображения выше, вероятно, не распространяются по той же лицензии CC в отличие от данного материала</p> +</div> +<p><span class="short_text" id="result_box" lang="ru"><span class="hps">Вот ключевые</span> <span class="hps">сходства и различия между</span></span> этими тремя темами:</p> +<ul> + <li>Все ОС используют иконки 16x16 пикселей. Только у окружения Gnome есть набор с большими иконками 24x24 пикселей.</li> + <li>Всего несколько иконок имеют различные состояния. Для состояния 'недоступно' большинство иконок обрабатываются средствами CSS.</li> + <li>У каждого набора иконок различные поля (padding). Для Windows они образуют рамку в 19x19 пикселей, в то время как для Mac OS в 20x20 пикселей. Но это не так важно, так как сама иконка останется 16x16 и будет размещена в центре рамки.</li> + <li>Иконки для Mac OS X Lion светлее.</li> + <li>В Linux, иконки по умолчанию 24x24 пикселй. С тех пор как Firefox является <a class="external" href="http://www.gtk.org/" title="http://www.gtk.org/">GTK</a> приложением, используются <a class="external" href="http://library.gnome.org/devel/gtk/stable/gtk-Stock-Items.html" title="http://library.gnome.org/devel/gtk/stable/gtk-Stock-Items.html">GTK иконки</a> насколько это возможно. Значки в изображениях выше те, которых нет в GTK. GTK иконки доступны по специальным URL, например: <a class="external" rel="freelink">moz-icon://stock/gtk-go-back?size=menu</a>. Вы можете перейти по этому URL в Firefox для Linux и убедиться, что иконка отображается. Поэтому в наборе для Linux все еще остаются цветные значки.</li> +</ul> +<p>Now let's look at the CSS work involved in a toolbar that works on the aforementioned systems. If you want your toolbar to look right on all systems, you should consider having different icon sets for each. You should also consider using a graphic designer for this work, as it takes a lot of attention to detail to make good icons.</p> +<p>You can have a different skin directory for each operating system using Manifest Flags in the chrome.manifest file:</p> +<pre>skin xulschoolhello classic/1.0 skin/unix/ +skin xulschoolhello classic/1.0 skin/win/ os=WINNT +skin xulschoolhello classic/1.0 skin/mac/ os=Darwin +</pre> +<p>The <a href="/en/Chrome_Registration#Manifest_flags" title="https://developer.mozilla.org/en/Chrome_Registration#Manifest_flags">osversion flag</a> can be used in case we wanted to have different icons for Mac OS X Lion and above, and others for older systems. In this example we won't bother.</p> +<p>There is a separate skin directory for each system, with the Unix theme as the default (as most other systems are Unix-based). This makes it easy to keep the themes separate and to make changes to one of them without having to worry about the rest. On the other hand, it is often the case that there are multiple images and CSS sheets that are the same for all systems. For example, your extension logo icon will probably be the same. Having multiple copies of these files can be wasteful, so you may want to have a "common" directory.</p> +<div class="note"> + <p>Image files use the most space in an extension package, by far. Most extensions are a few hundred kilobytes in size or smaller. If your file is getting too big, you should look into optimizing your images.</p> +</div> +<p>Given the way manifest files work, we have found that the best solution is to have a separate package name for OS-specific skin files.</p> +<pre>skin xulschoolhello classic/1.0 skin/all/ +skin xulschoolhello-os classic/1.0 skin/unix/ +skin xulschoolhello-os classic/1.0 skin/win/ os=WINNT +skin xulschoolhello-os classic/1.0 skin/mac/ os=Darwin +</pre> +<p>All we did here is add a new entry for "common" styles that points to the <em>all</em> directory. The OS-specific entries now use a different package name: <em>xulschoolhello-os</em>. Now you just need to be careful about when to use <em><a class="external" rel="freelink">chrome://xulschoolhello/skin/</a></em> and when to use <em><a class="external" rel="freelink">chrome://xulschoolhello-os/skin/</a></em>. It's a bit hacky, but it works well.</p> +<p>As for the image files themselves, you may be wondering why it is that all icons are included in a single file instead of having one file for every icon. One reason is that it would be complicated to manage that many files, and it becomes more likely that changes made to some of the files lead to an inconsistent appearance that is not obvious by looking at the individual files. It is easier to be able to edit all icons in one go. There is also a performance gain from using a single file. To get the region that corresponds to a specific state of an icon, the <a href="/en/CSS/-moz-image-region" title="en/CSS/-moz-image-region">-moz-image-region</a> CSS property is used.</p> +<p>Here are some examples of how the CSS for a <em>toolbarbutton</em> would look like on the 3 major platforms. This assumes that you've set the class<em> xs-hw-toolbarbutton</em> to all of your buttons.</p> +<p>Windows:</p> +<pre>/* The second and third selectors at the bottom are necessary to prevent + conflicts with installed themes. */ +toolbarbutton.xulschoolhello-toolbarbutton, +window:not([active="true"]) toolbarbutton.xulschoolhello-toolbarbutton, +toolbar[iconsize="small"] toolbarbutton.xulschoolhello-toolbarbutton { + list-style-image: url("chrome://xulschoolhello-os/skin/toolbar.png"); +} + +#xulschoolhello-hello-world-button { + -moz-image-region: rect(0px, 16px, 16px, 0px); +} + +</pre> +<p>Mac OS X:</p> +<pre>/* The second and third selectors at the bottom are necessary to prevent + conflicts with installed themes. */ +toolbarbutton.xulschoolhello-toolbarbutton, +window:not([active="true"]) toolbarbutton.xulschoolhello-toolbarbutton, +toolbar[iconsize="small"] toolbarbutton.xulschoolhello-toolbarbutton { + list-style-image: url("chrome://xulschoolhello-os/skin/toolbar.png"); +} + +#xulschoolhello-hello-world-button { + -moz-image-region: rect(0px, 16px, 16px, 0px); +} +</pre> +<p>Linux:</p> +<pre>/* The second and third selectors at the bottom are necessary to prevent + conflicts with installed themes. */ +toolbarbutton.xulschoolhello-toolbarbutton, +window:not([active="true"]) toolbarbutton.xulschoolhello-toolbarbutton { + list-style-image: url("chrome://xulschoolhello-os/skin/toolbar-large.png"); +} + +#xulschoolhello-hello-world-button { + -moz-image-region: rect(0px, 24px, 24px, 0px); +} + +toolbar[iconsize="small"] #xulschoolhello-hello-world-button { + list-style-image: url("chrome://xulschoolhello-os/skin/toolbar.png"); + -moz-image-region: rect(0px, 16px, 16px, 0px); +} +</pre> +<p>Several CSS rules apply by default to all toolbar buttons. These add the button-like look you want. If for some reason you want to override these styles (not recommended), you'll need the following rule:</p> +<pre>-moz-appearance: none; +</pre> +<p><a href="/en/CSS/-moz-appearance" title="en/CSS/-moz-appearance">-moz-appearance</a> can be used in many cases where you want to strip the native look out of an element. This will save you a lot of time trying to remove all the CSS rules that give the buttons a native look. You'll probably still need to override a couple other CSS rules to get a completely plain look.</p> +<h2 id="The_Customize_Toolbars_Dialog">The Customize Toolbars Dialog</h2> +<p>Firefox has the option to customize its toolbars. We've already mentioned this before, and if you follow our recommendations, then you shouldn't have many problems making your toolbar compatible with the Customize Toolbars dialog. The dialog can be opened from View > Toolbars > Customize..., or by right-clicking on the main toolbar (or any toolbar with the correct <em>context</em> attribute value) and clicking on the Customize option.</p> +<p>Other than what we have stated before, you should take into account the controls at the bottom of the Customize Toolbars dialog. You should test your toolbar buttons and items under all combinations of Icons / Icons and text / Text, Use Small Icons, and hiving your icons in different toolbars. You should also test that the Reset to Defaults button works correctly. Adding elements to your toolbar that are not <em>toolbarbutton</em> or <em>toolbaritem</em> will cause it to fail. Make sure your icons look OK while the Customize Dialog is open, and after clicking on the OK button. If you use XBL bindings, make sure everything works normally after customizing toolbars. All of this is very important to test because, when the dialog is opened, Firefox changes the DOM of the toolbar, adding wrapper elements that allow the customization. This tends to break very specific CSS, and XBL bindings lose their internal state when moved around the DOM.</p> +<h2 id="Добавление_кнопок_на_уже_существующие_панели_инструментов">Добавление кнопок на уже существующие панели инструментов</h2> +<p>Finally, there is the very common case where you just want to add one button to the main toolbar. In this case you still need to add the button to the palette using an overlay. In order to add your button to the main toolbar on first run, you'll have to use Javascript code. Keep in mind that you shouldn't assume anything about the location (or presence!) of any specific buttons; remember users could have moved them or removed them altogether. The <a href="/en/Code_snippets/Toolbar#Adding_button_by_default" title="en/Code snippets/Toolbar#Adding button by default">Toolbar Code Snippets</a> page has a code sample you can use to do this.</p> +<p>Remember to validate if your button is already present, to prevent duplicates. It's also a good idea to set a preference that indicates that you added your button already, so that it can be removed permanently if the user chooses to. Another option is to use <a href="/en/Toolkit_API/extIExtension" title="en/FUEL:Extension">FUEL's firstRun</a> property, which also relies on a preference.</p> +<p><strong>Firefox 3</strong></p> +<pre class="brush: js">let extension = Application.extensions.get(YOUR_EXTENSION_ID); + +if (extension.firstRun) { + // add button here. +} +</pre> +<p><strong>Firefox 4</strong></p> +<pre class="brush: js">Application.getExtensions(function (extensions) { + let extension = extensions.get(YOUR_EXTENSION_ID); + + if (extension.firstRun) { + // add button here. + } +})</pre> +<p><strong>Both</strong></p> +<pre class="brush: js">function firstRun(extensions) { + let extension = extensions.get(YOUR_EXTENSION_ID); + + if (extension.firstRun) { + // add button here. + } +} + +if (Application.extensions) + firstRun(Application.extensions); +else + Application.getExtensions(firstRun); +</pre> +<p>The FUEL library currently only works on Firefox 3 and above.</p> +<p>{{ PreviousNext("XUL_School/Adding_Menus_and_Submenus", "XUL_School/Adding_events_and_commands") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> diff --git a/files/ru/xul_school/добавление_событий_и_команд/index.html b/files/ru/xul_school/добавление_событий_и_команд/index.html new file mode 100644 index 0000000000..ef43cd2e1c --- /dev/null +++ b/files/ru/xul_school/добавление_событий_и_команд/index.html @@ -0,0 +1,93 @@ +--- +title: Добавление событий и команд +slug: XUL_School/Добавление_событий_и_команд +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/Adding_Events_and_Commands +--- +<p>{{ PreviousNext("XUL_School/Adding_Toolbars_and_Toolbar_Buttons", "XUL_School/The_Box_Model") }}</p> +<h2 id="Event_handlers">Event handlers</h2> +<p>Just like with HTML, most JavaScript code execution is triggered by event handlers attached to DOM elements. The most commonly used event is the <a href="/en/DOM/window.onload" title="en/DOM/window.onload">onload event</a>, which is used in overlays and other windows to detect when the window has loaded and then run initialization code:</p> +<pre class="brush: js">// rest of overlay code goes here. +window.addEventListener( + "load", function() { XulSchoolChrome.BrowserOverlay.init(); }, false); +</pre> +<p>You can do something similar with the <a href="/en/DOM/window.onunload" title="en/DOM/window.onunload">onunload event</a>, to do any cleanup you may need.</p> +<div class="note"> + Please read <a href="/en/XUL_School/Appendix_A:_Add-on_Performance" title="en/XUL School/Appendix A: Add-on Performance">Appendix A</a> for recommendations on how to use the load event to initialize your add-on without having a negative performance impact on Firefox.</div> +<p>Another way to attach event handlers, just like HTML, is to place the handler in the XUL code:</p> +<pre><overlay id="xulschoolhello-browser-overlay" + onload="XulSchoolChrome.BrowserOverlay.init();" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +</pre> +<p>We prefer the first method because it keeps a better separation of content and behavior. Also, note that the <a href="/en/DOM/element.addEventListener" title="en/DOM/element.addEventListener">addEventListener</a> method receives the event name without the "on" prefix, while element attributes do have the prefix. There's a long <a href="/en/XUL/Events" title="en/XUL/Events">list of events</a> you can listen to, and which you use depend on the situation. Elements only implement the events that are relevant to them, but there are several events that are implemented for most elements. These are some notable events you should keep in mind:</p> +<ul> + <li><a href="/en/XUL/Attribute/oncommand" title="en/XUL/Attribute/oncommand">oncommand</a>. This is one of the most important and commonly used events in XUL. It's very useful because it represents the most common action for input controls such as menu items, buttons and checkboxes. For a button, it represents the action of the user clicking on it, or focusing it with the keyboard and then pressing the ENTER key. It's an abstraction of the main way to interact with a control element.</li> + <li><a href="/en/XUL/Attribute/onselect" title="en/XUL/Attribute/onselect">onselect</a>. Fired when the selection in a tree or listbox changes.</li> + <li><a href="/en/XUL/Attribute/onclick" title="en/XUL/Attribute/onclick">onclick</a>. Triggered when the user clicks on the element, including right clicks. You shouldn't normally use this event to trigger actions on input controls such as buttons. Use oncommand instead.</li> + <li><a href="/en/DOM/element.onfocus" title="en/DOM/element.onfocus">onfocus</a> and <a href="/en/DOM/element.onblur" title="en/DOM/element.onblur">onblur</a>. Used when an element receives or loses focus when the user is navigating with the keyboard. You can combine these with <a href="/en/CSS/-moz-user-focus" title="en/CSS/-moz-user-focus">-moz-user-focus</a> to add custom focus behavior to elements that normally wouldn't have it.</li> + <li><a href="/En/DragDrop/Drag_and_Drop" title="en/DragDrop/Drag and Drop">Drag and drop</a>. Drag and drop operations involve several events. Since drag and drop is a complicated thing to manage, there are some high level wrappers that facilitate working with it. Also keep in mind that there are 2 drag and drop APIs, the newest (and preferred) one introduced in Firefox 3.5.</li> +</ul> +<p>Event handlers can take an <em>event</em> argument, which is an <a href="/en/DOM/event" title="en/DOM/event">Event</a> object that holds information on the event. You can get information on key modifiers (in case the user was holding a modifier key like Alt while performing the event), screen coordinates for mouse events, and most importantly, the target element for the event. For example:</p> +<pre><button label="&xulschoolhello.defaultGreeting.label;" + oncommand="XulSchoolChrome.BrowserOverlay.changeGreeting(event);" /> +</pre> +<p>Then on the Javascript code you would have something like this:</p> +<pre class="brush: js">changeGreeting : function(aEvent) { + // more stuff + aEvent.target.setAttribute("label", someNewGreeting); +} +</pre> +<p>The target in this example is the button element, so clicking on it will change its text. The advantage of using the <em>event</em> argument is that the method is not dependent of the specific button, so it can also be used for other elements.</p> +<p>For more advanced event handling, you should read about <a href="/en/XUL_Event_Propagation" title="en/XUL Event Propagation">Event Propagation</a>. In a nutshell, events propagate from the root of the DOM tree all the way down to the target element and then all the way up back to the root, in the capture and bubble phases, respectively. You can capture and cancel events during any of these phases, provided that they aren't canceled before they reach the point where you intended to capture them. The <em>addEventListener</em> method allows you to control the phase where you want to handle an event, with the last argument of the function.</p> +<div class="note"> + In general, you should avoid adding event handlers in the capturing phase, or canceling events. This can lead to unexpected behavior for the user since most events have a default behavior associated to them.</div> +<h3 id="Custom_events">Custom events</h3> +<p>This is a very powerful tool that you should know, even if it isn't that frequently used. The DOM <a href="/en/DOM/document.createEvent" title="en/DOM/document.createEvent">createEvent</a> function allows you to create custom events that you can dispatch and capture.</p> +<p>Custom events serve as a good communication mechanism, specially when dealing with a somewhat common problem: communication between window XUL and web page content. It isn't hard for XUL code to control the content on pages being loaded or displayed, as we will see later on, but it can be hard for your extension XUL code to receive information from pages in a secure manner. This is because it would be very insecure to have a website JS controlling the behavior of Firefox and running JavaScript code with chrome privileges.</p> +<p>Suppose your extension interacts with pages from a website, and you want some actions on this site to trigger actions in your extension. One way to solve this is to have the actions on the site to generate a custom event that can be easily recognized by your extension. You can capture the events in the XUL overlay, since they'll bubble all the way up:</p> +<pre class="brush: js">// in the overlay code. +document.addEventListener( + "XSHelloGreetingEvent", function(aEvent) { /* do stuff*/ }, false); +</pre> +<p>Be careful when doing this! You should at least validate the URL of the page that is generating the custom event, so that you know that it's coming from the right place. You should also avoid this kind of events to trigger actions that could be destructive to the user's data, because a malicious site could try to trigger these events and cause damage. There's a reason for the division between remote content and local chrome, so make sure you respect it.</p> +<p>There's a section further ahead on Intercepting Page Loads which complements this section very well. This should give you a solid foundation to handle interaction between web content and XUL. Additional information on custom events and how they can be used to effect communication between web content and XUL can be found in the <a href="/en/Code_snippets/Interaction_between_privileged_and_non-privileged_pages" title="en/Code snippets/Interaction between +privileged and non-privileged pages">Interaction between privileged and non-privileged pages</a> code snippets, which describe and provide examples of this sort of communication.</p> +<h2 id="Broadcasters">Broadcasters</h2> +<p>Keeping a consistent UI is another important aspect of extension behavior. Maybe your extension needs to disable or enable a series of controls when the user logs in or out of a service, or when Firefox detects it's <a href="/en/Online_and_offline_events" title="en/Online and offline events">online or offline</a>. It's common that you need to change several elements at the same time, and this can be difficult to manage through JavaScript. The <a href="/en/XUL/broadcaster" title="en/XUL/broadcaster">broadcaster</a> element can help you out in these cases.</p> +<p>First you need to add a <em>broadcaster</em> element to your XUL code, as a child of a <a href="/en/XUL/broadcasterset" title="en/XUL/broadcasterset">broadcasterset</a> element.</p> +<pre><broadcasterset id="xulschoolhello-broadcasterset"> + <broadcaster id="xulschoolhello-online-broadcaster" /> +</broadcasterset> +</pre> +<p>These elements are completely invisible, so you can put them anywhere. It is recommended that you have them at the top of the XUL code, along with script declarations and other invisible elements with as <em>popupset</em> and <em>commandset</em>.</p> +<p>Then you need to identify which of your XUL elements will be linked to this broadcaster, using the <a href="/en/XUL/Attribute/observes" title="en/XUL/Attribute/observes">observes attribute</a>:</p> +<pre><menuitem id="xulschoolhello-hello-menu-item" + label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloItem.accesskey;" + <strong>observes="xulschoolhello</strong><strong>-online-broadcaster"</strong> + oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" /> +</pre> +<p>The attribute value is set to be the <em>id</em> of the <em>broadcaster</em> element, indicating that this element will observe all attribute changes that happen in the <em>broadcaster</em>. You can have as many elements as you want observing a <em>broadcaster</em>.</p> +<p>With that set, all you need to do now is set or remove attributes in the <em>broadcaster</em> using JavaScript. All nodes observing it will automatically have those attribute values set or removed as well. You can override pre-existing values, such as the <em>label</em> attribute value in the example.</p> +<pre class="brush: js">let onlineBroadcaster = document.getElementById("xulschoolhello-online-broadcaster"); + +onlineBroadcaster.setAttribute("label", "Something"); +</pre> +<p>You can also have finer-grained control to this behavior by adding the <a href="/en/XUL/observes" title="en/XUL/observes">observes</a> element as a child to your observer node. This allows you to choose which attributes you want it to observe.</p> +<p>Broadcasters allow you to easily maintain consistency among numerous elements without having to add much code. They also save you the trouble of having to know if a given element is present in the DOM or not. For example, if you have a customizable toolbar, you can't be sure if a given button is present or not, so it's easier to use a <em>broadcaster</em>. This way you only need to set values to the broadcaster instead of having to check if the button is there or not.</p> +<h2 id="Commands">Commands</h2> +<p>The <a href="/en/XUL/Attribute/command" title="en/XUL/Attribute/command">command</a> element is a specialized type of <em>broadcaster</em>, meant to be used with the <em>oncommand</em> event. This is the recommended way of centralizing common UI behavior in Firefox and extensions. Commands are heavily used in Firefox, as a quick look into the DOM Inspector should show.</p> +<p>Their behavior is identical as <em>broadcaster</em> elements, but they should be used when <em>oncommand</em> is one of the shared attributes. Our menu example is in fact better suited for a command.</p> +<pre><commandset id="xulschoolhello-commandset"> + <command id="xulschoolhello-hello-command" + oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" /> + <!-- More commands. --> +</commandset> +<!-- More code here... --> +<menuitem id="xulschoolhello-hello-menu-item" + label="&xulschoolhello.hello.label;" + accesskey="&xulschoolhello.helloItem.accesskey;" + command="xulschoolhello-hello-command" /> +</pre> +<p>Commands allow you to keep your JavaScript calls in a single place, avoiding code repetition and possible bugs. Your UI can easily scale this way. You can create an extension that adds toolbar buttons, statusbar buttons and menu items, all with equivalent behavior, and without having to repeat lots of XUL code in the process. Commands and broadcasters also facilitate working with complex form windows and dialogs. You should always keep them in mind when adding the event-driven code for your extension.</p> +<p>{{ PreviousNext("XUL_School/Adding_Toolbars_and_Toolbar_Buttons", "XUL_School/The_Box_Model") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> diff --git a/files/ru/xul_school/коробочная_модель/index.html b/files/ru/xul_school/коробочная_модель/index.html new file mode 100644 index 0000000000..d822bd9317 --- /dev/null +++ b/files/ru/xul_school/коробочная_модель/index.html @@ -0,0 +1,124 @@ +--- +title: Коробочная модель +slug: XUL_School/Коробочная_модель +translation_of: Archive/Add-ons/Overlay_Extensions/XUL_School/The_Box_Model +--- +<p>{{ PreviousNext("XUL_School/Adding_events_and_commands", "XUL_School/Adding_windows_and_dialogs") }}</p> +<p>In order to master XUL, you'll need to have a fairly good understanding of its <a href="/en/XUL_Tutorial/The_Box_Model" title="en/XUL Tutorial/The Box Model">Box Model</a>. This is the system that determines how all elements are laid out visually in a XUL document. It is important to know how it works in order to make interfaces that are easy to localize, skin and use in different types of operating systems, screen sizes and resolutions.</p> +<p>The XUL box model is a significant improvement over the HTML layout model, which is mostly vertical. With XUL you can define vertically oriented as well as horizontally oriented interfaces, providing greater flexibility in interface design.</p> +<p>Any XUL interface can be broken down into the following basic components:</p> +<ul> + <li>Boxes</li> + <li>Text</li> + <li>Images</li> + <li>Alignment and flexibility</li> + <li>Widths and heights</li> + <li>Margins and paddings</li> +</ul> +<p>Menus, toolbar buttons, and even the most complex elements in XUL are composed of these simple ingredients. Complex elements are created from simpler ones through XBL, which will be covered later on. Once you grasp this simple idea, you'll be able to use the DOM Inspector and CSS to mold XUL elements and layouts with great precision and flexibility.</p> +<p>Most of the examples shown in the rest of this section were generated using the <a href="/samples/xultu/examples/aligner.xul" title="samples/xultu/examples/aligner.xul">XUL Box Alignment Example</a>. We recommend you play around with it for a while to get an idea of how the basic parts of the box model work. In order to use this page, you'll need to install the <a class="link-https" href="https://addons.mozilla.org/firefox/addon/remote-xul-manager/" title="https://addons.mozilla.org/firefox/addon/remote-xul-manager/">Remote XUL Manager</a> extension and add developer.mozilla.org to the whitelist.</p> +<h2 id="Boxes">Boxes</h2> +<p>A XUL box is very similar to an HTML <em>div</em>. It's an invisible rectangular container with no styling at all (<em>divs</em> may have some default styling, though). Their behavior is similar. However, one of the fundamental differences between XUL and HTML has been the fact that XUL boxes can be oriented vertically or horizontally (this behavior is being introduced into HTML standards).</p> +<p>There are 3 basic box elements in XUL: <a href="/en/XUL/hbox" title="en/XUL/hbox">hbox</a>, <a href="/en/XUL/vbox" title="en/XUL/vbox">vbox</a> and <a href="/en/XUL/box" title="en/XUL/box">box</a>. An <em>hbox</em> is oriented horizontally by default, meaning that its child nodes are displayed next to each other from left to right. A <em>vbox</em> is oriented vertically by default, its child nodes displayed one below the other from top to bottom. A <em>box</em> is a generic version that you can orient as you please, but its default is horizontal orientation, so it's pretty much equivalent to an <em>hbox</em> and it is seldom used.</p> +<p>Here's a very simple example of an <em>hbox</em> with 3 child buttons:</p> +<pre><hbox> + <button label="Cat" /> + <button label="Parrot" /> + <button label="Porcupine" /> +</hbox> +</pre> +<p>This is how it looks on Mac OS (the black border was added for illustrative purposes, boxes don't have borders by default):</p> +<p><img alt="" class="internal" src="/@api/deki/files/4199/=box1.png" style="width: 303px; height: 64px;"></p> +<p>If you use a <em>vbox</em> instead, it looks like this:</p> +<p><img alt="" class="internal" src="/@api/deki/files/4200/=box2.png" style="width: 121px; height: 132px;"></p> +<p>The orientation of boxes (and most XUL elements) can be controlled using the <a href="/en/XUL/Attribute/orient" title="en/XUL/Attribute/orient">orient</a> attribute or the <a href="/en/CSS/box-orient" title="en/CSS/-moz-box-orient">-moz-box-orient</a> CSS property. With these you can make an <em>hbox</em> have vertical orientation and viceversa, although that isn't very useful. The CSS property may be useful on some occasions, but using the orient attribute is not recommended because it mixes content and presentation.</p> +<h2 id="Flexibility"> Flexibility</h2> +<p>An HTML <em>div</em> is as big as its contents unless you override its dimensions using CSS. This is similarly the case for XUL, except there are two flexibility directions to consider. An <em>hbox</em> is as big as its contents horizontally, but it will occupy all the available space vertically. You can make an <em>hbox</em> flexible horizontally with the CSS property <a href="/en/CSS/box-flex" title="en/CSS/-moz-box-flex">-moz-box-flex</a> or the <a href="/en/XUL/Attribute/flex" title="en/XUL/Attribute/flex">flex</a> attribute. The same applies to a <em>vbox</em>, but in the other direction.</p> +<p>Unlike most style attributes, the <em>flex</em> attribute is considered acceptable to use in XUL code. This is because this attribute is used much too often, and it would require a great deal of CSS code to avoid using it. At any rate, it can always be overriden using CSS, so your extension won't lose skinability because of it.</p> +<p>Flexibility is defined as a numeric value. The default value for most elements is 0, which means that the element will not stretch in the direction of its orientation, and its size in that dimension will be determined by its contents and padding. If you want an element to be flexible, you should set its flexibility to 1. This makes the element stretch to occupy as much available space there is in the direction of its orientation. If we add flexibility to the hbox in our first example, we get the following result:</p> +<p><img alt="" class="internal" src="/@api/deki/files/4201/=hboxflex.png" style="width: 585px; height: 64px;"></p> +<p>The box flexes to cover the available horizontal space. The buttons maintain their size.</p> +<p>If we also add flexibility to the "Cat" button, this is what we get:</p> +<p><img alt="" class="internal" src="/@api/deki/files/4202/=catflex.png" style="width: 585px; height: 64px;"></p> +<p>Now the flexible button is taking the available inner space, moving the other two buttons all the way to the end of the box.</p> +<p>What would happen if we also add flexibility to the "Parrot" button?</p> +<p><img alt="" class="internal" src="/@api/deki/files/4203/=catparrotflex.png" style="width: 585px; height: 64px;"></p> +<p>Since both buttons have a flexibility of 1, the available space is distributed evenly among the two. Note that this is not always the case. If one of the buttons has a very long label that restricts its minimum size, then it could be the label determining its size, while the other button would flex taking the rest of the room.</p> +<p>Now, if you want a different size distribution in flexible elements, you can use flexibility values higher than 1.</p> +<p><img alt="" class="internal" src="/@api/deki/files/4204/=morecatflex.png" style="width: 585px; height: 64px;"></p> +<p>In this case, the "Cat" button has a <em>flex</em> value of 3, while the "Parrot" button still has a <em>flex</em> value of 1. The "Cat" button is now larger in a 3 to 1 proportion. Note that, again, this can depend on the contents of the elements, in this case, the labels and paddings in the buttons. If the label of the "Parrot" button was something much longer, the size ratio would not be kept.</p> +<p>You can have even more control over the size of flexible elements using the <a href="/en/XUL/Attribute/minwidth" title="en/XUL/Attribute/minwidth">minwidth</a>, <a href="/en/XUL/Attribute/maxwidth" title="en/XUL/Attribute/maxwidth">maxwidth</a>, <a href="/en/XUL/Attribute/minheight" title="en/XUL/Attribute/minHeight">minheight</a> and <a href="/en/XUL/Attribute/maxheight" title="en/XUL/Attribute/maxheight">maxheight</a> attributes, or their CSS counterparts: <a href="/en/CSS/min-width" title="en/CSS/min-width">min-width</a>, <a href="/en/CSS/max-width" title="en/CSS/max-width">max-width</a>, <a href="/en/CSS/min-height" title="en/CSS/min-height">min-height</a> and <a href="/en/CSS/max-height" title="en/CSS/max-height">max-height</a>. The latter are recommended to keep style code in the skin section of the chrome. As their names should make clear, you can control the flexibility boundaries of elements, thus preventing them from growing or shrinking too much.</p> +<div class="panel" style="border-width: 1px;"> + <div class="panelContent"> + <div class="note"> + All CSS properties involving lengths should be handled with caution. We recommended that you use proportional units (em, %) instead of absolute units (px) whenever possible. Using the former allows the UI to scale proportionately depending on font size settings, which are often changed by users with accessibility limitations. A common exception to this rule is when your CSS is directly related to images, where you'll usually handle measurements in pixels (px).</div> + </div> +</div> +<p>Also, just like in HTML, you can control the dimensions of inflexible elements using the <a href="/en/CSS/width" title="en/CSS/width">width</a> and <a href="/en/CSS/height" title="en/CSS/height">height</a> CSS properties and attributes. These attributes won't have any effect on flexible elements.</p> +<h3 id="Margins_paddings_and_spacers">Margins, paddings and spacers</h3> +<p>Margins and paddings are frequently used in both HTML and XUL to define spacing between elements and inside of elements. The <a href="/en/CSS/margin" title="en/CSS/margin">margin</a> determines the space between an element and the elements surrounding it, while the <a href="/en/CSS/padding" title="en/CSS/padding">padding</a> determines the space between the borders of a container element and its child nodes, kind of like an inner margin.</p> +<p>Sometimes you also need to define flexible spaces between elements. In this case you should use a <a href="/en/XUL/spacer" title="en/XUL/spacer">spacer</a> element with a <em>flex</em> value. A <em>spacer</em> element is completely invisible and doesn't do more than take space. You should only use it when you need flexible space. If you need fix-sized space it's best to use margins and paddings and avoid adding unnecessary nodes to your XUL document.</p> +<h2 id="Alignment">Alignment</h2> +<p>XUL, unlike HTML, provides an easy way to align elements both horizontally and vertically. You can either use the <a href="/en/XUL/Attribute/align" title="en/XUL/Attribute/align">align</a> and <a href="/en/XUL/Attribute/pack" title="en/XUL/Attribute/pack">pack</a> attributes, or the <a href="/en/CSS/box-align" title="en/CSS/-moz-box-align">-moz-box-align</a> and <a href="/en/CSS/box-pack" title="en/CSS/-moz-box-pack">-moz-box-pack</a> CSS properties. Packing determines the positioning of the child elements in the direction of the container's orientation. Alignment determines the positioning in the other direction. So, in a flexed <em>hbox</em>, having <em>center</em> alignment and <em>end</em> packing results in this:</p> +<p><img alt="" class="internal" src="/@api/deki/files/4205/=alignment.png" style="width: 427px; height: 204px;"></p> +<p>One important thing to notice is that aligment and flexibility can't be mixed in some cases. If you add flexibility to one of the buttons, the packing will no longer be useful, but the alignment still makes a difference. It also wouldn't make sense to use flexibility or packing in the <em>hbox</em> if it didn't have any available horizontal space; the container element needs to either be flexible itself, or have a fixed width larger than its contents.</p> +<h2 id="Text">Text</h2> +<p>There are 2 XUL elements that are typically used for displaying text: <a href="/en/XUL/label" title="en/XUL/label">label</a> and <a href="/en/XUL/description" title="en/XUL/description">description</a>. Their behavior is nearly identical, but they are meant to be used in different situations.</p> +<p>The <em>label</em> element should be used mainly for text in XUL forms, such as the ones you see in the Firefox Options / Preferences window. Here's a typical usage of the <em>label</em> element:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><label control=<span class="code-quote">"xulschoolhello-greeting-textbox"</span> + value=<span class="code-quote">"&</span><span class="code-quote">xulschoolhello</span><span class="code-quote">.typeGreeting.label;"</span> /> +<textbox id=<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">-greeting-textbox"</span> /></pre> + </div> +</div> +<p>The label says something like "Type a greeting message", and the textbox next to it allows the user to type the message. The <a href="/en/XUL/Attribute/control" title="en/XUL/Attribute/control">control</a> attribute links the label to the textbox. If the user clicks on the label, the textbox will be focused. Also, if the user has a screen reader, the label will be read when the focus is placed on the textbox.</p> +<p>The <em>description</em> element is used for the rest of the cases, where the text is only meant as additional information and is not related to input elements.</p> +<p>Handling text in XUL may seem simple, but it's actually quite a tricky subject. You always have to keep in mind that localized strings may be significantly longer in other languages, specially much longer than English strings. You should avoid using long blocks text, and also avoid designing your UI so that everything fits just right around text. You should always keep in mind that the text can be much longer, and your UI should adapt to it.</p> +<p>Labels should generally be short, and they should always be displayed in a single line. Descriptions may be longer, and in general you should plan it so that they can wrap into multiple lines. In order to have wrapping descriptions, you need to set the text as a child node instead of using the <em>value</em> attribute:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><description>&<span class="code-quote">xulschoolhello</span>.description.label;</description></pre> + </div> +</div> +<p>Even then, the text will extend as much as it can in a single line, so you need to add some CSS limits in order to make it wrap inside a XUL dialog or window. You can use the CSS property <em>width</em> to restrict the width of the <em>description</em> so that it wraps as you need it to.</p> +<div class="panel" style="border-width: 1px;"> + <div class="panelContent"> + <div class="note"> + Never cut text lines into separate locale strings in order to bypass wrapping difficulties. This makes localization much harder, or even impossible in some cases.</div> + </div> +</div> +<p>There are other more complicated text wrapping cases where a <em>description</em> won't be good enough. For instance, <a href="/en/XUL_Tutorial/Templates" title="en/XUL Tutorial/Templates">templates</a> don't allow you to set the internal text in a <em>description</em> element in a way that it wraps properly. One way to work around this is using a <a href="/en/XUL/textbox" title="en/XUL/textbox">textbox</a> element instead. <a class="external" href="http://xulsolutions.blogspot.com/2006/07/how-to-handle-text-and-keep-your.html">This blog post</a> is a good guide on the subject, and you should keep it in mind if you need to do some advanced text handling.</p> +<p>Another way to handle excessive text length is to use the <a href="/en/XUL/Attribute/crop" title="en/XUL/Attribute/crop">crop</a> attribute. If the line of text is longer than its container will allow, the text will be cut, showing "..." in the place where it was cut. You can choose where to cut the text, but cropping at the end is the most common practice. Similarly as with wrapping, cropping will only occur is there is no room for the text to grow, so you'll need to restrict the width using CSS.</p> +<h3 id="Text_links">Text links</h3> +<p>XUL makes it very easy for you to create a <em>label</em> that is also a link. All you need is to set the <a href="/en/XUL/Style/text-link" title="en/XUL/Style/text-link">text-link</a> class to the label, and add an <em>onclick</em> handler (<em>oncommand</em> won't work for this). The label is displayed with the expected link style so that users can easily recognize it as a link.</p> +<p>A trickier case is when you need only part of a label to be clickable, just like in HTML. Since labels can't handle rich text, workarounds have to implemented using Javascript. One possibility is to use special markup in a locale property so that the link can be easily recognized:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><span class="code-quote">xulschoolhello</span>.linkedText.label = Go to <a>our site</a> <span class="code-keyword">for</span> more information</pre> + </div> +</div> +<p>The syntax is similar to HTML because it's easier to read this way, but string bundles won't do anything special with it. You'll have to break the string using <a href="/en/JavaScript/Reference/Global_Objects/RegExp" title="en/Core JavaScript 1.5 Reference/Global Objects/RegExp">regular expressions</a> and generate 3 different labels, one with the <em>text-link</em> class. You'll also need to do some CSS work on the labels so that the inner spacing in the text looks right.</p> +<p>Another option is to take it up a notch and really use HTML.</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><span class="code-quote">xulschoolhello</span>.linkedText.label = Go to <html:a onclick=<span class="code-quote">"%S"</span>>our site</html:a> <span class="code-keyword">for</span> more information</pre> + </div> +</div> +<p>To include HTML in a XUL document, you need to add the namespace for it in the document root:</p> +<div class="code panel" style="border-width: 1px;"> + <div class="codeContent panelContent"> + <pre class="code-java"><overlay id=<span class="code-quote">"</span><span class="code-quote">xulschoolhello</span><span class="code-quote">-browser-overlay"</span> + xmlns=<span class="code-quote">"http:<span class="code-comment">//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</span> + xmlns:html=<span class="code-quote">"http://www.w3.org/1999/xhtml"</span>></span></pre> + </div> +</div> +<p>Then you can have an <em>html:p</em> (paragraph) element where you insert the result of parsing the property string. You can easily parse XML using the <a href="/en/DOM/DOMParser" title="en/DOMParser">DOMParser</a> object.</p> +<div class="note"> + Since XUL documents are strict XML, you can only use strict XHTML in XUL, and not the more loosely-formatted forms of HTML.</div> +<h2 id="Exercise">Exercise</h2> +<p>Use the DOM Inspector extension to look into the Firefox chrome. Select toolbar buttons, menu items, textboxes, etc. and look into the Box Model, CSS Style Rules and Computed Style views. Look into the computed width and height values, and how the paddings and margins affect the dimensions of XUL nodes.</p> +<p>Modify the Hello World extension so that it changes the appearance of Firefox drastically using only CSS. Play with changing the dimensions and appearance of buttons, changing the background color of the toolbars and status bars, font styles, sizes, etc. Note that this is not really what you would expect from an extension, it's more like a theme. However, it's very interesting and useful to see how you can manipulate the appearance of Firefox so easily.</p> +<p>If you're not familiar with CSS, you should read this <a href="/en/CSS/Getting_Started" title="en/CSS/Getting Started">CSS Getting Started Guide</a> and other online resources before continuing with this tutorial.</p> +<p>{{ PreviousNext("XUL_School/Adding_events_and_commands", "XUL_School/Adding_windows_and_dialogs") }}</p> +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast.</span></p> diff --git a/files/ru/xul_school/настройка_среды_разработки/index.html b/files/ru/xul_school/настройка_среды_разработки/index.html new file mode 100644 index 0000000000..efe52c1c1b --- /dev/null +++ b/files/ru/xul_school/настройка_среды_разработки/index.html @@ -0,0 +1,237 @@ +--- +title: Настройка среды разработки +slug: XUL_School/Настройка_среды_разработки +translation_of: >- + Archive/Add-ons/Overlay_Extensions/XUL_School/Setting_Up_a_Development_Environment +--- +<p>{{ PreviousNext("XUL_School/The_Essentials_of_an_Extension", "XUL_School/Adding_menus_and_submenus") }}</p> + +<h2 id="Выбираем_правильные_инструменты">Выбираем правильные инструменты</h2> + +<p>Есть три основных инструмента, которые на наш взгляд необходимы для эффективной разработки дополнения: редактор исходного кода, сиcтема управления версиями и система сборки.</p> + +<p>Что касается редактирования кода, официальной интегрированной среды разработки от компании Mozilla нет. С другой стороны, расширения используют те же (или похожие) языки, используемые для веб-разработки, поэтому для этой задачи подойдут большинство текстовых редакторов или интегрированных сред разработки. Большинство XUL-инструментов и плагинов, которые вы найдете в сети Интернет, являются простыми шаблонами, которые создают структуру папок проекта, и это не очень помогает.</p> + +<p>Мы рекомендуем текстовый редактор <a class="external" href="http://www.activestate.com/komodo_edit/" title="http://www.activestate.com/komodo_edit/">Komodo Edit</a>. Он бесплатный, с открытым исходным кодом и кроссплатформенный. Он основан на платформе Mozilla XULRunner, поэтому поддерживает некоторые особенности при разработке расширений Firefox. Komodo Edit поддерживает автодополнение тегов и аттрибутов XUL, расширение <a href="/en-US/docs/Web/CSS/Mozilla_Extensions" title="en/Mozilla CSS Extensions">Mozilla's CSS extensions</a> (CSS значения и свойства, начинающиеся на "-moz"). У редактора есть система дополнений, схожая с той, что используется в браузере Firefox, и есть несколько Komodo расширений, которые предоставляют дополнительную помощь в разработке. Это приложение предоставляет больше возможностей, по сравнении с множеством других редакторов, поэтому мы рекомендуем вам попровать его. Все наши примеры исходных кодов разрабатываются на Komodo Edit, поэтому если в скачанных файлах с примерами вы увидете расширения <em>.kpf</em> или <em>.komodoproject</em> , то знайте, что это файлы проекта Komodo.</p> + +<p>Что касается системы управления версиями, мы рекомендует лишь чтобы она у вас была. Самая распространенная система - это GitHub, но подойдет и любая другая.</p> + +<p>Для упаковки XPI-файлов мы используем утилиту <a class="external" href="http://www.gnu.org/software/make/">make</a>. Мы выбрали этот способ, потому что он используется компанией Mozilla для сборки Firefox, и доступен для большинства операционных систем. Утилита <em>make</em> - это стандартный инструмент для Unix-совместимых операционных систем. Она может быть установлена на Mac OS X в составе пакета программ XCode Tools и на Windows с пакетом программ <a class="external" href="http://www.cygwin.com/">cygwin</a>. При установке <em>cygwin</em> у вас будет возможность явно выбрать утилиты <em>make</em> и <em>zip</em> из длинного списка для скачивания и установки.</p> + +<p>Также убедитесь в том, что утилита <em>make</em> корректно прописалась в системную директорию для запуска. Для этого после ее установки выполните команду "make -ver" в командной строке, и если все сделано правильно - на экран будет выведена версия утилиты <em>make</em>.</p> + +<p>Мы рекомендуем установить утилиту <em>make</em> в вашей операционной системе, поскольку все наши примеры предоставляются со всеми необходимыми файлами для сборки и установки получившегося XPI-файла используя этот инструмент. Это сбережет вам время при упаковке. Или вы можете создать свою собственную систему, используя бат-файл, утилиту Ant или любую другую в зависимости от ваших предпочтений. В конечном счете, вы можете просто сжимать содержимое папки <em>src</em> используя любой zip-архиватор или любой другой, и получить аналогичный результат.</p> + +<h2 id="Build_system">Build system</h2> + +<p>Let's start by downloading the project used to build the second version of Hello World, from the exercise in the last section.</p> + +<p><a href="/@api/deki/files/5142/=HelloWorld2.zip" title="https://developer.mozilla.org/@api/deki/files/5142/=HelloWorld2.zip">Hello World 2 Project</a>.</p> + +<p>Unzip the file anywhere you want. Inside the <em>HelloWorld2</em> directory, you'll see two directories: <em>bin</em> and <em>src</em>. The <em>bin</em> directory should be empty. This is where all the resulting build files will be created, and where you'll find the extension XPI file once you get it to build.</p> + +<p>Open the project file (<em>HelloWorld2.komodoproject</em>) from the <em>src</em> directory in Komodo Edit. In the Projects tab you should be able to see the directory structure inside the <em>src</em> directory. This structure should be familiar, as it is almost identical to the unpacked XPI from the previous section.</p> + +<p>The only notable additions is a file named <em>Makefile</em> under <em>src</em>. This is the file that <em>make</em> uses to build the XPI. You should take some time to read it and understand it, or at least identify the parts that you should change to get a project of your own going. This <a class="external" href="http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_toc.html">GNU Make Manual</a> is a very good reference to get to know <em>make</em> and Makefiles.</p> + +<p>In most cases you'll only need to change the first lines in <em>Makefile</em>. These define the extension name, the extension id (as specified in <em>install.rdf</em>) and the name of the profile directory where the extension will be installed during development and testing. More about this further ahead.</p> + +<p>Let's try and build the XPI from the command line first. Open the command line program in your system and navigate to the <em>src</em> directory in your project. Run the following command:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">make</pre> +</div> +</div> + +<p>That's it. If everything went well, you should see an output similar to this:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">Creating XPI file. + adding: install.rdf (deflated 50%) + adding: chrome.manifest (deflated 50%) + adding: content/browserOverlay.js (deflated 42%) + adding: content/browserOverlay.xul (deflated 69%) + adding: skin/browserOverlay.css (stored 0%) + adding: locale/en-US/browserOverlay.dtd (deflated 52%) + adding: locale/en-US/browserOverlay.properties (stored 0%) +Creating XPI file. Done! + +Build finished successfully. +</pre> +</div> +</div> + +<p>If you inspect the <em>bin</em> directory, you should see the <em>xulschoolhello2.xpi</em> file.</p> + +<p>If you run <em>make</em> again, you'll only see the last line of the build process. That is because <em>make</em> can tell that the file in the <em>bin</em> directory is up to date, and nothing needs to be done. Making changes on source files will make <em>make</em> run the necessary steps to build the XPI again.</p> + +<p>You can clean up the <em>bin</em> directory by just running the following command (again, from the <em>src</em> directory):</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">make clean</pre> +</div> +</div> + +<p>You can also run these commands from Komodo. Click on Tools > Run Command.... In the "Run" textbox you should type this:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">bash -c <span class="code-quote">"make"</span></pre> +</div> +</div> + +<p>Or replace "make" with "make clean" for the clean command. The "bash -c" part forces Komodo to use <em>bash</em>, which for some reason can't be set properly as the default command shell. It isn't necessary to add this, but it's better so that it is consistent with the <em>make</em> command we'll see next.</p> + +<p>In the "Start in" textbox you should choose <em>%p </em>(directory path of active project). If you don't see this textbox, click on the "More" button. You also have the option to save the command, by clicking on the "Add to Toolbox" checkbox. To see the Toolbox, click on View > Tabs > Toolbox, from the main menu. With that, you should now have a very easy way to build your XPI, by just double clicking on the created commands.</p> + +<p>We can make it even better. Once you're testing and debugging your code, you'll find that constantly building and installing an XPI can be very tedious. This is the reason why we introduced "make install". This only works if your extension is already installed in a Firefox profile. Just like in the provided project, you need the add-on id and profile location set in the file <em>Makefile</em>. We use this information to locate the installation path of the extension and overwrite the installed files. If Firefox is open at the time you run "make install", you'll have to restart it in order to see the changes. It's still better than installing the XPI all over again.</p> + +<p>In order to set the profile location to the right value, you should read the <a class="external" href="http://support.mozilla.com/en-US/kb/Profiles">support article on profiles</a>, at the Mozilla Support site. We'll also delve deeper in this topic later on in this section.</p> + +<p>To make "make install" work on non-Windows systems, you need an extra step. The install process requires using an environment variable called <em>OSTYPE</em>, which is not exported. Long story short, if you want to run it from a command line, you need to run:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">export OSTYPE; make install</pre> +</div> +</div> + +<p>And in the command in Komodo, you should enter the following:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">bash -c <span class="code-quote">"export OSTYPE; make install"</span></pre> +</div> +</div> + +<p>The <em>export</em> command won't work correctly unless you use "bash -c".</p> + +<div class="note">The file <em>Makefile</em> specifies which profile folder the add-on will be reinstalled to. This is set in the <em>profile_dir</em> variable (set to "xulschool-dev" in this case). When creating a development profile for your add-on, make sure you choose an easy name for the profile folder, and set it in your <em>Makefile</em> in order to take advantage of the install command.</div> + +<h3 id="Building_IDL_files">Building IDL files</h3> + +<p>Some extensions require developing XPCOM components to add certain advanced functions. There's a section dedicated to XPCOM in this tutorial, but we'll briefly discuss the impact it has on building the extension. You can skip this section and keep it present as a reference in case you do need to use XPCOM in your project.</p> + +<p>XPCOM interfaces are defined using IDL files. These are text files that define the attributes and methods in one or more interfaces. These IDL files are compiled into binary form and included in the extension as XPT files.</p> + +<p>To compile an IDL file to XPT, you need a command line tool called <em>xpidl</em>. This tool is included in the Mozilla <a href="/en/Gecko_SDK" title="en/Gecko SDK">Gecko SDK</a>. If you need to compile IDLs, go to the SDK page and download a compiled version for your system. Also note any prerequisites you may need. If your system is not listed in the supported builds, you'll have to build the SDK yourself from the Mozilla source. Good luck with that.</p> + +<p>You should also set up your environment so that <em>xpidl.exe</em> (or just <em>xpidl</em> on other systems) is in the default executable path, and also add a variable called GECKO_SDK, that points to your SDK build:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">export GECKO_SDK=/path/to/your/sdk</pre> +</div> +</div> + +<p>Our build system should pick it up from there. To make it work in Komodo in Unix-based systems, we add the command to the <em>.bash_login</em> file in the home directory, and we modify the commands to this:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">bash -c <span class="code-quote">". ~/.bash_login; make"</span></pre> +</div> +</div> + +<p>An example project with XPCOM components is included in the XPCOM section. There is also a mention about building C++ XPCOM, which is something much more complicated.</p> + +<h3 id="Signing_extensions">Signing extensions</h3> + +<p>In order to provide additional security for your users, you can choose to <a href="/en/Signing_an_extension" title="en/Signing an extension">add a signature to your extension</a>. The signature verifies that you are the author of this extension, and it can only be done if you have a valid certificate provided by a trusted Certificate Authority.</p> + +<p>The only noticeable difference for the user is that the XPI installation dialog will say that the extension was created by you, making the dialog a little easier to trust. It's not common to sign extensions because most users will trust the official add-ons site (<a class="link-https" href="https://addons.mozilla.org" title="https://addons.mozilla.org">AMO</a>) rather than rely on extension signatures. On the other hand, it is standard practice for big companies to sign their extensions.</p> + +<p>You'll need to download some libraries in order to be able to sign your extension. Follow the <a href="/en/Signing_an_extension" title="en/Signing an extension"><span class="external">instructions</span></a>, and add something like the following to your Makefile:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java"># The directory where the signature sources are located. +signature_dir := signature + +# The signing key /certificate file. +signature_extra_files := $(build_dir)/META-INF/manifest.mf \ + $(build_dir)/META-INF/zigbert.sf +# The signing key /certificate file. +signature_rsa_file = $(build_dir)/META-INF/zigbert.rsa# The signing key /certificate file. +signature_files := $(signature_extra_files) \ + $(signature_rsa_file) + +$(signature_files): $(build_dir) $(xpi_built) + @signtool -d $(signature_dir) -k $(cert_name) \ + -p $(cert_password) $(build_dir)</pre> +</div> +</div> + +<p>Keep in mind that your password should not be in your Makefiles, and you must be very careful with the certificate information. Ideally this should be handled by a single person, and only done near the end of the release process. You should also have a different <em>make</em> command, such as <em>make signed</em> in order to distinguish the signed and unsigned development builds.</p> + +<h2 id="Firefox_profile_management">Firefox profile management</h2> + +<p>It is good development practice to keep your test environment separate from everything else. You don't want unstable extensions to break your everyday Firefox profile, risking data loss. It's much better to have a different "version" of Firefox for testing. This is what Firefox profiles are for.</p> + +<p>You can learn about setting up multiple Firefox profiles in the Mozilla Support article <a class="external" href="http://support.mozilla.com/en-US/kb/Managing+profiles">Managing Profiles</a>. You can have as many profiles as you like. You can also mix them with multiple Firefox installations. For instance, you may want to test your extension in Firefox 3.5 and Firefox 3.6, or test it in a localized version of Firefox. You can install as many Firefox versions as you want, and mix profiles and versions.</p> + +<p>On Windows and Linux it's easy to create shortcuts for every profile you create, using the commands mentioned in the support article.</p> + +<p>For Mac OS X developers, there is also a way to set up "shortcuts". You can do this by opening the Automator application, choosing Run Shell Script and then entering the profile-loading script in the textbox:</p> + +<div class="code panel" style="border-width: 1px;"> +<div class="codeContent panelContent"> +<pre class="code-java">/Applications/Firefox.app/Contents/MacOS/firefox-bin -no-remote -p MyProfile > /dev/<span class="code-keyword">null</span> &</pre> +</div> +</div> + +<p>You can change "/dev/null" to a file location, in case you want to see <em>dump</em> output from Firefox, or other extensions. The last <em>&</em> prevents Automator from waiting for your Firefox session to finish. Save this as an Application, not a Workflow. And you probably want to have these on your Desktop or Dock, for easy access.</p> + +<p>There are also some configuration changes you should make in your testing profiles, so that you get detailed error information in case something fails. The Firefox <a href="/en/Error_Console" title="en/Error Console">Error Console</a> (Tools > Error Console) normally displays JavaScript errors that occur on web pages, but with some tweaking you can get error information from your extension. Read this piece on <a href="/en/Setting_up_extension_development_environment#Development_preferences" title="en/Setting up extension development environment#Development preferences"><span class="external">Development preferences</span></a>.</p> + +<h2 id="Developer_extensions">Developer extensions</h2> + +<p>There's a wide variety of Firefox extensions that aid web development and add-on development. A good place to look for them is the <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/browse/type:1/cat:4">Mozilla Add-ons site</a>, and there's also a good <a href="/en/Setting_up_extension_development_environment#Development_extensions" title="en/Setting up extension development environment#Development extensions"><span class="external">development extension list</span></a> here. You should also take some time to play around with the Web Developer tools that are included in Firefox. Some of them can be very useful for add-on development and overlap with the add-ons listed. In this section we'll cover a few that we have found to be very useful.</p> + +<h3 id="DOM_Inspector">DOM Inspector</h3> + +<p>The <a href="/en/DOM_Inspector" title="en/DOM Inspector"><span class="external">DOM Inspector</span></a> used to be part of Firefox as an installer option, but since Firefox 3 it has been separated as another add-on you can add and remove. It's a very useful inspection tool that lets you look into the DOM of HTML and XUL documents, as well as applied CSS rules and associated JavaScript objects. <a href="/en/DOM_Inspector/Introduction_to_DOM_Inspector" title="en/Introduction to DOM Inspector">Introduction to DOM Inspector</a> is a good guide on how to get started using it.</p> + +<p>The DOM inspector is particularly useful in finding out how to overlay a window, and how to replace default CSS style rules. You can see the names of the files involved, which gives you a good starting point when looking into the <a class="external" href="http://mxr.mozilla.org/">Mozilla source</a>. You can even change styles, attributes and execute Javascript code in it, although that's not completely reliable.</p> + +<h3 id="JavaScript_Debugger">JavaScript Debugger</h3> + +<p>The name says it all. The <a href="/en/Venkman" title="en/Venkman">Venkman JavaScript Debugger</a> is a great way to trace execution of your JavaScript code.</p> + +<p>To debug extension and browser code, right-click on the Loaded Scripts panel and uncheck Exclude Browser Files. The list of loaded scripts will grow long to include all of the scripts in Firefox. Having our file naming conventions prove very useful in this case. You can set breakpoints, step in and out of methods, and even get profiling information from Javascript execution. You can inspect variables, keep track of watch expressions, and evaluate arbitrary JS at any point in execution.</p> + +<p>This extension has seen little maintenance in quite some time, so it is very buggy. It is specially unreliable when debugging code in Javascript XPCOM and XBL files. Nevertheless, it is a valuable tool when trying to figure out why a certain function is misbehaving.</p> + +<h3 id="Tamper_Data">Tamper Data</h3> + +<p><a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/966" title="https://addons.mozilla.org/en-US/firefox/addon/966">Tamper Data</a> intercepts HTTP requests and their responses. It allows you to cancel them and even replace payload data before it is sent. There are several similar extensions, such as <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/3829">Live HTTP Headers</a>, but Tamper Data is the one that we use the most. We'll cover more on HTTP debugging later on.</p> + +<h3 id="Firebug">Firebug</h3> + +<p>The <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/1843" title="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> extension includes pretty much all tools mentioned so far, but it's mostly focused on web development. The <a class="external" href="http://getfirebug.com/wiki/index.php/Chromebug_User_Guide" title="http://getfirebug.com/wiki/index.php/Chromebug_User_Guide">Chromebug</a> extension helps in making Firebug more useful for extension development, but it may still not be powerful enough to replace all of the previously mentioned add-ons.</p> + +<p>On the other hand, Firebug has a very friendly, integrated user interface, and sees much more development that its counterparts. It's definitely worth a try.</p> + +<h3 id="Leak_Monitor">Leak Monitor</h3> + +<p>Memory leaks have always been a big criticism drawn against Firefox. Mozilla has proven with time that they take memory usage seriously, improving performance on several critical areas and removing all kinds of memory leaks.</p> + +<p>However, extensions are also capable of causing memory leaks. If you want your extension to be included in the Mozilla Add-ons site, you better not have any memory leaks. <a href="/en/Using_XPCOM_in_JavaScript_without_leaking" title="en/Using XPCOM in JavaScript without leaking"><span class="external">Using XPCOM in JavaScript</span></a> has some guidelines you should follow to avoid them. One of the most common errors developers make is to register a JS event listener or observer, and never removing it. The simple practice of always including removal code for everything you add makes a big difference.</p> + +<p>To make sure your extension doesn't leak, you should use the <a href="/en/Leak_Monitor" title="en/Leak Monitor"><span class="external">Leak Monitor extension</span></a> when testing it. Always test opening and closing windows. Leaks usually surface when doing this.</p> + +<h2 id="Exercise">Exercise</h2> + +<ul> + <li>Set up a new Firefox profile for XUL School. Make sure you can open and close your XUL School Firefox without having to close the instance of Firefox you use to browse normally (you <em>use</em> Firefox, don't you?). Make any modifications you want to the XUL School project, and use <em>make</em> and <em>make install</em> to see the extension work with your changes.</li> + <li>Install DOM Inspector. Use it to locate the menu you created. Inspect the CSS rules Firefox applies to it by default. Look at the final, computed style for the menu items. Browse around the rest of the Firefox DOM, and try to figure out what the nodes correspond to in the Firefox UI.</li> + <li>Install the Tamper Data extension. Open the Tamper Data window and go to a AJAX-heavy page such as Gmail or Facebook (don't click on the Start Tamper button, it's not necessary for this). Try to identify what is going on with some of the requests being sent.</li> +</ul> + +<p>Now that you know how to quickly monitor your project and test changes, we'll learn how to add new UI elements to Firefox, through overlays and new windows.</p> + +<p>{{ PreviousNext("XUL_School/The_Essentials_of_an_Extension", "XUL_School/Adding_menus_and_submenus") }}</p> + +<p><span style="font-size: small;">This tutorial was kindly donated to Mozilla by Appcoast._</span></p> |