Опубликован: 10.12.2007 | Уровень: специалист | Доступ: платный
Лекция 2:

Верстка с XUL

2.6. Хороший стиль кодирования на XUL

Разработка XUL-приложений подразумевает создание XML-документов. Лучше всего делать это вручную, так как хороших визуальных редакторов XUL пока еще нет. Очень важно, что здесь недопустима небрежность, которую можно было себе позволить в HTML. В листинге 2.10 показан пример не соответствующего стандартам HTML-кода.

<HTML><HEAD>
<STYLE>
P { font-size : 18pt; }
</STYLE>
<SCRIPT>
function set_case(obj) {
  if (obj.value)
    obj.value = obj.value.toUpperCase();
  return true;
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="yellow">
  <P>Enter a name</P>
  <FORM>
    <INPUT TYPE="text" ONCHANGE="set_case(this)">
  </FORM>
</BODY>
</HTML>
Листинг 2.10. Плохо структурированный HTML

Этот код написан в не очень современном стиле, но он работает. На XUL так писать нельзя, здесь требуется больше формальности. При этом XUL-документ должен быть хорошо организован. Хотя с помощью XUL можно создать интерфейс быстрее, чем если писать обычный код с использованием GUI-библиотеки, это все равно структурное программирование. Правила хорошего кодирования на XUL таковы:

  1. Всегда пользуйтесь XML-синтаксисом. В любом случае в XUL не применяется синтаксис вроде HTML.
  2. Избегайте использования встроенных скриптов. Вынесите все скрипты в отдельный файл .js.
  3. Избегайте применения встроенных таблиц стилей. Вынесите всю информацию о стилях в отдельный файл .css.
  4. Не переусердствуйте в использовании обработчиков событий. Одного обработчика onLoad достаточно. Задействуйте остальные из JavaScript с помощью addEventListener() (как это делается, рассказано в "События" , "События").
  5. Избегайте использования встроенных стилей. Задавайте все стили с помощью таблицы стилей.
  6. Избегайте обычного текста в XUL-документе. Для этого применяйте сущности, определенные в собственном DTD-файле.

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

Если применить все эти рекомендации к тому HTML-документу, который был приведен выше, результаты могут быть похожими на показанные в листинге 2.11.

<!-- text.dtd -->
<!ENTITY text.label "Enter a name">
/* styles.css */
p { font-size : 18pt; }
body { background-color : yellow; }
// scripts.js
function load_all() {
  document.getElementbyId("txtdata").
  addEventListener("change",set_case,0);
}
function set_case(e) {
  if (e.target.value)
    e.target.value = e.target.value.toUpperCase();
  return true;
}
<!-- content.html -->
<?xml version="1.0"?>
<?xml-stylesheet href="styles.css" type="text/css"?>
<!DOCTYPE html [
<!ENTITY % textDTD SYSTEM "text.dtd">
%textDTD;
] >
<html>
<head>
  <script src="scripts.js"/>
</head>
<body onload="load_all()">
  <p>&text.label;</p>
  <form>
    <input id="txtdata" type="text"/>
  </form>
</body>
</html>
Листинг 2.11. Структурированный HTML

Вместо 18 строк код стал занимать 28 и размещается теперь в четырех файлах, но собственно HTML-разметка занимает только 14 строк, и из них только 8 строк имеет какое-то содержимое. Это очень важный момент: содержимое или вынесено отдельно, или сведено к минимуму. При написании кода на XUL нужно будет поступать именно так.

Этот пример структурирования показывает, как следует работать с XUL с самого начала. Первый шаг - создать файлы .xul, .css, .js и, возможно, .dtd. Директива <?xml-stylesheet?> - стандартная часть XML, доступная всегда: она чем-то похожа на #include из C. Добавление DTD в HTML обычно не используется, но это очень часто происходит в XUL.

Разработка прототипа обычно делается на скорую руку, и вы можете заметить, что используете время от времени быстро решающие проблему "хакерские" приемы наряду с новыми правилами кодирования. Если это так, не забывайте об одной-двух ловушках в скриптах, которые могут испортить создаваемый документ.

Ловушка XML-синтаксиса связана с терминаторами. И в HTML, и в приложениях Mozilla XML элемент <script> содержит код, обычно на JavaScript. В случае HTML, если этот код по какой-то причине включает строку "</script>", она будет считаться закрывающим тегом. Решение: разбить строку на две части:

var x = "</scr" + "ipt>";

Эта проблема актуальна для поддержки HTML, XML и XUL в Mozilla.

Более серьезная проблема связана с использованием операторов && и & в JavaScript. XML- и XUL-документы воспринимают & как начало ссылки на XML-сущность. Это также может привести к неправильному разбору документа. Похожим образом операторы << и < воспринимаются XML и XUL как начало тега.

В подобных случаях следует использовать литералы CDATA так, как показано в листинге 2.12.

<script><![CDATA[
if ( 1 < 2 ) {
  var x = "harmless </script>";
}
]]>
</script>
Листинг 2.12. Использование литералов CDATA в XML для включения скриптов

Но и у этого решения есть недостатки. Следующая строка кода может привести к неправильному разбору документа, так как содержит подстроку "]]>":

if ( a> 0 ) { return; }

При создании приложений Mozilla единственным действительным решением этих проблем может быть только не использовать встроенные скрипты вообще.

Есть и вторая ловушка, связанная со скриптами в XML. В HTML было особое согласование между HTML и JavaScript. Если первая строка JavaScript-кода начиналась как тег комментария:

<!--

использовался особый режим обработки, в котором JavaScript-код был доступен интерпретатору. Использование таких комментариев в XUL- или XML-документах приведет к полному сокрытию JavaScript-кода от интерпретатора.

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

2.7. Альтернатива: таблицы стилей

В ходе обсуждения фреймов и расширений стилей мы говорили о том, что многие аспекты XUL-тегов доступны и из расширенной системы стилей в Mozilla. Это делает язык XUL прозрачным. Можно определить новый XML- элемент (например, с помощью DTD), добавить к нему стиль, и этот элемент будет неотличим от "официальных" элементов со своими стилями. Самые очевидные расширения CSS в Mozilla полностью совпадают с некоторыми элементами XUL, см. таблицу 2.1.

Эти стили определяют, чем именно является данный тег XUL. К сожалению, эти стили не всегда можно применить к пользовательским элементам вроде <mystack>. В C/C++-коде Mozilla порой встречаются предположения, связывающие имя элемента с характером его отображения. Одной из целей проекта Mozilla является избавление от таких мест, и в версии 1.4 почти все они исчезли. Так как же определить, будет ли тег с именем <mystack> вести себя так же, как и <stack>, если стиль отображения у него -moz-stack? Ответ: попробуйте и узнаете.

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

Модель визуального форматирования, используемая в Mozilla, местами может быть очень сложной. В XUL, HTML и MathML используется некоторая общая функциональность, и ситуация осложняется наличием режима совместимости для старых версий HTML. В итоге существует несколько стилей, которые "подсказывают" системе стилей, как должен выглядеть тот или иной объект. В чистом XUL и даже в смеси XUL и HTML это последнее средство для решения проблем с размещением объектов. Возможно, вы просто что-то чрезмерно усложняете. Эти расширения стилей описаны в таблице 2.3.

Как уже упоминалось, CSS 3 все еще находится в разработке, и в Mozilla этот будущий стандарт поддерживается частично. В CSS 3 будет включена модель границ блока из IE 6.0, которую противники Microsoft часто называют "корявой моделью блока". В конечном счете, Mozilla, вероятнее всего, будет ее поддерживать.

Таблица 2.1. Значения свойства display, соответствующие структурирующим тегам
Значение CSS-свойства "display:" Эквивалентный XUL-тег
-moz-box <box>
-moz-stack <stack>
-moz-deck <deck>
-moz-grid <grid>
-moz-grid-group <columns> или <rows>
-moz-grid-line <column> или <row>
-moz-groupbox <groupbox>
Таблица 2.2. Свойства стилей, соответствующие атрибутам размещения блоков
Новое CSS-свойство Эквивалентный XUL-атрибут
-moz-box-align align=
-moz-box-direction dir=
-moz-box-orient orient=
-moz-box-pack pack=
-moz-box-flex уникальное значение flex=
-moz-box-flex-group equalsize=
Таблица 2.3. Расширения стилей - подсказки для системы стилей Mozilla
Свойство Значение Описание
-moz-box-sizing border-box, content-box, padding-box Дает указание системе визуализации, какую часть элемента использовать для вычисления его краев
-moz-float-edge border-box, margin-box, content-box, padding-box Определяет, какой внешний ограничитель для перемещаемого элемента должен использоваться при размещении вокруг него остального содержимого
Дмитрий Гуменюк
Дмитрий Гуменюк
Россия, Звенигород
Konstantin Grishko
Konstantin Grishko
Россия, Москва, Московский финансово-промышленный университет "Синергия", Москва