22 июня 2011 г.

Как создать свой плагин для Firefox

Задача: Разобраться как создавать плагины (дополнения) для Firefox.

Для начала заходим на Add-on Developer Hub и посредством формы создаем простой плагин (будем использовать его как болванку для разработки своего плагина). В качестве уникального ID можно указать собственный e-mail или что-то вроде того.

Скачав сгенерированный код сразу можно его проверить, для этого достаточно переименовать .zip на .xpi и установить как обычное расширение к Firefox (Меню > Инструменты Дополнения, в открытом окне Файл Установить расширения).


Распакуем полученный архив и разберемся со структурой плагина.


./chrome
      /content
           about.xul
           ff-overlay.js
           ff-overlay.xul
           options.xul
           overlay.js
      /locale
      /en-US
            about.dtd
            options.dtd
            overlay.dtd
            overlay.properties
      /skin
            overlay.css
            toolbat-button.png
./defaults/
      /preferences
            prefs.js

chrome.manifest
install.rdf


Начнем с файла chrome.manifest. Этот файл отвечает за привязку дополнительных объектов к базовым объектам Firefox. К примеру, базовый объект браузера описан в файле chrome://browser/content/browser.xul, для того чтобы иметь возможность использовать свои обработчики для событий браузера нам необходимо создать свой объект. В файле chrome.manifest происходит наложение (overlay) нового объекта на базовому:

overlay chrome://browser/content/browser.xul chrome://HelloWorld/content/ff-overlay.xul

Файл ff-overlay.xul имеет формат XUL (XML User Interface Language), другими словами это специфический XML-файл. В нашем случае он имеет следующий начальный вид:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://HelloWorld/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://HelloWorld/locale/overlay.dtd">
<overlay id="HelloWorld-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="overlay.js"/>
  <script src="ff-overlay.js"/>

  <stringbundleset id="stringbundleset">
    <stringbundle id="HelloWorld-strings" src="chrome://HelloWorld/locale/overlay.properties"/>
  </stringbundleset>

  <menupopup id="menu_ToolsPopup">
    <menuitem id="HelloWorld-hello" label="&HelloWorld.label;"
              oncommand="HelloWorld.onMenuItemCommand(event);"/>
  </menupopup>

  <popup id="contentAreaContextMenu">
    <menuitem id="context-HelloWorld" label="&HelloWorldContext.label;"
              accesskey="&HelloWorldContext.accesskey;"
              insertafter="context-stop"
              oncommand="HelloWorld.onMenuItemCommand(event)"/>
  </popup>

  <toolbarpalette id="BrowserToolbarPalette">
  <toolbarbutton id="HelloWorld-toolbar-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
    label="&HelloWorldToolbarButton.label;" tooltiptext="&HelloWorldToolbarButton.tooltip;"
    oncommand="HelloWorld.onToolbarButtonCommand()"/>
  </toolbarpalette>

</overlay>


Заглянем в файлик overlay.js.

var HelloWorld = {

    onLoad: function() {
        // initialization code
        this.initialized = true;
        this.strings = document.getElementById("HelloWorld-strings");
    },

    onMenuItemCommand: function(e) {
        var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
        .getService(Components.interfaces.nsIPromptService);
        promptService.alert(window, this.strings.getString("helloMessageTitle"),
        this.strings.getString("helloMessage"));
    },

    onToolbarButtonCommand: function(e) {
        // just reuse the function above.  you can change this, obviously!
        HelloWorld.onMenuItemCommand(e);
    }
};

window.addEventListener("load", function () { HelloWorld.onLoad(); }, false);

В этом файле находится сгенерированный класс (HelloWorld) для обработки определенных событий. Для инициализации "прослушивания" обработчиков используется метод DOM объекта Window addEventListener().

Событие "load" возникает при загрузке нового окна браузера. Согласно нашему коду, этому событию будет отвечать метод  onLoad класса HelloWorld.

Создадим новый метод, который будет обрабатывать все открываемые браузером страницы и заменять их содержание на предложение "Hello World!".

onPageLoad: function(aEvent) {
   var doc = aEvent.originalTarget;
   // doc - документ, на котором произошло событие "onload"
   doc.body.innerHTML = "Hello World!";
}

К методу OnLoad добавим код, который будет "перехватывать" событие, отвечающее за загрузку страниц в окне браузера (DOMContentLoaded) и вызывать созданный нами метод:

var appcontent = document.getElementById("appcontent");   // browser
if(appcontent)
   appcontent.addEventListener("DOMContentLoaded", HelloWorld.onPageLoad, true);

Получился следующий скрипт:

var HelloWorld = {
    onLoad: function() {
        // initialization code
        this.initialized = true;
        this.strings = document.getElementById("HelloWorld-strings");

        var appcontent = document.getElementById("appcontent");   // browser
        if(appcontent)
            appcontent.addEventListener("DOMContentLoaded", HelloWorld.onPageLoad, true);
    },

    onMenuItemCommand: function(e) {
      // ...
    },

    onToolbarButtonCommand: function(e) {
        // ...
    },

    onPageLoad: function(aEvent) {
        var doc = aEvent.originalTarget;
       // doc - документ, на котором произошло событие "onload"
        doc.body.innerHTML = "Hello World!";
    }
};

window.addEventListener("load", function () { HelloWorld.onLoad(); }, false);

Теперь можем запаковать измененный код в zip-архив, поменять расширения файла на .xpi, и попробовать установить как дополнение в Firefox (см. више).

Результат работы плагина HelloWorld:



Разберемся как работают настройки плагина.

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

Все параметры настройки плагина описаны в файле /defaults/preferences/prefs.js. Для того чтобы добавить новый параметр достаточно прописать в этом файле следующую строчку:

pref("extensions.HelloWorld.counter",0);

Теперь добавим к нашему методу onLoad объекта HelloWorld код для работы с созданным параметром настройки:

    onLoad: function() {
        // initialization code
        this.initialized = true;
        this.strings = document.getElementById("HelloWorld-strings");

        //находим компонент настроек и получаем доступ к узловой ветке
        var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        //подключаемся к ветке нашего плагина
        prefs = prefs.getBranch("extensions.HelloWorld.");

        //получение значения параметра counter
        counter = prefs.getIntPref("counter");
        counter = counter+1;
       //сохранение нового значения параметра
        prefs.setIntPref("counter",counter);
       
         alert("Вы открываете Фаерфокс уже в "+counter+" раз!");    
    }

Подробнее о методах и функциях для работы с настройками можно почитать на странице nsIPrefBranch - MDC Doc.

В результате при каждом запуске Firefox или открытии нового окна будет отображаться диалог с количеством просмотров.




Полезные ссылки по теме:

  1. DOM Window Object methods
  2. Code snippets - MDC Doc
  3. nsIPrefBranch - MDC Doc



Комментариев нет:

Отправить комментарий