Разработка дополнений FireFox: различия между версиями

Материал из Викиверситета
Содержимое удалено Содержимое добавлено
Строка 83: Строка 83:
</RDF>
</RDF>
</source>
</source>
В соответствии с этим файлом происходит установка дополнения (или не происходит в случае слишком старых или слишком новых версий).
В соответствии с этим файлом происходит установка дополнения (или не происходит в случае слишком старых или слишком новых версий). 8.0.* - тут указывается максимальная версия Firefox, с которой может работать расширение. Поэтому следует изменить это значение на то, для с какой версией планируется работа расширения.


== Инструменты ==
== Инструменты ==

Версия от 15:08, 29 января 2015

Семинар «Разработка дополнений FireFox» является частью обучающих материалов кафедры веб-технологий.

Дополнения к FireFox распространяются в виде файлов с расширением xpi. Эти файлы являются zip-архивами. Внутри архива могут находиться javascript, xul, css-файлы и даже jar-архивы. В большинстве случаев файлы структурированы в диретории и эти директории имеют стандартные названия. В-общем, всё довольно человекопонятно и человекодоступно. Давайте попробуем создать простое расширение. Пусть это будет кнопка, которую мы могли бы разместить на произвольной панели инструментов FireFox и по нажатию на неё должно появляться всплывающее окно.

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

Подготовка рабочего пространства

Итак, для начала создадим отдельный FireFox профиль, который не жалко сломать. Для этого закрываем FireFox, нажимаем Win+R и вводим команду

firefox -P

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

D:\my_experiments\firefox

Далее скачиваем и устанавливаем шаблонный проект helloworld.xpi. На панели управления должна появиться кнопка, по нажатию которой отображается приветствие 'Hello, World!'.

После установки внутри директории

D:\my_experiments\firefox\extensions

появится папка с названием

helloworld@ru.wikiversity.org.xpi

с ней-то мы и будем работать в дальнейшем.

Содержимое пакета helloworld.xpi

content\overlay.xul

<?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">
    <toolbarpalette  id="BrowserToolbarPalette">
        <toolbarbutton  id="helloButton" label="&helloworld;" oncommand="alert('Hello, World!');"/>
    </toolbarpalette>
</overlay>

Это корневой файл, он говорит, что кнопка вообще должна быть и должна быть добавлена по умолчанию на панель инструментов BrowserToolbarPalette. Этот код написан на языке XUL.

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

locale\en-US\overlay.dtd

<!ENTITY helloworld "Hello World!">

Это просто справочник текстовых констант.

skin\...

В этой папке содержатся изображение для кнопки и файл со стилями

chrome.manifest

content	helloworld	content/
overlay	chrome://browser/content/browser.xul	chrome://helloworld/content/overlay.xul

locale	helloworld	en-US	locale/en-US/

skin	helloworld	classic/1.0	skin/
style	chrome://global/content/customizeToolbar.xul	chrome://helloworld/skin/overlay.css

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

install.rdf

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">

  <Description about="urn:mozilla:install-manifest">
  
    <em:id>helloworld@ru.wikiversity.org</em:id>
    <em:name>Hello World extension for Firefox</em:name>
    <em:version>1.0</em:version>
    <em:description>Demo Hello World extension.</em:description>
    <em:creator>Wikiversity student</em:creator>
    <em:unpack>true</em:unpack> <!-- чтобы архив распаковался при установке -->

    <!-- Firefox -->
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>3.6</em:minVersion>
        <em:maxVersion>8.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>

  </Description>
</RDF>

В соответствии с этим файлом происходит установка дополнения (или не происходит в случае слишком старых или слишком новых версий). 8.0.* - тут указывается максимальная версия Firefox, с которой может работать расширение. Поэтому следует изменить это значение на то, для с какой версией планируется работа расширения.

Инструменты

Для разработки потребуется программистский текстовый редактор. Чтобы изменения содержимого файлов вступили в силу, требуется перегружать FireFox. Это неудобно, т.к. перегружать приходится часто. Поэтому нужно установить дополнение Extension Developer. После установки на панель управления FF нужно вытащить кнопку 'Reload all Chrome'.

Процесс разработки будет выглядеть так: редактируем файлы в текстовом редакторе, сохраняем, жмём на 'Reload all Chrome', проверяем.

JavaScript

Внутри XUL могут содержаться скрипты (внутри тега script) или подключаться из отдельных файлов.

<script>
function showHello(){
    alert('hello!');
}
</script>
...
<toolbarbutton  id="helloButton" label="&helloworld;" oncommand="showHello();"/>

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

В JavaScript-е могут быть использованы компоненты XPCOM.

Работа с файлами

Чтение

function read(path) {
     try {
          netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
     } catch (e) {
          alert("Permission to read file was denied.");
     }
     var file = Components.classes["@mozilla.org/file/local;1"]
          .createInstance(Components.interfaces.nsILocalFile);
     file.initWithPath( path );
     if ( file.exists() == false ) {
          alert("File does not exist");
     }
     var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
          .createInstance( Components.interfaces.nsIFileInputStream );
     is.init( file,0x01, 00004, null);
     var sis = Components.classes["@mozilla.org/scriptableinputstream;1"]
          .createInstance( Components.interfaces.nsIScriptableInputStream );
     sis.init( is );
     return sis.read( sis.available() );
}
alert(read("D:\\1.txt"));

Следует обратить внимание, что путь файла должен чётко соответствовать системе: в Windows используются обратные слэши, в Linux - прямые.

Окно для выбора файла

Окно для выбора файла на чтение:

	fp = Components.classes["@mozilla.org/filepicker;1"]
	    .createInstance(Components.interfaces.nsIFilePicker);
	fp.init(window, "File Open Dialog", fp.modeOpen);
	fp.show();

С точки зрения рантайма окно отображается синхронно (приостанавливает работу js). После выбора файла соответствующий дескриптор будет доступен в fp.file.

Окно для сохранения файла:

fp.init( window, "File Save Dialog", fp.modeSave );

Таймер

<script>
var event = {
  notify: function(timer) {
    alert("Будильник!!!");
  }
}
var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(event,3000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
</script>

Разработка библиотек XPCOM

Внутри JavaScript-а могут быть использованы компоненты XPCOM. Для того, чтобы разрабатывать библиотеки XPCOM нужно скачать XULRunner-SDK.

После распаковки архива нужно прописать путь к бинарным файлам в PATH.

XPIDL

IDL - расшифровывается как язык описания интерфейсов (interface description language). XPIDL - это Mozilla Cross-platform IDL. Интерфейсы, видимо, следует понимать как программные интерфейсы, а не GUI.

Рассмотрим пример:

#include "nsISupports.idl"
[scriptable, uuid(00000000-0000-0000-0000-000000000000)]
interface IMyComponent : nsISupports
{
  long Add(in long a, in long b);
};

Этот текст надо положить в файл с названием IMyComponent.idl и можно компилировать его в .xpt из командной строки:

xpidl.exe -m typelib -w -v -I D:\my_path_to\xulrunner-sdk\idl -e IMyComponent.xpt IMyComponent.idl

См. также