Расширения Firefox — Работа с настройками

    Сегодня я хотел бы рассказать о том, как можно реализовать систему настроек для своего расширения. Начиная с определения опций и заканчивая добавлением в ваше расширение возможности менять настройки с помощью созданных вами диалоговых окон.

    Первую статью, надеюсь из будущего цикла моих статей, можно найти здесь.


    Система настроек расширений в Firefox имеет очень простую структуру. Наберите в адресной строке about:config, и вы увидите все настройки не только самого браузера, но и всех установленных расширений. Тут же их можно изменить под свои нужды.

    Чтобы ваше расширение имело собственный набор настроек, нужно создать каталог defaults/preferences (если он ранее не был создан) и поместить туда .js-файл с настройками. Вот пример такого файла.

    1. pref("extensions.sample.username", "Joe");
    2. pref("extensions.sample.sort", 2);
    3. pref("extensions.sample.showAdvanced", true);
    * This source code was highlighted with Source Code Highlighter.

    Таким образом, мы создали набор настроек по-умолчанию. Перезапустите Firefox. Теперь просмотреть, а также изменить значения этих параметров можно на странице about:config.

    Чтение настроек


    Следующий отрывок кода показывает, как получить доступ к настройкам:

    1. init : function()
    2.     {
    3.         this.prefs = Components.classes["@mozilla.org/preferences-service;1"]
    4.                             .getService(Components.interfaces.nsIPrefService)
    5.                             .getBranch("extensions.sample.");
    6.         this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
    7.         this.prefs.addObserver("", this, false);
    8.     }
    * This source code was highlighted with Source Code Highlighter.

    Последняя строка функции init указывает, что все события, связанные с изменением настроек, должны посылаться нашему объекту.

    Итак, теперь переменная this.prefs ссылается на объект с интерфейсом nsIPrefBranch. Прочитать значения какой либо опции можно следующим образом:

    1. this.prefs.getCharPref("username");
    * This source code was highlighted with Source Code Highlighter.

    Т.к. при инициализации объекта настроек мы указали в качестве пространства имен extensions.sample., то будет прочитана опция extensions.sample.username, которую мы создали ранее.

    Дополнительно о методах предоставляемых интерфейсом nsIPrefBranch можно прочитать тут.

    Изменение настроек


    Для изменения настроек вашего расширения есть возможность создать диалоговое окно, в котором можно будет отобразить нужные вам опции, и пользователь сможет менять их значения на нужные ему.


    Создайте файл options.xul в каталоге chrome/content и добавьте в него следующее содержимое:

    1. <?xml version="1.0"?>
    2. <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
    3. <prefwindow id="test-prefs"
    4.      title="Test options"
    5.      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    6. <prefpane id="test-pane" label="Test Settings">
    7.  <preferences>
    8.     <preference id="pref_username" name="extensions.sample.username" type="string"/>
    9.  </preferences>
    10.  <hbox align="center">
    11.     <label control="username" value="Username: "/>
    12.     <textbox preference="pref_username" id="username" maxlength="24"/>
    13.  </hbox>
    14. </prefpane>
    15. </prefwindow>
    * This source code was highlighted with Source Code Highlighter.

    Теперь по порядку:
    • <prefpane> — является контейнером для элементов управления диалогового окна, также этот элемент содержит ссылки на настройки компонента
    • <preferences> — содержит ссылки на опции вашего компонента
    • <preference> — ссылка на опцию. В параметре name указывается имя опции, в параметре type тип этой опции (string, int или boolean), параметр id задает идентификатор настройки внутри диалогового окна, по которому уже элементы управления будут сами считывать и записывать значения настроек (посмотрите на атрибут preference элемента textbox)
    • Далее следуют элементы управления диалогового окна, с помощью которых можно изменить опции вашего расширения

    Если вы создали этот файл для уже установленного расширения, то необходимо это расширение удалить и установить заново, чтобы кнопка «Настройка» стала доступной.


    И последнее, о чем я хотел рассказать — это реакция расширения на какие-либо изменения его настроек. В самом начале мы указали, что хотим обрабатывать все сообщения, связанные с изменением настроек. Вот пример функции, которая может с этим справиться:

    1. observe: function(subject, topic, data)
    2.     {
    3.         if (topic != "nsPref:changed")
    4.         {
    5.             return;
    6.         }
    7.  
    8.         switch(data)
    9.         {
    10.             case "username":
    11.                 alert(this.getUserName());
    12.                 break;
    13.         }
    14.     }
    * This source code was highlighted with Source Code Highlighter.

    Коротко о входных параметрах:
    1. subject — ссылка на измененный объект или событие (подробней тут)
    2. topic — указывает на тип события, нас в данном случае интересует «nsPref:changed»
    3. data — это данные, передаваемые вместе с событием, в нашем случае это будет имя опции, которую изменили

    Это необходимый минимум для работы с настройками расширений, более подробно можно об этом узнать по предоставленным мною ссылкам или на сайте developer.mozilla.org.

    Исходники примера можно взять здесь.
    Поделиться публикацией

    Похожие публикации

    Комментарии 22

      +1
      как раз думал как же это реализовать, спасибо избавили от проблем.
        +1
        как раз думал как же это реализовать, спасибо избавили от проблем.
          +1
          офтоп: а что с аккаунтом flashguy?
            0
            flashguy — это мой друг, и ему спасибо за то, что помог попасть на хабр.
              0
              Наздоровье, рад был помочь.
            0
            Было бы здорово, научится в своих расширениях использовать flash…
              +1
              Проанализируйте исходный код вон того примера: Марк Финкель показывал именно на этом примере, как можно код HTML включать в код XUL — что пригодится, если именно такова та задача, решение которой немедленно позволит «использовать Flash в расширениях».

              Готовый пример вставки SWF в XUL приводит Филип Теппер в Mozilla.Dev.Tech.XUL:
              <binding id="blipfox-embed-youtube">
                  <content>
                      <html:embed
                      src="http://whatever/swf/file.swf"
                      width="240"
                      type="application/x-shockwave-flash" />
                  </content>
              </binding>
                0
                Нужно будет попробовать это реализовать.
              +2
              Смотрел вот этот код:
              init: function()
              {
                  this.prefs = Components.classes["@mozilla.org/preferences-service;1"]
                      .getService(Components.interfaces.nsIPrefService)
                      .getBranch("extensions.sample.");
                  this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
                  this.prefs.addObserver("", this, false);
              }
              Много думал.

              Я бы, наверное, через FUEL действовал, через extIPreferenceBranch: всё бы меньше писанины выходило. Код тогда получается попроще — где-то такой:
              Application.prefs.get("extensions.sample.").events.addListener("change", someFunction);
              Как вам этот вариант покажется?

              (Конечно, использование FUEL означает необходимость полагаться на Firefox 3 (более ранние FUEL не содержат), однако разве простота кода того не стоит?)
                0
                Да, конечно, проще, и думаю, довольно часто можно использовать.
                +1
                Хватит минусовать Мицгола за то, что он Мицгол. Вполне адекватные вещи пишет (в данном случае, по крайней мере).
                  0
                  navigator.preference уже не работает для установки/чтения пропертей? или это вчерашний день?
                    –1
                    В пособиях MDC сказывают, что вчерашний.
                      0
                      киньте ссылку, потому как «старый способ» прост, как 3 коп.
                        0
                        Вон там сказано:
                        navigator.preference
                            Sets a user preference. This method is only available to privileged code, and you should use XPCOM Preferences API instead.
                        Причём ссылка «navigator.preference» у них там в вики вообще красная.
                          0
                          Да, спс. Красная, но не obsolete. )

                          Расширения на автомате (насколько я понимаю) в привилегированном положении, так что get-set своих пропертей они могут делать всего одной строкой через navigator.preference(). Само собой для простых значений only.
                    0
                    Спасибо за статью, пригодится.
                      0
                      Спасибо за статью!
                      Может подскажете как иконку в трэй поместить как в Thunderbird при получении письма? Или как NotifyPopup в нижнем правом углу показать в то время как главное окно свернуто?
                        –2
                        Работа над портированием в Firefox кода из Thunderbird (а также Prism и Jabberzilla), обеспечивающего появление значка в системном лотке, ведётся (баг 325353), и ведётся мощно, но пока ещё не достигла окончательного завершения.
                          0
                          А как такое в самом Thunderbird добиться.

                          Я пилю под себя плагин добавляющий IM на Jabber основе в Thunderbird и хотел иконку в трей помещать, если пришло сообщение а Thunderbird был свернут. А так же хотелось бы свои всплывающие сообщения сделать, а то Thunderbird совсем кривые предлагает, да и только одно сообщение за раз можно показать.
                        +1
                        Куда пропал файл с примером? :(
                          0
                          Видимо, сервер, на котором хостятся файлы временно недоступен. Думаю, скоро это исправятю

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое