Пользователь
0,0
рейтинг
3 июня 2011 в 12:41

Разработка → Kango — фреймворк для создания кроссбраузерных расширений

Вступление

Kango позволяет создавать расширения для популярных браузеров используя только JavaScript, причем код един для всех браузеров. На данный момент поддерживается Chrome, Firefox, Internet Explorer (в публичном доступе только версия с поддержкой Chrome и Firefox) и ведется работа над поддержкой Opera и Safari. Ниже будет рассмотрено как можно быстро создать простой кроссбраузерный Gmail Checker

Что должно получиться в итоге:




Подготовка среды для работы с Kango

Для начала работы с Kango нужно выполнить всего пару действий:
  1. Установить Python версии 2.7 (http://www.python.org/download/)
  2. Скачать по ссылке и распаковать в любую папку архив с фреймворком.

Создание нового проекта

Создаем на диске папку для проекта и запускаем из папки фреймворка kango.py
d:\dev\kango\kango.py create
На запрос имени проекта вводим Gmail Checker.
Теперь можно переходить к написанию кода своего расширения.
В дальнейшем имя и версию расширения можно установить с помощью файла common\extension_info.json.

Пишем Gmail Checker

Расширение будет периодически проверять количество непрочитанных сообщений на Gmail и отображает это количество на кнопке в браузере.

После создания проекта заходим в папку src\common и видим что для нас уже создан исходный шаблон в файле main.js.

Инициализация расширения


Подпишемся на событие готовности модуля UI. Нужно использовать его т.к. в нашем расширении есть визуальные компоненты, а именно кнопка в браузере.
kango.ui.addEventListener(kango.ui.event.Ready, function() {
    return new MyExtension();
});

Получаем количество непрочитанных писем


Количество непрочитанных сообщений можно получить по ссылке https://mail.google.com/mail/feed/atom в формате Atom 0.3 (для корректной работы необходимо чтобы пользователь был авторизован в Gmail в текущем браузере).

Для AJAX запросов используется метод kango.xhr.send.

var details = {
    url: 'https://mail.google.com/mail/feed/atom',
    method: 'GET',
    async: true,
    contentType: 'xml'    
};
kango.xhr.send(details, function(data) {
    if(data.status == 200) {
   	 var doc = data.response;
   	 var count = doc.getElementsByTagName('fullcount')[0].childNodes[0].nodeValue;
    }
});

Отображение количества сообщений на кнопке

Управление свойствами кнопки осуществляется с помощью объекта kango.ui.browserButton.

_setUnreadCount: function(count) {
    kango.ui.browserButton.setTooltipText('Unread count: ' + count);
    kango.ui.browserButton.setIcon('icons/icon16.png');
    kango.ui.browserButton.setBadge((count != 0) ? {text: count} : null);
}

Собираем все вместе

Добавим таймер, который будет с заданной периодичностью проверять количество новых сообщений и обработку ошибок, в итоге получится примерно такой код:
function GmailChecker() {
    var self = this;
    self.refresh();    
    kango.ui.browserButton.addEventListener(kango.ui.browserButton.event.Command, function() {
   	 self.refresh();
    });
    window.setInterval(function(){self.refresh()}, self._refreshTimeout);
}

GmailChecker.prototype = {

    _refreshTimeout: 60*1000*15,    // 15 minutes
    _feedUrl: 'https://mail.google.com/mail/feed/atom',
    
    _setOffline: function() {
   	 kango.ui.browserButton.setTooltipText('Offline');
   	 kango.ui.browserButton.setIcon('icons/icon16_gray.png');
   	 kango.ui.browserButton.setBadge(null);
    },
    
    _setUnreadCount: function(count) {
   	 kango.ui.browserButton.setTooltipText('Unread count: ' + count);
   	 kango.ui.browserButton.setIcon('icons/icon16.png');
   	 kango.ui.browserButton.setBadge((count != 0) ? {text: count} : null);
    },
    
    refresh: function() {   	 
   	 var details = {
   		 url: this._feedUrl,
   		 method: 'GET',
   		 async: true,
   		 contentType: 'xml'    
   	 };
   	 var self = this;
   	 kango.xhr.send(details, function(data) {
   		 if(data.status == 200) {
   			 var doc = data.response;
   			 var count = doc.getElementsByTagName('fullcount')[0].childNodes[0].nodeValue;
   			 self._setUnreadCount(count);
   		 }
   		 else { // something went wrong
   			 self._setOffline();
   		 }
   	 });
    }
};

kango.ui.addEventListener(kango.ui.event.Ready, function() {
    return new GmailChecker();
});

Итого всего 50 строк кода для расширения, которое будет работать под всеми популярными браузерами.

Иконки

В папку common/icons нужно положить иконки в формате PNG под именами icon16.png, icon32.png, icon48.png, icon128.png размерами 16x16, 32x32, 48x48, 128x128 пикселей соответственно, а так же иконку icon16_gray.png для отображения неактивного сотояния.

Сборка проекта

Для сборки проекта запускаем kango.py с аргументом build и путем до папки проекта

d:\dev\kango\kango.py build ./

Для сборки хромовского расширения нужен установленный Google Chrome под Windows, либо Chromium под Linux.

На выходе должны получиться gmailchecker_0.1.0.xpi и gmailchecker_0.1.0.crx, которые являются готовыми файлами расширений. Для Chrome также будет сгенерирован файл gmailchecker.pem для того, чтобы расширение потом можно было обновлять.

Дальнейшие перспективы

Большая часть API находится в фазе закрытого бета тестирование и в скором времени для публичного доступа будет доступна версия с возможностью модификации содержимого страниц (полный доступ к DOM) и возможностью открывать всплывающие HTML окна по клику на кнопке.

Ссылки

@nestor
карма
29,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (36)

  • +4
    Будут ли собранные расширения работать под Mac OS и Linux?
    • +8
      Python и JS кроссплатформены. — полагаю да.
      • +3
        Будут работать и расширения и сам сборщик под MacOS & Linux тоже работает.
        • +1
          Сборщик работает, но для этого нужно нечто следующее (например):

          @@ -243,7 +243,8 @@
          return outDir

          def pack(self, dst, src):
          - chrome_path = self.get_chrome_path()
          + chrome_path = '/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome'
          if(chrome_path != ''):
          extension_path = os.path.abspath(src)
  • +3
    На сколько фреймворк утяжеляет каждое расширение? Каждый килобайт обёрточного кода по крайней замедляет запуск браузера.
    • +1
      Присоединяюсь. Возможно, фреймворк нужно использовать для быстрого создания приложений под разные браузеры, а уже потом допиливать руками.
      • +5
        Прослойка между браузерным API и Kango API очень узкая и даже в бета версии неплохо оптимизирована — на скорость загрузки практически не влияет. Точные цифры подсчитывать ещё рано, но одной из задач сборщика является уменьшения оверхеда путём вырезания лишнего кода для каждой из платформ.

        Кроме того, единый код позвляет легче поддерживать аддон под всеми браузерами а не допиливать по отдельности всё.
        • +5
          Тогда это прекрасно :)
  • +4
    «Для сборки хромовского расширения нужен установленный Google Chrome под Windows, либо Chromium под Linux.»
    Странное заявление. А Google Chrome под Linux или Chromium под Windows не подойдут?

    А так всё клёво, такие фреймворки должны были сразу быть. А еще лучше — полная унификация расширений под браузеры. Хотя учитывая «альтернативно одаренные» браузеры из двух букв это навсегда будет фантастикой.
    • 0
      FF?
      • 0
        А я уж и забыл что IE имеет расшифровку в два слова, честно говоря. My bad. Имел в виду, конечно же, вечный тормоз развития веба Internet Explorer.
    • 0
      Альтернативная одаренность тут ни причем, чистая хронология. Сначала расширения появились в IE, они пишутся на C. Дальше пошли расширения в FF, на XUL+JS. И последние по времени Chrome+Safari+Opera расширения — на HTML+JS.
      Тенденция ясна?
      • 0
        Да знаю я, что появились в разное время и на разных технологиях. Я про то что не собираются никак унифицировать это. Потому что каждый гнёт свою линию. Причем если Mozilla и Google еще могут договориться о более-менее едином формате, то MS на это никогда не пойдет.
        • 0
          MS придётся сделать это, да они уже и идут к этому, потому что именно к этому всё и идёт, цитирую:

          thenextweb.com/dd/2011/06/02/windows-8-apps-to-be-built-in-html-javascript/

          Apps that use the “new Windows” approach to programming will be built in HTML and JavaScript, said Windows president Steven Sinofsky at D9′s Windows 8 announcement today.

          Windows 8 will run traditional Windows applications as well, but the company will encourage developers to adopt this new approach to application development that depends on the new wave of web technologies.


  • +2
    Шедеврально! :)
  • +2
    Кстати есть аналогичный фреймворк — FireBreath и тоже на питоне. О нем уже писали на хабре тут и тут
    • +7
      FireBreath это фреймворк для создания плагинов (NPAPI, ActiveX), а этот фреймкорк, как я понял, для создания расширений (позволяет добавлять кнопку в браузер и т.д.) и на выходе не дает бинарников — только JS.
  • 0
    Ожидается ли поддержка элементов UI, отличных от кнопки? Нотификаторы, попапы, и т.п.
    • +8
      Попапы и нотификаторы запланированны и находятся в стадии тестирования. Отдельно хочу заметить, что тулбаров здесь небдет никогда.
      • +2
        тулбаров здесь не будет никогда.

        Так вроде в chrome ext их и нет…
        • 0
          В экспериментальном API есть. Ждите, готовьтесь)
          • 0
            Нет, вру. Не тулбары будут, а сайдбары
      • 0
        спасибо за это
  • 0
    Интересует момент, например, из-под хрома можно программно скопировать выделенный на странице текст в буфер, чего в лисе сделать нельзя. Как будет себя вести сгенерированное расширение под лисой, непредсказуемо или просто данный функционал не будет работать?
    • 0
      Его просто не будет в API фреймворка
  • 0
    Интересно было бы почитать про то, как портировать расширения между платформами. Можно на примере работы этого фреймворка.
  • 0
    А можно итоговый вариант расширений?
    Просто понравилась реализация gmail для FF.

    Заранее спасибо.
    • +4
      Собранные расширения можно найти тут :Firefox, Chrome
    • 0
      Для FF уже проще стало, сделали стандартное builder.addons.mozilla.org/
  • 0
    Посмотрите еще в сторону CrossRider. Ну и еще сейчас, думаю, буду не единственным, если скажу что пишу и использую уже свой мини-фреймворк)
  • 0
    XUL? XPCOM? XBL? Components?
  • +1
    Дизайн kangoextensions.com/ напоминает www.assistly.com/ :)
    А фреймворк попробую, спасибо.
    • +1
      и не только на assistly, ещё на десятки сотен подобных, это тред
      а фреймворк да, надо потестить, очень кстати…
  • –1
    Ужасно много букв для такого расширения, можно ли это все ужать с помощью jQuery или лучше Mootools?
    Хотя я все же погляжу поближе. Спасибо
  • –2
    Он транслирует питоновский код в js? или для работы должен быть установлени питон? Вобщем, интересует как оно устроено?
  • 0
    В описании к последней версии указана поддержка Mac OS, с ошибкой кстати (Builder: Mas OS support added), но у меня процесс сборки расширения падает с ошибкой:
    Building chrome extension
    Traceback (most recent call last):
    File "../kango-framework-latest/kango.py", line 971, in main()
    File "../kango-framework-latest/kango.py", line 968, in main
    CommandLineProcessor().process()
    File "../kango-framework-latest/kango.py", line 962, in process
    args.execute(args)
    File "../kango-framework-latest/kango.py", line 930, in execute
    builder.build()
    File "../kango-framework-latest/kango.py", line 813, in build
    self._build_extension(builderClass)
    File "../kango-framework-latest/kango.py", line 787, in _build_extension
    self._copy_extension_files(self.jsSourceDir, out, builder.key)
    File "../kango-framework-latest/kango.py", line 775, in _copy_extension_files
    self._merge_dirs(os.path.join(src, dir), out)
    File "../kango-framework-latest/kango.py", line 759, in _merge_dirs
    self._merge_dirs(srcname, dstname)
    File "../kango-framework-latest/kango.py", line 760, in _merge_dirs
    elif not self._merge_jss(srcname, out):
    File "../kango-framework-latest/kango.py", line 730, in _merge_jss
    self._merge_files(dst_path, file, dst_path)
    File "../kango-framework-latest/kango.py", line 714, in _merge_files
    content += '\r\n\r\n// Merged from ' + second + '\r\n\r\n' + f.read()
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 34: ordinal not in range(128)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.