Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Создаем дополнение для веб-браузера Firefox

Оригинал: Create a Firefox add-on for fun and profit
Автор: Ben Everard
Дата публикации: 19 ноября 2015 г.
Перевод: А.Панин
Дата перевода: 21 ноября 2015 г.

Улучшите качество вашего веб-серфинга, добавив новые функции в веб-браузер, и поделитесь своей работой с миллионами пользователей!

Для чего это нужно?

  • Дополнительные функции веб-браузера позволят улучшить качество веб-серфинга.

  • Дополнение позволит отслеживать сайты, следящие за тем, какие ресурсы вы посещаете.

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

С момента публикации данной статьи организация Mozilla изменила политику безопасности в отношении загрузки дополнений для своих продуктов. Новые версии Firefox не будут загружать дополнения до тех пор, пока они не будут снабжены электронной подписью от Mozilla, поэтому вы сможете использовать данное руководство для разработки дополнения только в том случае, если работаете с одной из старых версий Firefox (версией 42 или более ранней), с версией для разработчиков или с ночной сборкой Firefox. Дополнительная информация о данном изменении политики безопасности доступна на веб-сайте организации Mozilla по адресу https://wiki.mozilla.org/Add-ons/Extension_Signing.

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

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

Организация Mozilla предоставляет набор необходимых для разработки дополнений инструментов в форме SDK. Вы можете загрузить его по адресу http://add-ons.mozilla.org/en-US/developers/builder.

Разархивируйте загруженный файл архива и перейдите в созданную директорию:

unzip add-on-sdk-1.17.zip
cd add-on-sdk-1.17

После этого вы сможете приступить к работе с SDK, воспользовавшись командой:

source bin/activate

Для корректного выполнения данной команды необходимо, чтобы в вашей системе по умолчанию использовался интерпретатор языка программирования Python версии 2, что справедливо для большинства современных дистрибутивов Linux. Однако, в том случае, если вы работаете с таким дистрибутивом с новейшими версиями программного обеспечения, как Arch, по умолчанию наверняка будет использоваться интерпретатор языка программирования Python версии 3. Если вы столкнетесь с ошибкой сценария Python, она наверняка будет вызвана описанным несоответствием версий интерпретаторов. Вы можете избежать подобных ошибок, изменив первую строку каждого из cfx-файлов из поддиректории bin на следующую строку:

#!/usrbin/env python2

После этого при исполнении сценариев все также будут выводиться предупреждения, но сами сценарии будут корректно исполняться.

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

Основной код дополнения чаще всего размещается в файле сценария main.js, но в нашем случае большая часть кода будет размещена в файле сценария tracker.js

Основной код дополнения чаще всего размещается в файле сценария main.js, но в нашем случае большая часть кода будет размещена в файле сценария tracker.js

После того, как вы выполните приведенную выше команду, вы должны обнаружить, что приветствие вашей командной оболочки изменилось. Это означает, что вы начали работу с SDK. Активация SDK осуществляется не на постоянной основе, поэтому каждый раз при запуске новой командной оболочки вам придется повторно выполнять команду source bin/activate для повторной активации SDK. Если вы собираетесь вести разработку дополнений в течение достаточно длительного промежутка времени, вы можете добавить данную команду в файл профиля Bash для того, чтобы она автоматически исполнялась при запуске командной оболочки.

SDK работает на уровне директорий, поэтому вам придется создать новую директорию для файлов вашего дополнения. Эта директория может быть расположена в любой точке файловой системы. После того, как вы создадите новую директорию, перейдите в нее, выполнив команду cd в вашей командной оболочке с активированным SDK, после чего выполните еще одну команду:

cfx init

Данная команда позволяет создать структуру директорий и файлы, необходимые для корректного функционирования вашего дополнения. В результате в директории дополнения должны быть созданы поддиректории с именами data, lib и main и файл с именем package.json. Находясь в данной директории, вы также можете использовать инструмент cfx, являющийся частью SDK, для запуска веб-браузера Firefox с автоматической загрузкой активацией вашего дополнения:

cfx run

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

Сервис Twitter позволяет компании Google отслеживать перемещения просматривающих твиты пользователей с помощью Google Analytics

Сервис Twitter позволяет компании Google отслеживать перемещения просматривающих твиты пользователей с помощью Google Analytics

Пять лучших дополнений по нашей классификации

  • Ghostery является в некотором роде усовершенствованной версией создаваемого в данном руководстве дополнения. Оно также позволяет блокировать ресурсы, следящие за вашим перемещением по глобальной сети и при этом выводит больший объем информации о некоторых из таких ресурсов. Однако, в отличие от нашего дополнения, оно не выводит информации о всех серверах, которые могут исследовать ваш веб-трафик (https://add-ons.mozilla.org/en-US/firefox/add-on/ghostery).

  • Firebug является наиболее популярным дополнением для веб-разработчиков. Оно добавляет ряд возможностей в и без того впечатляющий набор инструментов Firefox для веб-разработки (https://add-ons.mozilla.org/en-US/firefox/add-on/firebug).

  • NoScript Security Suite позволяет указать типы сценариев, которые могут исполняться при загрузке веб-сайтов. Данное дополнение повышает безопасность, анонимность и скорость веб-серфинга (https://add-ons.mozilla.org/en-US/firefox/add-on/noscript).

  • Leech Block - это дополнение для тех, кто, как и мы, нередко отвлекается от работы для просмотра веб-сайтов и теряет часы рабочего времени на некоторых из них. Leech Block является дополнением, которое позволяет принудительно закрыть доступ к подобным веб-сайтам и вернуться к работе (https://add-ons.mozilla.org/en-US/firefox/add-on/leechblock).

  • Last Pass помогает запомнить пароли для сетевых учетных записей. (https://add-ons.mozilla.org/en-US/firefox/add-on/lastpass-password-manager).

Начнем разработку

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

Первым файлом сценария JavaScript дополнения, загружаемым Firefox, является файл lib/main.js. Сценарий из состава SDK создает этот файл в процессе создания директории дополнения, но не заполняет его каким-либо содержимым. Обычно данный файл используется лишь для загрузки необходимых компонентов SDK и передачи управления другим сценариям JavaScript из директории data.

Для нашего дополнении потребуется компонент SDK tabs, позволяющий взаимодействовать с просматриваемыми пользователем веб-страницами, а также компонент self, позволяющий просто загружать дополнительные сценарии. Добавьте следующий код в файл сценария lib/main.js:

var tabs = require("sdk/tabs").on("load", runTracker);
var self = require("sdk/self");
function runTracker(tab) {
	tab.attach({contentScriptFile: self.data.url("tracking.js")});
}

Данный код позволяет подключить сценарий data/tracking.js к страницам в процессе их загрузки. В данном случае используется немного неточная терминология. Компонент SDK с именем tabs используется для взаимодействия именно с веб-страницами, а не с вкладками браузера.

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

Основные функции нашего дополнения будут реализованы в рамках сценария tracking.js, поэтому следует создать пустой текстовый файл с данным именем в поддиректории data. Первым действием, которое нам придется выполнить, является создание области, в которой будет выводиться информация для пользователя. Подобная область может быть создана различными способами, но мы будем выводить информацию с помощью обычных сообщений, которые создаются с помощью функции alert() языка JavaScript. Эти сообщения являются обычными всплывающими окнами, которые будут показываться каждый раз при загрузке страниц. Наш сценарий tracking.js должен содержать следующий код для показа описанных сообщений:

alertText="Кто следит за вашим посещением этой страницы?\n"
// вывод информации о следящих ресурсах
alert(alertText);

Нам придется всего лишь заменить комментарий на код, который позволит установить различные ресурсы, следящие за посещением страницы.

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

// вывод информации о следящих ресурсах
var spyElements = document.querySelectorAll('img, script')
var domains = [];
for(var i = 0; i < spyElements.length; i++) {
  try {
    var domain = new URL(spyElements[i].src).hostname;
  }
  catch(err) {
    domain = null;
  } 
  if(domain && domains.indexOf(domain)==-1 ) {
       domains.push( domain );
       alertText += domain + "\n";
   }     
}
//сортировка по типам

Функция document.querySelectorAll() используется для получения массива изображений и сценариев на странице. Мы можем получить информацию о расположении источника (src) каждого из этих ресурсов, на основе которой впоследствии может быть получено соответствующее имя домена.

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

Условная инструкция if используется для проверки того, определено ли в переменной domain имя домена и не находится ли данное имя в массиве domains (мы ведь не хотим сообщать о каждом домене более одного раза). В том случае, если имя домена проходит данный тест, мы добавляем его в массив domains, а также в строку, которая будет показана на экране.

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

Популярное дополнение Firebug дополняет инструментарий веб-разработчиков, предназначенный для отладки сценариев веб-страниц

Популярное дополнение Firebug дополняет инструментарий веб-разработчиков, предназначенный для отладки сценариев веб-страниц

Google Chrome

Большая часть популярных веб-браузеров позволяет пользователям расширять свой набор функций тем или иным образом. В популярном веб-браузере Chrome от компании Google для этой цели используются расширения. По многим параметрам эти расширения схожи с дополнениями веб-браузера Firefox. Они также разрабатываются с использованием таких технологий, как HTML, CSS и JavaScript, причем для хранения их описаний также используются файлы формата JSON. Однако, в них используются отличные методы для взаимодействия с веб-браузером. Если вы хотите разрабатывать расширения для веб-браузера Chrome, вы найдете всю необходимую для начала работы информацию на ресурсе https://developer.chrome.com/extensisons.

Веб-браузер Opera в данное время основывается на технологиях веб-браузера Chromium, поэтому расширения данного веб-браузера работают практически также, как и расширения веб-браузера от компании Google. При этом Opera предоставляет дополнительный API для взаимодействия с Speed Dial (https://dev.opera.com/extensions/speeddial.html).

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

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

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

В первую очередь нам придется объявить переменные для хранения данных:

var advertisers = "";
var others = "";
var trackers = "";
var found = false;
var knownDomains = [['google', 'Google', 'Ad'],
	['doubleclick', 'DoubleClick(Google)', 'Ad'], 
	['facebook', 'Facebook', 'Ad'], 
	['adnxs', 'AppNexus', 'Tr']];

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

Следующая операция, которую нам придется выполнить, заключается в обходе массива со всеми собранными именами доменов и добавлении каждого из имен доменов в конец строки advertisers, others или trackers. Разместите следующий код в конце файла сценария tracking.js.

for(var i=0; i<domains.length; i++) {
   found = false;
   for (var j=0; j<knownDomains.length; j++) {
      if (domains[i].indexOf(knownDomains[j][0]) > -1) {
         found = true;
         if (knownDomains[j][2] == 'Ad') { 
            if ( advertisers.indexOf(knownDomains[j][1]) == -1) {
advertisers += knownDomains[j][1] + ", "
            }
         }
         else {
            if (trackers.indexOf(knownDomains[j][i]) == -1) {
trackers += knownDomains[j][1] + ", "
             }
         }
      }
   }

   if (found == false) {
   others += domains[i] + ", ";
   }
}

alertText += "\n**Рекламные ресурсы**\n" + advertisers + 
"\n**Ресурсы, собирающие статистику посещений**\n" + trackers + "\n**Другие ресурсы**\n" + others;

alert(alertText);

Данный код выполняет все необходимые действия, поэтому вы можете протестировать дополнение прямо сейчас с помощью команды cfx run.

Вы можете найти множество полезных дополнений для вашего веб-браузера, перейдя по адресу about:addons. Выше приведен список наших рекомендаций относительно выбора дополнений

Вы можете найти множество полезных дополнений для вашего веб-браузера, перейдя по адресу about:addons. Выше приведен список наших рекомендаций относительно выбора дополнений

Темы

Темы являются другой формой дополнений веб-браузера Firefox. Они не добавляют каких-либо дополнительных функций, но позволяют улучшить (или, по крайней мере, изменить) внешний вид пользовательского интерфейса веб-браузера. Простейший способ создания темы заключается в создании легковесной темы. Подобная тема не позволяет изменить внешний вид пользовательского интерфейса веб-браузера настолько, насколько это позволяет полноценная тема, но для ее создания не потребуется писать какой-либо код. Вы можете просто выбрать нравящиеся вам изображения и добавить необходимые данные в файл описания темы. Информация, необходимая для начала работы над подобной темой, находится по адресу: https://add-ons.mozilla.org/en-US/developers/docs/themes.

Полноценные темы позволяют осуществлять взаимодействие с описанием XUL графического интерфейса веб-браузера (использующим синтаксис XML) с использованием технологии CSS. Таким образом, вы можете реализовать множество вариантов модификаций графического интерфейса веб-браузера, а не ограничиваться размещением изображений на его элементах, однако, подобная тема всегда гораздо сложнее легковесной темы. Вы можете ознакомиться с дополнительной информацией по ссылке: https://developer.mozilla.org/en-US/docs/Building_a_Theme.

Переход в интерактивный режим

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

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

Для этого нам понадобится другой API: ui/ActionButton. Данный API позволяет разместить кнопку с иконкой на главной панели веб-браузера для упрощения использования дополнения. Первая задача, которую нам необходимо выполнить, заключается в подборе иконки для данной кнопки. В сети существует множество коллекций иконок, распространяемых в соответствии с условиями различных лицензий. Мы можем использовать иконку с глазом, расположенную по адресу https://www.iconfinder.com/icons/126581/eye_eyeball_view_icon. Нам понадобятся изображения формата PNG с размерами 16x16, 32x32 и 64x64 пикселя. Такие изображения могут быть загружены с упомянутого выше веб-сайта. Данная иконка создана Timothy Miller и распространяется в соответствии с условиями лицензии Creative Commons Attribution Share Alike, поэтому вы вольны использовать ее для любых целей с условием упоминания имени автора и распространения любых изменений в соответствии с условиями лицензии оригинала.

Загрузите файлы изображений в директорию data дерева директорий вашего дополнения и измените их имена на icon-16.png, icon-32.png и icon64-png в соответствии с размерами. Описание кнопки должно быть добавлено в файл сценария main.js. Измените содержимое этого файла следующим образом:

var self = require("sdk/self");
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");

var button = buttons.ActionButton({
  id: "track",
  label: "tracker",
  icon: {
    "16": "./icon-16.png",
    "32": "./icon-32.png",
    "64": "./icon-64.png"
  },
  onClick: handleClick
});

Для добавления кнопки вам всего лишь потребуется задействовать соответствующий компонент SDK, после чего указать значения свойств кнопки: id (идентификатор), label (метка) и icon (иконка). Строка onclick: handleClick сообщает дополнению о том, какую функцию необходимо вызвать тогда, когда пользователь нажмет на кнопку с иконкой. Реализация этой функции также должна быть добавлена в файл сценария main.js и может выглядеть следующим образом:

function handleClick(state) {
tabs.activeTab.attach({
	contentScriptFile: self.data.url("tracking.js")});
}

В данной реализации используется вызов метода attach(), который использовался ранее, но вместо привязки сценария к странице на каждой вкладке в процессе ее загрузки, мы осуществляем привязку сценария к странице на активной вкладке при нажатии кнопки с иконкой. После добавления приведенного выше кода вы можете использовать команду cfx run для запуска Firefox с новой версией дополнения, после чего у вас должна появится возможность отслеживания ресурсов, следящих за вашим перемещением по глобальной сети через активную вкладку, по нажатию на кнопку с иконкой.

SDK для разработки дополнений снабжен отличной документацией, доступной по адресу http://developer.mozilla.org/en/Add-ons/SDK

SDK для разработки дополнений снабжен отличной документацией, доступной по адресу http://developer.mozilla.org/en/Add-ons/SDK

Упаковка нашего дополнения

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

{
  "name": "LVPrivacy",
  "title": "Linux Voice Privacy",
  "id": "jid1-jBER4uLTx3qzfQ",
  "description": "See who's spying on your web browsing",
  "author": "Ben Everard",
  "license": "MPL 2.0",
  "version": "0.1"
}

Можете изменить содержимое этого файла для соответствия вашему дополнению. Полное описание параметров рассматриваемого файла доступно по ссылке https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json.

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

cfx xpi

После ее исполнения будет создан файл с расширением XPI, который вы можете установить в Firefox, перейдя в меню "Дополнения" > Меню настроек в верхнем правом углу > "Установить дополнение из файла ".

Полезные компоненты SDK

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

  • add-on-page: с помощью данного компонента вы можете создать страницу about для вашего дополнения.

  • panel: данный компонент предназначен для вывода уведомлений по аналогии с сообщениями, создаваемыми с помощью функции alert() языка JavaScript, причем вы можете включать в ваши уведомления код HTML, что делает их более удобными при необходимости вывода сложной информации или включения в выводимую информацию изображений.

  • notifications: данный компонент предназначен для вывода другого типа всплывающих уведомлений. С помощью данного компонента создаются уведомления окружения рабочего стола, которые предназначены для сообщения пользователю о наступлении того или иного события. В Linux для вывода данных уведомлений используется разделяемая библиотека libnotify.so, поэтому внешний вид уведомлений будет зависеть от используемого вами окружения рабочего стола.

  • request: это API для формирования запросов HTTP. Он позволяет лучше контролировать процесс формирования и отправки запроса HTTP для получения того или иного ресурса, чем в случае использования средств языка JavaScript.

  • simple storage: если вам необходимо сохранить данные между сессиями браузера, вам понадобится данный API.

  • tabs: вы уже видели, как данный компонент может использоваться для интеграции сценариев в веб-страницы, но соответствующий API также позволяет получать информацию с веб-страниц и взаимодействовать с ними различными способами.

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

  • io/file: как вы наверняка догадались, прочитав название данного компонента SDK, он реализует API для взаимодействия с файловой системой. Данный API предоставляет широкий спектр функций для работы с элементами файловых систем, не доступный где-либо еще.