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

Окна и панели

Внешний вид заметки NoteTaker показан на Рисунке 10.3. В браузер загружена обыкновенная web-страница.

Следует с осторожностью подходить к выбору используемых возможностей HTML, поскольку мы не знаем, какому именно стандарту будет соответствовать отображаемая страница. В частности, это означает, что код HTML и XML должен быть действительным с формальной точки зрения, поскольку страница может отображаться в режиме строгого соответствия стандартам. В то же время, мы можем использовать любые расширения HTML, характерные для Mozilla, поскольку наше приложение предназначено для данной платформы. Эта ситуация отличается от традиционного подхода к разработке web-страниц, рассчитанных на отображение в различных браузерах. Код HTML для заметки, показанной на рисунке, представлен в листинге 10.5.

Пример заметки NoteTaker, реализованной на основе HTML.

Рис. 10.3. Пример заметки NoteTaker, реализованной на основе HTML.
<span id="notetaker-note">
  <span id="notetaker-note-summary">
    Note Summary
  </span>
  <span id="notetaker-note-details">
    All the details go here
  </span>
</span>
Листинг 10.5. Код HTML для заметки NoteTaker

Строго говоря, нам следовало бы выполнить некоторые дополнительные действия для того, чтобы этот код, добавленный к web-документу, всегда относился к правильному пространству имен. Однако сейчас мы не будем вдаваться в подробности. Стили CSS для этого кода приведены в листинге 10.6.

#notetaker-note {
  display : block;
  position : absolute;
  z-index : 2147483646; /* на один уровень ниже, чем всплывающие меню */
  overflow : auto;
  background-color : lightyellow;
  border : solid;
  border-color : yellow;
  width : 100px;
  height : 90px;
  top : 80px;
  left : 70px;
}
#notetaker-note-summary {
  display : block;
  font-weight: bold;
}
#notetaker-note-details {
  display : block;
  margin-top : 5px;
}
Листинг 10.6. Заметка NoteTaker: код CSS

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

Для того чтобы просто добавить к web-странице заметку, нам необходимо представить фрагменты кода HTML и стилей CSS в виде строк JavaScript. Вместо того, чтобы жестко закодировать конкретные параметры в тексте программы, мы можем использовать шаблоны, в которых строка вида:

"... width : 100px ..."

представлена как

"... width : {width}px ..."

С помощью регулярных выражений JavaScript мы можем подставить в эту строку значения, введенные пользователем в панели инструментов или диалоговом окне Edit. Имея готовую строку, мы можем создать заметку, как показано на листинге 10.7.

function display_note()
{
  var style = generate_style();
  var html = generate_html();
  var doc = window.content.document;

  var stree = doc.getElementById("notetaker-styles");
  if ( !stree ) // add the topmost <style>
  {
    stree = doc.createElement("style");
    stree.setAttribute("id","notetaker-styles");
    var head = doc.getElementsByTagName('head').item(0);
    head.appendChild(stree);
  }
  stree.innerHTML = style;
  var htree = doc.getElementById("notetaker-note");
  if ( !htree ) // add the topmost <span>
  {
    htree = doc.createElement("span");
    htree.setAttribute("id","notetaker-note");
    var body = doc.getElementsByTagName('body').item(0);
    body.appendChild(htree);
  }
  htree.innerHTML = html;
}
Листинг 10.7. Создание заметки NoteTaker средствами динамического HTML

В этом коде используется функция getElementsByTagName() для того, чтобы получить теги <head> и <body> web-документа – мы не знаем идентификаторов ( id ) этих тегов. Затем код создает теги для стилей и заметки, которые добавляет к содержимому тегов <head> и <body> соответственно. Затем специальное свойство innerHTML, поддерживаемое Mozilla, используется для того, чтобы добавить остальное содержимое заметки, существующее в форме строки. Для простоты мы полагаем, что отображаемая страница не является системой фреймов ( frameset ), а также содержит теги <head> и <body>. Мы могли бы обойти эти ограничения, но для этого нам пришлось бы лишь написать больше кода DHTML, не узнав ничего нового о Mozilla. Функция generate_html(), представленная на листинге 10.8, тривиальна; функция generate_style() устроена аналогичным образом.

function generate_html() {
  var source =
    '<span id="notetaker-note-summary">{summary}</span>' +
    '<span id="notetaker-note-details">{details}</span>';
  source = source.replace(/\{summary\}/, note.summary);
  source = source.replace(/\{details\}/, note.details);
  return source;
}
Листинг 10.8. Добавление данных заметки к шаблону средствами DHTML

Новый код не так просто протестировать, поскольку для этого необходима его интеграция с браузером. Для корректной интеграции необходимы оверлеи, с которыми мы познакомимся в "Оверлеи и Chrome" . Пока же нам придется прибегнуть к временному решению – модифицировать код браузера.

Для этого нужно скопировать файл navigator.xul, находящийся в архиве comm.jar в каталоге chrome, в подкаталог notetaker/content каталога chrome. Теперь, запустив Mozilla при помощи следующей команды:

mozilla -chrome chrome://notetaker/content/navigator.xul

мы получим обычное окно браузера. Именно эту копию мы и будем модифицировать. Прежде всего, нужно добавить теги вида <script src=> для всех необходимых скриптов. Затем следует найти строку вида:

<toolbar id="nav-bar" ...

Этот тег описывает основную панель навигации. Сразу же после указанной строки необходимо добавить следующий тег:

<toolbarbutton label="Test" onclick="display_note()"/>

После того, как мы сохраним и вновь запустим измененный файл, к панели навигации браузера добавится новая кнопка. Нажатие на эту кнопку приведет к открытию заметки при условии, что в окно браузера загружена web-страница. Мы можем использовать для этой кнопки любой обработчик события onclick, включая обращения к execute(), action() и любым другим методам. При желании мы можем поместить в этот файл даже тег <toolbar> приложения NoteTaker со всем его содержимым.

В ходе тестирования пользователь, прежде чем нажать кнопку, должен дождаться загрузки web-страницы. Однако мы не можем требовать этого от пользователя окончательной версии NoteTaker. Поэтому наше приложение должно самостоятельно определять, загружена ли страница в окно. Самый простой способ – периодически опрашивать главное окно браузера.

function content_poll() {
  if ( !window.content ) return;
  var doc = window.content.document;
  if ( !doc ) return;
  if ( doc.getElementsByTagName("body").length == 0 ) return;
  if ( doc.location.href == "about:blank" ) return;
  if ( doc.visited ) return;
  display_note();
  doc.visited = true;
}
setInterval("content_poll()", 1000);

Чтобы определить, нужно ли отображать заметку, этот код периодически исследует содержимое окна. Если в окне нет документа, еще не загружен тег <body>, в окне содержится пустой документ или заметка уже отображена, код не делает ничего. В противном случае загружается заметка для данной страницы.

Итак, посмотрим, чего мы достигли к настоящему моменту. Мы создали окна, которые используются для взаимодействия NoteTaker с пользователем. Текущая заметка представлена в памяти объектом JavaScript. Мы создали логику, связывающую отображаемую заметку с этим объектом, а также обеспечили определенное взаимодействие между окнами. Для того чтобы этот механизм обрел завершенную форму, нам нужно поработать над связью данных, вводимых пользователем, и объектом JavaScript, представляющим заметку. Кроме того, в приложении пока отсутствует корректная работа с URL.

Предполагается, что каждой web-странице соответствует отдельная заметка. Наше приложение хранит заметки на web-сервере и загружает их оттуда. Заметка даже перезагружается при перезагрузке страницы. Существующий механизм подразумевает, что мы должны отправить запрос web-серверу, чтобы получить текст заметки – это не слишком эффективно. Единственная альтернатива, которой мы располагаем к настоящему моменту, – хранить заметки в локальном текстовом файле. Однако платформа Mozilla предусматривает более эффективное решение – хранение заметок в виде данных RDF. Мы обсудим этот вариант во второй части книги.