Опубликован: 10.12.2007 | Доступ: свободный | Студентов: 822 / 20 | Оценка: 5.00 / 5.00 | Длительность: 58:33:00
Лекция 9:

Команды

9.1. Команды и Mozilla

Система команд Mozilla - одна из менее очевидных сторон платформы, и, но в то же время она мощная и гибкая. Она позволяет программисту думать о функциональности приложения как о наборе сообщений. Каждое сообщение - или команда, или о команде. При правильном применении система команд действует как точка интеграции и организации функций приложения. Использование команд в собственно классической Mozilla организовано неплохо, но часть ее также похоронена под грузом другого кода.

Система команд Mozilla спроектирована для поддержки сложных приложений. Простым приложениям команды не нужны; они могут обойтись и простыми обработчиками событий. Для сложных приложений целью Mozilla было предоставить систему, в которой:

  • элементы пользовательского интерфейса могут пользоваться одной командой, даже если они находятся в разных файлах с исходными текстами;
  • у команд может быть собственное состояние, которое можно менять и о котором можно сообщать;
  • команды и элементы управления могут добавляться и меняться независимо;
  • могли бы разобраться все типы программистов, а не только авторы приложений;
  • существовала бы осмысленная реакция по умолчанию;
  • простые случаи использования поддерживались бы простым синтаксисом;
  • повторно использовалась система событий DOM, где это возможно.

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

Обнаружить команду в терминах исходного кода не так легко. Самый очевидный признак команды - простая строка, чье имя - имя команды. Такие имена могут определяться платформой или программистом приложения. К сожалению, остальная часть инфраструктуры команд довольно сильно разбросана по платформе. Части системы команд есть в XUL, JavaScript, XPCOM, существующих файлах chrome и внутренностях платформы.

9.1.1. Hello, World

Простой пример использования системы команд приведен в листинге 9.1.

<?xml version="1.0"?>
<!DOCTYPE window> 
  <window 
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <command id="hello" oncommand="alert('hello, world');"/>
  <button label="Say It" command="hello"/>
</window>
Листинг 9.1. Пример "hello, world", реализованный как команда Mozilla

Тег <command> реализует команду, в данном случае простой обработчик событий, который вызывает alert(). Тег <button> идентифицирует эту команду по имени. Когда мы нажимаем кнопку, генерируется событие DOM 2 специального типа command, и идентифицированная команда захватывает это событие и запускается. Результатом будет появление окошка alert().

Команды не всегда столь просты, и не всегда основаны на обработке события. Если реализовать эту команду на JavaScript, эффект, вызываемый кодом листинга 9.2, будет тот же, что и в листинге 9.1.

<?xml version="1.0"?> 
<!DOCTYPE window> 
<window 
  xmlns= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 
  <script> 
    var control = { 
      supportsCommand : function (cmd) { return true; }, 
      doCommand : function (cmd) { alert(cmd + ", world"); }, 
      isCommandEnabled : function (cmd) { return true; }, 
      onEvent : function (event_name) {} 
    }; 
    window.controllers.appendController(control); 

    function execute(cmd) { 
      var disp = document.commandDispatcher 
      var cont = disp.getControllerForCommand(cmd); 
      cont.doCommand(cmd); 
    } 
  </script> 
  <button label="Say It" onclick="execute('hello')"/> 
</window>
Листинг 9.2. Пример hello, world, реализованный как команда на JavaScript.

Этот код описывает объект control, реализующий команду; фактически, данный объект может реализовать несколько команд. Команда реализована в методе doCommand(). Затем объект нужно встроить в инфраструктуру команд платформы. Он будет вызываться каждый раз, когда потребуется выполнить данную команду. И, наконец, команда может быть вызвана в любом месте документа XUL с помощью функции execute(). В данном случае удобно использовать обработчик onclick.

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