XUL/Первый проект
Создадим каталог «example1» с типовой структурой XUL проекта, и разберёмся, что означает каждый файл:
example1 |-- application.ini |-- chrome | |-- chrome.manifest | |-- content | | `-- example1.xul | `-- locale | |-- en-US | | `-- example1.dtd | `-- ru-RU | `-- example1.dtd |-- components `-- defaults `-- preferences `-- prefs.js
application.ini
«application.ini» - главный файл нашего проекта, с чтения которого начинается выполнение программы. В этом файле указывается имя проекта, дата сборки, автор, минимальная и максимальная версии Gecko для исполнения данного проекта. Строки, начинающеся со знака «;» считаются комментарием. Например:
; Имя проекта. Необходимое поле. Name=example1 ; ; Версия проекта. Необязательное поле. Version=0.1.0 ; ; Временной штамп времени сборки. Необходимое поле. BuildID=2008090918 ; ; Краткая заметка об авторских правах. Необязательное поле. Copyright=Copyright (c) 2008 Me ; ; Уникальный идентификатор проекта. В качестве значения можно ; использовать UUID или формат имя_проекта@имя_организации.tld. ; UUID может быть сгенерирован, например, утилитой uuidgen, входящей в состав ; пакета e2fsprogs. Необязательное поле. ID={bde97359-5ff3-4823-a833-f5e07093c1f2} [Gecko] ; ; Минимальная версия Gecko, необходимая для запуска приложения. Необходимое поле. MinVersion=1.8 ; ; Максимальная версия Gecko, необходимая для запуска приложения. Необязательное поле. MaxVersion=1.9.0.*
Каталог chrome
В каталоге «chrome» лежит файл-описание ресурсов проекта «chrome.manifest». В этом файле описываются расположение собственно .xul файлов для запуска, локали и скинов. Например:
content example1 file:content/ locale example1 en-US file:locale/en-US/ locale example1 ru-RU file:locale/ru-RU/
Путь к содержимому (XUL, JS, CSS файлам), которое необходимо исполнять, задаётся директивой content. Далее следует имя проекта, и наконец путь с префиксом. Префикс file: означает обычное физическое расположение файлов на диске в каталоге content. Префикс jar: указывает на расположение ресурса в JAR архиве в формате jar:<имя_файла.jar>!/<путь в архиве>, например:
content example jar:example1.jar!/content/
JAR файл можно создать утилитой zip.
Очевидно, что структура с прямым доступом к файлам удобна при разработке проекта, а использование JAR файлов удобно при распространении проекта, т.к. значительно уменьшает его размер.
Путь к локализованным строкам проекта задаётся директивой locale. Далее следует имя проекта, локаль в формате LL-CC, где LL - код языка, CC - код страны, и физическое расположение файлов локализации, аналогично предыдущему случаю с content.
Каталог content
Здесь традиционно лежат собственно файлы описания интерфейса (.xul), файлы управления (.js) и файлы определяющие внешний вид (.css). Главный файл интерфейса, который и будет исполняться (аналог функции main()) должен иметь имя, описанное в файле настроек prefs.js, который мы рассмотрим далее. В нашем случае этот каталог содержит только один файл описания интерфейса:
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <!DOCTYPE window SYSTEM "chrome://example1/locale/example1.dtd"> <window title="Example" width="320" height="200" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <label value="&example1.helloworld;" flex="1" /> </window>
Здесь мы создаём окно размером 320x200, с заголовком "Example" и текстовым полем "Hello, world!". Рассмотрим некоторые аспекты описания XUL интерфейса:
<?xml version="1.0"?> определяет, что это XML файл.
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> импортирует глобальную таблицу стилей из пакета-исполнителя (из xulrunner, например). Каждый XUL файл должен импортировать глобальную таблицу стилей. Локальные CSS файлы импортируются аналогично:
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <?xml-stylesheet href="css/example1.css" type="text/css"?> ...
<!DOCTYPE window SYSTEM "chrome://example1/locale/example1.dtd"> указывает где искать локализованные строки (без указания подкаталога-локали).
<window ...> описывает окно. Все элементы интерфейса должны описываться внутри окна. Одно окно или диалог должны описываться в одном .xul файле.
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> задаёт пространство имён для XML тегов, указывает что мы используем теги, относящиеся именно к XUL. Теперь, чтобы использовать теги из других пространств имён, эти пространства нужно указывать принудительно (например, «<html:div>»)
Каталог locale
Здесь хранятся переводы проекта на различные языки.
Содержит подкаталоги, каждый подкаталог имеет имя локали в формате LL-CC, описанном выше. В каждом подкаталоге должен лежать файл с локализованными строками, использующимися в проекте. Файл локализации есть ни что иное, как DTD файл, позволяющий определять синтаксис и семантику определённого XML файла, но в данном случае используется всего лишь как хранилище XML сущностей (entities). Файлы локализации, содержащие не-ASCII символы, должны храниться в UTF-8 виде. Как правило, один .dtd файл соответствет одному .xul файлу. Формат файла:
<!ENTITY example1.helloworld "Hello, world!"> <!ENTITY ...
В файле локализации в каждой строке пишется структура, заключённая в угловые строки, и описывающая одну сущность (entity). В начале следует директива !ENTITY, далее имя сущности, и перевод. Имя сущности используется в .xul файле для задания строки текста, например, на кнопке или элементе меню. Например:
<label value="&example1.helloworld;" />
Форма использования сущности в .xul файле абсолютно идентична сущностям в HTML - это амперсанд, имя сущности, точка с запятой.
Чтобы привязать данный .xul файл к .dtd локализации, в .xul файле необходима специальная директива, описанная выше.
Каталог components
Здесь находятся различные XPCOM компоненты, необходимые для выполнения проекта. Пока мы не используем свои XPCOM компоненты, но об этом каталоге нужно помнить.
Каталог defaults
Содержит подкаталог preferences, в котором лежит JavaScript файл prefs.js, в котором описываются настройки для движка, которые Вы бы хотели поменять (строго говоря, интерпретатор считывает все .js файлы из этого каталога, так что файлов с настройками может быть несколько). Должен содержать как минимум функцию изменения параметра toolkit.defaultChromeURI, например:
pref("toolkit.defaultChromeURI", "chrome://example1/content/example1.xul");
Этой директивой мы указываем движку главный файл интерфейса (аналогично функции main() в Си). Можно также поменять любую настройку движка (все настройки можно просмотреть в браузере Firefox, набрав «about:config» в строке адреса, или передав этот URL элементу <browser> в любом XUL приложении). Например:
pref("browser.dom.window.dump.enabled", true); pref("javascript.options.showInConsole", true); pref("javascript.options.strict", true);
Поехали!
Итак, заходим в каталог example1, и запускаем наш проект на выполнение с помощью xulrunner:
# xulrunner ./application.ini
или используя Firefox 3:
# firefox -app ./application.ini
Вы должны увидеть окошко с надписью "Привет, мир!".