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

Команды

9.6. Команды и компоненты XPCOM

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

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

Единственный способ решить эту проблему - подробно охарактеризовать лишь сами интерфейсы. Таблица 9.1. следует версии платформы 1.4. Лишь некоторые из этих интерфейсов в настоящее время приняли завершенный вид, в более поздних версиях они могут немного меняться.

Таблица 9.1. Компоненты XPCOM, используемые в инфраструктуре системы команд
Имя интерфейса Существующая реализация XPCOM Цель
nsICommand Хотя имя кажется логичным, такого интерфейса нет
nsICommandHandler @mozilla.org/embedding/browser/nsCommandHandler;1 Реализация команд нижнего уровня - не используется в JavaScript
nsICommandHandlerInit @mozilla.org/embedding/browser/nsCommandHandler;1 Используется для инициализации объектов nsICommandHandler
nsIController @mozilla.org/embedcomp/base-command-controller;1 Базовый контроллер, поддерживающий таблицу команд
nsIControllerContext @mozilla.org/embedcomp/base-command-controller;1 Используется для инициализации контроллера
nsIControllerCommandTable @mozilla.org/embedcomp/controller-command-table;1 Изменяемый набор команд
nsICommandController @mozilla.org/embedcomp/base-command-controller;1 Некорректно названный интерфейс, добавляющий базовому контроллеру вызов команды с аргументами
nsIControllerCommandGroup @mozilla.org/embedcomp/controller-command-group;1 Используется для группирования изменяемого множества команд
nsIControllerCommand None Базовый функтор
nsICommandManager @mozilla.org/embedcomp/command-manager;1 Используется для управления вспомогательными методами функтора
nsICommandParams @mozilla.org/embedcomp/command-manager;1 Структура данных, используемая как список параметров при выполнении команды с параметрами
nsIControllers None Набор контроллеров как свойство элемента DOM
NsIDOMXULCommandDispatcher Диспетчер, не являющийся компонентом XPCOM Диспетчер команд XUL
nsPICommandUpdater Внутренний интерфейс, не используемый в приложениях
nsISelectionController Не работает с системой распространения команд
nsIEditorController @mozilla.org/editor/composercontroller;1 @mozilla.org/editor/editor-controller;1 Два контроллера, использующиеся в приложении Mozilla Composer
nsITransaction @mozilla.org/transaction-manager;1 Три интерфейса, полезные, когда контроллер становится слишком сложен. Используйте их для реализации undo/redo, макросов, истории команд, аудита и другой развитой функциональности
nsITransactionList
nsITransactionManager

Существуют также несколько интерфейсов для реализации синтаксиса командной строки. Их можно использовать для запуска платформы, но они не имеют дела с системой распространения команд.

9.7. Существующие команды

До сих пор мы рассматривали аспекты XUL, AOM и XPCOM системы распространения команд платформы Mozilla. Mozilla, однако, - не только платформа, но и законченное приложение (классическая Mozilla). Некоторые команды приложения можно применять и в платформе. Иногда программисты приложений используют это свойство платформы. Простой пример повторного использования существующей технологии - контроллер фокуса. Этот контроллер всегда доступен в окне XUL. Диспетчер команд задействует методы advanceFocus() и rewindFocus(), обеспечивающие управление фокусом, которое обычно пользователь осуществляет с помощью клавиши Tab. Названные методы посылают команды контроллеру фокуса. Этот контроллер можно использовать и для обновления команд. Тег, который должен быть обновлен, может получать извещение об обновлении команды, как результат некоторого события, произошедшего с фокусом. Почему контроллер посылает два события commandupdate на каждый шаг навигации по кольцу фокуса, мы объясним позже.

Другая разновидность повторного использования кода - заимствование. [theft - дословно "кража", но о какой краже может идти речь, если мы рассматриваем GPL-код? - прим. пер.] Файл globalOverlay.js в архиве toolkit.jar в chrome содержит полезные функции, позволяющие манипулировать командами и контроллерами. Архитектуру команд, использованную в адресной книге почтового клиента Mozilla и в системе контроллеров приложения Composer, можно применять в качестве образца. Некоторые из связок клавиатура-команда реализованы достаточно компактно, чтобы можно было использовать содержащие их файлы оверлеев.

Сверх этого повторное использование кода команд Mozilla затруднительно. Но есть один специальный случай эффективного использования существующей системы команд.

Набор приложений Mozilla Composer, Messenger и Navigator содержит около сотни команд. Одного взгляда достаточно, чтобы понять, что даже простейшее пользовательское действие должно быть воплощено в ту или иную команду, поскольку это действие влечет за собой изменение интерфейса. Это значит, что все действия, от незначительных (например, "Select Current Word"), средней значимости (например, "Delete Message") и до очень важных (например, "Load URL") должны иметь реализацию в наборе приложений Mozilla. Многие из этих команд реализованы на C++, но некоторые доступны непосредственно на JavaScript в chrome.

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

Полезно ознакомиться с кодом команд классической Mozilla, доступным в файле ComposerCommands.js в архиве comm.jar в chrome.

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

Последняя разновидность повторного использования связана с небольшой, но важной областью - XUL-тегом <textbox>. Операции с ним реализованы в командах браузера Mozilla. Если даже все остальные команды Mozilla не использовать в приложении, по крайней мере, эти команды всегда помогут корректно организовать работу с элементами формы.

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