Как сделать дополнение firefox

Быстрый старт в разработке дополнений Firefox

Про создание дополнений Firefox я знаю мало, но для того чтобы узнать это немногое мне потребовалось несколько дней. Эти знания мне не довелось пока применить для реальной задачи, и кто знает когда придётся. По теме есть много информации на английском языке, но в силу скудности моего английского эта информация была для меня трудновоспринимаема. Статьи, что я видел на русском, это в основном переводы, в которых много внимания уделяется деталям, но после их прочтения не возникает целостной картины. Моя статья — это попытка создать маленькое, но целостное знание: с чего начать и как с этим можно работать.

Думаю, все знают, что дополнения Firefox распространяются в виде xpi-файлов. xpi-файл представляет собой zip-архив, внутри которого есть какое-то количество файлов и директорий. Файлы могут быть js, css, xul, файлы изображений и, кажется, даже jar. У директорий обычно задаются стандартные названия, но жёстких требований нет.

В качестве первого своего дополнения мне захотелось сделать кнопку, по клику на которой отобразилось бы сообщение «Hello, World!». Кнопка должна была уметь размещаться на произвольной панели Firefox. И сделать это у меня получилось. Такое дополнение мне хотелось сделать ещё и потому, что обычно новые проекты удобнее создавать не с нуля, а с какого-то шаблона. Кроме этого, мне было интересно, можно ли работать с файловой системой, т.к. это, наверное, самое существенное ограничение JavaScript-а.

Думаю, Вам не будет интересно проходить тот же путь, по которому шёл я, чтобы создать всего лишь «Hello, World», а Вы сможете взять накопленную информацию и сразу двинуться дальше.

Подготовка к работе

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

появится папка с названием

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

Содержимое архива helloworld.xpi

Я не очень хорошо знаю, для чего предназначен каждый файл и тем более каждое слово в нём. Выделяю лишь те моменты, на которые сам обратил внимание.

content\overlay.xul

Это основной файл, он говорит, что кнопка должна быть добавлена на панель BrowserToolbarPalette. Где-то видел, что все панели имеют идентификаторы. В таком файле можно создать не только кнопку, но и свою панель. Код написан на языке XUL.

Внутри XUL может содержаться JavaScript или JavaScript может подключаться из внешних файлов.

locale\en-US\overlay.dtd

Это просто справочник текстовых констант.

В этой папке содержатся изображение для кнопки и файл со стилями

chrome.manifest

Очевидно, что это важный файл, который конфигурирует работу приложения. Подробнее не разбирался.

install.rdf

В соответствии с этим файлом происходит установка дополнения. Интересен тег id, идентификатор Firefox-а как продукта и без него работать не будет, а у Seamonkey другой идентификатор.

Рабочий процесс

Думаю, что рабочий процесс большинства JS-разработчиков выглядит как и мой: написал несколько строчек — посмотрел что получилось. Чтобы посмотреть, что изменилось в XUL надо перегрузить Firefox. Это немного напрягает… совсем чуть-чуть. Потому что хочется параллельно и документацию в интернете почитать. И перегружать получается не быстро.

Я нашёл дополнение Extension Developer. После установки на панель управления Firefox нужно вытащить кнопку ‘Reload all Chrome’. Изменения внутри кода разрабатываемого дополения вступят в силу сразу после клика по кнопке.

Функция read

В плане работы с файловой системой у меня возникла (большей частью скопирована откуда-то) функция:

Как я понял, записывать в файлы тоже можно, но уже не разбирался.

Заключение

Вот в-общем-то и всё, что я смог узнать за несколько дней (несколько свободных вечеров) о разработке дополнений Firefox. Надеюсь, тем кто впервые сталкивается с этой темой статья окажется полезной. На мой взгляд, всё для быстрого старта у вас есть: начальная информация, инструменты и процесс.

Просьба к читателям не ругать сильно, на роль «знающего» человека не претендую и на дополнительные вопросы вряд ли смогу ответить.

Источник

Устройство расширений для браузера Firefox (WebExtensions)

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

Тому, кто разбирается в веб-разработке, будет несложно создать новое расширение для браузера. Сейчас большинство самых популярных браузеров поддерживает стандартную систему разработки, которая использует в основном только JavaScript, HTML и CSS, — WebExtensions.

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

Вступление

Что нужно, чтобы начать

О браузерах

Firefox до версии 60 хуже поддерживал WebExtensions — там не были реализованы многие полезные функции. Но вообще более-менее сносно Firefox поддерживает эту систему начиная с версии 52.

В Google Chrome или Chromium расширения на основе WebExtensions всегда работают хорошо, ведь эта система изначально была сделана как их часть. У них, собственно, другие браузеры и позаимствовали эту систему. У API для браузера Firefox есть существенные отличия, о которых можно узнать из статьи Building a cross-browser extension. Она может помочь и для того, чтобы сделать расширение, которое подойдёт как для Firefox, так и для Chrome.

Независимо от того, для какого браузера создаётся расширение, может пригодиться информация об API расширений Chrome.

Многие из популярных браузеров работают на том же «движке», что и Google Chrome. Это и Яндекс-Браузер, и Opera, и Microsoft Edge. Поэтому и механизм расширений у всех этих браузеров очень похож на тот, что используется в Chrome. Отличия в API WebExtensions у этих браузеров от браузера Chrome, конечно, есть, но обычно их меньше, чем у Firefox.

Для Яндекс-Браузера на момент написания статьи рекомендовалось использовать расширения из каталога для браузера Opera. Значит, скорее всего, API для расширений у двух этих браузеров если и различаются, то мало. Поэтому, если будет нужно создать расширение для Яндекс-Браузера или Opera, обязательно просмотрите API для браузера Opera.

Если нужно сделать расширение для Edge, тогда смотрите список его средств API на сайте Microsoft.

Первый взгляд на расширение

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

Расширение — это набор скриптов. Самый главный из них — manifest.json. В некоторых случаях расширение может состоять вообще только из этого файла — такое может быть у расширения-темы, которое только изменяет стиль оформления окна браузера. В файле-манифесте содержится вся информация о расширении, а также о том, что и когда нужно запускать, что расширению разрешено делать, к каким ресурсам оно само даёт доступ, и некоторые настройки браузера. Остальное — скрипты Javascript, HTML, CSS, а также данные для них (например, файлы изображений).

Если совсем коротко, вот что может делать расширение:

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

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

По умолчанию расширению доступны только «безопасные» возможности, то есть только часть API WebExtensions. Чтобы использовать больше средств API, нужно дать расширению разрешения на доступ к ним.

Дополнительно можно почитать эти статьи:

Описание системы WebExtensions

Теперь рассмотрим основные понятия и особенности, связанные с созданием расширения в системе WebExtensions, с которыми придётся часто сталкиваться и в данной статье, и при чтении документации на MDN. Почти все ссылки этого раздела тоже ведут к разным местам текущей статьи.

API WebExtensions: точка входа

Состав объекта browser может отличаться как в разных скриптах, так и в разных расширениях. Это зависит от того, к какой части API WebExtensions разрешён доступ всему расширению, и в каком контексте выполнения работает скрипт.

Контексты выполнения

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

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

Все контексты выполнения можно разделить на две группы. В первую группу входит всего один вид контекстов — контексты содержимого веб-страниц. В каждом из них работает набор скриптов, добавленных нашим расширением к загруженной с сервера веб-странице. То есть каждой вкладке браузера, в которую наше расширение добавило скрипты, соответствует один такой контекст выполнения. Во вторую группу входят все остальные, привилегированные контексты. В них работают те части расширения, которые добавляют функционал к самой программе браузера. Например, всплывающее меню, боковая панель, фоновый скрипт (или «фоновая страница») — работают в таких контекстах.

Привилегированные контексты выполнения

У привилегированных контекстов выполнения есть такие особенности:

Контексты содержимого (не привилегированные)

Контекст содержимого веб-страницы отличается такими особенностями:

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

Время жизни

Взаимодействие между контекстами выполнения

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

Структура папки проекта

Я советую не создавать файлы расширения прямо в корневой папке проекта, а сделать там несколько папок: одну — собственно, для файлов расширения («Extension»), ещё одну — для файлов, описывающих дизайн («Design»), и ещё одну — для внешней программы, если она нужна («Native»). Можно ещё добавить папку «Build», чтобы складывать туда готовые к публикации файлы-архивы. А внутри папки расширения для тех контекстов выполнения, которым соответствует более одного файла, лучше создать отдельные папки. В папке расширения файлы, которые не являются скриптами, тоже обычно раскладывают по папкам: например, для иконок обычно создают папку «icons», а файлы локализации обязательно должны быть в папке «_locales» (если расширение поддерживает несколько языков). В итоге папка проекта может выглядеть так:

Манифест расширения

Файл-манифест не только обязателен для любого расширения. Он может быть и единственным файлом в расширении. Например, можно сделать расширение, при установке которого изменяется тема оформления браузера, используя только один файл манифеста. Смотрите документацию к элементу манифеста theme.

Документацию к файлу манифеста смотрите в статье о manifest.json на MDN.

Основные элементы манифеста

Файл манифеста лучше всего начинать с общего описания расширения, а именно — с трёх обязательных элементов:

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

Следующим лучше добавить краткое описание расширения — с помощью элемента description

Информация об авторе

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

Вместо этих двух элементов можно использовать один элемент-группу developer. Он делает то же самое, только выглядит немного иначе.

Идентификатор расширения, поддерживаемые версии браузера

Этот элемент необязателен и поддерживается только браузером Firefox, но часто бывает полезным. С помощью него можно указать диапазон версий браузера, в которых расширение может работать, а также ID расширения. Если в расширении используется внешняя программа (которую мы рассмотрим позже) или взаимодействие с другими расширениями, то этот ID должен быть известен и лучше указать его вручную. А если ID знать не нужно, можно вообще не беспокоиться о его существовании. Тогда просто не указывайте его, и он будет присвоен расширению автоматически — когда будет нужен.

Иконка-логотип

В документации на MDN сказано, что стандартный размер иконки для Менеджера Дополнений — 48×48 пикселов, но на момент написания статьи намного чаще используется размер 32×32. А ещё желательно добавить иконки размером в два раза больше — для экранов с большим разрешением, таких как Retina display в устройствах от фирмы Apple. Таким образом, чтобы иконка всегда хорошо отображалась, нужно добавить изображения таких размеров: 32×32, 64×64, 48×48 и 96×96 пикселов.

Рекомендуется использовать изображения в формате PNG или SVG. Даже если использовать один и тот же файл SVG для разных размеров иконки, лучше определить его в манифесте несколько раз — для разных размеров. Кстати, браузер Google Chrome не поддерживает файлы SVG в качестве иконок.

Пример начала файла манифеста

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

Разрешения на доступ к API

В целях безопасности, по умолчанию расширению доступен не весь API WebExtensions. Для того, чтобы открыть доступ к «небезопасным» средствам API, в файле-манифесте расширения нужно объявить соответствующие разрешения на доступ.

Такие разрешения добавляют с помощью элемента permissions в манифесте расширения. Если объявлены такие разрешения, при установке расширения пользователь увидит всплывающее окно, где будут перечислены дополнительные возможности, которые требует расширение, и вопрос, можно ли дать разрешение на доступ к ним. Если пользователь посчитает, что расширение требует слишком много возможностей и поэтому может быть опасным, он ответит «Не разрешать», и установка расширения будет отменена.

Разрешения для доступа к содержимому веб-страниц

Изначально доступ скриптов расширения к содержимому веб-страниц немного ограничен. Чтобы снять ограничения, нужно дать разрешение на доступ к определённым сайтам (host permissions) или к активной вкладке браузера ( activeTab ). В зависимости от целей, лучше выбрать один из этих видов разрешений.

Разрешения host permissions более потенциально опасны. В списке разрешений они обычно представлены как шаблоны адреса URL и дают расширению практически полный доступ к веб-сайтам, чей адрес URL совпадает с одним из этих шаблонов. К разрешённым таким образом сайтам можно добавлять скрипты содержимого из любых привилегированных скриптов, отправлять запросы AJAX из любого скрипта содержимого — даже из тех, которые были добавлены к странице другого сайта, а также читать и изменять данные HTTP-запросов и файлов cookie. Разрешение тоже относится к host permissions. Оно даёт доступ ко всем сайтам сразу, поэтому его лучше использовать только в крайних случаях.

Страница настроек расширения (options page)

Эту страницу создают таким же образом, как и обычную веб-страницу: файл HTML, к которому подключены CSS и JavaScript.

Страница опций работает в отдельном контексте выполнения, который, конечно же, является привилегированным. Время жизни скриптов этой страницы — пока она открыта.

Более подробное описание страницы опций есть в статье Options page.

Для хранения настроек расширения используйте storage API.

Можно заметить, что в Менеджере Дополнений браузера у каждого расширения есть опция Подробности. В старых версиях Firefox (приблизительно до 68) она, как правило, открывала ту же самую страницу опций. В более свежих версиях браузера опция Подробности открывает вкладку с общей информацией о расширении. Причём краткое описание расширения берётся не из файла-манифеста расширения или из какого-то другого файла. Его нужно написать при регистрации расширения на сайте расширений Firefox.

Фоновый скрипт

Очень часто расширению нужен фоновый скрипт. Он работает всё время, пока работает браузер — при условии, что расширение установлено и включено.

Можно создать один или более таких файлов JavaScript, или целую фоновую HTML-страницу с подключёнными к ней скриптами (и даже файлами CSS!). Эти файлы добавляются в расширение с помощью элемента background файла манифеста. Конечно, фоновая страница никогда не будет видна пользователю, а её элементы DOM нельзя полноценно использовать в других контекстах выполнения. Поэтому польза от фонового файла HTML небольшая.

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

В API WebExtensions есть одна любопытная функция — browser.runtime.getBackgroundPage(). Она наталкивает на мысль, что фоновую страницу можно использовать как библиотеку элементов DOM или функций JavaScript. Но, во-первых, она ненадёжна: если она используется в скрипте всплывающего меню, и пользователь открыл веб-страницу в приватном режиме, функция возвращает пустое значение. Во-вторых, она вообще не работает в скриптах содержимого — в единственном месте, где действительно пригодилась бы библиотека HTML-элементов.

С помощью механизма сообщений WebExtensions тоже нельзя передать HTML-элементы и функции. Конечно, можно передавать HTML в виде текста, но тогда для превращения этой строки обратно в элемент DOM придётся создать специальную функцию или использовать дополнительные библиотеки (смотрите ответ на StackOverflow). Чаще всего для всплывающих меню и боковых панелей такая HTML-библиотека не нужна, а для скриптов, добавленных в страницу, есть способы добавить отдельный файл HTML.

Если нужно добавить в расширение библиотеки функций, лучше используйте элемент user_scripts манифеста расширения, который появился в Firefox с версии 68. Или подключайте нужные файлы JavaScript к каждому контексту выполнения.

Добавление элементов управления в браузер

Вот в какие места вкладки браузера можно добавить элементы управления:

О всплывающих меню можно больше узнать из статьи Popups на MDN

Каждому всплывающему меню, а также боковой панели, будет соответствовать отдельный контекст выполнения. Все эти контексты — привилегированные и «живут», пока видно соответствующее меню или боковая панель.

Добавление скриптов в веб-страницы

Как было сказано в описании контекстов выполнения, в любую веб-страницу, открытую во вкладке браузера, можно добавить код JavaScript и стили CSS. Скрипты, которые добавили к одной и той же веб-странице в одной вкладке браузера, работают в одном и том же контексте выполнения — независимо от того, в какой момент времени и каким способом они добавлены. В данной статье такой контекст выполнения называется контекстом содержимого.

Добавить скрипты к веб-странице можно сразу тремя способами:

Привилегированные скрипты могут открывать в новых вкладках браузера HTML-файлы, которые находятся в составе расширения — с помощью функции browser.windows.create(). Если нужно добавить скрипты содержимого в такие страницы, расширению для этого не нужны никакие разрешения ( permissions ) — независимо от того, каким способом добавляются скрипты.

Любой контекст содержимого, образованный скриптами, добавленными во вкладку браузера, «умирает» при начале перезагрузки страницы или при закрытии вкладки браузера (или окна браузера, или всего браузера).

Как уже было сказано, к содержимому веб-страницы можно добавлять только файлы CSS и JavaScript. Но, если очень хочется, всё-таки можно использовать файлы HTML. Правда, для этого придётся использовать некоторые хитрости — например, как в этом ответе на StackOverflow.

Горячие клавиши

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

Таким образом можно назначить группу сочетаний клавиш для одного имени события. Можно указать одно из специальных событий — тогда при нажатии горячих клавиш будет открываться боковая панель браузера, или нажиматься одна из кнопок в его панели инструментов. В этом случае само событие ввода горячих клавиш нельзя перехватить и обработать — браузер реагирует на них так же, как если бы пользователь нажал на кнопку в панели инструментов мышкой или открыл боковую панель через меню браузера. А можно добавить своё событие с любым именем. Его можно использовать в любом контексте выполнения — обработчик события можно добавить функцией browser.commands.onCommand.addListener().

Опции контекстного меню

Чтобы добавить опцию в контекстное меню, используют функцию browser.menus.create(). С помощью неё можно добавить опции в меню разных контекстов вызова (не путать с контекстами выполнения расширения). Например, можно добавить одни опции в меню, которое появляется при правом клике на пустом месте страницы, другие — на выделенном тексте, третьи — на пункте меню закладок.

На действия с добавленными опциями меню можно реагировать, добавив обработчики событий в любом привилегированном контексте выполнения. Например, можно добавить обработчик для события browser.menus.onClicked. Этот обработчик получит в качестве параметров все данные о пункте меню, выбранном пользователем, и об условиях, в которых вызвано это меню: в какой вкладке браузера, на каком HTML-элементе, какой текст при этом выделен и многое другое.

Если нужно сделать изменения в DOM веб-страницы, при правом клике на которой вызвано меню, в обработчике события нажатия на пункт меню нужно добавлять строку JavaScript к содержимому этой страницы — с помощью функции browser.tabs.executeScript(). В строку кода можно добавить все необходимые данные: например, выделенный текст или идентификатор HTML-элемента, на котором вызвано меню. Можно использовать пример для функции browser.menus.getTargetElement().

Обмен сообщениями между контекстами выполнения

Основные объекты API

Для взаимодействия между контекстами выполнения используются два объекта из API WebExtensions. Объект browser.runtime предоставляет средства взаимодействия с общим рабочим окружением расширения. Через его API любые контексты выполнения могут взаимодействовать с привилегированными контекстами выполнения. Второй объект — это browser.tabs. Он служит для взаимодействия с системой вкладок браузера. С помощью API этого объекта привилегированные контексты выполнения могут обращаться к контекстам содержимого.

То есть при использовании API WebExtensions для взаимодействия между скриптами полезно помнить, что:

Формат сообщения

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

Разовый обмен сообщениями

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

Обратите внимание, что при использовании этого способа общения только разработчик расширения определяет условия удачного или неудачного обмена сообщениями, ведь ошибок связи здесь не бывает — могут быть только необработанные сообщения. Например, если в сообщении передана команда (придуманная разработчиком расширения), тогда именно от результата её выполнения другим скриптом должно зависеть, «успешная» ветка Promise выбрана или «ошибочная».

Общение с установлением соединения

Особенность такого способа в том, что общение происходит по установленному «каналу связи». Документация к API говорит, что в рамках одного соединения можно установить только один канал связи между двумя контекстами выполнения — несмотря на то, что теоретически можно установить много каналов от одного скрипта к другим. Этот способ хорошо подходит для обмена большим количеством информации. Общение происходит так:

Внешние программы

Что такое внешняя программа

Если возможностей, которые предоставляет API WebExtensions в рамках браузера, окажется недостаточно, можно подключить внешнюю программу (также называемую «родной» или «native»), которая будет работать не внутри браузера, а прямо в операционной системе. Браузер будет запускать эту программу и обмениваться с ней сообщениями.

Все недостатки такого подхода вытекают из того, что у разных видов операционных систем API сильно отличается. Один из способов решения этой проблемы — создать универсальную программу на платформе, которая мало зависит от типа операционной системы (например, Python, Node.js или Java), учитывая некоторые особенности работы в разных системах. Второй — сделать отдельную программу для каждого вида операционной системы. В любом случае пользователю придётся выполнить больше действий для установки расширения, использующего внешнюю программу. Иногда могут возникнуть трудности с установкой.

Самые популярные способы создания внешней программы — сделать скрипт для интерпретатора языка Python или для платформы Node.js, но в принципе можно использовать любые технологии и языки. Можно связать с расширением и обычную программу, установленную на компьютере, которая не рассчитывалась для обмена сообщениями с браузером. Для этого программа должна поддерживать интерфейс командной строки. Кроме того, придётся сделать свою программу-переходник, которая будет общаться с браузером через его механизм взаимодействия, а нужную программу запускать как команду.

Полная инструкция об использовании внешней программы в расширении есть в статье Native messaging. Рассмотрим общие принципы установки такой программы, и чуть подробнее — как браузер взаимодействует с ней.

Установка внешней программы

Внешняя программа, которую использует браузер, должна быть установлена в операционной системе, как и все остальные программы. Кроме того, при установке расширения, в специальной папке, которая находится где-то среди файлов настроек браузера, должен быть создан файл-манифест внешней программы (не путайте его с манифестом расширения). Этот файл нужен для того, чтобы браузер «знал», какие расширения могут использовать внешнюю программу и где находится её исполняемый файл. Конечно, для разных видов операционных систем и браузеров манифест внешней программы устанавливается по-разному. Подробности о том, как создать этот файл и установить его, читайте в статье Native Manifests.

Особенности взаимодействия с внешней программой

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

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

Сообщения, которые расширение отправляет внешней программе, вводятся в виде объектов JavaScript, совместимых с JSON. При передаче сначала этот объект преобразуется в строку символов в кодировке UTF-8. Затем строка превращается в последовательность байт (массив), а перед ним ставится целое число размером 4 байта. Это число — количество байт в массиве. Вся эта последовательность байт передаётся в стандартный поток ввода внешней программы (обычно называемый stdin). Внешняя программа отправляет ответ в свой стандартный поток вывода (stdout) в том же совместимом с JSON формате, что и принятое сообщение. Браузер преобразовывает эти данные в объект JavaScript, который передаётся скрипту расширения.

Внешняя программа должна уметь делать такие же преобразования, как те, что делает браузер. Обычно данные, полученные программой через поток ввода, преобразуют в некоторый объект или структуру данных, которые отражают объект JSON — для того, чтобы сообщение было удобнее обрабатывать. При отправке ответа используют такой же объект или структуру данных, преобразуя их в последовательность байт, описанную выше, и отправляя в стандартный поток вывода.

Разовый обмен сообщениями

Это происходит так:

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

Установление соединения с внешней программой

Можно установить соединение с внешней программой. Тогда взаимодействие с ней происходит так:

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

Больше возможностей

API WebExtensions предоставляет ещё много возможностей. Вот самые интересные из них:

Запуск и отладка расширения

Инструмент web-ext

В статьях о расширениях WebExtensions на сайте MDN часто упоминается инструмент web-ext. Это программа, работающая на платформе Node.js, которая помогает запускать расширение в браузере во время разработки, проверять синтаксис его файлов, а также упаковать файлы готового расширения в архив, готовый к опубликованию на сайте расширений Mozilla. Эта программа очень полезна в случаях, когда нужно протестировать расширение, создаваемое для мобильного браузера, или попробовать, как оно работает в разных версиях «настольного» браузера. Но на практике если нужно сделать расширение для «настольного» браузера Firefox той версии, что установлен в системе, и новее, то все эти действия можно делать вручную.

Информация об инструменте web-ext есть на сайте Extension Workshop. Мы рассмотрим, в основном, только как делать всё «вручную».

Пробный запуск расширения

Для запуска расширения, когда оно ещё на стадии разработки, в виде набора файлов, нужно сделать так:

Теперь расширение будет временно установлено в браузере. С помощью страницы about:debugging можно в любое время отключить расширение или удалить его из браузера. При следующей перезагрузке браузера расширение «исчезнет» из него.

Отладка

Когда расширение установлено, можно запустить его отладку:

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

Как упаковать и опубликовать расширение

Для упаковки расширения браузера Firefox рекомендуют использовать инструмент web-ext, но, вместо этого, можно вручную архивировать все файлы, относящиеся к расширению, в файл ZIP. Конечно, в этом архиве не должно быть ничего лишнего: файлов, относящихся к GIT, NPM и к другим инструментам разработчика, скриптов для тестирования, файлов внешней программы, внешних ресурсов для Managed Storage и модулей безопасности PKCS#11.

Надеюсь, что эта статья помогла понять устройство расширения браузера и узнать какие возможности доступны разработчику, и что этого будет достаточно, чтобы спроектировать расширение со всем нужным функционалом. Если хочется узнать больше о возможностях расширения, можно просмотреть документацию ко всем элементам манифеста расширения и к элементам API WebExtensions. Если в статье есть ошибки или неточности — пожалуйста, расскажите о них в комментариях.

Полезные ссылки

Вот список «корневых» страниц, с которых можно начинать поиск информации:

Источник

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *