В этой статье я хотел бы показать вам, как создать очень простое расширение Firefox, используя популярный фреймворк JavaScript Vue.

Эта статья разделена на две части. Первая часть охватывает все необходимые основы создания расширения Firefox, а вторая посвящена процессу его преобразования в Vue.

Предпосылки

Несмотря на то, что в статье не используются передовые методы Vue, а знания JavaScript должно быть достаточно, читателю рекомендуется иметь хотя бы базовое понимание Vue. Вы также увидите, как я создаю файлы через Терминал / Командную строку. Хотя это хороший и чистый способ создания новых файлов и папок, это не является обязательным требованием - эти вещи можно создавать, как вы предпочитаете :)

Оглавление

  • Создание расширения Firefox
  • Установка
  • Сделай что-нибудь

Создание расширения Firefox

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

Имея это в виду, давайте создадим новый каталог с именем MyExtension и войдем в него.

mkdir MyExtension
cd MyExtension

Расширение Firefox может содержать множество других дополнительных каталогов и файлов, поэтому давайте поговорим об обязательных. Собственно, обязательный. Единственный необходимый файл для расширения Firefox - это manifest.json, который должен находиться в корневом каталоге нашего расширения. Итак, давайте создадим один

touch manifest.json

и заполните его следующим json-объектом:

{
    "manifest_version": 2,
    "name": "MyExtension",
    "version": "1.0.0"
}

Это наименьшая рабочая конфигурация для работы расширения Firefox. Как вы можете догадаться, на данный момент это не очень полезно, но для начала это хорошее начало.

Я надеюсь, что каждое свойство в файле manifest.json говорит само за себя, но на всякий случай вот краткий обзор:

  • manifest_version - указывает версию самого файла манифеста. Для более подробной информации посетите Документацию Mozilla.
  • имя - так мы назвали наше расширение.
  • версия - это строка, указывающая текущую версию нашего расширения. Вы можете называть его как хотите, но есть некоторые соглашения, которым вы можете следовать. Подробнее см. Семвер.

Прямо сейчас весь наш проект выглядит так.

Прежде чем расширять его функциональностью, давайте посмотрим, как установить и отладить такое расширение.

Установка

Во-первых, нам нужно открыть страницу отладки. В адресной строке Firefox введите about:debugging и нажмите Enter. У вас должно получиться примерно следующее:

Нажмите кнопку Загрузить временное дополнение и откройте свой manifest.json файл. Теперь вы должны увидеть загруженное расширение в разделе Временные расширения.

Сделай что-нибудь

Теперь вам удалось создать и загрузить временное расширение Firefox! Несмотря на то, что это большое достижение и есть чем гордиться, давайте будем настоящими. Это бесполезно.

Он ни на что не похож, и пока ничего не делает; он просто сидит и берет ресурсы (почти ничего, но дело не в этом).

Так что давайте исправим эту часть «ни на что не похожа». Под этим я подразумеваю, что давайте дадим нашему расширению возможность представить себя миру - иконку.

Добавление значка к расширению

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

Давайте создадим папку, в которой будут жить наши изображения, а позже и большая часть исходного кода приложения.

mkdir -p assets/img

Параметр -p говорит, что команда должна создать все каталоги на пути, если они не существуют. Таким образом, в этом случае он создаст каталог asset и каталог img внутри него. Поместите выбранное изображение значка в папку img под именем _14 _ - и все готово.

Теперь наш проект выглядит так

MyExtension
    assets/
        img/
            logo.png
    manifest.json

Если вы нажмете кнопку перезагрузить на странице about:debugging, вы заметите, что ничего не происходит. Чтобы на самом деле указать расширению использовать наше изображение в качестве значка, нам нужно указать это явно. Для этого давайте обновим наш manifest.json файл.

Ключевым свойством для определения значков является (как вы никогда не догадались) свойство с именем icons. Это объект, где ключ - это размеры значка, а значение - путь к нему. Вы можете прочитать больше об этом здесь".

{
    "manifest_version": 2,
    "name": "MyExtension",
    "version": "1.0.0",
    "icons": {
        "48": "assets/img/logo.png"
    }
}

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

Теперь, когда он выглядит так, мы можем наконец показать его друзьям! Но это по-прежнему мало что делает. Знаете что? Лучше пока никому не показывать ...

Вместо этого давайте посмотрим, как на самом деле сделать наше расширение чем-то полезным.

Действия в браузере

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

Всплывающее окно, которое открывается после нажатия кнопки, представляет собой простую HTML-страницу, поэтому, прежде чем мы создадим кнопку, давайте подготовим для этой цели простую HTML-страницу с именем app.html.

touch app.html

Теперь ваша файловая структура должна выглядеть так

MyExtension
    app.html
    assets/
        img/
            logo.png
    manifest.json

и заполните app.html следующим содержимым

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    Hello Firefox extension!
</body>
</html>

Теперь нам нужно зарегистрировать этот html как всплывающее окно по умолчанию в manifest.json.

{
    "manifest_version": 2,
    "name": "MyExtension",
    "version": "1.0.0",
    "icons": {
        "48": "assets/img/logo.png"
    },
    "browser_action": {
        "default_icon": "assets/img/logo.png",
        "default_title": "Opens MyExtension",
        "default_popup": "app.html"
    }
}

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

default_title - это текст, который отображается, когда пользователь наводит курсор на кнопку.
default_popup - это наш HTML-код, который используется в качестве всплывающего окна. Вы можете узнать больше о browser_action в официальных документах.

Продолжайте, перезагрузите свое расширение в about:debugging, и теперь вы должны увидеть кнопку.

Поздравляем, вы успешно создали первое функциональное расширение Firefox, и на этот раз оно действительно что-то делает! :)

Запрос разрешений

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

Для этого нам нужно явно запросить доступ к вкладкам браузера, и он должен быть предоставлен нам пользователем. Обычно это делается в процессе установки, когда пользователя спрашивают, согласны ли он предоставить определенные разрешения для расширения.

Как вы могли догадаться, это снова происходит в manifest.json. На этот раз это свойство называется permissions и содержит массив всех разрешений, запрошенных расширением. Так что продолжайте и поместите tabs в этот массив.

{
    "manifest_version": 2,
    "name": "MyExtension",
    "version": "1.0.0",
    "icons": {
        "48": "assets/img/logo.png"
    },
    "browser_action": {
        "default_icon": "assets/img/logo.png",
        "default_title": "Opens MyExtension",
        "default_popup": "app.html"
    },
    "permissions": ["tabs"]
}

Теперь, когда вы попытаетесь установить расширение, вам будет предложено предоставить разрешение, которое запрашивает расширение. Что ж, на самом деле вам ничего не будет предложено, так как мы находимся в режиме отладки, но поверьте мне, он будет там.

Добавьте интерактивности

Пришло время получить и обработать некоторые данные. Мы воспользуемся предоставленным нам разрешением tabs и будем обращаться к нему через объект browser.

Но перед этим давайте создадим кнопку в app.html, которая будет запускать событие, и элемент ul, который покажет результаты.

...
<body>
    Hello Firefox extension!
    <button id="button">Show me tabs</button>
    <ul id="results"></ul>
</body>
...

Теперь нам нужно создать функцию loadTabs() и зарегистрировать ее как прослушиватель onlick. Итак, давайте создадим файл с именем app.js и поместим его в корневую папку нашего расширения. Зарегистрируйте функцию и свяжите ее в app.html.

...
<body>
    Hello Firefox extension!
    <button id="button">Show me tabs</button>
    <ul id="results"></ul>
    <script src="app.js"></script>
</body>
...

И наконец app.js

const btn = document.querySelector('#button');
if (btn)
    btn.addEventListener('click', loadTabs);
function loadTabs() {
    alert('Hello there!');
}

Перезагрузите расширение и нажмите кнопку. Если он правильно показывает окно с предупреждением, вы должны получить что-то похожее на это:

Последнее, что нужно сделать, это удалить вызов функции alert и заменить его фактическим запросом к браузеру, чтобы получить все открытые вкладки:

const btn = document.querySelector('#button');
if (btn)
    btn.addEventListener('click', loadTabs);
function loadTabs() {
    // This is the request to obtain an array of active tabs. It returns a promise.
    // It accepts a config object (see docs)
    browser.tabs.query({ currentWindow:true })
        .then(tabs => {
            const results = document.querySelector('#results'),
                  parts = [];
            for (let tab of tabs) {
                parts.push(`<li>${tab.title}: ${tab.url}</li>`);
            }
            results.innerHTML = parts.join('');
        });
}

Теперь, после нажатия кнопки, вы должны увидеть все вкладки, перечисленные в неупорядоченном списке. Поздравляю!

Прежде чем завершить первую часть статьи, позвольте мне показать вам еще кое-что.

Отладка всплывающих окон

Определенно будут моменты, когда вам нужно будет проверять элементы вашего всплывающего окна (html-документа) как обычной html-страницы. Для этих целей есть кнопка Отладка рядом с кнопкой Reload в разделе Временные расширения. Это не секрет, так как кнопка хорошо видна. Но как только вы перейдете к отладке, вы заметите, что как только вы щелкнете по окну инспектора, чтобы поиграть с элементами, ваше всплывающее окно закрывается. Это очень неудобно, но, к счастью, есть исправление.

Нажмите кнопку с тремя точками в правом верхнем углу окна проверки и нажмите Отключить автоматическое скрытие всплывающих окон.

На этом первая часть статьи завершается. В Части 2 мы рассмотрим добавление Vue в микс, используя его для создания интерфейса нашего расширения для браузера.

Часть 2 готова - вы можете прочитать ее здесь!

Эта статья опубликована на Github как проект с открытым исходным кодом, поэтому, если у вас есть какие-либо рекомендации, или вы обнаружили опечатку или ошибку, не стесняйтесь вносить свой вклад!

Кредиты

Особая благодарность Sunil и Wyatt за их вклад в эту статью.