Bexf — Фрэймворк для создания расширений

    image

    Недавно мне пришлось доточить одно расширение Оперы под себя, раньше я ими совершенно не занимался. Открываю код, о ужас! Куча непонятных цепочек пространств имен (window.opera.extension.tabs, window.opera.contexts.toolbar, window.opera.extension.broadcastMessage) которые с первого взгляда и не пойми что таят (я и не ждал легкого пути). Пришлось открыть dev.opera.com для дальнейшего изучения. Расширение я все-таки доточил и решил заодним написать фрэймворк, который значительно упрощает разработку расширений для Оперы.


    Рассмотрим код (index.html), который приходится писать до Bexf:
    window.addEventListener('load', function () {
        // Создаем кнопку
        var button = opera.contexts.toolbar.createItem({
            disabled: false,
            title: "Bexf Button Example",
            icon: "icon.png",
            popup: {
                href: "popup_1.html"
            },
            badge: {}
        });
        // Обновляем параметры попапа
        button.popup.href = "popup.html";
        button.popup.width = 400;
        button.popup.height = 150;
        // Обновляем тайтл кнопки
        button.title = 'Bexf Button Example\nTitle Updated via attr' + widget.preferences.getItem('some_option');
        // Вешаем событие "Клик"
        button.addEventListener('click', function () {
            // Открываем таб
            var tab = opera.extension.tabs.create({url: 'https://www.google.com/', focused: true});
            // Меняем текст в бедже
            button.badge.textContent = ~~(Math.random() * 10);
            // Можно закрыть таб
            // tab.close();
        }, false);
        // Вешаем событие "Кнопку убрали с панели"
        button.addEventListener('remove', function () {
            // Создаем новый таб
            opera.extension.tabs.create({url: 'http://www.ya.ru/', focused: true});
        }, false);
        // Добавялем на панель
        opera.contexts.toolbar.addItem(button);
        
        window.setTimeout(function () {
            // Через 10 секунд убираем кнопку с панели
            opera.contexts.toolbar.removeItem(button);
        }, 10000);
    }, false);

    С комментариями все вроде-бы ясно, а если убрать, то появляется куча непонятных пространств имен, свойств и методов:
    • window.opera.extension.tabs
    • window.opera.contexts.toolbar
    • button.popup.href
    • button.badge.textContent
    • window.widget.preferences.setItem|.getItem
    И двувариантные подходы: window.opera.extension.broadcastMessage или window.postMessage (хотя тут все верно)
    Вобщем с первого взгляда с расширениями без бутылки не разобраться. На помощь приходит Bexf.

    Рассмотрим тот же код (index.html), после Bexf:
    $.ready(function () {
        // Создаем кнопку
        var button = $.createButton({
            disabled: false,
            title: "Bexf Button Example",
            icon: "icon.png",
            popup: {
                href: "popup_1.html"
            }
        })
        // Обновляем параметры попапа
        .attr({
            href: "popup.html",
            width: 400,
            height: 150
        })
        // Обновляем тайтл кнопки
        .attr('title', 'Bexf Button Example\nTitle Updated via attr' + $.opt('some_option'))
        // Вешаем событие "Клик"
        .click(function () {
            // Открываем таб
            var tab = $.createTab({url: 'https://www.google.com/', focused: true});
            // Меняем текст в бедже
            button.text(~~(Math.random() * 10));
            // Можно закрыть таб
            // tab.close();
        })
        // Вешаем событие "Кнопку убрали с панели"
        .remove(function () {
            // Создаем новый таб
            $.createTab({url: 'http://www.ya.ru/', focused: true});
        })
        // Добавляем на панель
        .addToPanel();
    
        window.setTimeout(function () {
            // Через 10 секунд убираем кнопку с панели
            button.removeFromPanel();
        }, 10000);
    });
    Совсем другое дело, правда?

    Мы избавляемся от кучи пространств имен и приводим все к удобочитаемому виду, который знаком всем разработчикам jQuery (цепочки, названия методов, события и хелперы, сеттер-геттер). Получаем простые и понятные методы и классы:
    • Button
    • Tab
    • Window
    • .attr()
    • .bind()
    • $.createButton()
    • Button.addToPanel()
    • .click()
    • .remove()
    • $.ajax()
    • $.opt()
    И исключаем двувариантрый подход broadcastMessage/postMessage, теперь он заменен одни методом $.postMessage который вызывает тот или иной вариант в зависимости от места нахождения Bexf (popup или index).

    Файлы и ссылки


    Проект доступен на гуглокоде code.google.com/p/browser-extensions-framework
    Код фрэймворка с комментариями (16.2 Кб) browser-extensions-framework.googlecode.com/files/Bexf-1.0.js
    Минимизированный код (4.9 Кб) browser-extensions-framework.googlecode.com/files/Bexf-1.0.min.js

    Пример Bexf расширения (proof of concept): browser-extensions-framework.googlecode.com/files/bexf-example.oex
    Сразу опишу не явное поведение расширения: создает кнопку на панели и по таймеру меняет значение беджа кнопки, как только значение доходит до 0 удаляет кнопку, открывает таб с google.com через 5 секунд закрывает этот таб и открывает новый с ya.ru

    PS кроме тестовых расширений было создано одно «живое» расширение Habra Meter (думаю из названия понятно, что оно делает). Оно пока не прошло модерацию. Если кого-то заинтересовал Bexf или процесс написания расширений для Оперы я могу написать статью об создании и публикации Habra Meter с нуля (что там: красивая архитектура расширения, bexf, динамические иконки на кнопке через canvas).
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

    Комментарии 15

      0
      Спасибо, очень толково :)
        –27
        фу гадость какая. лучше всего у хрома расширения писать, потом аддон-ы мозилле.
          +13
          да при чем тут хром вообще? речь идет про расширения для оперы (есть такой браузер и им пользуются). в каждой теме одно и то же
            –8
            >лучше всего у хрома расширения писать
            автор нам красиво расписал как неудобно делать под оперу расширения. тот кто хоть раз делал ext для хрома со мной согласится — это удобно. аддон делать сложнее, но возможностей больше.
            к опере я вообще никак не отношусь.
              +5
              Автор нам расписал ни как неудобно делать под оперу расширение, а то что он столкнулся с не знакомыми вещами, после изучил предметную область и решил оптимизировать труд последующих товарищей. У которых не будет время сидеть и читать доки, а проще воспользоваться фреймворком автора.
          +1
          Автор, извини конечно, но нативный код, для меня читабельнее в разы.
            +3
            Если кого-то заинтересовал Bexf или процесс написания расширений для Оперы я могу написать статью об создании и публикации Habra Meter с нуля
            Конечно будет интересно ознакомиться с процессом написания расширения. Пишите статью ;)
              0
              Кстати, если не секрет, то какое именно расширение «доточили»?
                0
                Google Reader Checker (добавил возможность следить только за определенными группами rss каналов)
              +3
              Спасибо, идея интересная. Покажу разработчикам API для расширений Opera.
                +1
                А в чем прикол? Нельзя чтоли для jquery плагинов написать, чем с ноля какйо-то недо-фрейморк?
                В фреймворке для всех браузеров, а не только для оперы была бы реальная польза.
                  +1
                  а если кто захочет использовать jQuery в свое расширении, не возникнет ли конфликтов между вашим "$" и "$" от jQuery?
                    –1
                    Это предусмотрено
                    Вот основное замыкание Bexf
                    (function (exports, global, exportAs) {
                        // тут код Bexf
                        exports[exportAs] = BexfFactory;
                    }(this, this, '$'));
                    
                    Нужно исправить строку в самом конце скрипта. Меняем '$' на любое значение(прим 'Bexf') и Bexf экспортируется в любой нэймспэйс (в нашем случае в window.Bexf).
                    +2
                    А зачем вообще комментировать и давать короткие имена, если код «opera.contexts.toolbar.addItem» сам за себя всё говорит.
                      +1
                      > если код «opera.contexts.toolbar.addItem» сам за себя всё говорит
                      Код говорит, но удобно ли такой код писать и держать в памяти? Когда у вас кроме window.opera.extension.tabs, opera.contexts.toolbar.addItem ещё куча методов и пространств имен. С такими именами в 3 нэймспейса ваши шансы запутаться многократно возрастают и время написания возрастает.
                      Приведу пример названия класса Zend: Zend_Controller_Action_Helper_AutoComplete_Abstract вспомните такой по памяти?

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

                    Самое читаемое