Решил я сделать одно небольшое расширение для Firefox, попутно описывая весь процесс разработки. Пишу больше для себя, чтоб легче было разобраться самому.
Что оно будет делать. Расширение будет присутствовать на панели Firefox в виде отдельной кнопки и отображать на этой кнопке флаг страны, в зависимости от того, какой у пользователя внешний IP. По нажатию на кнопку будет вываливаться всплывающее окно с опцией, которых будет одна — адрес скрипта, который выдаст нам нужные данные, и собственно, самим IP-адресом.
IP и страну будем получать с https://api.myip.com/, который выдает нужную информацию в виде JSON:
{"ip":"162.247.73.193","country":"United States","cc":"US"}
Создадим где-нибудь в удобном месте каталог, например, deoip
, он будет корневым каталогом нашего плагина, а в нем 2 подкаталога icons
и flags
Плагину требуется как минимум одна иконка 48×48 для отображения в менеджере дополнений, и желательна еще одна 96×96 пикселей. В Мозиловском примере говорится, что можно сделать иконку в формате SVG, но я не стал экспериментировать и сделал две PNG-шки.
Флаги стран, которые будут отображаться на кнопке панели, должны иметь размер 32×32 пикселя, а имена файлов соответствовать двухбуквенному ISO-коду страны. Я использовал готовые иконки из коллекций плюс еще одну иконку по умолчанию (0none.png
).
manifest.json
— это главный файл расширения, содержащий основные опции плагина.
Пока он выглядит так:
{ "manifest_version": 2, "name": "External IP GeoIP", "description": "Display you external IP and IP country", "version": "0.0.1", "icons": { "48": "icons/48.png", "96": "icons/96.png" }, "browser_action": { "default_icon": "flags/0none.png", "default_title": "External IP GeoIP" }, "permissions": [ "activeTab", "tabs", "storage" ] }
Сначала идут обязательные опции manifest_version
и name
— имя расширения, далее дополнительные, но желательные description
и version
, соответственно, краткое описание и версия. В секции icons
указываются пути к иконкам для менеджера дополнений (все пути должны быть относительными, относительно, собственно manifest.json
). В секции browser_action
описывается кнопка на панели браузера и привязанные к ней действия, пока действий у нас никаких (потом добавим выплывающее меню), а задача просто отобразить кнопку на панели. Поэтому добавляем опцию default_icon
— путь к иконке по умолчанию, и всплывающую подсказку default_title
(появится, если к кнопке подвести указатель мыши).
Далее интересная секция permissions
. Это разрешения для нашего плагина. Я уже примерно прикинул какие разрешения нам понадобятся: доступ к вкладкам (tabs
), к активной вкладке (activeTab
) и хранилищу, которое используется для сохранения настроек плагина (storage
).
Особая подготовка не требуется, но я рекомендую все-таки сделать отдельный пустой тестовый профиль. Набираем в адресной строке about:profiles
, жмем Enter, попадаем на страницу профилей, создаем отдельный профиль test и жмем «Запустить еще один браузер с этим профилем»
В браузере с новым профилем набираем в адресной строке about:debugging
, слева выбираем «Этот Firefox«, и жмем кнопку «Загрузить временное дополнение» и выбираем наш manifest.json
. Теперь идем в меню «Инструменты —> Дополнения» или набираем в адресной строке about:addons
, и если все сделано правильно, то видим наше дополнение в списке дополнений, а если откроем просто пустую вкладку, то увидим и кнопку.
Теперь приделываем нашему расширению всплывающую панель. В ней, как я уже говорил, можно будет увидеть IP-адрес и наименование страны, а также сменить адрес скрипта, который будет предоставлять эту информацию.
Закрываем тестовый профиль и идем дизайнить всплывающую панель. Это обычный HTML-файл, в котором необходимо прописать все необходимые элементы управления и прочее. Для оформления можно использовать CSS, который прописать, как внутри самой страницы, так и во внешнем файле CSS. В общем обычный web-дизайн.
Надизайнили? Сохраняем в каталог с manifest.json
html-файл и CSS.
Теперь надо добавить в manifest.json
в browser_action
параметр "default_popup"
:
"default_popup": "ip_popup.html"
Не забудьте запятую перед предыдущим параметром, если добавляете в конец секции, и после параметра, если добавляете в начало или середину.
Как написано в инструкции от Мозилла, после изменения manifest.json
временное расширение будет выгружено, его придется загрузить снова, как это описано выше в разделе «Первый запуск». Сам HTML можно допилить походу, если что-то пошло не так.
В CSS желательно прописать ограничение размеров самой страницы:
body { width: 380px; height: 180px; }
Удобнее потом будет регулировать, если что-то надо будет добавить/убрать.
Открываю браузер с тестовым профилем, загружаю дополнение.
Ну вот что у меня получилось:
Не обращайте внимание на то, что кнопка изменилась. Изначально была такая, как на этом скриншоте, но потом я ее перерисовал.
Финальный код будет в конце заметки.
Поскольку далее мы будем работать с хранилищем, то в manifest.json
надо добавить Addon ID, иначе потом получим ошибку: «Error: The storage API will not work with a temporary addon ID. Please add an explicit addon ID to your manifest. For more information see https://bugzil.la/1323228.»
Ставим запятую после ]
в "permissions"
и дописываем:
"applications": { "gecko": { "id": "external-ip-geoip@mozilla.org" } }
Весь manifest.json
:
{ "manifest_version": 2, "name": "External IP GeoIP", "description": "Display you external IP and IP country", "version": "0.0.1", "icons": { "48": "icons/48.png", "96": "icons/96.png" }, "browser_action": { "default_icon": "flags/0none.png", "default_title": "External IP GeoIP", "default_popup": "ip_popup.html" }, "permissions": [ "activeTab", "tabs", "storage" ], "applications": { "gecko": { "id": "external-ip-geoip@mozilla.org" } } }
С дизайном вроде закончили, теперь займемся логикой нашего всплывающего окна. В конец HTML-страницы перед закрывающим тегом </body>
дописываем ссылку на файл с javascript:
<script src="ip_popup.js"></script>
создаем файл ip_popup.js
и сохраняем его в каталог с ip_popup.html
Тег <script>
обязательно надо поместить в конце тела HTML-файла после всех элементов, иначе скрипт просто не увидит элементов (полей, кнопок ввода и т.д.) HTML-страницы.
В файле заведем две переменных для адреса по умолчанию и текущего адреса скрипта, который будет выдавать информацию об IP:
var defAddr='https://api.myip.com/';
var curAddr='';
и оформим вспомогательную функцию, которая будет проверять, пуст ли некий объект ({}
), или нет:
function isEmptyObject(obj) { for (var i in obj) { if (obj.hasOwnProperty(i)) { return false; } } return true; }