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

XBL-связки

15.1. Общая концепция XBL-связок

XBL расширяет XML так же, как C++ расширяет C. Он добавляет объектно-ориентированные возможности системе, у которой средств для работы с объектами не было.

15.1.1. Пример XBL-связки

Каждый документ XBL - это просто список связок (bindings), каждая из которых начинается с тега <binding>. Конструирование связки подобно конструированию класса объектов. В Листинге 15.2 показана простая связка XBL, являющаяся вариантом тега-связки <checkbox>.

<?xml version="1.0"?> 
<bindings xmlns="http://www.mozilla.org/xbl"
  xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" > 
  <binding id="checkbox" extends="general.xml#basetext"> 
    <resources> 
      <stylesheet src="chrome://global/skin/checkbox.css"/> 
    </resources> 
    <content>
      <xul:image class="checkbox-check"
        xbl:inherits="checked,disabled"/>
      <xul:hbox> 
      <xul:image class="checkbox-icon" xbl:inherits="src"/>
      <xul:label xbl:inherits="xbl:text=label,accesskey,crop"/> 
      </xul:hbox>
    </content> 
    <implementation implements="nsIDOMXULCheckboxElement">
      <method name="check" action="this.checked = true"/> 
        <property name="checked" onset="if (val) 
          this.setAttribute('checked','true');"
          onget="return this.getAttribute('checked') == 'true';" />
    </implementation> 
    <handlers> 
      <handler event="click" button="0" 
        action="if (!this.disabled) this.checked = !
          this.checked;"/> 
      <handler event="keypress" key=" "> 
        <![CDATA[ this.checked = !this.checked; ]]>
      </handler> 
    </handlers> 
  </binding> 
</bindings>
Листинг 15.2. Пример связки XBL, подобной тегу-связке <checkbox>.

Листинг 15.2 демонстрирует многие стандартные черты связок. Разделы <resource> и <content> описывают данные в форме стилей, изображений, тегов и других простых элементов XUL. Эти разделы содержат контент XML. Разделы <implementation> и <handlers> описывают свойства, методы и связанные с событиями хуки. Эти секции существуют в форме DOM и JavaScript. Содержательные и скриптовые стороны связок подобны соединению кода и данных в программах для PC или Макинтоша. На границе - XUL и код JavaScript. Он связывает части, но сам не является частью языка XBL.

Рекомендуем изучать связки, созданные другими людьми. В разделе "Чтение чужого кода" "Объекты XPCOM" , "Объекты XPCOM", и в Таблице 16.1 приведены некоторые советы, облегчающие изучение связок, созданных командой mozilla.org.

15.1.2. Стандарты

XBL - это приложение XML. Его XML-определение можно найти по адресу http://www.mozilla.org/xbl. Mozilla не грузит этот URL, он используется лишь как идентификатор. Стандартным суффиксом для XBL-файлов является .xml.

Стандартный тип MIME для документов XBL - application/xml.

Связки XBL идентифицируются с помощью URL. Специальной схемы URL для XBL не существует, используются схемы http: и chrome:. Так же, как для RDF, URL связки включают суффикс #id, идентифицирующий каждую связку внутри документа XBL. Как и в случае с RDF, каждая связка, идентифицируемая по #id, рассматривается как целый ресурс, а не фрагмент ресурса. Пример:

chrome://global/content/bindings/button.xml#button.

XBL был принят консорциумом W3C как "предложение" (Note). Это означает, что документ, описывающий XBL, был предложен в консорциум со стороны, для дальнейшего рассмотрения. Это не черновик стандарта (draft) и не стандарт ("on the standards track"), а всего лишь предложение. Последнюю версию "XBL Note" можно найти по адресу http://www.mozilla.org/projects/xbl/xbl.html.

Реализация XBL в Mozilla отличается от предложенной в W3C. Она содержит добавочные особенности и не реализует полностью все свойства, описанные в "Предложении". Разница рассматривается в разделе "Не-теги и не-атрибуты" данной лекции.

Стандарты, конкурирующие с XBL, это ECMA-290 "ECMAScript Components", используемый Microsoft в технологии WSH (Windows Scripting Host). Стандарт WSDL и связанные с ним стандарты также предлагают распределенную систему именования, но WSDL не так тесно увязан с взаимодействием с пользователем, как XBL. Наполовину конкурирующим стандартом является XSL. XSL может обрабатывать файлы XML и заменять указанные теги другим контентом. Это то же самое, что делает XBL, но XSL работает в пакетном режиме, просматривая XML документ от начала до конца один раз. XBL же может работать с документом после его полной загрузки. Никакие иные стандарты не нацелены на ту нишу, которую занимает XBl.

XBL имеет более широкую область применения, чем любой иной стандарт W3C. HTML, CSS и JavaScript сами могут взаимодействовать весьма ограниченно. Эти три стандарта фокусируются на единственном теге, стиле или объекте в один момент времени. Хотя эти стандарты позволяют тегу, стилевому правилу и свойству объекта сгруппироваться в единое целое, такая группировка весьма узка. Для программиста нет структурной поддержки, охватывающей все три области и предлагающей высокоуровневые объектно-ориентированные удобные концепции. XBL исправляет этот недостаток, интегрируя XML, скрипты и стили в одну структуру - "связку" (binding).

15.1.3. Взаимодействие с иерархией DOM.

Чтобы связки XBL можно было использовать, они должны быть предварительно встроены в иерархию DOM.

Перед тем, как связка будет использована, ее нужно связать с существующими XML-тегами документа. Эти теги называются граничными тегами (bound tag), а документ - целевым документом. Если граничный тег имеет собственный контент, он называется эксплицитным контентом. Если же сама связка имеет тег <content>, то теги внутри него называются анонимным контентом. Есть только один набор анонимного контента на связку, но могут быть различные наборы эксплицитного контента на каждый граничный тег в целевом документе. Оба типа контента, плюс остальные детали связки, добавляются документу, эту связку использующему.

Когда мы вызываем XBL-связку, иерархия DOM целевого документа растет. Возникают три изменения:

  1. Граничный тег приобретает свойства, методы и обработчики событий связки.
  2. Контент граничного тега заменяется смесью эксплицитного и анонимного контента.
  3. Анонимный контент добавляется в иерархию DOM отдельно, для доступа к нему предусмотрен специальный механизм.

Шаги 1 и 2 повторяются для каждого граничного тега. Процесс порождения контента очень похож на такой же процесс для оверлеев и шаблонов. Так же как в оверлеях, контент добавляется в целевой документ в определенной точке. Так же как в шаблонах, добавочный контент порождается повторным копированием определенного набора тегов. Платформа Mozilla автоматически выполняет эти шаги.

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

Эти принципы подробно рассматриваются в разделе "Как обрабатываются связки".

15.1.4. Действия по умолчанию

Систему XBL можно использовать для реализации действий, выполнения которых требуют HTML и XUL-теги.

Такое действие по умолчанию можно видеть на примере тега HTML <input type="submit">. Когда мы кликаем по кнопке виджета, принадлежащего этому тегу, данные из формы посылаются браузером на некий web-сервер. Не нужно никакого скрипта, чтобы это произошло. Действие по умолчанию - часть обработки событий DOM, реализованная для всех тегов XML. Но как это реализовано, и как это событие встраивается в обработку событий DOM?

Ответ состоит в том, что действие по умолчанию можно встроить в XBL-связку. Связка дает способ связать вместе событие DOM и обработчик JavaScript. Когда порождается событие, связка XBL автоматически определяется как источник действия по умолчанию, запускается необходимый обработчик и таким образом выполняется требуемое действие.

Данный виджет может иметь различное действие по умолчанию для каждого порождаемого пользователем события. В случае тега <input type="submit"> нажатие клавиш Return или Enter или клик по изображенной кнопке произведут одинаковый эффект. Но это не обязательно так для произвольной связки - каждое событие может иметь свою реакцию по умолчанию.

Разработчик приложения может изменить действие по умолчанию, используя обычный обработчик событий. К этой задачке, однако, нужно подходить аккуратно. Если обработчик события установлен в форме значения атрибута (как, например, onclick ), то будет использован именно он, а не обработчик XBL. Если обработчик события установлен с помощью функции addEventListener(), то этот обработчик должен быть установлен до того, как обработчик XBL будет включен в тег. Это требование ставит обработчики приложения перед обработчиками XBL в списке обработчиков события. См. замечания в разделе "Скриптинг".

Система XBL не ответственна за обнаружение события и процесс "всплытия" события. Она не отвечает также за состояние фокуса и состояние фокусного кольца. Это вещи, обрабатываемые глубоко внутри C/С++-части кода платформы. Поддержка специальных функций (для людей с ограниченными возможностями) выполнена на XBL, но система ввода, которая осуществляет первую реакцию на команды этого типа, есть часть ядра системы.

15.1.5. Объектные свойства связок

Связки XBL имеют объектно-ориентированные свойства и могут рассматриваться как объекты с точки зрения JavaScript или DOM.

Интерфейс объекта имеет атрибуты, методы и исключения. Интерфейс связки содержит свойства, методы и обработчики событий. Свойства соответствуют атрибутам, обработчики - специализированным методам. Исключения также могут быть реализованы в связках, но XBL не имеет для этого явного синтаксиса. Чтобы создать исключение, используйте оператор throw в JavaScript.

XBL поддерживает традиционные концепции объектно-ориентированного подхода. В таблице 15.1 приведено описание поддержки ОО в XBL.

Таблица 15.1. Поддержка объектов в XBL
Концепция Поддержка в XBL
Агрегирование Теги XBL собирают контент (включая контент граничного тега) и код JavaScript в единую связку, сливая эксплицитный и анонимный контент в единое целое
Локализация Граничный тег хранит логику всего контента и JavaScript. XBL-связка может содержать другой граничный тег, и, следовательно, следующую связку
Инкапсуляция Граничный тег содержит всю полезную информацию о связке, хотя некоторая полезная информация может быть получена из JavaScript-объекта document
Наследование XBL имеет атрибут inherits, для наследования XBL-атрибутов, и атрибут extends, для наследования целых связок
Скрытие информации Код подключенной связки скрыт и недоступен из граничного тега. Доступен только соответствующий интерфейс
Интерфейсы Связка, предоставляющая интерфейс, может быть наследована другой связкой с помощью атрибута extends. Связка может поддерживать интерфейсы XPCOM с помощью атрибута implements
Позднее связывание Связки подгружаются в граничный документ независимо и асинхронно. Связка может быть подгружена и выгружена в любое время с помощью правил CSS2. На связки следует ссылаться конкретно, нет механизма определения исходной связки по производной от нее связке
Объектность Граничная связка с точки зрения JavaScript является объектом
Объектно-ориентированность Атрибут extends позволяет XBL-связке быть основанной на ряде (цепочке наследования) других связок. См. Последующее обсуждение
Множественное наследование Не поддерживается
Определение типов Не поддерживается. Можно использовать лишь интерфейс nsIClassInfo

XBL-связка может наследовать другую связку. Та, в свою очередь, может наследовать следующую. Множество унаследованных связок образует упорядоченный список, называемый цепочкой наследования. Когда данный граничный тег встраивается в документ, он является началом (головным элементом) цепочки наследования. Он также называется первичной связкой. Таким образом цепочка наследования всегда имеет длину не меньше единицы. Если длина цепочки - единица, то наследования как такового нет.

На рисунке 15.1 приведен пример цепочки наследования, которую имеет тег <button>.

Иерархия наследования для XUL-тега <button>.

увеличить изображение
Рис. 15.1. Иерархия наследования для XUL-тега <button>.

В примере показаны цепочки наследования трех элементов. Связка "button" привязана к тегу <button>. Эта связка - начало цепочки наследования. Две другие связки - это связки общего назначения, наследуемые во множестве мест в XUL. Связка button-base используется во всех (или почти всех) кнопкоподобных виджетах, а связка basetext используется во всех виджетах, имеющих дело с текстом. Связки button и button-base определены в одном и том же XBL-документе, (button.xml), а basetext в другом, general.xml. Все три связки добавляют некоторое содержание в DOM-объект тега <button>.

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

В Таблице 15.2 описано, как наследуются различные свойства связок XBL.

Таблица 15.2. Наследование свойств в XBL-связках
Свойство XBL Наследуется?
<resources> Все связки цепочки наследования загружают свои ресурсы. Все стилевые таблицы имеют по умолчанию одинаковый вес, но правила у начала цепочки подгружаются позже, и, следовательно, отменяют ранее загруженные правила
<content> Нет наследования. Используется единственная связка из начала цепочки наследования. Если граничные теги содержатся в теге <content>, а не наследуются, используются их связки
<field>, <property>, <method> Свойства и методы наследуются. Если имя составной связки совпадает с именем элементарной, составная замещает основную, и последняя становится недоступна из скриптов составной
<constructor> и <destructor> Оба свойства наследуются. Конструкторы запускаются по одному, начиная с первой основной связки и заканчивая последней составной. Деструкторы также запускаются по одному в обратном порядке
<handlers> Обработчики событий наследуются. Обработчики событий составной связки отменяют действие обработчика базовой связки, если речь идет об одном и том же событии
Атрибут display Нет наследования. Используется атрибут последней составной связки
15.1.6. Набор компонентов XBL

Система XBL - это очень простой набор компонентов. Он позволяет стандартизированным компонентам взаимодействовать удобным образом.

Компонентная система, подобная XBL - система модулей Perl, доступных с помощью ключевых слов use и require. Обе системы достаточно примитивны. К связкам XBL можно получить доступ через DOM, так же как к модулям Perl через символьные таблицы. Связки XBL не включаются в другие связки также прямолинейно, как модули Perl, но в обоих случаях это использование другого кода.

Имена компонентов в системе XBL - это URLs в форме Resource#Id, где Resource - это web-адрес документа, а id - значение атрибута id тега <binding>. Так же как RDF, XBL понимает URL с id как ресурс, а не как сдвиг (offset) в существующем ресурсе.

XBL не имеет регистра компонентов или их службы имен, и не имеет возможности доступа к внутреннему устройству связок. Вместо этого документ XUL или HTML имеет простой внутренний список активных связок, используемых данным документом.

Компонентная система XBL является распределенной системой, поскольку связка может быть получена по URL откуда угодно. Связки не имеют доступа к серверу, с которого были загружены, если только не содержат кода именно для этой цели.

Система XBL не имеет свойств, подобных сложным компонентным системам, таким как COM от Microsoft, XPCOM самой платформы Mozilla, OMG CORBA или JavaBeans фирмы Sun. Ее сила в простоте и ясности.

15.1.6.1. Связки как компоненты XPCOM

Связка XBL может реализовывать один или несколько интерфейсов XPCOM. Это позволяет объекту DOM граничного тега вести себя как компонентам XPCOM с этими интерфейсами.

Связки не могут вести себя как компоненты XPCOM до тех пор, пока они не привязаны.

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