В этой лекции описывается большая часть XUL-тегов, использующихся для ввода данных. Также здесь будет рассказано, как отправлять содержимое форм в Internet. Об элементах управления и тегах, связанных с перемещением пользователя по документам, речь пойдет в лекции 8, "Навигация".
Лучший способ помочь пользователям при вводе данных - давать им подсказки и обеспечивать обратную связь. Бумажные документы, оформленные для этого особым образом, называются формами. В лекции 4, "Первые элементы управления и темы", подробно рассматривались кнопки. В этой лекции будут описаны другие основные элементы управления для создания форм, необходимые наряду с кнопками: меню, флажки, текстовые поля и т.д. Каждый из этих элементов управления плюс элементы управления меню является совершенно новым элементом или новой их группой.
На иллюстрации к этой лекции показано, где в Mozilla реализуются
меню и формы. Неудивительно, что XUL-теги форм и меню активно
пользуются библиотекой графических элементов
Формы и меню подчиняются тем же ограничениям, что и тег <button>:
чтобы их признали как формы (или меню), они должны выглядеть похожими
на формы (меню). Следовательно, информация о стиле играет важную роль
для этих элементов управления. Иллюстрация в начале лекции также
подчеркивает важность XBL-определений (связок). Теги форм и меню
обычно активно используются в скриптах, и программисту нужны XBL-
определения для этих тегов, чтобы знать, какие свойства и методы
доступны.
Наконец, иллюстрация показывает, что в реализации форм участвуют некоторые XPCOM-компоненты. Отправка заполненной формы на сервер - классическое применение технологии Mozilla и первый пример использования платформы как клиентского программного обеспечения по отношению к какому-либо серверу.
HTML-теги форм широко распространены. XUL-формы похожи на HTML- формы, поэтому мы начнем с краткого сравнениях обоих вариантов. Затем мы рассмотрим все XUL-теги, из которых составляются формы.
В HTML/XHTML есть тег <FORM>. Этот тег объединяет теги <BUTTON>, <SELECT>, <INPUT> и < в одну группу. У DOM-объекта,
соответствующего <FORM>, есть методы, составляющие значения полей
формы в HTTP-запрос GET или POST. Это автоматизация процесса
постоянного сбора данных формы путем их отправки на какой-либо
web-сервер. В результате web-приложения на основе HTML теперь
распространены повсеместно.
В XUL нет эквивалента тегу <FORM>. Эквивалентные элементы
управления форм в XUL не объединяются в группы (за исключением группы < ). В XUL нет аналога <INPUT TYPE="reset"> или <INPUT TYPE="submit"> и нет полуавтоматического процесса отправки данных
формы. Если пользователю дан один лишь только XUL-документ, при вводе
информации ничего не произойдет.
Это означает, что если XUL-приложение должно вести себя как HTML-форма, тогда процедура отправки данных должна добавляться вручную. Это делается с помощью скриптов, которые пишутся для каждого XUL-документа, который должен вести себя как форма. К счастью, писать такие скрипты несложно.
С другой стороны, элементы управления XUL-форм более разнообразны,
чем в HTML. Теги <button>, <textbox> и <menu> более гибки, чем их HTML-аналоги. Кроме того, в XUL существует множество более
функциональных тегов вроде <menubar>, <listbox> и <tree>, гораздо
более сложных, чем то, что может предложить HTML. Эти дополнительные
теги рассматриваются в более поздних лекциях.
В таблице 7.1 перечислены XUL-теги, наиболее похожие на HTML-теги форм и меню.
| HTML-тег | XUL-тег | Примечания |
|---|---|---|
<FORM> |
нет | Используйте объект |
<BUTTON> |
<button> |
|
<INPUT TYPE="button"> |
<button> |
|
<INPUT TYPE="text"> |
<textbox> |
|
<INPUT TYPE=" |
< |
Или <button type=" |
<INPUT TYPE="checkbox"> |
<checkbox> |
Или <button type="checkbox"> |
<INPUT TYPE="password"> |
<textbox type="password"> |
|
<INPUT TYPE="submit"> |
нет | Используйте <button> и скрипт |
<INPUT TYPE="reset"> |
нет | Используйте <button> и скрипт |
<INPUT TYPE="file"> |
нет | Используйте объект FilePicker |
<INPUT TYPE="hidden"> |
нет | Используйте обычную переменную JavaScript |
<INPUT TYPE="image"> |
<button> |
В любом случае для отправки формы используйте скрипт |
<SELECT> |
<menulist> или <listbox> |
|
<OPTGROUP> |
нет | Вместо этого используйте <menuseparator> |
<OPTION> |
<menuitem> |
|
< |
<textbox multiline="true"> |
Поддерживает атрибуты rows и cols |
<LABEL> |
<label> |
См. обзор альтернативных возможностей доступа |
<FIELDSET> |
< |
|
< |
< |
|
<INPUT TYPE=" |
< |
Формы и меню в приложениях с графическим интерфейсом обычно появляются вместе. Поддержка меню в XUL почти так же разнообразна, как поддержка кнопок. В отличие от обзора кнопок в лекции 4, "Первые элементы управления и темы", меню описываются в разных частях книги. Краткое сравнение всех типов меню представлено в разделе "Варианты меню" текущей лекции. Или же можно руководствоваться в поиске следующим списком:
<menulist>, который строится из <menupopup>, <menuitem> и других тегов, также описанных здесь;<listbox> описывается в лекции 13, "Списки и деревья";<menu>, описываются в лекции 8, "Навигация". Но в этой лекции рассказано об использовании <menu> для создания подменю;<menupopup>, описываются в лекции 10, "Окна и панели".Единственное существенное различие между меню в XUL заключается в
разнице между <listbox> и <menulist>. Первый из них гораздо сложнее.
Все остальные упомянутые теги - вариации на тему <menulist>. Все
выпадающие меню реализуются с помощью тега <menupopup>.
Форма, в которой некоторое число изменяемых пользователем элементов
собирается в структурированную группу - центральное понятие и для
HTML, и для XUL. HTML - это
HTML- и XUL-формы в Mozilla очень похожи. Простейшие элементы формы почти идентичны. Обработчики событий и навигация в обоих случаях работают в основном похожим образом. Любое введение в HTML с примерами использования JavaScript - хорошая подготовка для применения XUL-форм. Однако не стоит ожидать, что это сходство распространится до мельчайших деталей. Эти две системы форм реализованы отдельно, хотя некоторый общий код у них есть.
В этой лекции мы обсудим простейшие XUL-теги для создания форм. Набор основных тегов таков:
<button> <checkbox> <radio> <radiogroup> <textbox> <label>
Любой графический элемент формы называется элементом управления
формы ( "form control" в терминологии Microsoft) или просто
элементом формы ( "form element" - термин, изначально
появившийся в графическом дизайне и заимствованный оттуда Netscape и
W3C). Такие элементы могут взаимодействовать с пользователем самыми
разными способами, но все они объединяются общим дизайном.
Если пользователю нужно что-то ввести в форму, самый простой подход - взаимодействие в каждый момент только с одним элементом формы. И в XUL, и в HTML разрешается выделять один элемент управления за раз. Кроме того, интерактивные элементы форм в документе упорядочиваются. В терминах W3C это называется порядком переходов. В Mozilla упорядоченный набор таких элементов управления называется кольцом фокуса, так как, перейдя от последнего в наборе элемента далее, пользователь попадает снова на первый элемент. Все элементы форм входят в кольцо фокуса.
Более подробно изменение фокуса рассматривается в лекции 8, "Навигация".
В процессе разработки стандарта CSS 3 консорциум W3C создал
черновой документ "
Mozilla реализует множество положений этого черновика стандарта. В
частности, она воплощает четыре свойства стиля, представляющие
интерактивные возможности простых элементов XUL-форм. Эти стили в
Mozilla реализуются интерфейсом nsINSDOMCSS2Properties. В системе
стилей они доступны как расширения с префиксом -moz. Вот они:
user-input user-modify user-select user-focus
Эти свойства стиля в некотором смысле не зависят друг от друга и
они очень важны, так как облегчают понимание системы ввода данных
пользователем. Достичь этого понимания раньше было сложно, так как
результаты применения обработчиков событий наподобие onclick и DOM-методов
вроде обычно зависят от нескольких из этих четырех
состояний сразу. Теперь, когда эти состояния обозначены отдельно друг
от друга, легче понять, какой эффект произведут обработчики элементов
формы. Вы можете взять набор из этих четырех состояний и события и
написать новые состояния, которые появятся, если определенный элемент
формы с такими состояниями получит данное событие.
Помимо этих четырех стилей у элементов формы есть два других общих
понятия. Первое из них - собственное состояние. Все простые элементы
формы обладают, по крайней мере, одним общим атрибутом - disabled,
чьим значением может быть true. На рисунке 7.1 показаны активные и
неактивные ( disabled ) элементы управления формой.
(рис 7.1) Активные и неактивные элементы управления формойНаконец, у всех простых элементов формы есть общий набор обработчиков событий и соответствующих объектных методов для интерактивных событий вроде получения и потери фокуса.
Программное обеспечение можно сделать доступным для людей с ограниченными физическими возможностями. Гипертекстовые HTML-документы, ссылки и окна XUL-приложений - все это может быть доступно для таких пользователей. Элементы форм особенно интересны потому, что правительство любого государства заинтересовано в том, чтобы предоставить через Internet различные службы, которые будут одинаково доступны всем, в том числе людям с ограниченной дееспособностью.
Во всех обсуждениях до этого момента XUL-тег <label> был
идентичным тегу <description> во всем, за исключением
возможности сведения к атрибуту label. Но если взглянуть с точки
зрения доступности, сразу будут видны отличия <label> от <description>. Тег <label> позволяет предоставлять
альтернативное содержимое, необходимое для создания системы
доступности.
Если у элемента формы есть атрибут label, Mozilla предоставит его
значение как вспомогательную информацию, которую система доступности
передает пользователю. Если у элемента формы нет такого атрибута,
Mozilla будет искать его тег-<label> и использует его.
Если подходящего потомка не найдется, она будет искать тег <label>, чье значение атрибута control совпадает с
идентификатором, заявленным в атрибуте id тега элемента формы. Если и
такой тег не найден, тогда вспомогательная информация недоступна.
Поддержка расширенной доступности в Mozilla предусмотрена для всех
простых элементов XUL-форм. Эта поддержка есть и для тегов <menuitem>, <menulist> и <tab>.
Как работает такая доступность, подробнее рассматривается в лекции 8, "Навигация".
На рисунке 7.2 показаны простые теги форм с примененными к ним
дополнительными стилями, так что их структура становится понятнее.
Пунктирные линии означают теги <label>, толстые сплошные - теги <box>, а тонкие сплошные - теги <image>. Два средних
раздела - теги <, второй из которых содержит теги <button type=".
(рис 7.2) Простые элементы XUL-форм с открытой внутренней структуройИз рисунка 7.2 видно, что все простые теги форм содержат, по
крайней мере, один другой тег, даже если этот тег - <image> без
содержимого. Все эти теги форм определены в XBL.
В Mozilla есть специальные обработчики событий, написанные на
C/C++. Они добавляются к объекту XUL-документа с помощью C/C++-версии addEventListener(). Такие обработчики событий перехватывают
информацию, связанную с простыми элементами управления. Так
реализуется недоступная через XBL
У таких тегов есть DOM-интерфейсы, очень похожие на соответствующие
HTML-интерфейсы. Все имена XPCOM-интерфейсов начинаются с префикса nsIDOMXUL.
Тег <button> широко обсуждается в лекции 4, "Первые
элементы управления и темы". Вспомните, что атрибут type
позволяет превращать кнопку в флажок, переключатель или кнопку
раскрытия меню.
Тег <checkbox> составляется из простых содержательных XUL-
тегов. У него есть XBL-определение. Изображения флажков, появляющиеся
при отображении этого элемента управления, составляются из обычных
картинок. С помощью стилей можно сделать их больше или меньше или даже
заменить их. У <checkbox> есть следующие собственные
атрибуты:
src label crop checked disabled accesskey
src передается необязательному изображению, которое появляется
между флажком и текстом. передается <label>, содержащему
текст. checked принимает булевы значения, соответствующие состояниям <checkbox>, а disabled, если его значение - true, делает флажок
полностью недоступным пользователю. Сопроводительный текст может
появиться справа от флажка, если указан атрибут dir=".
Состояние каждого флажка не зависит от состояний других флажков. Если
щелкнуть по тексту ( <label> ) флажка, эффект будет тот же, что и
при щелчке по пиктограмме самого флажка.
С помощью <checkbox> отправляет событие CheckboxStateChange при смене
состояния. За этим состоянием, если нужно, может наблюдать код
приложения.
Тег < составляется из простых XUL-тегов. У него есть
XBL-определение. Пиктограммы переключателей - обычные изображения, и с
помощью стилей их можно увеличить, уменьшить или заменить другими. У
тега < есть следующие собственные атрибуты:
src label crop selected disabled accesskey
Эти атрибуты имеют то же значение, что и для тега <checkbox>,
только checked заменяется атрибутом selected. Если тег <
является потомком <, только у одного переключателя из
группы может быть атрибут selected="true". У нижнего тега < в первой группе переключателей на рисунке 7.2 задан
атрибут dir=". Для выбора переключателя можно щелкать и
по тексту ( <label> ), и по его пиктограмме.
До недавних версий Mozilla тег < не всегда правильно
определял, когда он должен получать фокус. Чтобы прояснить ситуацию с < в конкретной версии Mozilla, нужно обратиться к ее базе
данных ошибок.
Тег < связывает набор тегов < или <button type=" вместе и превращает в единое
целое. Если любой переключатель в такой группе выбран, все остальные
теряют выделение. Тег < поддерживает следующие
атрибуты:
disabled selectedItem focusedItem selectedIndex
disabled делает недоступной для пользователя всю группу. selectedItem и focusedItem сообщают, какой переключатель в группе
выбран или получил фокус, соответственно. selectedIndex содержит номер
текущего выбранного переключателя в группе, начиная с 0.
С помощью < отправляет события RadioStateChange и selected при
смене состояния. За этими событиями, если нужно, может наблюдать код
приложения.
Тег <textbox> позволяет пользователю вводить текст. Это
четыре тега в одном: обычное поле ввода, поле ввода пароля,
многострочное поле ввода и поле ввода с автодополнением. У <textbox> есть XBL-определение. Тег <textbox> реализуется
с помощью HTML-тегов <input type="text"> или <. У стандартного тега <textbox> есть следующие
особые атрибуты:
value disabled readonly type maxlength size multiline
Все эти атрибуты, кроме multiline и type, соответствуют атрибутам
HTML-тега <input type="text">. Значением multiline
может быть true, а значением type - password или autocomplete. Если type="password", <textbox> действует так, как HTML-тег <input type="password"> ; однако иначе и быть не может
- они одинаковы. Если значение multiline - true, у <textbox>
появляется другой набор атрибутов:
value disabled readonly rows cols wrap
Эти атрибуты соответствуют атрибутам HTML-тега <.
Так как в XUL нет анонимного содержимого, изначально отображаемый
текст не может заключаться между открывающим и < в HTML.
Для всех этих трех вариантов текстового поля начальное значение
может быть задано, только если поле не многострочное. В случае
многострочных полей начальное значение задается из JavaScript с
помощью свойства value соответствующего объекта. Вот пример для тега <textbox id="txt"/>:
document.getElementById("txt").value = "initial text";
Четвертый вариант <textbox> имеет место, когда значением type
является autocomplete. Это сложный тег с большой долей зависящей от
приложения функциональности. После тщательного тестирования мы не
рекомендуем использовать тег <textbox type= "autocomplete">
как основной инструмент в своих приложениях. Дело в том, что данный
тег применим еще далеко не во всех случаях.
Где этот тег на высоте, так это в классическом браузере. Простого
объявления вроде приведенного ниже достаточно для предоставления
быстрого доступа к журналу посещений браузера, мини-базам данных
адресов электронной почты или адресов
<textbox type="autocomplete" searchSessions="addrbook"/>
Так как ни одна из этих баз данных не может быть доступна как
отдельное приложение, применение <textbox> довольно ограничено.
Однако можно применять его к любой мини-базе данных, даже такой
простой, как массив значений в JavaScript. Делая это, вы обрекаете
себя на борьбу с интерфейсом, который еще не до конца стабилен или
вообще не предназначался для повторного использования. Затратив
примерно день, вы можете проанализировать XBL-определение
autocomplete.xml для этого тега и найти какие-то обходные пути,
подходящие вашим данным. Это может быть одноразовое решение, но можно
и создать собственное XBL-определение с нуля, если вы задумали
серьезное приложение.
XUL не связывает элементы форм с целевым URL так, как это делает HTML, но все же цель заполнения формы - отправить куда-то информацию. В Mozilla возможности хранения данных так же универсальны и разнообразны, как и в любых других средах программирования. Это не очень удобно, если вы хотите быстро создать работающий прототип. Mozilla предоставляет два варианта эффективной отправки данных XUL-формы на web-сервер.
Первый метод отправки данных XUL-формы, очень быстрый и не самый аккуратный, подразумевает использование пространств имен XML. Можно создать документ, который начинается с XUL, но включает все функции HTML. В листинге 7.1 показан такой документ.
<?xml version="1.0"?>
<!DOCTYPE window>
<window xmlns="http://www.mozilla.org/keymaster/
gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<vbox>
<script>
function copy() {
var getID = document.getElementByID;
getID("h1").value = getID("x1").value;
getID("h2").value = getID("x2").value;
return true;
}
</script>
<html:form action="test.cgi" method="GET"
enctype="application/x-www-form-urlencoded">
<html:input id="h1" type="hidden"/>
<html:input id="h2" type="hidden"/>
<radiogroup>
<button id="x1" label="Кнопка 1" type="radio"/>
<button id="x2" label="Кнопка 2" type="radio"/>
</radiogroup>
<html:input type="submit" onsubmit="return copy();">
</html:form>
</vbox>
</window>
Этот документ отображает форму, состоящую из двух XUL-кнопок и одной XHTML-кнопки для отправки данных. В обычном XHTML нельзя поместить кнопки в группу переключателей, но здесь это допустимо, так как Mozilla поддерживает сочетание XUL и HTML. XHTML-элементы формы связываются с процессом отправки данных формы, но XUL-элементы - нет. Простая функция на JavaScript копирует необходимые данные в скрытые поля перед отправкой информации.
Можно создать действительный документ из XHTML+XUL, не прибегая к
пространствам имен xmlns. Для этого нужно начать с "чистого"
XHTML-документа (или XUL-документа) и добавить <!DOCTYPE>. Такой
документ не использует особый механизм xmlns, с помощью которого
Mozilla определяет тип документа. Это значит, что для таких
дополнительных тегов не будет использоваться никакая дополнительная
обработка (поддержка). Это отсутствие определения типов - причина
того, что добавление тега <A> в XUL-документ не приводит к
созданию XHTML-ссылки.
Во второй методике отправки данных XUL-формы используется объект . Это доступный из скриптов AOM-объект, применимый во
всех Image в HTML-документах. Он
позволяет отправлять HTTP-запросы напрямую из JavaScript. Ответ
сервера на такой запрос не замещает текущий отображаемый документ.
Такой ответный документ просто читается как одна большая строка.
Объект основывается на следующем XPCOM-компоненте:
@mozilla.org/xmlextras/xmlhttprequest;1
Этот компонент реализует XPCOM-интерфейсы nsIXMLHttpRequest и nsIJSXMLHttpRequest, которые хорошо объясняются в файлах определений.
Эти интерфейсы позволяют отправлять HTTP-запросы синхронно и
асинхронно. Синхронная отправка означает, что скрипт приостанавливает
свою работу, пока не будет получен полный ответ. Асинхронная отправка
- аналог самонаводящегося снаряда, только этот запрос можно
отслеживать, а конечный результат - забрать. В листинге 7.2 показано,
как работают синхронные запросы.
var req = new XMLHttpRequest();
// Запрос
var res = null;
// Ответ
var params = encodeURI("param1=value1;param2=value2");
// -- GET-запрос
req.open("GET", "test.cgi" + "?" + params);
req.send("");
if ( req.status / 100 == 2 )
// Ответ HTTP 2xx?
res = req.responseText;
// -- POST-запрос
req.open("POST", "test.cgi");
req.send(params);
if ( req.status / 100 == 2 )
// Ответ HTTP 2xx?
res = req.responseText;
Функция encodeURI() - аналог для ;
поддерживаются обе. Второй аргумент open() - любой корректный URL. Так
как send() не возвращает ничего, пока пара запрос-ответ не будет
полной, программист должен предоставить пользователю какой-нибудь
индикатор вроде "Ожидается..." сразу перед вызовом send(),
чтобы пользователь знал, что приложение продолжает работу, а не просто
"зависло".
Асинхронная отправка данных форм полезна, когда нужно выполнить
несколько HTTP-запросов. Более эффективно отправить все запросы за
раз, а затем время от времени проверять их состояние. Простейший
способ выполнить асинхронную отправку - поместить ее в функцию и
запланировать с помощью . В листинге 7.3 показан более
формальный и структурированный подход с использованием интерфейса nsIXMLHttpRequest.
var req = new XMLHttpRequest(); // Запрос var res = null;
// Ответ var url = "test.cgi?text1=value1";
// Часть, специфичная для асинхронных запросов
function finished() {
res = req.responseText;
}
function inprogress() {
if ( req.readyState != req.COMPLETED ) {
res = "Waiting ...";
setTimeout(inprogress, 100);
}
}
req.COMPLETED = 4;
// из интерфейса
req.onload = finished;
// -- GET-запрос (POST аналогичен)
req.open("GET", url, false);
// false == асинхронный req.send();
// следующая инструкция выполняется немедленно
setTimeout(inprogress,100);
В этом примере метод send() возвращает ? почти сразу, оставляя
HTTP-запрос в обработке. Функция finished() создана как обработчик
событий, который запускается, когда ответ наконец-то получен
полностью. Между этими двумя точками во времени используется для простой регулярной проверки состояния. При
использовании таких асинхронных запросов пользователю могут не
требоваться уведомления о состоянии. Тем не менее, программист должен
позаботиться о том, чтобы последующие действия пользователя не
повлияли на обработку ответа, когда он появится. Например,
пользователи, покупающие акции, не должны иметь возможность опустошить
свои банковские счета во время процесса покупки акций.
Меню и формы сочетаются как вино и сыр. Теги меню в Mozilla строятся из более простых XUL-тегов, как и большая часть остальных XUL-тегов, обсуждавшихся до этого момента. Однако меню немного сложнее по нескольким причинам:
Для списков в <listbox>. XUL-меню применяются только для
всплывающих меню. Меню Mozilla следуют правилам дизайна, применимым к
простым элементам форм, потому могут считаться своего рода простым
элементом форм.
В этом разделе описывается поддержка меню в XUL, начиная от самого маленького тега. Теги, которые автор приложения может использовать для создания простых всплывающих меню, включают в себя:
<menulist> <menupopup> <menuitem> <menuseparator> <menu> <button> <toolbarbutton>
Следующие дополнительные структурирующие теги можно использовать, если нужно исследовать систему меню в XUL более внимательно. Вообще говоря, они не обязаны находиться в XUL-документе:
<dropmarker> <arrowscrollbox> <scrollbox> <autorepeatbutton>
На рисунке 7.3 показана структура полнофункционального, но простого XUL-меню с двумя элементами.
(рис 7.3) Полная структура XUL-менюНа этом рисунке показаны два аспекта одного и того же меню. В схеме
слева показаны теги, указанные автором приложения. В схеме справа меню
состоит из тегов, которые на самом деле создаются XUL/XBL-системой
Mozilla. Очевидно, что задействуется много тегов. Система меню
спроектирована так, что меню всегда составляется из полного набора
данных, но ненужные части скрываются. Например, теги <autorepeatbutton> не показываются, если элементов меню так
мало, что они все видны сразу. Второй пример - различные надписи и
изображения. У каждого пункта меню может быть пиктограмма и клавиша
доступа, а также обычный описательный текст - вместе один тег <image> и два <label>. Эти теги проявляются благодаря
атрибутам, предоставленным программистом, или в зависимости от условий
отображения меню.
Сложная структура тегов меню не означает сложной обработки событий.
Событие command и его обработчик oncommand - все, что нам нужно для
связывания простых меню с логикой работы своего приложения.
Возможны также различные виды адаптации XUL-меню на уровне тегов.
Внутри меню теги <menuitem> можно заменить тегами <menuseparator> или <menu>. Снаружи теги, окружающие <menupopup>, можно переорганизовать, заменив <menulist> на
что-то другое.
Тег <menuitem> представляет один пункт меню. У него есть
несколько XBL-определений, из которых применяется только одно.
Атрибуты этого тега со специальными значениями:
type disabled image validate src checked label accesskey acceltext crop value
Атрибут type в простых случаях не используется, но его значением
может быть или checkbox. Эффект использования этих значений -
пункт меню будет выглядеть и реагировать как эквивалентный элемент
формы. Атрибут disabled делает пункт меню недоступным для выбора.
Следующий набор атрибутов относится к пиктограмме пункта меню. Если
она указана, то по умолчанию появляется слева, но стандартные атрибуты
выравнивания содержимого блоков вроде dir могут изменить ситуацию. И image, и src задают URL изображения пиктограммы. В стандартном меню <menulist> текущий выбранный пункт появляется на кнопке меню,
если меню не раскрыто. Если используется src, то пиктограмма
выбранного пункта меню также появится на кнопке меню. Если заданы и type, и src или image, пиктограмма переключателя или флажка получает
больший приоритет, чем пиктограмма самого пункта меню. У то
же значение, что и в случае тега <image> ; у checked смысл тот
же, что и в тегах < и <checkbox>.
Третий набор атрибутов относится к обычному сопроводительному
тексту пункта меню. Этот текст может отсутствовать. Текст
предоставляется label. accesskey предоставляет клавишу доступа к
пункту меню, как описано в лекции 8, "Навигация".
acceltext и применимы только к меню, создаваемым с помощью
тега <menu>. поступает с текстом пункта меню так же, как и
в случае <label>. acceltext предоставляет текст справа от текста
пункта меню, который сообщает о том, какая комбинация клавиш выбирает
этот пункт меню. Такой текст никогда не обрезается. Обычно это просто
описание комбинации клавиш, например, "Shift-A". Если acceltext присутствует, отображается его значение. Если он
отсутствует, но есть атрибут key, тогда текст берется из
соответствующего тега <key>. Этот тег предоставит текст из
своего атрибута keytext или, если таковой отсутствует, из атрибута key, или, если и его нет, то из атрибута keycode. Во всех трех случаях
текст будет дополнен содержимым атрибута modifiers тега <key>.
Это простое напоминание пользователю, что любое нажатие клавиш может
соответствовать пункту меню, и обозначение связи между нажатиями и
пунктами меню.
Атрибут value задает внутреннее значение пункта меню. Это значение
может использоваться как идентификатор данного пункта меню, так как
сопроводительный текст может быть переведен на другой язык системой
локализации платформы.
На рисунке 7.4 показаны примеры использования многих из этих атрибутов. Изображенное окно составлено из нескольких кусков настоящего кода. Обратите внимание, что на самом деле создать два одновременно выпадающих меню нельзя.
(рис 7.4) Примеры разных <menuitem>Из рисунка 7.4 ясно, что <menuitem> очень гибок. У этого тега
имеется также целый арсенал стилей, с помощью которых можно менять его
внешний вид.
Тег <menuseparator> - почти анонимный XUL-тег с некоторыми
собственными правилами стилей. Он отображается как горизонтальная
линия, визуально разделяющая пункты меню. Множество примеров можно
найти в строке меню самой Mozilla. Этот тег находится на одном уровне
с <menuitem>. У него нет особых атрибутов, но иногда полезно
присваивать ему идентификатор ( id ).
Платформа Mozilla определяет этот тег при выполнении операций с меню.
Теги <arrowscrollbox> и <scrollbox> позволяют
пользователю перемещаться по содержимому, расположенному в виде
прямоугольника, который не помещается на экран целиком. Оба тега
обсуждаются в лекции 8, "Навигация", но у них есть применения
и в меню. В меню оба создаются автоматически.
Тег <arrowscrollbox> создается для отображения слишком
длинного меню, выходящего за пределы экрана. Если меню длинное,
автоматически появляются кнопки <autorepeatbutton> - части <arrowscrollbox>. Проще всего увидеть работу этого тега на
личной панели Навигатора Mozilla.
Для этого следует убедиться, что папка закладок находится на личной
панели и что в ней много закладок. Закладок и папок должно быть
столько, чтобы их список занимал, по крайней мере, половину высоты
экрана. Переместите окно Навигатора так, чтобы личная панель по высоте
находилась примерно в середине экрана, и нажмите на кнопку закладок
(напоминаем, закладок должно быть много). Появится список закладок,
вверху и внизу которого будут пиктограммы <arrowscrollbox>. Они
также появятся, если задать тегу <menupopup> атрибут maxheight с
каким-нибудь маленьким значением, например, 200 пикселов.
Тег <scrollbox> создает перемещаемую область внутри <arrowscrollbox>. Полосы прокрутки показываются, только если они
используются внутри тега <textbox type="autocomplete">.
При использовании внутри <arrowscrollbox> у него нет класса стиля и обычно его не стоит
трогать.
Кнопки тега <arrowscrollbox> можно менять с помощью стилей.
Они также не могут прокручивать содержимое вбок, только вверх и
вниз.
Тег <menupopup> - сердце системы XUL-меню. Он отвечает за
создание окна вне нормального потока размещения элементов XUL-документа
и может выходить за пределы окна Mozilla. Для этого
используется функциональность
Тег <menupopup> универсален. Он создает маленькое окно,
действующее как <, в которое можно поместить простейшее
XUL-содержимое. Почему это сделано так, не совсем ясно, но такая
особенность позволяет создавать очень красиво оформленные меню.
Единственное, что можно выделять в <menupopup> - теги <menuitem> и <menu>. Тег <menupopup> можно указывать
и без содержимого вообще. Содержимое может добавляться позднее с
помощью JavaScript, шаблонов или других XUL-техник.
При создании меню автор приложения должен использовать этот тег.
Атрибуты, имеющие особое значение в <menupopup>:
popupanchor popupalign position allowevents onpopupshowing onpopupshown onpopuphiding onpopuphidden
popupanchor задает угол родительского тега, рядом с которым
появится <menupopup> - так называемую опорную точку. popupalign
определяет угол всплывающего меню, который будет зафиксирован
относительно опорной точки. Следовательно, меню будет выравниваться по
заданному углу родительского тега. Оба атрибута могут принимать одно
из следующих значений:
topleft topright bottomleft bottomright none
Атрибут position предоставляет использовавшийся ранее и менее гибкий способ выравнивания, и его следует избегать. Он устарел.
Значением атрибута allowevents может быть true, но обычно этого
делать не рекомендуется. В платформе Mozilla производится специальная
обработка меню. На рисунке 7.3 показан сложный набор тегов,
составляющих меню. Если применять к этому набору полноценную DOM-модель
событий, выбор пункта меню приводил бы к созданию множества
событий. Платформа Mozilla сводит эти события в одно управляемое
событие команды.
Оставшиеся четыре атрибута - обработчики упоминавшихся ранее DOM-
событий. Это парные цели событий. События -showing -shown запускаются
в начале и в конце процесса открытия меню соответственно. События - и -hidden запускаются в начале и в конце процесса сворачивания
меню соответственно. Процесс отображения проходит три стадии, каждая
из которых помечается Mozilla заданием значения true одному из
следующих трех временных атрибутов:
menutobedisplayed menugenerated menuactive
Первый из них означает, что что-то должно произойти, но еще не произошло. Второй показывает, что содержимое меню было собрано. Третий сообщает, что меню раскрыто и получило фокус.
Полезное содержимое <menupopup> состоит из трех тегов: <menuitem>, <menuseparator> и <menu>. Тег <menu> очень похож на <menuitem>, но создает новое меню
сбоку от уже существующего. Вот особые атрибуты этого тега:
label accesskey crop acceltext disabled
Значение этих атрибутов то же, что и в случае <menuitem>. Тег <menu> не может содержать пиктограмму, соответствующую его
действию, но ее можно добавить с помощью подходящего стиля. При
отображении у этого тега автоматически появляется пиктограмма в виде
стрелки, говорящая о том, что здесь есть подменю. Единственный тег,
который может появиться внутри <menu> - <menupopup>.
Тег <menu> также используется в строках меню:
<menulist id="foo" editable="true"/>
Тег <menulist> - самый внешний тег для простых XUL-меню. Это
оболочка тега <menupopup>, дающая пользователю возможность
видеть что-то и взаимодействовать с чем-то, когда всплывающее меню
свернуто. <menulist> отображается в виде кнопки, показывающей
текущий выбранный пункт меню и кнопки раскрытия меню. В <menulist> всегда отображается текущий выбранный пункт меню.
Внутри <menulist> может находиться только тег <menupopup>. Особые атрибуты <menulist>:
src label crop accesskey disabled editable value
Смысл этих атрибутов тот же, что и у соответствующих атрибутов <menuitem>, только disabled делает недоступным все меню целиком.
Новый атрибут - editable.
Название этого атрибута не совсем корректно. Если его значение - true, надпись на кнопке <menulist> заменяется текстовым полем
HTML <input type="text">, куда пользователь может
ввести строку. Когда фокус переходит с <menulist>, эта строка
будет сравниваться с существующими пунктами меню. Если она совпадает с
основным текстом какого-нибудь пункта, этот пункт станет выбранным.
Все пункты меню обрабатываются так, как если бы у них был атрибут type="checkbox". Атрибут editable не дает возможности
вставлять, удалять и обновлять пункты меню.
Тег <menulist> - оболочка для тега <menupopup>. Есть и
другие оболочки. Вот их полный список:
<menulist> <menulist editable="true"> <menu> <button type="menu"> <button type="menu-button> <toolbarbutton type="menu"> <toolbarbutton type="menu-button"> <textbox type="autocomplete"> <menubutton>
Использование любого из этих тегов, кроме <textbox>,
подразумевает добавление <menupopup> как единственного их
содержимого. <menubutton> - анонимный тег, использующийся для
хранения стилей и обработчиков меню, появляющихся на панелях
инструментов (см. лекцию 8, "Навигация").
В MacOS можно добавлять пункт "Настройки..." и нужные
подменю в меню приложения. Чтобы это сделать, следует убедиться, что у
подходящего тега <menuitem> есть специальный идентификатор id="menu_preferences".
Как и в случае статического содержимого и кнопок, Mozilla дублирует большую часть информации о формах и меню в системе стилей.
Возможно, самые важные особенности стилей - те правила, которые
определяют XBL-связку, относящуюся к данному XUL-тегу. Атрибут type
(для <button>, <toolbarbutton> и <textbox> ) и
атрибут editable (для <menulist> ) - все они указываются в
правилах стиля. Эти правила определяют для основного XUL-тега
конкретную связку, которая в итоге влияет на содержимое тега, его
внешний вид и поведение. Изучив XBL, вы сможете добавлять собственные
связки и соответствующие правила стилей. Атрибут type затем может
предоставить другие варианты элементов управления.
Некоторые стандартные стили
| Свойство или селектор | Значения | Описание |
|---|---|---|
:-moz- |
(селектор) | Любой элемент, над которым мышью перетаскивается объект |
:-moz-selection |
(селектор) | В версии 1.2.1 почти полная поддержка ::selection из CSS 3 |
-moz-key- |
См. черновик стандарта | Эквивалент key- из черновика CSS 3 |
-moz- |
Те же, что и для margin, но используйте пикселы |
Эти атрибуты похожи на атрибут margin, но они определяют скругленность углов границы или контура |
-moz- |
Пикселы | Скругленность конкретного угла; 0 означает отсутствие скругления |
-moz- |
То же, что и для |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для color |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для border-style |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для border-width |
Почти полная поддержка из CSS 2 |
| $$-moz-user-focus$$ | См. черновик стандарта | Эквивалент user- из черновика CSS 3 |
-moz-user-input |
См. черновик стандарта | Эквивалент user-input из черновика CSS 3 |
-moz-user-modify |
См. черновик стандарта | Эквивалент user-modify из черновика CSS 3 |
-moz-user-select |
См. черновик стандарта плюс -moz-all |
Эквивалент user-select из черновика CSS 3 |
Стили, относящиеся к контурам, до определенной степени
соответствуют стилям границ (см. раздел "Альтернатива: таблицы
стилей" лекции 2, "Проектирование с XUL"). Значения -moz-all для стиля -moz-user-select позволяют быть выбранными
нескольким элементам форм. Это полезно, если вы разрабатываете
графическую среду разработки для XUL и хотите иметь возможность
группировать элементы формы одним действием.
Тег <menupopup> основывается на следующем стиле:
display: -moz-popup
Свойство стиля -moz- заставляет данный тег принимать
внешний вид, характерный для
radio checkbox textfield menulist menulist-button menulist-text menulist-textfield checkbox-container radio-container
После многих лекций, в которых мы закладывали фундамент приложения, у
нас наконец-то появились некоторые полезные элементы управления. В
этом разделе мы избавимся от некоторых накопившихся в окне NoteTaker
несуразностей и заменим их нормальными элементами XUL-форм. Мы
избавимся от файла .properties и будем отправлять собранные в форме
данные на web-сервер. Если диалог будет появляться в результате
HTTP-запроса GET, значения параметров из этого запроса также будут
использоваться.
Прежде всего, займемся наведением порядка. Мы откажемся от атрибута и функции handle_click(). Если мы еще хотим отключать
какое-либо содержимое, имеет смысл делать это теперь собственными средствами
тегов. То есть все load_data(), все еще
актуальна, но текущая реализация нам больше не подходит.
Наконец, мы избавимся от вспомогательных стилей boxes.css /
boxesTemp.css и их тегов <box>. Вместо них у нас будут:
<textbox> для раздела Summary ;<textbox> для раздела Details ;<checkbox> для раздела Options ;<textbox> для раздела Size.Как показано в листинге 7.4, соответствующие теги очень просты.
<textbox id="dialog.summary"/> <textbox id="dialog.details multiline="true" flex="1"/> <checkbox id="dialog.chop-query" dir="rtl" label="Chop Query" checked="true"/> <checkbox id="dialog.home-page" dir="rtl" label="Home Page" checked="true"/> <textbox id="dialog.width" value="100" maxwidth="3" size="3"/> <textbox id="dialog.height" value="90" maxwidth="3" size="3"/> <textbox id="dialog.top" value="80" maxwidth="3" size="3"/> <textbox id="dialog.left" value="70" maxwidth="3" size="3"/>
После внесения этих изменений и некоторой корректировки размещения диалог должен быть похож на снимок на рисунке 7.5.
(рис 7.5) Диалог на основе формПеред заменой load_data() мы немного поэкспериментируем.
DOM-объекты тегов XUL-форм очень похожи на DOM-объекты тегов <checkbox> и так далее, либо просто вспоминая разные
трюки, использовавшиеся на web-страницах. Заменим этот код в load_data():
desc = document.createElement("description");
desc.setAttribute("value",value);
box = document.getElementById("dialog." + names);
box.appendChild(desc);
на этот:
if (box.value) box.value = value;
Так как у большинства элементов форм есть свойство value, нам
удалось загрузить большую часть файла .properties в форму одним
простым действием.
Поработав над формой, мы бы хотели теперь обработать вводимые пользователем данные: описание заметки. Теперь мы хотим читать данные формы и заполнять ее. Есть много мест, куда можно отправить информацию, но мы попробуем воспользоваться web-сервером. Возможно, когда-нибудь эту заметку можно будет просмотреть из любого браузера Mozilla.
Чтобы сохранить заметку NoteTaker, мы используем уже знакомый по
этой лекции код, только слегка адаптируем его и поместим в метод action(). Мы также сохраним массив имен ( names ), который ранее был
локальным для load_data(), но сейчас мы сделаем его глобальным. В
листинге 7.5 показан новый алгоритм.
if (task == "save") {
var req = new XMLHttpRequest(); // Request
var params = "";
var i = names.length -1; // build up params
while (i>=0) { var widget = document.getElementById
("dialog." + names);
if (widget.tagName == "checkbox")
params += names + "=" + widget.checked + ";";
else
params += names + "=" + widget.value + ";"; i--;
}
params = encodeURI(params); req.open("POST", "test.cgi");
req.send(params);
if ( req.status / 100 != 2 ) // HTTP 2xx Response?
throw("Save attempt failed");
}
Конечно, на web-сервере должен быть test.cgi или его аналог. Если
мы запускаем приложение из
NoteTaker работает с классическим браузером, поэтому вряд ли он
будет загружаться с удаленного сервера. Тем не менее возможно, что во
время создания окна ему будут передаваться какие-то аргументы. Так как
программное окружение нашего приложения то же, что и у остального
chrome://notetaker/content/editDialog.xul
но тот же документ можно загрузить с помощью
chrome://notetaker/content/editDialog.xul?top=440;left=200
Эта информация далее может быть прочитана с помощью AOM-свойства
window.location. Мы сделаем это, создав новую задачу для метода action(), которую назовем load. В отличие от остальных задач, которые
как-либо связаны с графическим интерфейсом, эта функция - чистый
скрипт. Новый обработчик onload тега <window> будет:
onload="action('load')"
Код, добавляемый в метод action(), показан в листинге 7.6. Объект window.location - один из немногих AOM-объектов, которые доступны и в
HTML-, и в XUL-документах. Он предоставляет объект с помощью
интерфейса nsIDOMLocation и полезен в XUL только в описанном
случае.
if (task == "load" ) {
var pair, widget;
params = window.location.toString();
if ( params.indexOf("?") == -1 )
return;
params = params.replace(/.*\?/,"");
params = params.split(/[;]/);
i = params.length – 1;
while (i >=0 ) {
pair = params.split(/=/);
pair[0] = decodeURI(pair[0]);
pair[1] = decodeURI(pair[1]);
widget = document.getElementById("dialog."+ pair[0])
if (widget.tagName == "checkbox")
widget.checked = ( pair[1] == "true" );
else widget.value = pair[1];
i--;
}
}
В этом коде используется поддержка регулярных выражений из
replace() применяется для удаления всех символов
до символа ?, с которого начинается строка параметров. split()
разделяет оставшуюся строку на массив строк с разделением везде, где
происходит совпадение с ; или . Наконец, каждая пара
Формы и события не так уж интересны, если только вы не составляете собственные элементы управления. Некоторые стандартные методики могут упростить задачу.
Тег <menupopup> появляется, только когда вы нажимаете на
связанную с ним кнопку. Это может быть неудобно, если просто требуется
проверить, корректно ли составленное содержимое. Вы можете поместить
меню в нормальный поток XUL-документа, изменив его стиль отображения
так:
menupopup { display: -moz-box ! important }
После этого меню больше не будет интерактивным, но можно будет, по крайней мере, без труда просматривать его содержимое. На рисунке 7.6 показан тот же документ, что и на рисунке 7.3, только с использованием указанного выше стиля.
(рис 7.6) Пример встраивания содержимого <menupopup> в документВообще это не лучшая стратегия реализации или даже тестирования; просто такой способ работает и иногда бывает наиболее удобным.
Для освоения сложных элементов управления вроде <menulist>
могут потребоваться некоторые усилия, особенно если вам не нравится
содержимое, внешний вид или поведение по умолчанию. Простейшая
стратегия - анализировать данный тег с помощью Инспектора DOM. Этот
инструмент раскроет содержимое, идентификаторы и классы стилей данного
тега, вам нужно будет только нажать на кнопку. Это так просто, почему
бы не поэкспериментировать?
Другая используемая в этой лекции и некоторых других стратегия - применение специальных таблиц стилей. Некоторые из примеров в этой книге дополнены простыми стилями, которые создают визуальные подсказки. В листинге 7.7 показаны примеры таких вспомогательных стилей.
label {
border: dashed thin;
padding: 2px;
margin: 2px;
}
image {
border: solid thin;
padding: 2px;
margin: 2px;
}
.radio-check {
width:20px;
height:20px;
}
.checkbox-check {
width:20px;
height:20px;
}
vbox, hbox, box, deck {
border: solid;
padding: 2px;
margin: 2px;
border-color: grey;
}
* {
font-family:Arial;
font-weight: bold;
}
Все это довольно просто, за исключением, возможно, стилей для флажков, которые можно исследовать с помощью Инспектора DOM. Без этих двух стилей пиктограммы флажков будут сильно уменьшены из-за полей, добавляемых другими правилами.
В этой лекции описывается XUL-интерфейс для форм и меню Mozilla, но не JavaScript-интерфейсы для соответствующих DOM-объектов этих тегов. Есть несколько способов поиска AOM- и DOM-свойств и методов этих объектов.
SelectedIndex, focus () и blur() - все они работают ожидаемым образом. Они также задокументированы в стандарте DOM 1 Core, в разделе, посвященном HTML.Формы и меню - первая жизненно важная точка доступа для
пользователей, которые хотят взаимодействовать с приложениями на
основе Mozilla. XUL поддерживает простые элементы управления формы
(или просто элементы формы), с которыми пользователи браузеров уже
знакомы. Однако поддержка в XUL такими простыми элементами форм и меню
не ограничивается. Эта поддержка идет гораздо дальше и не связана
жестко с действиями пользователя, как в случае
В отличие от HTML, XUL-приложения могут отправлять данные форм в Сеть только с помощью скрипта. Однако такая отправка может быть более гибкой, чем любая отправка данных из HTML-формы.
И формы, и меню достаточно интересны, но если увлечься ими слишком сильно, пользователь не сможет отправиться куда-то еще или исследовать другие части сложного приложения. Поддержка возможностей навигации - тема следующей лекции.
В этой лекции описывается большая часть XUL-тегов, использующихся для ввода данных. Также здесь будет рассказано, как отправлять содержимое форм в Internet. Об элементах управления и тегах, связанных с перемещением пользователя по документам, речь пойдет в лекции 8, "Навигация".
Лучший способ помочь пользователям при вводе данных - давать им подсказки и обеспечивать обратную связь. Бумажные документы, оформленные для этого особым образом, называются формами. В лекции 4, "Первые элементы управления и темы", подробно рассматривались кнопки. В этой лекции будут описаны другие основные элементы управления для создания форм, необходимые наряду с кнопками: меню, флажки, текстовые поля и т.д. Каждый из этих элементов управления плюс элементы управления меню является совершенно новым элементом или новой их группой.
На иллюстрации к этой лекции показано, где в Mozilla реализуются
меню и формы. Неудивительно, что XUL-теги форм и меню активно
пользуются библиотекой графических элементов
Формы и меню подчиняются тем же ограничениям, что и тег <button>:
чтобы их признали как формы (или меню), они должны выглядеть похожими
на формы (меню). Следовательно, информация о стиле играет важную роль
для этих элементов управления. Иллюстрация в начале лекции также
подчеркивает важность XBL-определений (связок). Теги форм и меню
обычно активно используются в скриптах, и программисту нужны XBL-
определения для этих тегов, чтобы знать, какие свойства и методы
доступны.
Наконец, иллюстрация показывает, что в реализации форм участвуют некоторые XPCOM-компоненты. Отправка заполненной формы на сервер - классическое применение технологии Mozilla и первый пример использования платформы как клиентского программного обеспечения по отношению к какому-либо серверу.
HTML-теги форм широко распространены. XUL-формы похожи на HTML- формы, поэтому мы начнем с краткого сравнениях обоих вариантов. Затем мы рассмотрим все XUL-теги, из которых составляются формы.
В HTML/XHTML есть тег <FORM>. Этот тег объединяет теги <BUTTON>, <SELECT>, <INPUT> и < в одну группу. У DOM-объекта,
соответствующего <FORM>, есть методы, составляющие значения полей
формы в HTTP-запрос GET или POST. Это автоматизация процесса
постоянного сбора данных формы путем их отправки на какой-либо
web-сервер. В результате web-приложения на основе HTML теперь
распространены повсеместно.
В XUL нет эквивалента тегу <FORM>. Эквивалентные элементы
управления форм в XUL не объединяются в группы (за исключением группы < ). В XUL нет аналога <INPUT TYPE="reset"> или <INPUT TYPE="submit"> и нет полуавтоматического процесса отправки данных
формы. Если пользователю дан один лишь только XUL-документ, при вводе
информации ничего не произойдет.
Это означает, что если XUL-приложение должно вести себя как HTML-форма, тогда процедура отправки данных должна добавляться вручную. Это делается с помощью скриптов, которые пишутся для каждого XUL-документа, который должен вести себя как форма. К счастью, писать такие скрипты несложно.
С другой стороны, элементы управления XUL-форм более разнообразны,
чем в HTML. Теги <button>, <textbox> и <menu> более гибки, чем их HTML-аналоги. Кроме того, в XUL существует множество более
функциональных тегов вроде <menubar>, <listbox> и <tree>, гораздо
более сложных, чем то, что может предложить HTML. Эти дополнительные
теги рассматриваются в более поздних лекциях.
В таблице 7.1 перечислены XUL-теги, наиболее похожие на HTML-теги форм и меню.
| HTML-тег | XUL-тег | Примечания |
|---|---|---|
<FORM> |
нет | Используйте объект |
<BUTTON> |
<button> |
|
<INPUT TYPE="button"> |
<button> |
|
<INPUT TYPE="text"> |
<textbox> |
|
<INPUT TYPE=" |
< |
Или <button type=" |
<INPUT TYPE="checkbox"> |
<checkbox> |
Или <button type="checkbox"> |
<INPUT TYPE="password"> |
<textbox type="password"> |
|
<INPUT TYPE="submit"> |
нет | Используйте <button> и скрипт |
<INPUT TYPE="reset"> |
нет | Используйте <button> и скрипт |
<INPUT TYPE="file"> |
нет | Используйте объект FilePicker |
<INPUT TYPE="hidden"> |
нет | Используйте обычную переменную JavaScript |
<INPUT TYPE="image"> |
<button> |
В любом случае для отправки формы используйте скрипт |
<SELECT> |
<menulist> или <listbox> |
|
<OPTGROUP> |
нет | Вместо этого используйте <menuseparator> |
<OPTION> |
<menuitem> |
|
< |
<textbox multiline="true"> |
Поддерживает атрибуты rows и cols |
<LABEL> |
<label> |
См. обзор альтернативных возможностей доступа |
<FIELDSET> |
< |
|
< |
< |
|
<INPUT TYPE=" |
< |
Формы и меню в приложениях с графическим интерфейсом обычно появляются вместе. Поддержка меню в XUL почти так же разнообразна, как поддержка кнопок. В отличие от обзора кнопок в лекции 4, "Первые элементы управления и темы", меню описываются в разных частях книги. Краткое сравнение всех типов меню представлено в разделе "Варианты меню" текущей лекции. Или же можно руководствоваться в поиске следующим списком:
<menulist>, который строится из <menupopup>, <menuitem> и других тегов, также описанных здесь;<listbox> описывается в лекции 13, "Списки и деревья";<menu>, описываются в лекции 8, "Навигация". Но в этой лекции рассказано об использовании <menu> для создания подменю;<menupopup>, описываются в лекции 10, "Окна и панели".Единственное существенное различие между меню в XUL заключается в
разнице между <listbox> и <menulist>. Первый из них гораздо сложнее.
Все остальные упомянутые теги - вариации на тему <menulist>. Все
выпадающие меню реализуются с помощью тега <menupopup>.
Форма, в которой некоторое число изменяемых пользователем элементов
собирается в структурированную группу - центральное понятие и для
HTML, и для XUL. HTML - это
HTML- и XUL-формы в Mozilla очень похожи. Простейшие элементы формы почти идентичны. Обработчики событий и навигация в обоих случаях работают в основном похожим образом. Любое введение в HTML с примерами использования JavaScript - хорошая подготовка для применения XUL-форм. Однако не стоит ожидать, что это сходство распространится до мельчайших деталей. Эти две системы форм реализованы отдельно, хотя некоторый общий код у них есть.
В этой лекции мы обсудим простейшие XUL-теги для создания форм. Набор основных тегов таков:
<button> <checkbox> <radio> <radiogroup> <textbox> <label>
Любой графический элемент формы называется элементом управления
формы ( "form control" в терминологии Microsoft) или просто
элементом формы ( "form element" - термин, изначально
появившийся в графическом дизайне и заимствованный оттуда Netscape и
W3C). Такие элементы могут взаимодействовать с пользователем самыми
разными способами, но все они объединяются общим дизайном.
Если пользователю нужно что-то ввести в форму, самый простой подход - взаимодействие в каждый момент только с одним элементом формы. И в XUL, и в HTML разрешается выделять один элемент управления за раз. Кроме того, интерактивные элементы форм в документе упорядочиваются. В терминах W3C это называется порядком переходов. В Mozilla упорядоченный набор таких элементов управления называется кольцом фокуса, так как, перейдя от последнего в наборе элемента далее, пользователь попадает снова на первый элемент. Все элементы форм входят в кольцо фокуса.
Более подробно изменение фокуса рассматривается в лекции 8, "Навигация".
В процессе разработки стандарта CSS 3 консорциум W3C создал
черновой документ "
Mozilla реализует множество положений этого черновика стандарта. В
частности, она воплощает четыре свойства стиля, представляющие
интерактивные возможности простых элементов XUL-форм. Эти стили в
Mozilla реализуются интерфейсом nsINSDOMCSS2Properties. В системе
стилей они доступны как расширения с префиксом -moz. Вот они:
user-input user-modify user-select user-focus
Эти свойства стиля в некотором смысле не зависят друг от друга и
они очень важны, так как облегчают понимание системы ввода данных
пользователем. Достичь этого понимания раньше было сложно, так как
результаты применения обработчиков событий наподобие onclick и DOM-методов
вроде обычно зависят от нескольких из этих четырех
состояний сразу. Теперь, когда эти состояния обозначены отдельно друг
от друга, легче понять, какой эффект произведут обработчики элементов
формы. Вы можете взять набор из этих четырех состояний и события и
написать новые состояния, которые появятся, если определенный элемент
формы с такими состояниями получит данное событие.
Помимо этих четырех стилей у элементов формы есть два других общих
понятия. Первое из них - собственное состояние. Все простые элементы
формы обладают, по крайней мере, одним общим атрибутом - disabled,
чьим значением может быть true. На рисунке 7.1 показаны активные и
неактивные ( disabled ) элементы управления формой.
(рис 7.1) Активные и неактивные элементы управления формойНаконец, у всех простых элементов формы есть общий набор обработчиков событий и соответствующих объектных методов для интерактивных событий вроде получения и потери фокуса.
Программное обеспечение можно сделать доступным для людей с ограниченными физическими возможностями. Гипертекстовые HTML-документы, ссылки и окна XUL-приложений - все это может быть доступно для таких пользователей. Элементы форм особенно интересны потому, что правительство любого государства заинтересовано в том, чтобы предоставить через Internet различные службы, которые будут одинаково доступны всем, в том числе людям с ограниченной дееспособностью.
Во всех обсуждениях до этого момента XUL-тег <label> был
идентичным тегу <description> во всем, за исключением
возможности сведения к атрибуту label. Но если взглянуть с точки
зрения доступности, сразу будут видны отличия <label> от <description>. Тег <label> позволяет предоставлять
альтернативное содержимое, необходимое для создания системы
доступности.
Если у элемента формы есть атрибут label, Mozilla предоставит его
значение как вспомогательную информацию, которую система доступности
передает пользователю. Если у элемента формы нет такого атрибута,
Mozilla будет искать его тег-<label> и использует его.
Если подходящего потомка не найдется, она будет искать тег <label>, чье значение атрибута control совпадает с
идентификатором, заявленным в атрибуте id тега элемента формы. Если и
такой тег не найден, тогда вспомогательная информация недоступна.
Поддержка расширенной доступности в Mozilla предусмотрена для всех
простых элементов XUL-форм. Эта поддержка есть и для тегов <menuitem>, <menulist> и <tab>.
Как работает такая доступность, подробнее рассматривается в лекции 8, "Навигация".
На рисунке 7.2 показаны простые теги форм с примененными к ним
дополнительными стилями, так что их структура становится понятнее.
Пунктирные линии означают теги <label>, толстые сплошные - теги <box>, а тонкие сплошные - теги <image>. Два средних
раздела - теги <, второй из которых содержит теги <button type=".
(рис 7.2) Простые элементы XUL-форм с открытой внутренней структуройИз рисунка 7.2 видно, что все простые теги форм содержат, по
крайней мере, один другой тег, даже если этот тег - <image> без
содержимого. Все эти теги форм определены в XBL.
В Mozilla есть специальные обработчики событий, написанные на
C/C++. Они добавляются к объекту XUL-документа с помощью C/C++-версии addEventListener(). Такие обработчики событий перехватывают
информацию, связанную с простыми элементами управления. Так
реализуется недоступная через XBL
У таких тегов есть DOM-интерфейсы, очень похожие на соответствующие
HTML-интерфейсы. Все имена XPCOM-интерфейсов начинаются с префикса nsIDOMXUL.
Тег <button> широко обсуждается в лекции 4, "Первые
элементы управления и темы". Вспомните, что атрибут type
позволяет превращать кнопку в флажок, переключатель или кнопку
раскрытия меню.
Тег <checkbox> составляется из простых содержательных XUL-
тегов. У него есть XBL-определение. Изображения флажков, появляющиеся
при отображении этого элемента управления, составляются из обычных
картинок. С помощью стилей можно сделать их больше или меньше или даже
заменить их. У <checkbox> есть следующие собственные
атрибуты:
src label crop checked disabled accesskey
src передается необязательному изображению, которое появляется
между флажком и текстом. передается <label>, содержащему
текст. checked принимает булевы значения, соответствующие состояниям <checkbox>, а disabled, если его значение - true, делает флажок
полностью недоступным пользователю. Сопроводительный текст может
появиться справа от флажка, если указан атрибут dir=".
Состояние каждого флажка не зависит от состояний других флажков. Если
щелкнуть по тексту ( <label> ) флажка, эффект будет тот же, что и
при щелчке по пиктограмме самого флажка.
С помощью <checkbox> отправляет событие CheckboxStateChange при смене
состояния. За этим состоянием, если нужно, может наблюдать код
приложения.
Тег < составляется из простых XUL-тегов. У него есть
XBL-определение. Пиктограммы переключателей - обычные изображения, и с
помощью стилей их можно увеличить, уменьшить или заменить другими. У
тега < есть следующие собственные атрибуты:
src label crop selected disabled accesskey
Эти атрибуты имеют то же значение, что и для тега <checkbox>,
только checked заменяется атрибутом selected. Если тег <
является потомком <, только у одного переключателя из
группы может быть атрибут selected="true". У нижнего тега < в первой группе переключателей на рисунке 7.2 задан
атрибут dir=". Для выбора переключателя можно щелкать и
по тексту ( <label> ), и по его пиктограмме.
До недавних версий Mozilla тег < не всегда правильно
определял, когда он должен получать фокус. Чтобы прояснить ситуацию с < в конкретной версии Mozilla, нужно обратиться к ее базе
данных ошибок.
Тег < связывает набор тегов < или <button type=" вместе и превращает в единое
целое. Если любой переключатель в такой группе выбран, все остальные
теряют выделение. Тег < поддерживает следующие
атрибуты:
disabled selectedItem focusedItem selectedIndex
disabled делает недоступной для пользователя всю группу. selectedItem и focusedItem сообщают, какой переключатель в группе
выбран или получил фокус, соответственно. selectedIndex содержит номер
текущего выбранного переключателя в группе, начиная с 0.
С помощью < отправляет события RadioStateChange и selected при
смене состояния. За этими событиями, если нужно, может наблюдать код
приложения.
Тег <textbox> позволяет пользователю вводить текст. Это
четыре тега в одном: обычное поле ввода, поле ввода пароля,
многострочное поле ввода и поле ввода с автодополнением. У <textbox> есть XBL-определение. Тег <textbox> реализуется
с помощью HTML-тегов <input type="text"> или <. У стандартного тега <textbox> есть следующие
особые атрибуты:
value disabled readonly type maxlength size multiline
Все эти атрибуты, кроме multiline и type, соответствуют атрибутам
HTML-тега <input type="text">. Значением multiline
может быть true, а значением type - password или autocomplete. Если type="password", <textbox> действует так, как HTML-тег <input type="password"> ; однако иначе и быть не может
- они одинаковы. Если значение multiline - true, у <textbox>
появляется другой набор атрибутов:
value disabled readonly rows cols wrap
Эти атрибуты соответствуют атрибутам HTML-тега <.
Так как в XUL нет анонимного содержимого, изначально отображаемый
текст не может заключаться между открывающим и < в HTML.
Для всех этих трех вариантов текстового поля начальное значение
может быть задано, только если поле не многострочное. В случае
многострочных полей начальное значение задается из JavaScript с
помощью свойства value соответствующего объекта. Вот пример для тега <textbox id="txt"/>:
document.getElementById("txt").value = "initial text";
Четвертый вариант <textbox> имеет место, когда значением type
является autocomplete. Это сложный тег с большой долей зависящей от
приложения функциональности. После тщательного тестирования мы не
рекомендуем использовать тег <textbox type= "autocomplete">
как основной инструмент в своих приложениях. Дело в том, что данный
тег применим еще далеко не во всех случаях.
Где этот тег на высоте, так это в классическом браузере. Простого
объявления вроде приведенного ниже достаточно для предоставления
быстрого доступа к журналу посещений браузера, мини-базам данных
адресов электронной почты или адресов
<textbox type="autocomplete" searchSessions="addrbook"/>
Так как ни одна из этих баз данных не может быть доступна как
отдельное приложение, применение <textbox> довольно ограничено.
Однако можно применять его к любой мини-базе данных, даже такой
простой, как массив значений в JavaScript. Делая это, вы обрекаете
себя на борьбу с интерфейсом, который еще не до конца стабилен или
вообще не предназначался для повторного использования. Затратив
примерно день, вы можете проанализировать XBL-определение
autocomplete.xml для этого тега и найти какие-то обходные пути,
подходящие вашим данным. Это может быть одноразовое решение, но можно
и создать собственное XBL-определение с нуля, если вы задумали
серьезное приложение.
XUL не связывает элементы форм с целевым URL так, как это делает HTML, но все же цель заполнения формы - отправить куда-то информацию. В Mozilla возможности хранения данных так же универсальны и разнообразны, как и в любых других средах программирования. Это не очень удобно, если вы хотите быстро создать работающий прототип. Mozilla предоставляет два варианта эффективной отправки данных XUL-формы на web-сервер.
Первый метод отправки данных XUL-формы, очень быстрый и не самый аккуратный, подразумевает использование пространств имен XML. Можно создать документ, который начинается с XUL, но включает все функции HTML. В листинге 7.1 показан такой документ.
<?xml version="1.0"?>
<!DOCTYPE window>
<window xmlns="http://www.mozilla.org/keymaster/
gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<vbox>
<script>
function copy() {
var getID = document.getElementByID;
getID("h1").value = getID("x1").value;
getID("h2").value = getID("x2").value;
return true;
}
</script>
<html:form action="test.cgi" method="GET"
enctype="application/x-www-form-urlencoded">
<html:input id="h1" type="hidden"/>
<html:input id="h2" type="hidden"/>
<radiogroup>
<button id="x1" label="Кнопка 1" type="radio"/>
<button id="x2" label="Кнопка 2" type="radio"/>
</radiogroup>
<html:input type="submit" onsubmit="return copy();">
</html:form>
</vbox>
</window>
Этот документ отображает форму, состоящую из двух XUL-кнопок и одной XHTML-кнопки для отправки данных. В обычном XHTML нельзя поместить кнопки в группу переключателей, но здесь это допустимо, так как Mozilla поддерживает сочетание XUL и HTML. XHTML-элементы формы связываются с процессом отправки данных формы, но XUL-элементы - нет. Простая функция на JavaScript копирует необходимые данные в скрытые поля перед отправкой информации.
Можно создать действительный документ из XHTML+XUL, не прибегая к
пространствам имен xmlns. Для этого нужно начать с "чистого"
XHTML-документа (или XUL-документа) и добавить <!DOCTYPE>. Такой
документ не использует особый механизм xmlns, с помощью которого
Mozilla определяет тип документа. Это значит, что для таких
дополнительных тегов не будет использоваться никакая дополнительная
обработка (поддержка). Это отсутствие определения типов - причина
того, что добавление тега <A> в XUL-документ не приводит к
созданию XHTML-ссылки.
Во второй методике отправки данных XUL-формы используется объект . Это доступный из скриптов AOM-объект, применимый во
всех Image в HTML-документах. Он
позволяет отправлять HTTP-запросы напрямую из JavaScript. Ответ
сервера на такой запрос не замещает текущий отображаемый документ.
Такой ответный документ просто читается как одна большая строка.
Объект основывается на следующем XPCOM-компоненте:
@mozilla.org/xmlextras/xmlhttprequest;1
Этот компонент реализует XPCOM-интерфейсы nsIXMLHttpRequest и nsIJSXMLHttpRequest, которые хорошо объясняются в файлах определений.
Эти интерфейсы позволяют отправлять HTTP-запросы синхронно и
асинхронно. Синхронная отправка означает, что скрипт приостанавливает
свою работу, пока не будет получен полный ответ. Асинхронная отправка
- аналог самонаводящегося снаряда, только этот запрос можно
отслеживать, а конечный результат - забрать. В листинге 7.2 показано,
как работают синхронные запросы.
var req = new XMLHttpRequest();
// Запрос
var res = null;
// Ответ
var params = encodeURI("param1=value1;param2=value2");
// -- GET-запрос
req.open("GET", "test.cgi" + "?" + params);
req.send("");
if ( req.status / 100 == 2 )
// Ответ HTTP 2xx?
res = req.responseText;
// -- POST-запрос
req.open("POST", "test.cgi");
req.send(params);
if ( req.status / 100 == 2 )
// Ответ HTTP 2xx?
res = req.responseText;
Функция encodeURI() - аналог для ;
поддерживаются обе. Второй аргумент open() - любой корректный URL. Так
как send() не возвращает ничего, пока пара запрос-ответ не будет
полной, программист должен предоставить пользователю какой-нибудь
индикатор вроде "Ожидается..." сразу перед вызовом send(),
чтобы пользователь знал, что приложение продолжает работу, а не просто
"зависло".
Асинхронная отправка данных форм полезна, когда нужно выполнить
несколько HTTP-запросов. Более эффективно отправить все запросы за
раз, а затем время от времени проверять их состояние. Простейший
способ выполнить асинхронную отправку - поместить ее в функцию и
запланировать с помощью . В листинге 7.3 показан более
формальный и структурированный подход с использованием интерфейса nsIXMLHttpRequest.
var req = new XMLHttpRequest(); // Запрос var res = null;
// Ответ var url = "test.cgi?text1=value1";
// Часть, специфичная для асинхронных запросов
function finished() {
res = req.responseText;
}
function inprogress() {
if ( req.readyState != req.COMPLETED ) {
res = "Waiting ...";
setTimeout(inprogress, 100);
}
}
req.COMPLETED = 4;
// из интерфейса
req.onload = finished;
// -- GET-запрос (POST аналогичен)
req.open("GET", url, false);
// false == асинхронный req.send();
// следующая инструкция выполняется немедленно
setTimeout(inprogress,100);
В этом примере метод send() возвращает ? почти сразу, оставляя
HTTP-запрос в обработке. Функция finished() создана как обработчик
событий, который запускается, когда ответ наконец-то получен
полностью. Между этими двумя точками во времени используется для простой регулярной проверки состояния. При
использовании таких асинхронных запросов пользователю могут не
требоваться уведомления о состоянии. Тем не менее, программист должен
позаботиться о том, чтобы последующие действия пользователя не
повлияли на обработку ответа, когда он появится. Например,
пользователи, покупающие акции, не должны иметь возможность опустошить
свои банковские счета во время процесса покупки акций.
Меню и формы сочетаются как вино и сыр. Теги меню в Mozilla строятся из более простых XUL-тегов, как и большая часть остальных XUL-тегов, обсуждавшихся до этого момента. Однако меню немного сложнее по нескольким причинам:
Для списков в <listbox>. XUL-меню применяются только для
всплывающих меню. Меню Mozilla следуют правилам дизайна, применимым к
простым элементам форм, потому могут считаться своего рода простым
элементом форм.
В этом разделе описывается поддержка меню в XUL, начиная от самого маленького тега. Теги, которые автор приложения может использовать для создания простых всплывающих меню, включают в себя:
<menulist> <menupopup> <menuitem> <menuseparator> <menu> <button> <toolbarbutton>
Следующие дополнительные структурирующие теги можно использовать, если нужно исследовать систему меню в XUL более внимательно. Вообще говоря, они не обязаны находиться в XUL-документе:
<dropmarker> <arrowscrollbox> <scrollbox> <autorepeatbutton>
На рисунке 7.3 показана структура полнофункционального, но простого XUL-меню с двумя элементами.
(рис 7.3) Полная структура XUL-менюНа этом рисунке показаны два аспекта одного и того же меню. В схеме
слева показаны теги, указанные автором приложения. В схеме справа меню
состоит из тегов, которые на самом деле создаются XUL/XBL-системой
Mozilla. Очевидно, что задействуется много тегов. Система меню
спроектирована так, что меню всегда составляется из полного набора
данных, но ненужные части скрываются. Например, теги <autorepeatbutton> не показываются, если элементов меню так
мало, что они все видны сразу. Второй пример - различные надписи и
изображения. У каждого пункта меню может быть пиктограмма и клавиша
доступа, а также обычный описательный текст - вместе один тег <image> и два <label>. Эти теги проявляются благодаря
атрибутам, предоставленным программистом, или в зависимости от условий
отображения меню.
Сложная структура тегов меню не означает сложной обработки событий.
Событие command и его обработчик oncommand - все, что нам нужно для
связывания простых меню с логикой работы своего приложения.
Возможны также различные виды адаптации XUL-меню на уровне тегов.
Внутри меню теги <menuitem> можно заменить тегами <menuseparator> или <menu>. Снаружи теги, окружающие <menupopup>, можно переорганизовать, заменив <menulist> на
что-то другое.
Тег <menuitem> представляет один пункт меню. У него есть
несколько XBL-определений, из которых применяется только одно.
Атрибуты этого тега со специальными значениями:
type disabled image validate src checked label accesskey acceltext crop value
Атрибут type в простых случаях не используется, но его значением
может быть или checkbox. Эффект использования этих значений -
пункт меню будет выглядеть и реагировать как эквивалентный элемент
формы. Атрибут disabled делает пункт меню недоступным для выбора.
Следующий набор атрибутов относится к пиктограмме пункта меню. Если
она указана, то по умолчанию появляется слева, но стандартные атрибуты
выравнивания содержимого блоков вроде dir могут изменить ситуацию. И image, и src задают URL изображения пиктограммы. В стандартном меню <menulist> текущий выбранный пункт появляется на кнопке меню,
если меню не раскрыто. Если используется src, то пиктограмма
выбранного пункта меню также появится на кнопке меню. Если заданы и type, и src или image, пиктограмма переключателя или флажка получает
больший приоритет, чем пиктограмма самого пункта меню. У то
же значение, что и в случае тега <image> ; у checked смысл тот
же, что и в тегах < и <checkbox>.
Третий набор атрибутов относится к обычному сопроводительному
тексту пункта меню. Этот текст может отсутствовать. Текст
предоставляется label. accesskey предоставляет клавишу доступа к
пункту меню, как описано в лекции 8, "Навигация".
acceltext и применимы только к меню, создаваемым с помощью
тега <menu>. поступает с текстом пункта меню так же, как и
в случае <label>. acceltext предоставляет текст справа от текста
пункта меню, который сообщает о том, какая комбинация клавиш выбирает
этот пункт меню. Такой текст никогда не обрезается. Обычно это просто
описание комбинации клавиш, например, "Shift-A". Если acceltext присутствует, отображается его значение. Если он
отсутствует, но есть атрибут key, тогда текст берется из
соответствующего тега <key>. Этот тег предоставит текст из
своего атрибута keytext или, если таковой отсутствует, из атрибута key, или, если и его нет, то из атрибута keycode. Во всех трех случаях
текст будет дополнен содержимым атрибута modifiers тега <key>.
Это простое напоминание пользователю, что любое нажатие клавиш может
соответствовать пункту меню, и обозначение связи между нажатиями и
пунктами меню.
Атрибут value задает внутреннее значение пункта меню. Это значение
может использоваться как идентификатор данного пункта меню, так как
сопроводительный текст может быть переведен на другой язык системой
локализации платформы.
На рисунке 7.4 показаны примеры использования многих из этих атрибутов. Изображенное окно составлено из нескольких кусков настоящего кода. Обратите внимание, что на самом деле создать два одновременно выпадающих меню нельзя.
(рис 7.4) Примеры разных <menuitem>Из рисунка 7.4 ясно, что <menuitem> очень гибок. У этого тега
имеется также целый арсенал стилей, с помощью которых можно менять его
внешний вид.
Тег <menuseparator> - почти анонимный XUL-тег с некоторыми
собственными правилами стилей. Он отображается как горизонтальная
линия, визуально разделяющая пункты меню. Множество примеров можно
найти в строке меню самой Mozilla. Этот тег находится на одном уровне
с <menuitem>. У него нет особых атрибутов, но иногда полезно
присваивать ему идентификатор ( id ).
Платформа Mozilla определяет этот тег при выполнении операций с меню.
Теги <arrowscrollbox> и <scrollbox> позволяют
пользователю перемещаться по содержимому, расположенному в виде
прямоугольника, который не помещается на экран целиком. Оба тега
обсуждаются в лекции 8, "Навигация", но у них есть применения
и в меню. В меню оба создаются автоматически.
Тег <arrowscrollbox> создается для отображения слишком
длинного меню, выходящего за пределы экрана. Если меню длинное,
автоматически появляются кнопки <autorepeatbutton> - части <arrowscrollbox>. Проще всего увидеть работу этого тега на
личной панели Навигатора Mozilla.
Для этого следует убедиться, что папка закладок находится на личной
панели и что в ней много закладок. Закладок и папок должно быть
столько, чтобы их список занимал, по крайней мере, половину высоты
экрана. Переместите окно Навигатора так, чтобы личная панель по высоте
находилась примерно в середине экрана, и нажмите на кнопку закладок
(напоминаем, закладок должно быть много). Появится список закладок,
вверху и внизу которого будут пиктограммы <arrowscrollbox>. Они
также появятся, если задать тегу <menupopup> атрибут maxheight с
каким-нибудь маленьким значением, например, 200 пикселов.
Тег <scrollbox> создает перемещаемую область внутри <arrowscrollbox>. Полосы прокрутки показываются, только если они
используются внутри тега <textbox type="autocomplete">.
При использовании внутри <arrowscrollbox> у него нет класса стиля и обычно его не стоит
трогать.
Кнопки тега <arrowscrollbox> можно менять с помощью стилей.
Они также не могут прокручивать содержимое вбок, только вверх и
вниз.
Тег <menupopup> - сердце системы XUL-меню. Он отвечает за
создание окна вне нормального потока размещения элементов XUL-документа
и может выходить за пределы окна Mozilla. Для этого
используется функциональность
Тег <menupopup> универсален. Он создает маленькое окно,
действующее как <, в которое можно поместить простейшее
XUL-содержимое. Почему это сделано так, не совсем ясно, но такая
особенность позволяет создавать очень красиво оформленные меню.
Единственное, что можно выделять в <menupopup> - теги <menuitem> и <menu>. Тег <menupopup> можно указывать
и без содержимого вообще. Содержимое может добавляться позднее с
помощью JavaScript, шаблонов или других XUL-техник.
При создании меню автор приложения должен использовать этот тег.
Атрибуты, имеющие особое значение в <menupopup>:
popupanchor popupalign position allowevents onpopupshowing onpopupshown onpopuphiding onpopuphidden
popupanchor задает угол родительского тега, рядом с которым
появится <menupopup> - так называемую опорную точку. popupalign
определяет угол всплывающего меню, который будет зафиксирован
относительно опорной точки. Следовательно, меню будет выравниваться по
заданному углу родительского тега. Оба атрибута могут принимать одно
из следующих значений:
topleft topright bottomleft bottomright none
Атрибут position предоставляет использовавшийся ранее и менее гибкий способ выравнивания, и его следует избегать. Он устарел.
Значением атрибута allowevents может быть true, но обычно этого
делать не рекомендуется. В платформе Mozilla производится специальная
обработка меню. На рисунке 7.3 показан сложный набор тегов,
составляющих меню. Если применять к этому набору полноценную DOM-модель
событий, выбор пункта меню приводил бы к созданию множества
событий. Платформа Mozilla сводит эти события в одно управляемое
событие команды.
Оставшиеся четыре атрибута - обработчики упоминавшихся ранее DOM-
событий. Это парные цели событий. События -showing -shown запускаются
в начале и в конце процесса открытия меню соответственно. События - и -hidden запускаются в начале и в конце процесса сворачивания
меню соответственно. Процесс отображения проходит три стадии, каждая
из которых помечается Mozilla заданием значения true одному из
следующих трех временных атрибутов:
menutobedisplayed menugenerated menuactive
Первый из них означает, что что-то должно произойти, но еще не произошло. Второй показывает, что содержимое меню было собрано. Третий сообщает, что меню раскрыто и получило фокус.
Полезное содержимое <menupopup> состоит из трех тегов: <menuitem>, <menuseparator> и <menu>. Тег <menu> очень похож на <menuitem>, но создает новое меню
сбоку от уже существующего. Вот особые атрибуты этого тега:
label accesskey crop acceltext disabled
Значение этих атрибутов то же, что и в случае <menuitem>. Тег <menu> не может содержать пиктограмму, соответствующую его
действию, но ее можно добавить с помощью подходящего стиля. При
отображении у этого тега автоматически появляется пиктограмма в виде
стрелки, говорящая о том, что здесь есть подменю. Единственный тег,
который может появиться внутри <menu> - <menupopup>.
Тег <menu> также используется в строках меню:
<menulist id="foo" editable="true"/>
Тег <menulist> - самый внешний тег для простых XUL-меню. Это
оболочка тега <menupopup>, дающая пользователю возможность
видеть что-то и взаимодействовать с чем-то, когда всплывающее меню
свернуто. <menulist> отображается в виде кнопки, показывающей
текущий выбранный пункт меню и кнопки раскрытия меню. В <menulist> всегда отображается текущий выбранный пункт меню.
Внутри <menulist> может находиться только тег <menupopup>. Особые атрибуты <menulist>:
src label crop accesskey disabled editable value
Смысл этих атрибутов тот же, что и у соответствующих атрибутов <menuitem>, только disabled делает недоступным все меню целиком.
Новый атрибут - editable.
Название этого атрибута не совсем корректно. Если его значение - true, надпись на кнопке <menulist> заменяется текстовым полем
HTML <input type="text">, куда пользователь может
ввести строку. Когда фокус переходит с <menulist>, эта строка
будет сравниваться с существующими пунктами меню. Если она совпадает с
основным текстом какого-нибудь пункта, этот пункт станет выбранным.
Все пункты меню обрабатываются так, как если бы у них был атрибут type="checkbox". Атрибут editable не дает возможности
вставлять, удалять и обновлять пункты меню.
Тег <menulist> - оболочка для тега <menupopup>. Есть и
другие оболочки. Вот их полный список:
<menulist> <menulist editable="true"> <menu> <button type="menu"> <button type="menu-button> <toolbarbutton type="menu"> <toolbarbutton type="menu-button"> <textbox type="autocomplete"> <menubutton>
Использование любого из этих тегов, кроме <textbox>,
подразумевает добавление <menupopup> как единственного их
содержимого. <menubutton> - анонимный тег, использующийся для
хранения стилей и обработчиков меню, появляющихся на панелях
инструментов (см. лекцию 8, "Навигация").
В MacOS можно добавлять пункт "Настройки..." и нужные
подменю в меню приложения. Чтобы это сделать, следует убедиться, что у
подходящего тега <menuitem> есть специальный идентификатор id="menu_preferences".
Как и в случае статического содержимого и кнопок, Mozilla дублирует большую часть информации о формах и меню в системе стилей.
Возможно, самые важные особенности стилей - те правила, которые
определяют XBL-связку, относящуюся к данному XUL-тегу. Атрибут type
(для <button>, <toolbarbutton> и <textbox> ) и
атрибут editable (для <menulist> ) - все они указываются в
правилах стиля. Эти правила определяют для основного XUL-тега
конкретную связку, которая в итоге влияет на содержимое тега, его
внешний вид и поведение. Изучив XBL, вы сможете добавлять собственные
связки и соответствующие правила стилей. Атрибут type затем может
предоставить другие варианты элементов управления.
Некоторые стандартные стили
| Свойство или селектор | Значения | Описание |
|---|---|---|
:-moz- |
(селектор) | Любой элемент, над которым мышью перетаскивается объект |
:-moz-selection |
(селектор) | В версии 1.2.1 почти полная поддержка ::selection из CSS 3 |
-moz-key- |
См. черновик стандарта | Эквивалент key- из черновика CSS 3 |
-moz- |
Те же, что и для margin, но используйте пикселы |
Эти атрибуты похожи на атрибут margin, но они определяют скругленность углов границы или контура |
-moz- |
Пикселы | Скругленность конкретного угла; 0 означает отсутствие скругления |
-moz- |
То же, что и для |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для color |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для border-style |
Почти полная поддержка из CSS 2 |
-moz- |
То же, что и для border-width |
Почти полная поддержка из CSS 2 |
| $$-moz-user-focus$$ | См. черновик стандарта | Эквивалент user- из черновика CSS 3 |
-moz-user-input |
См. черновик стандарта | Эквивалент user-input из черновика CSS 3 |
-moz-user-modify |
См. черновик стандарта | Эквивалент user-modify из черновика CSS 3 |
-moz-user-select |
См. черновик стандарта плюс -moz-all |
Эквивалент user-select из черновика CSS 3 |
Стили, относящиеся к контурам, до определенной степени
соответствуют стилям границ (см. раздел "Альтернатива: таблицы
стилей" лекции 2, "Проектирование с XUL"). Значения -moz-all для стиля -moz-user-select позволяют быть выбранными
нескольким элементам форм. Это полезно, если вы разрабатываете
графическую среду разработки для XUL и хотите иметь возможность
группировать элементы формы одним действием.
Тег <menupopup> основывается на следующем стиле:
display: -moz-popup
Свойство стиля -moz- заставляет данный тег принимать
внешний вид, характерный для
radio checkbox textfield menulist menulist-button menulist-text menulist-textfield checkbox-container radio-container
После многих лекций, в которых мы закладывали фундамент приложения, у
нас наконец-то появились некоторые полезные элементы управления. В
этом разделе мы избавимся от некоторых накопившихся в окне NoteTaker
несуразностей и заменим их нормальными элементами XUL-форм. Мы
избавимся от файла .properties и будем отправлять собранные в форме
данные на web-сервер. Если диалог будет появляться в результате
HTTP-запроса GET, значения параметров из этого запроса также будут
использоваться.
Прежде всего, займемся наведением порядка. Мы откажемся от атрибута и функции handle_click(). Если мы еще хотим отключать
какое-либо содержимое, имеет смысл делать это теперь собственными средствами
тегов. То есть все load_data(), все еще
актуальна, но текущая реализация нам больше не подходит.
Наконец, мы избавимся от вспомогательных стилей boxes.css /
boxesTemp.css и их тегов <box>. Вместо них у нас будут:
<textbox> для раздела Summary ;<textbox> для раздела Details ;<checkbox> для раздела Options ;<textbox> для раздела Size.Как показано в листинге 7.4, соответствующие теги очень просты.
<textbox id="dialog.summary"/> <textbox id="dialog.details multiline="true" flex="1"/> <checkbox id="dialog.chop-query" dir="rtl" label="Chop Query" checked="true"/> <checkbox id="dialog.home-page" dir="rtl" label="Home Page" checked="true"/> <textbox id="dialog.width" value="100" maxwidth="3" size="3"/> <textbox id="dialog.height" value="90" maxwidth="3" size="3"/> <textbox id="dialog.top" value="80" maxwidth="3" size="3"/> <textbox id="dialog.left" value="70" maxwidth="3" size="3"/>
После внесения этих изменений и некоторой корректировки размещения диалог должен быть похож на снимок на рисунке 7.5.
(рис 7.5) Диалог на основе формПеред заменой load_data() мы немного поэкспериментируем.
DOM-объекты тегов XUL-форм очень похожи на DOM-объекты тегов <checkbox> и так далее, либо просто вспоминая разные
трюки, использовавшиеся на web-страницах. Заменим этот код в load_data():
desc = document.createElement("description");
desc.setAttribute("value",value);
box = document.getElementById("dialog." + names);
box.appendChild(desc);
на этот:
if (box.value) box.value = value;
Так как у большинства элементов форм есть свойство value, нам
удалось загрузить большую часть файла .properties в форму одним
простым действием.
Поработав над формой, мы бы хотели теперь обработать вводимые пользователем данные: описание заметки. Теперь мы хотим читать данные формы и заполнять ее. Есть много мест, куда можно отправить информацию, но мы попробуем воспользоваться web-сервером. Возможно, когда-нибудь эту заметку можно будет просмотреть из любого браузера Mozilla.
Чтобы сохранить заметку NoteTaker, мы используем уже знакомый по
этой лекции код, только слегка адаптируем его и поместим в метод action(). Мы также сохраним массив имен ( names ), который ранее был
локальным для load_data(), но сейчас мы сделаем его глобальным. В
листинге 7.5 показан новый алгоритм.
if (task == "save") {
var req = new XMLHttpRequest(); // Request
var params = "";
var i = names.length -1; // build up params
while (i>=0) { var widget = document.getElementById
("dialog." + names);
if (widget.tagName == "checkbox")
params += names + "=" + widget.checked + ";";
else
params += names + "=" + widget.value + ";"; i--;
}
params = encodeURI(params); req.open("POST", "test.cgi");
req.send(params);
if ( req.status / 100 != 2 ) // HTTP 2xx Response?
throw("Save attempt failed");
}
Конечно, на web-сервере должен быть test.cgi или его аналог. Если
мы запускаем приложение из
NoteTaker работает с классическим браузером, поэтому вряд ли он
будет загружаться с удаленного сервера. Тем не менее возможно, что во
время создания окна ему будут передаваться какие-то аргументы. Так как
программное окружение нашего приложения то же, что и у остального
chrome://notetaker/content/editDialog.xul
но тот же документ можно загрузить с помощью
chrome://notetaker/content/editDialog.xul?top=440;left=200
Эта информация далее может быть прочитана с помощью AOM-свойства
window.location. Мы сделаем это, создав новую задачу для метода action(), которую назовем load. В отличие от остальных задач, которые
как-либо связаны с графическим интерфейсом, эта функция - чистый
скрипт. Новый обработчик onload тега <window> будет:
onload="action('load')"
Код, добавляемый в метод action(), показан в листинге 7.6. Объект window.location - один из немногих AOM-объектов, которые доступны и в
HTML-, и в XUL-документах. Он предоставляет объект с помощью
интерфейса nsIDOMLocation и полезен в XUL только в описанном
случае.
if (task == "load" ) {
var pair, widget;
params = window.location.toString();
if ( params.indexOf("?") == -1 )
return;
params = params.replace(/.*\?/,"");
params = params.split(/[;]/);
i = params.length – 1;
while (i >=0 ) {
pair = params.split(/=/);
pair[0] = decodeURI(pair[0]);
pair[1] = decodeURI(pair[1]);
widget = document.getElementById("dialog."+ pair[0])
if (widget.tagName == "checkbox")
widget.checked = ( pair[1] == "true" );
else widget.value = pair[1];
i--;
}
}
В этом коде используется поддержка регулярных выражений из
replace() применяется для удаления всех символов
до символа ?, с которого начинается строка параметров. split()
разделяет оставшуюся строку на массив строк с разделением везде, где
происходит совпадение с ; или . Наконец, каждая пара
Формы и события не так уж интересны, если только вы не составляете собственные элементы управления. Некоторые стандартные методики могут упростить задачу.
Тег <menupopup> появляется, только когда вы нажимаете на
связанную с ним кнопку. Это может быть неудобно, если просто требуется
проверить, корректно ли составленное содержимое. Вы можете поместить
меню в нормальный поток XUL-документа, изменив его стиль отображения
так:
menupopup { display: -moz-box ! important }
После этого меню больше не будет интерактивным, но можно будет, по крайней мере, без труда просматривать его содержимое. На рисунке 7.6 показан тот же документ, что и на рисунке 7.3, только с использованием указанного выше стиля.
(рис 7.6) Пример встраивания содержимого <menupopup> в документВообще это не лучшая стратегия реализации или даже тестирования; просто такой способ работает и иногда бывает наиболее удобным.
Для освоения сложных элементов управления вроде <menulist>
могут потребоваться некоторые усилия, особенно если вам не нравится
содержимое, внешний вид или поведение по умолчанию. Простейшая
стратегия - анализировать данный тег с помощью Инспектора DOM. Этот
инструмент раскроет содержимое, идентификаторы и классы стилей данного
тега, вам нужно будет только нажать на кнопку. Это так просто, почему
бы не поэкспериментировать?
Другая используемая в этой лекции и некоторых других стратегия - применение специальных таблиц стилей. Некоторые из примеров в этой книге дополнены простыми стилями, которые создают визуальные подсказки. В листинге 7.7 показаны примеры таких вспомогательных стилей.
label {
border: dashed thin;
padding: 2px;
margin: 2px;
}
image {
border: solid thin;
padding: 2px;
margin: 2px;
}
.radio-check {
width:20px;
height:20px;
}
.checkbox-check {
width:20px;
height:20px;
}
vbox, hbox, box, deck {
border: solid;
padding: 2px;
margin: 2px;
border-color: grey;
}
* {
font-family:Arial;
font-weight: bold;
}
Все это довольно просто, за исключением, возможно, стилей для флажков, которые можно исследовать с помощью Инспектора DOM. Без этих двух стилей пиктограммы флажков будут сильно уменьшены из-за полей, добавляемых другими правилами.
В этой лекции описывается XUL-интерфейс для форм и меню Mozilla, но не JavaScript-интерфейсы для соответствующих DOM-объектов этих тегов. Есть несколько способов поиска AOM- и DOM-свойств и методов этих объектов.
SelectedIndex, focus () и blur() - все они работают ожидаемым образом. Они также задокументированы в стандарте DOM 1 Core, в разделе, посвященном HTML.Формы и меню - первая жизненно важная точка доступа для
пользователей, которые хотят взаимодействовать с приложениями на
основе Mozilla. XUL поддерживает простые элементы управления формы
(или просто элементы формы), с которыми пользователи браузеров уже
знакомы. Однако поддержка в XUL такими простыми элементами форм и меню
не ограничивается. Эта поддержка идет гораздо дальше и не связана
жестко с действиями пользователя, как в случае
В отличие от HTML, XUL-приложения могут отправлять данные форм в Сеть только с помощью скрипта. Однако такая отправка может быть более гибкой, чем любая отправка данных из HTML-формы.
И формы, и меню достаточно интересны, но если увлечься ими слишком сильно, пользователь не сможет отправиться куда-то еще или исследовать другие части сложного приложения. Поддержка возможностей навигации - тема следующей лекции.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.