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

Окна и панели

10.6. Составные документы

Можно объединять несколько различных документов в один, не изолируя их друг от друга при помощи тега <iframe>.

10.6.1 Различные типы документов XML в одном документе

Очень мощная, хотя и сложная в использовании особенность Mozilla – способность отображать документ, теги которого относятся к различным стандартам (типам документов XML). Это означает, что один документ может объединять, например, содержимое HTML, SVG, MathML и XUL. Для этого достаточно добавить к документу соответствующие пространства имен XML, после чего можно использовать любые теги, относящиеся к ним. Однако следует иметь в виду, что Mozilla обрабатывает лишь то содержимое XUL, которое находится в файлах с расширением .xul или в документах, имеющих правильный тип MIME для XUL. Этот вопрос обсуждался в "Формы и меню" "Формы и меню", где шла речь об использовании в одном документе форм XUL и HTML.

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

В случае поверхностного смешивания документ состоит из нескольких фрагментов, каждый из которых относится к отдельному типу содержимого и четко отделен от остальных. В качестве примера можно привести документ HTML с несколькими уравнениями, каждое из которых представлено фрагментом MathML.

Глубокое смешивание означает, что в документе невозможно выделить крупные фрагменты, относящиеся к различным стандартам. В таком документе разные типы содержимого перемешаны на уровне отдельных тегов. Такие документы часто возникают в результате недостаточной опытности автора, полагающего, что любой тег может быть использован в любом месте.

Поверхностное смешивание, как правило, не создает проблем с отображением документов. При глубоком смешивании проблемы возникают довольно часто. Наименее рискованным является глубокое смешивание HTML и MathML. Смешивание XUL с HTML или MathML требует осторожности, а глубокое смешивание SVG с другим типом содержимого просто не работает, поскольку для отображения документа SVG необходима выделенная область экрана.

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

  • Для различных типов содержимого предусмотрены различные модели размещения тегов. Точный набор правил для размещения смешанного содержимого установить очень трудно. Вы можете потратить много времени на работу со стилями, пытаясь добиться нужного результата.
  • Обработка смешанного содержимого не подвергается тщательному тестированию, в отличие от соответствия каждому из отдельных стандартов. Количество тестов, необходимых для проверки совместимости хотя бы двух стандартов, огромно. Смешивание содержимого возможно благодаря продуманной архитектуре платформы. Однако, создавая сложные ситуации, вы рискуете столкнуться с эффектами, которые никто не предусмотрел и не протестировал.
  • Различные типы отображаемых документов имеют различные корневые элементы. Это означает, что для отображения документов различных стандартов используются различные объекты C/C++, реализующие интерфейсы модели DOM 1. Поэтому отображение одного и того же тега зависит от типа документа, в котором он встречается. Для документа HTML с фрагментами XUL и документа XUL с фрагментами HTML механизмы отображения различны. Если документ активно использует скрипты (XUL или DHTML), различия в программных интерфейсах могут оказаться существенными.

Иногда возникает соблазн просто добавить к документу XUL тег HTML <A HREF=>, чтобы создать в окне справки ссылку на сайт разработчика. Вы можете добавить к документу тег HTML <FORM> и автоматически отправлять данные формы из XUL. Однако и в том, и в другом случае можно обойтись без всякого HTML. Необходимо следить за "чистотой" своего XUL.

Более поздние стандарты DOM предусматривают такие методы, как, например, createElementNS() и getAttributeNS(). NS в их именах означает namespace (пространство имен). Эти методы позволяют при работе с тегами и атрибутами XML указывать для них конкретное пространство имен.

10.6.2 Составные документы XUL

Тег <overlay> подобен усложненной версии директивы #include языков C/C++. Он позволяет объединить несколько документов XUL в один, используя атрибут id. Эта технология описана в "Оверлеи и Chrome" "Оверлеи и chrome".

10.7 Управление существующими окнами

В процессе работы приложения может возникнуть необходимость обратиться к ранее созданным окнам. Например, команда File | Inspect a Window в меню Инспектора DOM выбирает окно для анализа и получает информацию о его объектной модели. Еще более простой пример – перечень открытых окон в нижней части меню Mozilla "Окно". Выбор одного из этих пунктов передает фокус соответствующему окну.

Попытка жонглировать множеством независимых окон может привести к неудачной архитектуре приложения. В большинстве случаев пользователь может закрыть любое окно в любой момент. При этом удаляется вся информация о состоянии приложения, связанная с эти окном (возможно, за исключением апплетов Java и разделяемых объектов XPCOM). Довольно сложно сохранить разумную архитектуру приложения в ситуации, когда информация о его состоянии может произвольно исчезать. В идеале приложение должно иметь главное окно, от которого должны зависеть все остальные окна. Этого можно добиться, используя параметры dependent и modal в строке параметров метода window.open(). Возможно, однако, что приложение должно следовать метафоре рабочего стола, когда независимые документы находятся в независимых окнах. В этом случае либо все окна должны быть полностью независимы друг от друга без возможности взаимодействия, либо приложение должно иметь возможность установить, какие окна открыты в настоящий момент.

Mozilla предоставляет несколько компонентов и интерфейсов для управления окнами. Простейшей парой является следующая:

@mozilla.org/appshell/window-mediator;1 и nsIWindowMediator

Этот интерфейс позволяет получить список окон, открытых в данный момент. К моменту выхода версии Mozilla 1.2.1 он не был окончательно зафиксирован ( frozen ), и существовала возможность того, что в будущем он несколько изменится. Различные методы этого интерфейса позволяют получить список окон в разных формах. На листинге 10.3 показано, как получить статический список окон, открытых в настоящий момент.

var C, obj, iface, mediator, enum, windows;
C = Components;
obj = C.classes["@mozilla.org/appshell/window-mediator"];
iface = C.interfaces.nsIWindowMediator;
mediator = obj.createInstance(iface);
enum = mediator.getEnumerator(null);
windows = [];
// получить список окон, используя полученный 
 объект-перечислитель (интерфейс nsISimpleEnumerator)
while ( enum.hasMoreElements() )
	windows.push(enum.getNext());
// сделать что-либо с первым окном
windows[0].document.GetElementById ...
Листинг 10.3. Получение списка открытых окон при помощи nsIWindowMediator.

Чтобы отфильтровать получаемый список окон, методу getEnumerator() можно передать строку в качестве аргумента. При этом в возвращаемый список войдут только окна с корневым тегом <html>, <window>, <dialog> или <wizard>, чей атрибут windowtype совпадает с этой строкой.

Чтобы включить в список только окна XUL, вместо метода getEnumerator() следует использовать getXULWindowEnumerator(). Обсуждаемый интерфейс также позволяет получить порядок расположения окон (очередность перекрытия). Минимизированные окна будут перечислены как находящиеся в самом низу.

В ходе работы приложения окна могут постоянно открываться и закрываться, и может возникнуть необходимость динамически отслеживать этот процесс (как это делается для поддержания списка открытых окон в меню "Окно"). Один из способов сделать это – создать объект- приемник ( listener ) для соответствующих событий. Данному объекту, реализующему интерфейс nsIWindowMediatorListener, сообщается об открытии и закрытии окон, а также об изменении заголовка окна. Более сложное решение, требующее некоторого кодирования – использовать источник данных rdf:window-mediator непосредственно из XUL. Работа с RDF и источниками данных описана в "RDF" "RDF".

10.8 Использование стилей

Платформа Mozilla добавляет к системе стилей CSS2 ряд расширений, относящихся к окнам, которые создаются средствами XUL и HTML.

В частности, внешний вид подсказки, определяемой тегом <tooltip>, как и в случае с <menupopup>, о котором шла речь в "Формы и меню" "Формы и меню", определяется значением -moz-popup свойства display.

Свойство -moz-appearance, которое используется для поддержки тем операционной системы (рабочей среды), может также принимать следующие значения:

window dialog tooltip caret

Кроме того, существует целая система расширений, которые также могут использоваться для поддержки этих тем. Полезно, когда окна, а особенно - диалоговые окна, создаваемые при помощи XUL, выглядят в точности как собственные окна операционной системы или рабочей среды (например, Windows или GNOME). Диалоговые окна и сами по себе, без экзотических форм и цветов, могут представлять собой раздражающий фактор для пользователя. Поэтому Mozilla включает целый набор расширений, которые позволяют диалоговым и прочим окнам имитировать системные цвета и шрифтовое оформление рабочей среды. Эти расширения могут использоваться в любых правилах стиля, где можно задействовать обычные имена шрифтов или цветов.

Кроме того, Mozilla поддерживает имена шрифтов и цветов, установленные спецификацией CSS2 (раздел 18.2).

Продуманное использование этих расширений может сделать приложение XUL неотличимым от приложений, традиционных для данной среды, например написанных для Windows при помощи Visual Basic или для UNIX – на основе библиотеки GTK.

Дополнительные значения для системных цветов, поддерживаемые Mozilla, перечислены в таблице 10.2. Актуальный список таких расширений для текущей версии можно найти в файле nsCSSProps.cpp исходного кода.

Таблица 10.2. Расширения стилей CSS2: системные цвета
Имя системного цвета Соответствующий элемент Дополнительные имена цветов для Macintosh
-moz-field Фон поля ввода -moz-mac-focusring -moz-mac-menuselect -moz-mac-menushadow -moz-mac-menutextselect -moz-mac-accentlightesthighlight -moz-mac-accentregularhighlight -moz-mac-accentface -moz-mac-accentlightshadow -moz-mac-accentregularshadow -moz-mac-accentdarkshadow -moz-mac-accentdarkestshadow
-moz-fieldtext Текст в поле ввода
-moz-dialog Фон диалогового окна
-moz-dialogtext Текст в диалоговом окне
-moz-dragtargetzone Цвет, которым выделяется элемент при перетаскивании над ним объекта при помощи мыши
-moz-hyperlinktext Текст ссылки, например, на Active Desktop в Windows
-moz-visitedhyperlinktext Текст посещенной ссылки

Mozilla также поддерживает расширения для системных шрифтов, перечисленные в таблице 10.3, однако эти значения игнорируются, по крайней мере, в версиях Mozilla до 1.4.

Таблица 10.3. Расширения стилей CSS2: имена шрифтов
Имя системного шрифта
-moz-window
-moz-document
-moz-workspace
-moz-desktop
-moz-info
-moz-dialog
-moz-button
-moz-pull-down-menu
-moz-list
-moz-field

Исключением является значение -moz-fixed, которому соответствует моноширинный шрифт. Этот шрифт действительно отображается, причем для любого заданного размера и, следовательно, для любых значений свойства CSS font-size.

Дмитрий Гуменюк
Дмитрий Гуменюк
Россия, Звенигород
Konstantin Grishko
Konstantin Grishko
Россия, Москва, Московский финансово-промышленный университет "Синергия", Москва