...
...

Opera widgets. Сделай сам

В этой статье я расскажу и покажу приемы, позволяющие создавать ваши собственные "расширения" возможностей браузера opera. Почти год назад вышла очередная версия этого браузера под номером 9. Среди множества изменений, направленных на улучшение скорости и удобства работы, особняком стоят widget'ы.

До этого момента opera неизменно проигрывала firefox долю на рынке за счет того, что для последнего существует множество расширений/плагинов, реализующих некоторые дополнительные возможности, которыми изначально firefox не обладал. Среди наиболее известных плагинов – например, Performancing – редактор блогов, FireFTP – ftp-клиент, Forecastfox – информация об погоде, Adblock Plus – возможность выбросить из страницы рекламные баннеры или картинки, Sage – чтец rss reed (новостей сайта). И это не все – главное, как вы заметили, — то, что спектр решаемых этими плагинами задач очень широк. Для oper'ы до выхода 9-й версии все было гораздо хуже. Теоретически плагины можно было создавать и раньше, но для этого требовались знания "серьезного программирования" на c|delpi. Теперь же для разработки widget'а вам будет достаточно знаний html, css, javascript. Если сравнить подходы opera и firefox к методике создания плагинов/расширений, то особенностью firefox является технология chrome. Вкратце: chrome позволяет с помощью css|javascript|xul изменять интерфейс самого браузера. Можете попробовать, например, в папке: "C:\Documents and Settings\Имя_Пользователя\Application Data\Mozilla\Firefox\Profiles\Имя_Профиля \chrome" найти два файлика: userChrome- example.css и userContent-example.css. Переименуйте их, убрав из имени суффикс -example. Если вы знаете, как называются элементы пользовательского интерфейса (строка адреса, контекстное и падающие меню, наборы кнопок и т.д.), то, возможно, поменять внешний вид как самого браузера (за это отвечает файл userChrome.css), так и внешний вид посещаемых страниц (за него отвечает, соответственно, файл userContent). Ниже я привожу пример изменений, добавленных в текст файла userChrome.css.

searchbar-textbox {
font-family: verdana !important;
/*это комментарий, и здесь я устанавливаю для элемента интерфейса падающего списка с перечнем поисковых машин, расположенного в верхнем правом углу, стилевое оформление шрифта размером в 16 пикселей, выделение жирным и цвет светло-фиолетовый – это изменения в файле userChrome.css */ font-size: 16px !important;
font-weight: bold !important;
color: #8C82C4 !important;
}

Как вывод: chrome дает возможность создавать плагины, которые взаимодействуют, модифицируют и улучшают интерфейс firefox. Для oper'ы такой возможности нет. Если посмотреть список из размещенных на официальном сайте 900 с лишним widget'ов, то увидите, что большей частью они однотипны и представляют нечто вроде окошка, в котором отображаются новости с сайта x или же окошка, в котором отображается десятка лучших анекдотов с сайта y. Такого разнообразия функциональных возможностей, как у firefox, нет. Хотя пяток widget'ов я для себя выбрал: functions 3d – widget, отображающий график функции z=f(x,y) — этакий мини-mathcad, text-translator – когда лень запускать lingvo, touchthesky – свежие сводки погоды на рабочем столе, ScreenRuler – для веб-дизайнеров очень неплохое решение — служит для оценки размеров и местоположения элементов на веб-странице. Стоит отметить, что у всякой вещи обязательно есть недостатки, и, как правило, они — продолжение достоинств. Так, chrome дает гибкость пользовательского интерфейса браузера и забирает скорость работы и десяток-другой лишних мегабайт памяти. Скажем, есть проект k-meleon – разработка очень-очень быстрого браузера, использующего для отрисовки html-страниц средства gecko – ядро firefox, но средства интерфейса не используют chrome. С другой стороны, есть flock – социальный браузер, построенный на основе firefox и представляющий, по сути, набор плагинов, активно использующих средства chrome. Возвращаясь к opera, остается только верить, что widget'ы в 9-й oper'е — это только начало пути, и в будущих версиях opera можно будет создавать расширения, подобные firefox, при этом скорость работы браузера катастрофически не упадет. С другой стороны, средства html|css сейчас достаточно развиты, чтобы быстро разработать приложение с таблицами (мне приходилось видеть написанный на javascript проект "электронные таблицы а-ля excel"), с текстовым редактором (используйте библиотеку tinymce или fckeditor). Есть библиотечки "дерево элементов", "набор закладок", библиотека yahoo дает возможность использовать средства D&D (drag and drop). А новомодная технология ajax подарит возможность обращаться к информации, расположенной на удаленных серверах сети. Так что сделать с помощью ajax и tinymce собственный редактор блогов наподобие Performancing для firefox вполне реально. Итак, если у вас есть хорошая идея, то средств opera widgets для ее реализации вам должно хватить.

Widget подобен обычной веб-странице, но отличается тем, что не имеет таких характерных для браузера элементов интерфейса, как строка адреса, кнопки "назад", "вперед", "домашняя страница", хотя и располагаются при этом непосредственно на рабочем столе windows. Очень важная особенность в том, что widget может сохранять нужную для себя информацию на стороне клиента — это похоже на cookie, но, в отличие от cookie, нет таких жестких ограничений на размер сохраняемой информации, и информация хранится больше времени. Каждый widget может иметь несколько окон — например, у вас есть widget, который загружает новости с сайта tut.by подобно rss feed. Итак, одно окно – в нем отображаются новости, второе же окно содержит настройки — например, интервал времени, через который будут загружаться свежие новости. Пользователь может свободно перемещать окно widget по всему рабочему столу, перетаскивая его мышью за любую часть окна наподобие того, как перемещается окошко winamp, или же вы можете указать, какие области окна widget будут интерактивными. Технически widget – это обычный файл архива zip — в официальной документации рекомендуют, чтобы расширение файла было .wdgt, но до тех пор, пока вы не будете загружать его на сайт opera.com, лучше этой рекомендацией пренебречь. У меня на локальной машине wdgt-файлы не воспринимались oper'ой как файлы widget, а с расширением .zip проблем не было. Внутри архива находятся все файлы, необходимые для работы widget:

- Конфигурационный файл widget. В этом файле содержится общая информация: размер widget, сведения об авторе и назначении расширения, политике безопасности.
- HTML-документ – эта страничка является основой (скелетом) widget — именно его вы видите на рабочем столе. Интересно, что в качестве основы может быть не только html-документ, но и svg-, xml-файлы. Особый интерес представляет способность в качестве скелета использовать flash- приложение — к сожалению, успеха в этом я не добился. Так, после вставки flash-ролика страница widget'а приобретала белый цвет и никак не реагировала на мышь. Хотя на официальном сайте сайт есть widget'ы, использующие средства flash, будем считать, что это я где-то ошибался.

- Следующие составляющие widget – это набор изображений, файлов javascript и файлов css — на эти файлы будет ссылаться наш основной документ. Наш первый widget – это калькулятор с четырьмя действиями. Начнем его разработку с того, что создадим конфигурационный файл. Этот файл должен быть в формате xml и выглядеть, например, так:

<?xml version="1.0" encoding="utf-8" ?>
<widget>
<!-- главный тег, внутри которого находится вся остальная информация -->
<widgetname>Super Puper Calc</widgetname> <!-- название widget-->
<description>
<!-- произвольный текст, содержащий описание возможностей widget -->
Это суперкалькулятор, умеющий складывать, вычитать, делить и умножать
</description>
<width>400</width><!-- здесь задаются размеры widget в пикселях — его ширина -->
<height>400</height> <!-- аналогично здесь задается размер widget в пикселях — его высота -->
<author> <!--информация об авторе состоит из двух частей -->
<name>black zorro</name> <!--имя автора -->
<link> сайт <!-- адрес веб-сайта автора, если у вас нет собственного сайта, то ничего страшного --> <organization>black zorro inc.</organization> <!-- информация об организации-разработчике -->
</author>
<id><!-- ID — очень важная информация, служащая для различения widget — не должно быть двух widget, имеющих один и тот же ID -->
<host>example.com</host><!-- ID состоит из двух частей названия веб-ресурса, посвященного widget -->
<name>HelloWorld</name><!-- также в составе ID находится название widget-->
<revised>2007-01-01</revised><!-- дата создания или последней модификации в формате год-месяц-день -->
</id>
<icon>mark_4.gif</icon><!—картинка-иконка виджета должна быть в формате gif или png — вы увидите эту иконку в меню widgets -> список виджетов напротив имени вашего виджета-->
<security><access>
<host>tut.by</host><!-- здесь перечисляется набор серверов сети, к которым создаваемый widget может иметь доступ-->
<host>center</host>
</access>
<content>
<java>yes</java><!-- признак того, может ли widget обращаться и использовать java-апплеты-->
<plugins>yes</plugins><!-- возможно ли использовать иные плагины – например, flash-->
</content>
</security>
</widget>

Создав конфигурационный файл, приступим к разработке основного файла index.html, содержащего пользовательский интерфейс калькулятора. Важно задать фоновый цвет тела (body) документа — иначе невозможно перетаскивать окно widget с помощью D&D по рабочему столу; если вы не задали фоновый цвет для фрагмента страницы, то он считается прозрачным, и сквозь него виден рабочий стол.

<html>
<head>
<link href="calc_style.css" type="text/css" rel="stylesheet" />
</head>
<script type="text/javascript" src="logic.js" >
</script>
<body>
<div class="div_heading">Супер-Пупер-калькулятор v 1.0</div>
<div id="error_placeholder"></div>
<div class="div_digits" id="div_digits"></div><!-- табло калькулятора -->
<!-- в таблице ниже задается набор кнопок калькулятора -->
<table cellpadding="0" cellspacing="5" border="0">
<tr>
<td class="td_cell_digit" onclick="digit(1);">1</td>
<td class="td_cell_digit" onclick="digit(2);">2</td>
<td class="td_cell_digit" onclick="digit(3);">3</td></tr>
<tr>
<td class="td_cell_digit" onclick="digit(4);">4</td>
<td class="td_cell_digit" onclick="digit(5);">5</td>
<td class="td_cell_digit" onclick="digit(6);">6</td></tr>
<tr>
<td class="td_cell_digit" onclick="digit(7);">7</td>
<td class="td_cell_digit" onclick="digit(8);">8</td>
<td class="td_cell_digit" onclick="digit(9);">9</td></tr>
<tr>
<td class="td_cell_digit" onclick="digit(0);">0</td>
<td class="td_cell_digit" onclick="digit('.');">,</td>
<td class="td_cell_digit" ></td></tr>
<tr>
<td class="td_cell_digit" onclick="operation('+');">+</td>
<td class="td_cell_digit" onclick="operation('-');">-</td>
<td class="td_cell_digit" onclick="operation('*');">*</td></tr>
<tr>
<td class="td_cell_digit" onclick="operation('/');">/</td>
<td class="td_cell_digit" onclick="go();">=</td>
<td class="td_cell_digit"></td></tr>
</table>
</body>
</html>

В этом документе идет ссылка с помощью тега link на файл стилей css "calc_style.css", в котором находятся определения классов стилей, примененных для оформления ячеек таблицы (td_cell_digit, div_digits, div_heading). Также в index.html есть ссылка на файл логики работы калькулятора. В нем находятся функции, вызываемые по нажатию на ячейки таблицы (operation, digit, go).

Вот исходный текст файла css-стилей. Жирным шрифтом я выделил начало селекторов css, для файла javascript, приведенного еще ниже, также было выделено начало функций.

body {
font-family: Verdana,monospace; /*шрифт всего документа*/
background-color: #8C82C4; /*фоновый цвет документа*/}
td { /* все общие стилевые характеристики для кнопки как в активном, так и в неактивном состоянии можно назначить ячейке таблицы */ cursor : pointer;
padding: 5px;
border: 1px solid black;
font-size: 14px;
font-weight: bold;}
.td_cell_digit { /* здесь задается стилевое оформление для кнопки калькулятора */
color: green;
background-color: #CE9A82;}
.td_cell_digit:hover { /* этот стиль служит для изменения внешнего вида кнопки при наведении на нее мыши; если вы пишете имя некоторого класса css или тега html, после которого идет :hover, то это означает стиль для элемента при наведении мыши – правда, для iexplorer этот прием не работает, кроме тега "a" – ссылки, но ведь мы делаем widget для opera */
color: red;
background-color: #7D7DC4;}
.div_digits { /* стилевое оформление блока, в котором будут выводиться цифры табло калькулятора */
margin: 10px; padding: 5px; font-size: 26px; min-width: 200px;
height: 40px; border: 2px solid black; color: green;
}

Последним я привожу исходный текст файла javascript "logic.js". К главному файлу index.html он был подключен с помощью тега <script>, атрибут src которого указывает имя файла javascript. Внимание следует обратить на функцию my_alert: хотя она нигде не вызывается, но следует добавить в код функции digit проверку того, что набираемое пользователем число корректное — например, в нем нет двух запятых, — и вызвать окно сообщения об ошибке. В javascript есть функция alert, которая выводит окошко сообщения с некоторым текстом. К сожалению, в widget вызов этой функции игнорируется, поэтому пришлось создать собственную версию, названную my_alert, которая получает так же, как и alert, в качестве входного параметра текст сообщения об ошибке, но помещает его внутрь размещенного в файле index.html блока div с идентификатором id="error_placeholder". Попробуйте сами добавить проверку числа на корректность, добавьте также операции извлечения корня, логарифма и т.д. Специального оформления блоку error_placeholder я не задавал, но вы легко можете добавить новый стиль, скажем, большими красными буквами с выравниванием текста посередине экрана в файл стилей "calc_style.css".

var firstNumber = 0; // объявляем две глобальные переменные для хранения первого числа в математической операции и соответственно кода самой операции
var op = '?';

function digit (d){
var div_digits = document.getElementById ('div_digits');
// здесь я получаю ссылку на находящийся в документе html тег div с идентификатором (именем) id, равным значению div_digits
div_digits.innerHTML = div_digits.innerHTML + d;// помещаю внутрь этого блока страницы еще одну цифру
}
function my_alert (msg){
var error_placeholder= document.getElementById ('error_placeholder');
error_placeholder.innerHTML = msg;
}
function operation (_op){
var div_digits = document.getElementById ('div_digits');
firstNumber = parseFloat (div_digits.innerHTML); // сохраняем первое число, которое ввел пользователь
div_digits.innerHTML = '';// очищаем табло калькулятора для ввода следующего числа
op = _op; // сохраняем название операции
}

function go (){// эта функция служит для расчета конечного результата
var rez = '';
var div_digits = document.getElementById ('div_digits');
var secondNumber = parseFloat (div_digits.innerHTML); // получаем второе число для последующей операции
switch (op){// здесь мы сравниваем значение переменной op с четырьмя возможными вариантами операций, и в переменную rez помещается
соответствующее выражение
case '+': rez = firstNumber + secondNumber; break;
case '-': rez = firstNumber — secondNumber; break;
case '*': rez = firstNumber * secondNumber; break;
case '/': rez = firstNumber / secondNumber; break;
}
div_digits.innerHTML = rez; // помещаем внутрь блока div результат расчета
}

Эти четыре файла вместе с файлом иконки calc_style.css, config.xml, index.html, logic.js, mark_4.gif необходимо поместить в архив zip. Если открыть его любым способом в браузере opera, то появится новое плавающее окно на рабочем столе с калькулятором, а в меню widgets добавится новый пункт — Super Puper Calc. Вдоволь наигравшись с ним, удалите виджет с помощью меню Widget -> Manage Widgets. Результат работы представлен на скриншоте. Все исходные тексты примеров размещены на сайте сайт

В следующий раз я покажу, как создать второе окно widget – окно с настройками, а также расскажу о методике асинхронных вызовов, являющихся одним из краеугольных камней технологии ajax. В качестве более функционального примера попробуем widget, взаимодействующий с блог-сервером, скажем, livejournal или blogger.

black zorro

© Компьютерная газета

полезные ссылки
IP камеры видеонаблюдения