Показаны сообщения с ярлыком plugins. Показать все сообщения
Показаны сообщения с ярлыком plugins. Показать все сообщения

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



28 марта 2011 г.

ELGG: новые требования к структуре плагинов

Разработчики социального движка ELGG объявили новые требования к структуре плагинов. Это, по сути, и есть очередной шаг разработчиков этого проекта стандартизировать все, разрабатываемые сторонними лицами, плагины.

Итак, что же нам предлагают разработчики? Ниже приводятся требования к структуре файлов для для новой версии ELGG 1.8. Плагины, написанные для Elgg 1.7 и более ранних версий, разработчики настоятельно рекомендуют переработать под эту структуру.


Пример структуры

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

Файлы плагина example должны размещаться в /mod/example/

actions/
    example/
        action.php
        other_action.php
classes/
    ExampleClass.php
graphics/
    example.png
js/
    example.js
languages/
    en.php
lib/
    example.php
pages/
    example/
        all.php
        owner.php
vendors/
    example_3rd_party_lib/
views/
    default/
        example/
            js.php
            css.php
        forms/
            example/
                action.php
                other_action.php
        object/
            example.php
            example/
                context1.php
                context2.php
start.php
manifest.xml
CHANGES.txt
COPYRIGHT.txt
INSTALL.txt
LICENSE.txt
README.txt

Минимальная структура

Файлы start.php и manifest.xml обязательно должны присутствовать в корне каждого плагина, для того чтобы ELGG смог его распознать. Поэтому минимальная структура плагина выглядит следующим образом:

mod/example/
    start.php
    manifest.xml

Структура каталога Actions/

Все сценарии для обработки событий (actions) должны размещаться в соответственном каталоге actions/, и обязательно размещаться в каталоге с именем, отображающим событие - это необходимо для того, чтобы определить местоположение скрипта по названию события в адресной строке.

Например, скрипт для обработки события my/example/action  будет находиться  в my_plugin/actions/my/example/action.php. Это делает очевидным, какой сценарий связан с определенным событием.

По аналогичному принципу, тело формы, которая представляет это событие, должно быть расположено в forms/my/example/action.php.

Такое размещения файлов не только позволяет облегчить работу с обработчиками событий, но также позволяет с легкостью использовать новую (по состоянию на Elgg 1,8) функцию elgg_view_form().


Текстовые файлы

В корне каталога плагина могут размещаться различные текстовые файлы *.TXT, которые в основном предоставляют дополнительную документацию к плагину:

README.txt
Должен предоставлять дополнительные сведения о плагине, может содержать информацию неопределенного характера

COPYRIGHT.txt
Должен содержать дополнительную информацию по использованию авторских прав при работе с плагином, кроме теч, что указаны в manifest.xml

LICENSE.txt
Должен содержать текст лицензии, по которой выпущен текущий плагин.

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

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


Каталог Pages/

Структура каталога, в котором размещаются обработчики страниц, подобен структуре каталога для обработчиков событий. К примеру странице yoursite.com/my_handler/view/1234 соответствует обработчик в mod/my_plugin/pages/my_handler/view.php.

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


  1. Это необходимо для формирования логической связи между URL-адресами и скриптами, так чтобы человек, при рассмотрении кода, мог иметь представление как работает тот или иной обработчик, только взглянув на структуру файлов
  2.  Чтобы очистить корневую директорию, которая обычно быстро оказывается заваленной файлами дополнительных сценариев.

Каталог Classes/

Все дополнительные классы которые использует плагин должны размещаться в каталоге classes. Эта директория имеет особое значения для ELGGа. Файлы с классами, размещенные в данном каталоге загружаются автоматически, и не требуют дополнительного включения в код посредством оператора include.
  • Каждый файл должен содержать описание только одного класса.
  • Имя файла должно соответствовать названию класса (кроме суффикса .php).
Примечание: Файлы с расширением  ". class.php" НЕ будет распознан Elgg-ом


.Каталог Vendors/

Содержит библиотеки разработанные третьим лицом. К этому каталогу нет особых требований, которые бы подлежали дополнительной стандартизации.


Каталог Lib/

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


Каталог View/

Cодержит все отображения (шаблоны), которые используются в плагине. Этот каталоги имеет особое значения для ELGG, так как отображения, размещенные в этом каталоге, могут переопределять отображения, определенные ядром. Подробнее читайте здесь.


Использование Javascript/

Все javascript-библиотеки, которые используются в работе плагина, должны размещаться в каталоге plugin/js, и должны подключаться при помощи расширения отображения js/elgg. Больше информации о использовании Javascript читайте здесь.