Как написать свое расширение для firefox

В этой статье мы пройдём весь путь создания WebExtension для Firefox, от начала и до конца. Это дополнение будет просто добавлять красную рамку ко всем страницам, загруженным с «mozilla.org» или любого из его поддоменов.

Исходный код этого дополнения доступен на GitHub: https://github.com/mdn/webextensions-examples/tree/master/borderify.

Для начала вам нужен Firefox 45 или более поздней версии.

Написание WebExtension

Создайте новую директорию (папку) и перейдите в неё:

mkdir borderify
cd borderify

manifest.json

Теперь создайте новый файл, назовите его «manifest.json» в папке «borderify». Вставьте туда следующий код:

{

  "manifest_version": 2,
  "name": "Borderify",
  "version": "1.0",

  "description": "Adds a solid red border to all webpages matching mozilla.org.",
  "icons": {
    "48": "icons/border-48.png"
  },

  "applications": {
    "gecko": {
      "id": "borderify@mozilla.org",
      "strict_min_version": "45.0"
    }
  },

  "content_scripts": [
    {
      "matches": ["*://*.mozilla.org/*"],
      "js": ["borderify.js"]
    }
  ]

}
  • Первые три ключа: manifest_version, name и version, являются обязательными и содержат основные метаданные о дополнении.
  • description не обязателен, но рекомендуется: это описание отображается в Менеджере Дополнений.
  • icons не обязателен, но рекомендуется: позволяет указать значок для дополнения, который будет виден в Менеджере Дополнений.
  • applications является обязательным для Firefox, и определяет ID дополнения. Он так же может использоваться для указания минимальной и максимальной версии Firefox, поддерживаемой расширением.

Самый интересный ключ здесь — это content_scripts, который говорит Firefox загружать скрипт на Web страницах, чей URL совпадает с заданным шаблоном. В нашем случае, мы просим Firefox загрузить скрипт с названием «borderify.js» на всех HTTP или HTTPS страницах, полученных с «mozilla.org» или любого из его поддоменов.

  • Узнать больше content scripts.
  • Узнать больше о match patterns.

icons/border-48.png

Дополнение должно иметь иконку (значок). Эта иконка будет показана в списке дополнений в Менеджере Дополнений. Наш файл manifest.json сообщает, что иконка будет находиться в файле «icons/border-48.png».

Создайте директорию (папку) «icons» внутри директории «borderify» . Сохраните в ней иконку под именем «border-48.png». Вы можете использовать иконку из нашего примера, которая взята из набора иконок Google Material Design, и используется по лицензии Creative Commons Attribution-ShareAlike.

Вы можете использовать собственную иконку. Её размер должен быть 48×48 пикселей. Вы можете также использовать иконку размером 96×96 пикселей для отображения на мониторах высокого разрешения. В этом случае вам необходимо указать её в качестве свойства «96» объекта «icons" в файле manifest.json:

"icons": {
  "48": "icons/border-48.png",
  "96": "icons/border-96.png"
}

Также вы можете создать иконку в формате SVG и она будет корректно масштабироваться.

  • Узнать больше о ключе icons

borderify.js

Наконец, создайте в директории «borderify» файл с именем «borderify.js» и поместите туда следующий код:

document.body.style.border = "5px solid red";

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

  • Узнать больше о content scripts

Пробуем

Сначала внимательно проверьте, что вы правильно разместили файлы и дали им правильные имена:

borderify/
    icons/
        border-48.png
    borderify.js
    manifest.json

Установка

Начиная с версии Firefox 45 вы можете временно установить WebExtension с локального диска.

Откройте страницу «about:debugging», кликните «Load Temporary Add-on» и выберите файл manifest.json:

Теперь ваше дополнение установлено и останется в браузере до его перезапуска.

Для проверки, зайдите на страницу «about:addons» чтобы открыть Менеджер Дополнений. Вы должны увидеть своё дополнение с именем и иконкой:

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

Тестирование

Теперь зайдите на любую страницу домена «mozilla.org» и вы должны будете увидеть красную границу вокруг страницы:

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

Примечание: Обратите внимание, что после изменения файла manifest.json, вы должны вручную перезагрузить своё дополнение. В настоящий момент это значит, что вам нужно перезагрузить Firefox, а затем снова загрузить своё дополнение на странице «about:debugging». Мы работаем над улучшением этого процесса.

  • Узнать больше о временной установке дополнений

Упаковка и публикация

Чтобы другие люди могли использовать ваше дополнение, вам необходимо запаковать его. Дополнения Firefox в запакованном виде являются XPI файлами, которые представляют собой обычные ZIP архивы с расширением «xpi».

При упаковке необходимо учитывать следующее: в ZIP архиве должны быть только файлы, а не содержащая их директория (директория «borderify» не должна попасть в архив). Для того, чтобы создать правильный XPI файл из вашего дополнения, в командной строке перейдите в директорию «borderify» и выполните следующую команду:

zip -r ../borderify.xpi *

Начиная с Firefox 43 все дополнения должны быть подписаны прежде чем они будут установлены в браузер. Вы можете снять это ограничение только в Firefox Developer Edition или Firefox Nightly при помощи следующих шагов:

  • перейдите на страницу about:config в Firefox
  • при помощи строки поиска найдите xpinstall.signatures.required
  • дважды кликнув на этом свойстве или при помощи локального меню (через клик правой кнопкой мыши), выберите «Toggle», чтобы установить значение false.
  • Узнать больше об упаковке и инсталляции
  • Узнать больше о подписи и распространении (en-US)

Что дальше?

Время на прочтение
8 мин

Количество просмотров 45K

В данной статье представлена пошаговая инструкция по разработке простейшего расширения для FireFox.
Это частичный перевод оригинальной статьи.

Это не моя статья, а моего друга (его мыльце: templar8@gmail.com).

Он очень хочет попасть на Хабр. У меня самого не хватает кармы для инвайта.

Вступление

Это руководство — пошаговая инструкция по созданию простейшего расширения. Мы попробуем добавить в строку состояния еще одну небольшую панельку с фразой «Hello, World!».

Подготовка окружения

Расширения упаковываются и распространяются в виде zip-файлов или пакетов с расширением XPI.

Вот пример типичной внутренней структуры XPI-файла:

exampleExt.xpi:
        /install.rdf
        /components/*
        /components/cmdline.js
        /defaults/
        /defaults/preferences/*.js
        /plugins/*
        /chrome.manifest
        /chrome/icons/default/*
        /chrome/
        /chrome/content/

Нам нужно создать структуру каталогов, похожую на эту. Для начала создайте корневую директорию расширения (например, C:extensionsmy_extension или ~/extensions/my_extension/). Внутри этого каталога создайте каталог chrome, в котором создайте каталог content.

В корневом каталоге расширения создайте два пустых текстовых файла с именами chrome.manifest и install.rdf. В итоге должна получиться структура каталогов следующего вида:

<ext path>
        install.rdf
        chrome.manifest
        chrome
            content

Дополнительная информация о настройке окружения находится по этой ссылке.

Сценарий установки

Откройте файл install.rdf и добавьте в него следующий текст:

  1. <?xml version="1.0"?>
  2.  
  3. <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  4.      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  5.  
  6.  <Description about="urn:mozilla:install-manifest">
  7.     <em:id>sample@example.net</em:id>
  8.     <em:version>1.0</em:version>
  9.     <em:type>2</em:type>
  10.  
  11.     <!-- Target Application this extension can install into,
  12.          with minimum and maximum supported versions. -->
  13.     <em:targetApplication>
  14.      <Description>
  15.         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
  16.         <em:minVersion>1.5</em:minVersion>
  17.         <em:maxVersion>3.0.*</em:maxVersion>
  18.      </Description>
  19.     </em:targetApplication>
  20.  
  21.     <!-- Front End MetaData -->
  22.     <em:name>sample</em:name>
  23.     <em:description>A test extension</em:description>
  24.     <em:creator>Your Name Here</em:creator>
  25.     <em:homepageURL>www.example.com</em:homepageURL>
  26.  </Description>     
  27. </RDF>

* This source code was highlighted with Source Code Highlighter.

  • sample@example.net — ID расширения. Это значение записывается формате email-адреса и необходимо для идентификации расширения (оно не должно быть вашим email-адресом). Сделайте его уникальным. Вы также можете использовать GUID. ПРИМЕЧАНИЕ: Хотя этот параметр и записывается в формате email-адреса, он не обязательно должен быть валидным. (example.example.example)
  • Параметр <em:type>2</em:type> — 2 указывает на то, что это будет расширение. Допустим, для тем оформления это значение должно быть установлено в 4 (все коды типов можно посмотреть тут).
  • {ec8030f7-c20a-464f-9b0e-13a3a9e97384} — ID Firefox’а (прим. пер. – видимо, для Thunderbird будет другое значение).
  • 1.5 — номер минимально необходимой для работы расширения версии Firefox. Никогда не используйте символ * для указания minVersion, это может привести к неожиданным результатам.
  • 3.0.* — максимальный номер версии Firefox с которой будет работать расширение. Это значение должно быть не новее самой последней на данный момент версии браузера! В данном случае «3.0.*» указывает на то, что расширение будет работать с Firefox 3.0 и версиями 3.0.x.

(Если вы получили сообщение, что install.rdf неверен, полезным будет загрузить этот файл в Firefox (Файл->Открыть файл…), после чего браузер покажет вам xml ошибки. В моем случае был пробел перед «<?xml»)

Расширениям, созданным для работы с Firefox 2.0.0.x, нужно указать в качестве максимальной версию «2.0.0.*». Для расширений, созданных для работы с Firefox 1.5.0.x — «1.5.0.*».

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

Сохраните файл.

Расширение браузера с использованием XUL

Пользовательский интерфейс Firefox написан с использованием XUL и JavaScript. XUL — это подвид XML, позволяющий создавать элементы пользовательского интерфейса, такие как кнопки, меню, панели управления, деревья и т.п. Все действия пользователя обрабатываются с помощью JavaScript.

Чтобы «расширить» браузер, мы изменяем отдельные части интерфейса пользователя Firefox, добавляя или модифицируя виджеты (элементы управления). Мы добавляем виджеты путем добавления новых XUL DOM-элементов в окно браузера и управляем их поведением с помощью скриптов и обработки событий.

Интерфейс браузера определен в файле browser.xul ($FIREFOX_INSTALL_DIR/chrome/browser.jar содержит content/browser/browser.xul) В browser.xul мы можем найти описание строки состояния, которое выглядит приблизительно так:

  1. <statusbar id="status-bar">
  2. ... <statusbarpanel> ...
  3. </statusbar>

* This source code was highlighted with Source Code Highlighter.

<statusbar id="status-bar"> — это «связующая точка» XUL-слоя.

XUL-слои

XUL-слои — это способ добавления виджетов в XUL-документ. XUL-слой — это .xul-файл, который определяет XUL-фрагменты, описывающие связующие точки в «основном» документе. Эти фрагменты могут указывать на виджеты, которые будут добавлены, удалены или изменены.

Пример документа XUL-слоя

  1. <?xml version="1.0"?>
  2. <overlay id="sample"
  3.          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  4. <statusbar id="status-bar">
  5.  <statusbarpanel id="my-panel" label="Hello, World" />
  6. </statusbar>
  7. </overlay>

* This source code was highlighted with Source Code Highlighter.

Тег <statusbar> с id, равным «status-bar» указывает на виджет браузера в который мы хотим добавить наш элемент.

Тег <statusbarpanel> — это новый виджет, который мы хотим добавить.

Сохраните этот код в файле sample.xul каталога chrome/content.

Chrome URIs

XUL-файлы – это часть т.н. «Chrome Packages» — пакетов элементов пользовательского интерфейса, загружаемых через URI вида chrome://. Вместо того, чтобы загружать интерфейс, используя URI вида file:// (тем более, расположение Firefox может быть различным в зависимости от платформы и систем), разработчики Mozilla пришли к решению создать новый вид URI, используя который все установленные приложения будут иметь доступ к содержимому XUL.

URI для окна браузера – это chrome://browser/content/browser.xul. Попробуйте ввести этот URL в адресной строке Firefox.

Chrome URI состоит из нескольких частей:

  • 1-я — протокол (chrome), которая сообщает сетевой библиотеке Firefox, что это Chrome URI.
  • 2-я — название пакета (в данном примере, browser), который указывает на набор компонентов пользовательского интерфейса. Для вашего приложения эта часть должна быть уникальной, во избежание конфликтов с другими расширениями.
  • 3-я — тип запрашиваемых данных. Бывает трех типов: content (XUL, JavaScript, XBL связи и другие составляющие пользовательского интерфейса приложения), locale (DTD, файлы .properties, в которых могут быть и другие файлы, содержащие строки локализации пользовательского интерфейса) и skin (CSS и изображения темы).
  • Последняя часть – путь к загружаемому файлу.

Например, chrome://foo/skin/bar.png загружает файл bar.png из раздела skin темы foo.

Когда вы загружаете что-либо, оперируя Chrome URI, Firefox использует реестр Chrome (Chrome Registry) для преобразования этого URI в реальный путь к файлу на диске (или в JAR архивах).

Создание Chrome Manifest

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

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

content     sample     chrome/content/

(Не забудьте о закрывающем слеше, «/»! Без него пакет не будет зарегистрирован.)

Разберем каждый элемент:

  1. тип пакета chrome
  2. название пакета chrome (должно быть написано в нижнем регистре, потому что Firefox/Thunderbird в версии 2 и более ранних не поддерживают названия со смешанным регистром — баг 132183)
  3. размещение файлов пакетов chrome

Это означает, что файлы пакета sample расположены в каталоге chrome/content относительно места расположения файла chrome.manifest.

Обратите внимание, что файлы контента, локализаций и скинов должны находиться внутри каталога content, locale и skin подкаталога chrome соответственно.

Сохраните файл. Теперь, когда вы запустите Firefox с вашим расширением (как это сделать, будет описано ниже), пакет chrome будет зарегистрирован.

Регистрация слоя

Теперь необходимо связать ваш слой с окном браузера. Для этого добавьте следующие строки в файл chrome.manifest:

overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul

Эти две строки указывают Firefox’у связать sample.xul и browser.xul во время загрузки browser.xul.

Тестирование

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

  1. Перейдите в домашний каталог, а после в каталог, содержащий профиль Firefox, с которым вы собираетесь работать (например, Firefox/Profiles/<profile_id>.default/).
  2. Перейдите в каталог extensions/, если его не существует, то создайте.
  3. Создайте текстовый файл и поместите в него полный путь к каталогу с вашим расширением (например, C:extensionsmy_extension или ~/extensions/my_extension/). Пользователи Windows должны помнить о направлении слешей, обязательно добавьте закрывающий слеш и удалите все замыкающие пробелы.
  4. Сохраните файл с id расширения в качестве его имени (например, sample@example.net). Без расширения файла.

Теперь все готово к тестированию.

Запустите Firefox. Firefox по текстовой ссылке сам найдет каталог с вашим расширением и установит его. После запуска браузера вы увидите надпись «Hello, World!» в правой части строки состояния.

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

Создание пакета

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

Запакуйте архиватором zip содержимое каталога с вашим расширением (не сам каталог расширения) и измените расширение архива с .zip на .xpi.

Если вы являетесь счастливым обладателем ‘Extension Builder’-а, то он может сам сделать за вас всю грязную работу (Tools -> Extension Developer -> Extension Builder). Просто перейдите в каталог с вашим расширением и нажмите кнопку Build Extension. Это расширение имеет очень много инструментов облегчающих разработку.

Теперь загрузите получившийся .xpi-файл на ваш сервер и удостоверьтесь, что его тип установлен в application/x-xpinstall. После этого можно скачать и установить расширение.

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

Наша цель

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

Что вам нужно — настройка среды разработки

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

Создайте другой профиль разработки

Первым шагом является создание другого профиля в Firefox, так как вы сделаете некоторые настройки и изменения, которые вы, вероятно, не хотите использовать в своем обычном профиле. В моем случае я создал новый профиль разработки под названием «dev». Шаги, чтобы сделать это:

Диспетчер профилей в Windows

Откройте меню «Пуск» и выберите «Выполнить» (в Vista его может и не быть — просто нажмите Windows key+ Rв этом случае). В диалоговом окне запуска напишите firefox -Pи нажмите enter/ нажмите OK. Выберите Create Profile в диалоговом окне и следуйте инструкциям.

Менеджер профилей на Mac

Откройте терминал (находится в папке / Applications / Utilities) и введите /Applications/Firefox.app/Contents/MacOS/firefox -profilemanager. Выберите Create Profile в диалоговом окне и следуйте инструкциям.

Менеджер профилей в Linux

Откройте терминал, используйте, CDчтобы перейти в каталог Firefox и затем войти ./firefox -profilemanager. Выберите Create Profile в диалоговом окне и следуйте инструкциям.

Настройки конфигурации для Firefox

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

Рекомендуемые настройки

Это хорошо для включения ошибок расширения в Консоли ошибок Firefox (Инструменты> Консоль ошибок), отключения кэширования XUL и т. Д.

  • javascript.options.showInConsole = true
  • nglayout.debug.disable_xul_cache = true
  • browser.dom.window.dump.enabled = true

Дополнительные настройки

Это не обязательно, но они могут помочь вам. Лично я этим не пользуюсь.

  • javascript.options.strict = true
  • extensions.logging.enabled = true

Укажите ваш каталог расширений Firefox на ваше расширение

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

Найдите каталог своего профиля

В каталоге профилей вы найдете все настройки для ваших профилей Firefox, включая информацию о расширениях.

Найти каталог профиля в Windows

В Windows 2000 и XP откройте проводник и перейдите C:Documents and Settings[your user name]Application DataMozillaFirefoxProfilesв Vista и перейдите в C:Users[your user name]AppDataRoaming.

Найти каталог профиля на Mac

Откройте Терминал и введите CD ~/Library/Application Support/Firefox/profiles/. Там вы найдете свои профили Firefox, и они будут названы буквами и цифрами, за которыми следует точка (.), А затем имя вашего профиля, например 12a3bc4d.dev.

Найти каталог профиля в Linux

Откройте терминал и введите CD ~/.mozilla/. В этом месте вы найдете все свои профили Firefox, и они будут названы буквами и цифрами, за которыми будет точка (.), А затем имя вашего профиля, например 12a3bc4d.dev.

Указывая на расширение

В папке вашего профиля разработки вы найдете папку с именем extensions. В нем у вас будет код для всех установленных расширений. Вместо того чтобы размещать там свой код, вы можете создать файл указателя. Сделайте это, создав файл с уникальным именем для вас (это должно быть то же самое, что вы выбрали для своего em:idзначения в вашем install.rdfфайле — подробнее об этом ниже).

В нашем примере создайте файл с именем linktargetfinder@robertnyman.comбез какого-либо расширения, и в нем просто укажите его, где вы будете иметь свой код, например C:extensions(Windows) или ~/Sites/linktargetfinder/(Mac).

Создание структуры папок и файлов

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

[Img_assist | NID = 7650 | название = | убывание = | ссылка = нет | Align = нет | ширина = 156 | Высота = 166]

я nstall.rdf

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

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-RDF-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-RDF#">

<Description about="urn:mozilla:install-manifest">
<em:id>linktargetfinder@robertnyman.com</em:id>
<em:name>Link Target Finder</em:name>
<em:version>1.0</em:version>
<em:type>2</em:type>
<em:creator>Robert Nyman</em:creator>
<em:description>Finds links that have a target attribute</em:description>
<em:homepageURL>http://www.robertnyman.com/</em:homepageURL>
<em:optionsURL>chrome://linktargetfinder/content/options.xul</em:optionsURL>

<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>3.1b2</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Страшно, правда? Ну, даже если вы не привыкли к RDF, это не так уж и плохо. Как и большинство кода, есть некоторая обязательная информация, которую вам никогда не понадобится изменять, а затем добавьте свою собственную. Интересные части для нас:

В Descriptionузле

em:id

Здесь вы можете добавить свой уникальный идентификатор разработчика по своему выбору.
Обратите внимание, что это должен быть файл указателя, который вы создали выше.
em:name

Название вашего расширения.
em:version

Текущая версия вашего расширения.
em:type

Тип объявляет, что это расширение, в отличие, например, от темы.
em:creator

Ну вы!
em:description

Описывает вашу функциональность расширения.
Будет отображаться в окне «Инструменты»> «Дополнения».
em:homepageURL
URL веб — сайта вашего расширения.

em:optionsURL
URL , где вы будете иметь свой файл для редактирования опций / предпочтений.


В Description/em:targetApplicationузле

em:id

Это значение является фактическим идентификатором Firefox.
Измените это, если вы хотите разрабатывать для Thunderbird или что-то еще.
em:minVersion

Минимальная версия Firefox, необходимая для запуска расширения.
Допустимые версии приложения .
em:maxVersion

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

Подробнее о дополнительных параметрах читайте в разделе «Установочные манифесты» .

c hrome.manifest

Хром Firefox — это все вокруг окна контента. т. е. панель инструментов веб-браузера, меню, строка состояния и т. д. Следующий файл для нашего расширения, который, вероятно, будет неудобно редактировать, — это chrome.mainfestфайл. Это, однако, связано с install.rdfключом к тому, как ваше расширение будет добавлено в Firefox и как оно будет работать. Наш chrome.manifestфайл выглядит так:

content     linktargetfinder    chrome/content/
content linktargetfinder chrome/content/ contentaccessible=yes
overlay chrome://browser/content/browser.xul chrome://linktargetfinder/content/browser.xul

locale linktargetfinder en-US locale/en-US/

skin linktargetfinder classic/1.0 skin/
style chrome://global/content/customizeToolbar.xul chrome://linktargetfinder/skin/skin.css

Итак, что же это за варианты? Давайте пройдемся по ним:

content linktargetfinder chrome/content/

Путь к тому, где будут найдены ваши файлы содержимого расширения.
content linktargetfinder chrome/content/ contentaccessible=yes

То же, что и выше, но когда
contentaccessible=yesон добавлен, он позволяет Firefox 3 и более поздним версиям получать доступ к файлам расширения и отображать их в веб-браузере (как на веб-странице). Нашел эту отличную помощь через
веб-страницы, доступ к chrome: // запрещен .
overlay chrome://browser/content/browser.xul chrome://linktargetfinder/content/browser.xul

Путь к файлу, который вы будете использовать для переопределения элементов веб-браузера и добавления элементов на панель инструментов, в меню и строку состояния.
locale linktargetfinder en-US locale/en-US/

Используется для локализации контента.
skin linktargetfinder classic/1.0 skin/

Кожа ссылка.
style chrome://global/content/customizeToolbar.xul chrome://linktargetfinder/skin/skin.css

Наложения стилей для хромированных страниц.

Более подробную информацию можно найти в Chrome Manifest .

папка c hrome

Хорошо, как только обязательные части убраны, теперь вещи начинают становиться интересными. Это также когда мы начинаем смотреть на XUL, что означает XML User Interface Language. Он разработан Mozilla для создания интерфейсов в Firefox, Thunderbird и т. Д.

Сначала в chrome/contentпапке создайте три файла:

  • browser.xul
  • options.xul
  • linkTargetFinder.js

browser.xul

Это файл, который мы будем использовать, чтобы переопределить внешний вид веб-браузера по умолчанию, т. Е. Добавить кнопку на панель инструментов, элемент в меню «Инструменты» и значок в строке состояния. Давайте посмотрим на полный файл browser.xul, а затем разберем его:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://linktargetfinder/skin/skin.css" type="text/css"?>
<!DOCTYPE linktargetfinder SYSTEM "chrome://linktargetfinder/locale/translations.dtd">
<overlay id="sample" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="linkTargetFinder.js" />

<menupopup id="menu_ToolsPopup">
<menuitem label="&runlinktargetfinder;" key="link-target-finder-run-key" oncommand="linkTargetFinder.run()"/>
</menupopup>

<keyset>
<key id="link-target-finder-run-key" modifiers="accel alt shift" key="L" oncommand="linkTargetFinder.run()"/>
</keyset>

<statusbar id="status-bar">
<statusbarpanel id="link-target-finder-status-bar-icon" class="statusbarpanel-iconic" src="chrome://linktargetfinder/skin/status-bar.png" tooltiptext="&runlinktargetfinder;" onclick="linkTargetFinder.run()" />
</statusbar>

<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="link-target-finder-toolbar-button" label="Link Target Finder" tooltiptext="&runlinktargetfinder;" oncommand="linkTargetFinder.run()"/>
</toolbarpalette>
</overlay>

Сначала есть некоторый общий синтаксис XML , затем вы включаете свой код CSS и устанавливаете DOCTYPE для локализации. За ним следует overlayкорневой элемент с пространством имен, вдохновленным Ghostbuster (разработчики — настоящие гики :-)).

После этого вы можете написать любой XUL-файл, который вам нужен, и, в принципе, HTML должен был быть таким. Я имею в виду то, что он заполнен базовыми опциями интерфейса, которые нигде не встречаются в HTML . Для полного обзора того, что вы можете сделать, пожалуйста, прочитайте XUL Reference .

В нашем коде мы начинаем с добавления пункта меню в меню «Инструменты» в Firefox и подключаем его к сочетанию клавиш:

<menupopup id="menu_ToolsPopup">
<menuitem label="&runlinktargetfinder;" key="link-target-finder-run-key" oncommand="linkTargetFinder.run()"/>
</menupopup>

<keyset>
<key id="link-target-finder-run-key" modifiers="accel alt shift" key="L" oncommand="linkTargetFinder.run()"/>
</keyset>

Затем добавьте значок в строку состояния Firefox:

<statusbar id="status-bar">
<statusbarpanel id="link-target-finder-status-bar-icon" class="statusbarpanel-iconic" src="chrome://linktargetfinder/skin/status-bar.png" tooltiptext="&runlinktargetfinder;" onclick="linkTargetFinder.run()" />
</statusbar>

И в конце мы добавляем кнопку на панель инструментов Firefox:

<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="link-target-finder-toolbar-button" label="Link Target Finder" tooltiptext="&runlinktargetfinder;" oncommand="linkTargetFinder.run()"/>
</toolbarpalette>

Обратите внимание, что вам нужно перейти в меню «Вид»> «Панели инструментов»> «Настроить…», чтобы добавить кнопку на видимую панель инструментов.

В приведенных выше примерах вы могли заметить &runlinktargetfinder;код. Это используется для локализации текста, а его перевод можно найти в localeпапке. Подробнее об этом позже.

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

Если вы хотите использовать обычные элементы HTML вместо / вместе с XUL, вы можете включить определение XHTML в свой корневой элемент, а затем включить любой элемент HTML с html:префиксом. Как это:

<overlay id="sample" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:HTML="http://www.w3.org/1999/xhtml">

<html:input type="submit" value="Send" />

options.xul

Этот файл используется для диалога опций / предпочтений вашего расширения, и его путь указан в install.rdfфайле в Description/em:optionsURLузле. Полный файл опций для нашего расширения выглядит так:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<prefwindow
title="Link Target Finder Preferences"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<prefpane label="Link Target Finder Preferences">
<preferences>
<preference id="link-target-finder-autorun" name="extensions.linktargetfinder.autorun" type="bool"/>
</preferences>

<groupbox>
<caption label="Settings"/>
<grid>
<columns>
<column flex="4"/>
<column flex="1"/>
</columns>
<rows>
<row>
<label control="autorun" value="Autorun"/>
<checkbox id="autorun" preference="link-target-finder-autorun"/>
</row>
</rows>
</grid>
</groupbox>

</prefpane>

</prefwindow>

Опять же, некоторая регулярная информация XML и стилизация содержимого. Затем он использует XUL для разметки содержимого диалога настроек. Интересная часть здесь, однако, соединяет пользовательский ввод с фактическими настройками расширения (эти настройки можно найти в prefs.jsфайле, подробно описанном ниже).

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

<preferences>
<preference id="link-target-finder-autorun" name="extensions.linktargetfinder.autorun" type="bool"/>
</preferences>

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

<checkbox id="autorun" preference="link-target-finder-autorun"/>

Обратите внимание, что вам не нужно добавлять кнопку «ОК» для диалогового окна — например, на Mac ее не будет, пока она автоматически добавляется для пользователей Windows. Все о совместимости системы, друзья мои.

linkTargetFinder.js

Если вы похожи на меня, то здесь вы будете чувствовать себя как дома. Хороший старый код JavaScript.:-)

Здесь приятно то, что вы можете написать любой элемент в XUL и любой элемент в окне содержимого HTML . Все, что вам нужно, чтобы получить доступ к окну контента, — это предшествовать вызову документа contentключевым словом, например так:

content.document.getElementsByTagName("a");

Вот полный код linkTargetFinder.jsфайла:

var linkTargetFinder = function () {
var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
return {
init : function () {
gBrowser.addEventListener("load", function () {
var autoRun = prefManager.getBoolPref("extensions.linktargetfinder.autorun");
if (autoRun) {
linkTargetFinder.run();
}
}, false);
},

run : function () {
var head = content.document.getElementsByTagName("head")[0],
style = content.document.getElementById("link-target-finder-style"),
allLinks = content.document.getElementsByTagName("a"),
foundLinks = 0;

if (!style) {
style = content.document.createElement("link");
style.id = "link-target-finder-style";
style.type = "text/css";
style.rel = "stylesheet";
style.href = "chrome://linktargetfinder/skin/skin.css";
head.appendChild(style);
}

for (var i=0, il=allLinks.length; i<il; i++) {
elm = allLinks[i];
if (elm.getAttribute("target")) {
elm.className += ((elm.className.length > 0)? " " : "") + "link-target-finder-selected";
foundLinks++;
}
}
if (foundLinks === 0) {
alert("No links found with a target attribute");
}
else {
alert("Found " + foundLinks + " links with a target attribute");
}
}
};
}();
window.addEventListener("load", linkTargetFinder.init, false);

Хотя это довольно много кода, он также очень простой. Когда окно загружается, оно запускает initметод linkTargetFinderобъекта. Если для параметра autorunустановлено значение true, он runнемедленно вызывает свой метод. В противном случае он будет вызываться только при нажатии кнопки панели инструментов, элемента меню или значка строки состояния. Это происходит через oncommandатрибут на элементах в browser.xulфайле.

Код в runметоде довольно прост. Он добавляет файл CSS из папки расширений chrome в текущий документ, находит все ссылки в нем, просматривает их и проверяет, есть ли у них targetатрибут, подсчитывает их, выделяет их и предупреждает о количестве обращений.

Как видите, в коде есть указатель на то, что называется gBrowser. Вот как получить ссылку на текущий веб-браузер, и вы также можете использовать getBrowser(). Обратите внимание, что этот вид кода доступен только из контекста XUL веб-браузера. Дополнительную информацию и опции можно найти в браузере с вкладками.

Единственная необычная часть для JavaScript — это переменная prefManager, которая подключается к диспетчеру предпочтений Firefox и позже получает autorunпредпочтение с помощью этого кода:

var autoRun = prefManager.getBoolPref("extensions.linktargetfinder.autorun");

Три типа расширений: строковое, целое и логическое, и шесть методов для работы с ними:

  • getBoolPref()
  • setBoolPref()
  • getCharPref()
  • setCharPref()
  • getIntPref()
  • setIntPref()

д efaults папки

Внутри defaultsпапки вы создаете preferencesпапку, а в ней — файл с именем pref.js. Это используется для предпочтений, которые вы хотите использовать для вашего расширения, и выглядит так:

pref("extensions.linktargetfinder.autorun", false);

l ocale папка

Используется для локализации. В нашем случае у нас есть только одна дочерняя папка для en-USконтента, но она может быть легко расширена. У этой папки есть файл с именем translations.dtd, который содержит переводы для сущностей, используемых в файлах XUL. Наш файл выглядит так:

<!ENTITY runlinktargetfinder "Run Link Target Finder">

Помните &runlinktargetfinder;в browser.xulфайле? Вот где он получает свой перевод.

папка s kin

Теперь, когда у нас есть все функциональные возможности, давайте сделаем вещи немного более симпатичными (немного, хорошо?). В нашей skinпапке, у нас есть три файла: skin.css, status-bar.pngи toolbar-large.png. Изображения, естественно, используются для панели инструментов и строки состояния соответственно.

CSS в skin.cssиспользуется для установки изображения на панели инструментов, размер и место для значка STATUSBAR и выделения вида ссылок с targetатрибутом. Код выглядит так:

#link-target-finder-toolbar-button {
list-style-image: URL("chrome://linktargetfinder/skin/toolbar-large.png");
}

#link-target-finder-status-bar-icon {
width: 83px;
margin: 0 5px;
}

.link-target-finder-selected {
outline: 2px solid red !important;
}

Упаковка и установка

Расширения Firefox поставляются как файлы XPI, и в основном это просто ZIP-файлы с другим расширением. Поэтому, когда вы закончите со своим расширением, все, что вам нужно сделать, это сжать файлы вместе и дать ему расширение XPI. Примечание: не не ZIP вмещающей папки для расширения, только его содержимого ( chromeпапок, chrome.manifestи install.rdfфайлов и т.д.).

Получив файл XPI, вы можете просто перетащить его в Firefox, и он автоматически установится.

Упаковка с Windows

Выберите все содержимое вашей папки расширения, щелкните правой кнопкой мыши и выберите Send To > Compressed (Zipped) Folder. Переименуйте его .xpiвместо, .zipи все готово!

Упаковка с Mac

Откройте терминал, перейдите к вашему внутреннему номеру с помощью CDкоманды и введите zip -r LinkTargetFinder.xpi *. Та даа!

Упаковка с Linux

Откройте терминал, перейдите в папку расширений и введите zip -r LinkTargetFinder.xpi *All done!

Распределение вашего расширения

Есть два варианта распространения вашего расширения. Или используйте addons.mozilla.org или разместите его самостоятельно. Если вы делаете это самостоятельно, вы можете указать updateURLв своем install.rdfфайле, но учтите, что начиная с Firefox 3 это должно быть безопасное место, например, через SSL или подобное.

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

Чтобы убедиться, что это не займет больше времени, чем необходимо, я рекомендую прочитать
статью «Успешно рассмотрите свой аддон» .

Загрузки

Весь код, который я здесь создал, доступен как ZIP-файл, так что вы можете начать экспериментировать, что-то менять и посмотреть, что произойдет. Он также доступен в виде файла XPI, который вы можете установить в Firefox просто для проверки функциональности (перетащите его в Firefox).

  • Загрузите код Link Target Finder в виде ZIP-файла .
  • Загрузите Link Target Finder в виде файла XPI .

Счастливое расширение развивается!

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

27.06.2014, 08:45. Показов 57583. Ответов 1


1. Что такое расширения к браузерам?
Расширения к браузерам — это программы, которые внедряются в браузер и добавляют в него новые функции или настраивают имеющиеся.
Расширения к браузерам могут:

  • изменять html-код страниц, открываемых в браузере. В том числе внедрять в них скрипт, который на страницах не отображается, но выполняется для каждой странице при её загрузке.
    В хроме такой скрипт называется скриптом содержимого или контентным скриптом, в мазиле и опере — юзерскриптом.
    Примечание: в отличие от обычных видимых скриптов, этот скрипт может делать кроссдоменные запросы XMLHttpRequest.
  • добавлять кнопки на панели инструментов браузера и создавать новые тулбары
  • управлять вкладками браузера: создавать, закрывать, обновлять, посылать по определённому urlу
  • управлять закладками браузера: создавать, изменять, удалять
  • делать редиректы с одних url на другие, причём не только при открытии того или иного url во вкладке, но и при доступе к нему из фреймов, а также через XMLHttpRequest или через script, img, video.
  • просматривать и изменять историю посещенных страниц в браузере
  • и другое, в зависимости от браузера и его версии

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

Не стоит путать расширения с плагинами.

2. Что представляют собой расширения и как их пишут?
Расширения к браузерам обычно состоят из:

  • файла настроек расширения (ini, json, xml), где указаны, например, название расширения, его версия, автор, поддерживаемые версии браузера, а также файлы скриптов и html страниц, необходимых расширению
  • фонового JS-скрипта (или фоновой страницы с таким скриптом), который выполняется 1 раз при загрузке браузера, не отображается ни на каких страницах, но может менять какие-то настройки в браузере, скажем добавлять кнопку на тулбар
  • юзерскрипта, который внедряется в страницы, не отображается в их коде, но может их изменять так же свободно, как и если бы он был на данном сайте изначально
  • вспомогательных html-страниц, например, страницы настроек для пользователя или диалогового окна, открывающегося при нажатии на кнопку на тулбаре

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

Логику расширения пишут на JS, интерфейс пользователя создают с помощью HTML+CSS, а файл настроек пишут на INI/JSON/XML.
Для написания расширений достаточно блокнота.

Исключение — Internet Explorer, расширения для которого пишутся на компилируемом ЯП (C#, C++, Delphi, ..) с помощью COM. Его мы здесь рассматривать не будем.

3. С чего начать?
1. Сначала Chrome.
Во-первых, по нему больше всего инфы в инете.
Во-вторых, он попросту проще.
В-третьих, он не только популярнее сам по себе, но имеет множество клонов, которые, также как и он, основаны на Chromium и обычно совместимы с расширениями Chrome. Это Яндекс.Браузер, Амиго, Интернет от Mail.Ru… Тысячи их.
2. Потом Opera.
Когда вышла Opera 15 (Opera Next) на хромовском движке, оф. документацию по расширениям к старой опере аффффтары просто потёрли, глубоко наплевав на тех, кто привык к старой опере и вообще в гробу видел хром. А таких вот топиков в своё время никто не создал. В результате инфы в инете по опере не Next почти не осталось.
Мы в данном топике будем рассматривать оперу ниже 15, т.е. не Next.
3. Потом Firefox.
Расширения к нему можно создавать двумя способами — как я описал в пункте 2 и каким-то левым способом с помощью специального SDK, причём способы плохо совмещаются друг с другом. Поэтому добрая половина кода в инете, касаемо огнелиса, у вас может просто не заработать. Мы в данном топике будем учиться юзать именно способ без SDK, ибо он проще.
4. Ну и потом IE.
Который по вышеупомянутой причине рассматриваться в топике не будет.

4. Зачем нужен этот топик? Вон статья на хабре, вон оф. документация, вон ещё статья на хабре, что ещё надо?
1) Вам не нужно — вы и не создавайте топиков, и этот не читайте. А некоторым нужно. Мне бы в своё время пригодился.
2) По расширениям к хрому инфа и правда есть, но вот с огнелисом и оперой сложнее. Про оперу — см. выше.
3) Я не прошу отправлять этот топик в важные (хотя буду рад, если он туда попадёт), не буду его апить каждые полчаса. Так что вам он не мешает ничем. Не нужно его трогать.
4) Этот топик нужен мне. Чтобы в свободное время или просто когда лень работать продолжать углублять свои знания и расширять специализацию. И вы бы лучше занялись чем-то таким, нежели ругать и портить чужое.

5. Пишем простое расширение к Chrome.
Расширение будет добавлять всплывающий баннер с текстом «Ура!» на каждую страницу в браузере, в левый-верхний угол.
Итак, приступим.
1. Создаём отдельную папку. Называем её, например, HelloChromeAPI.
2. В папке создаём файл настроек расширения.
Для этого запускаем блокнот, пишем такой код

JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "name": "Hello Chrome API",
    "version": "1.0.0.0",
 
    "manifest_version": 2,
 
    "content_scripts": [
        {
            "matches": [ "http://*/*" ],
            "js": [ "content_scripts/end.js" ],
            "run_at": "document_end"
        }
    ]
}

сохраняем в нашу папку под именем manifest.json обязательно в кодировке UTF-8.
Такой формат представления данных называется JSON: записи через запятую, имена их в кавычках, каждая запись может включать в себя подзаписи разного типа (тогда заключается в {}) или подзаписи одного и того же типа (тогда называется массивом и заключается в []).
«name» — имя расширения, которое будет видно в браузере
«version» — версия расширения, которую тоже будет видно в браузере
«manifest_version», равное 2, указывает, что расширение будет совместимо с Chrome выше версии 13. Если вместо 2 указать 1, то расширение будет работать в хромах с 5 по

12. Такие хромы сейчас редки, но если уж писать серьёзный проект, то нужно сделать дубликаты расширения для обоих поколений хрома.
«content_scripts» — это массив контентных скриптов (то есть скриптов, которые, как говорилось выше, выполняются на каждой странице в браузере). В данном случае в списке один элемент (он ограничен скобками {}), так как скрипт в нашем расширении будет только 1
«matches» — маска, указывающая, на каких страницах будет выполняться скрипт. * означает любую последовательность символов. Наш скрипт будет выполнять на всех страницах протокола http. Почему только http? Потому что на страницах протокола https браузер проверяет, нет ли левого html-кода, и если есть, то ругается. Может ругаться и антивирус.
«run_at» указывает, на каком этапе загрузки страницы скрипт будет выполняться.
Значение «document_start» = не загружено ничего (скрипт сможет вывести окошко alert или изменить window.location.href, но не сможет работать с document.body, его просто не будет)
Значение «document_end» = загружен код страницы, доступны document и document.body, но могут выполнять какие-то скрипты, которые ещё просто не успели выполниться
Значение «document_idle» = простой, когда никакой другой скрипт не выполняется. точнее ближайший период простоя с начала загрузки. Рекомендуется использовать для сложных ресурсоёмких скриптов, когда в то же время не требуется, чтобы скрипт выполнился прямо сразу после загрузки.
«js» — это массив путей к скриптам, выполняющимся с данными matches. Скрипт один, он будет называться end.js (это будет означать, что скрипт выполняется по document_end) и лежать в подпапке content_scripts в нашей папке расширения.
3. Создадим подпапку content_scripts, а в ней скрипт end.js.
В нём пропишем код

Javascript
1
document.body.innerHTML += '<div style="background-color: #FFFFFF; border-color: black; border-style: solid; color: black; font-family: 'Segoe UI'; font-size: 24px; position: fixed; left: 0; top: 0; width: 300px; height: 110px; padding: 8px; z-index: 1000000000">Ура!</div>';

Этот скрипт добавляет код баннера в код body той страницы, на которой выполняется.
Он тоже обязательно должен быть сохранён в UTF-8.
Примечание: стилей так много затем, чтобы перекрыть стили, применённые на сайте, куда вставляется баннер, и баннер на всех сайтах выглядел одинаково.
4. Установим расширение в браузер.
Откроем меню браузера кнопкой справа-вверху, затем пункт Инструменты, затем выберем пункт Расширения.
Или просто пройдём по ссылке chrome://extensions
Поставим флажок Режим разработчика, нажмем Загрузить распакованное расширение и укажем нашу папку.
5. Теперь зайдём на любую страницу, использующую http (см. выше)
mail.ru подойдёт, наш форум подойдёт, а google.ru нет.
Когда страница загрузится до конца, слева-вверху появится обещанный баннер.
6. На странице расширений мы можем отключить или удалить расширение с помощью соотв. кнопок.
А если мы решим изменить код manifest.json, end.js и т.д., то чтобы изменения применились, мы должны воспользоваться кнопкой Обновить.

6. Добавляем кнопочку на панель инструментов Chrome
Теперь оно будет ещё добавлять кнопочку на панель инструментов хрома и при нажатии на кнопку открывать диалоговое окно.
Нам понадобится Chrome 20 или новее.
1. Откроем наш файл manifest.json
Изменим его таким образом

JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "name": "Hello Chrome API",
    "version": "1.0.0.0",
 
    "manifest_version": 2,
 
    "content_scripts": [
        {
            "matches": [ "http://*/*" ],
            "js": [ "content_scripts/end.js" ],
            "run_at": "document_end"
        }
    ], // <-- здесь добавим запятую
 
    "browser_action": {
          "default_icon": {                       // иконки для кнопки 
            "19": "/images/br-icon19.png",         // иконка 19x19 пкс
            "38": "/images/br-icon38.png"          // иконка 38x38 пкс
          },
          "default_title": "Наша кнопка",         // всплывающая подсказка появл при наведении мыши на кнопку
          "default_popup": "popup/popup.html"     // страница появл во всплывающем окне откр при нажатии на кнопку
    }
}

и сохраним.
2. Создадим подпапки images и popup.
В images создадим две картинки, как указано в манифесте. Картинки могут быть одинаковыми, отображается только одна, в зависимости от расширения монитора (на больших мониторах — 38×38, на маленьких — 19×19).
В popup создадим файл popup.html и запишем в него такой код

HTML5
1
<div style="width: 300px; height: 100px">Ура!</div>

Сохранять тоже лучше в UTF-8.
3. Чтобы изменения вступили в силу, зайдём в Расширения и нажмём кнопку Обновить под нашим расширением.
4. На панели инструментов (слева вверху) появится кнопка с заданной иконкой.
Нажав на кнопку, увидим окошко, в котором будет надпись «Ура!».
Заметим, что размер окошка соответствует размеру, указанному в style корневого элемента popup.html (т.е. 300 x 100 пкс).
Если этот размер не указывать, окошко будет таким, чтобы в него поместилось содержимое этого элемента, т.е. надпись «Ура!».

7. Добавляем иконку в расширение к Chrome.
1. Подправим манифест.

JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
    "manifest_version": 2,
 
    "name": "Hello Chrome API",
    "version": "1.0.0.0",
 
    "manifest_version": 2,
 
    // добавим такие строчки
    "icons": {
        "48": "/images/icon48.png"
    },
 
    "content_scripts": [
        {
            "matches": [ "http://*/*" ],
            "js": [ "content_scripts/end.js" ],
            "run_at": "document_end"
        }
    ],
 
    "browser_action": {
          "default_icon": {
            "19": "/images/br-icon19.png",
            "38": "/images/br-icon38.png"
          },
          "default_title": "Наша кнопка",
          "default_popup": "popup/popup.html"
    }
}

2. Создадим файл icon48.png в папке images.
Это будет иконка расширения, отображаемая на странице расширений вместо дефолтного значка с фрагментом мозаики.
Примечание: помимо иконки размером в 48 пкс, мы можем сделать иконки размером 16, 32, 128 пкс, дописав внутрь ветви «icons:» соотв. строчки, не забывая про запятые. Но это нужно только если мы решим нарисовать действительно разные иконки для расширения. Просто растянув иконку под 16, 32, 128 пкс, мы ничего не достигнем — хром это сделает и сам, где оно понадобится. Я ограничился 48 пкс.
3. Обновим расширение на странице расширений.

8. Пишем простое расширение к Opera.
Расширение будет работать аналогично расширению к хрому.
Опера у меня версии 12. На других не пробовал. На 15 и выше, ещё раз, работать не должно.
Все файлы, как и с хромом, лучше сохранять в UTF-8, иначе кириллица будет отображаться неверно.
Приступим.
1. Создаём отдельную папку. Называем её, например, HelloOperaAPI.
2. В папке создаём файл настроек расширения.
Для этого запускаем блокнот, пишем такой код

XML
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns="http://www.w3.org/ns/widgets">
    <name>Hello Opera API</name>
    <version>1.0.0.0</version>
</widget>

сохраняем в нашу папку под именем config.xml обязательно в кодировке UTF-8.
Такой формат представления данных называется XML.
<name> — имя расширения, которое будет видно в браузере
<version> — версия расширения, которую тоже будет видно в браузере
А вот никакого упоминания о скриптах в файле не будет. Мы просто создадим в папке с расширением подпапку include и файл .js с любым именем. Этого будет достаточно, чтобы скрипт работал.
3. Сказано — сделано. Создаём подпапку include и файл script_end.js

Javascript
1
2
3
4
5
6
7
// ==UserScript==
// @include [url]http://*/*[/url]
// ==/UserScript==
 
document.addEventListener("DOMContentLoaded", function() {
    document.body.innerHTML += '<div style="background-color: #FFFFFF; border-color: black; border-style: solid; color: black; font-family: 'Segoe UI'; font-size: 24px; position: fixed; left: 0; top: 0; width: 300px; height: 110px; padding: 8px; z-index: 1000000000">Ура!</div>';
}, false);

DOMContentLoaded позволяет создать эффект «document_end» из хрома (а сам юзерскрипт в опере выполняется фактически по «document_start».
«==UserScript==…==/UserScript==» вверху — это не просто комментарий. Там указываются настройки данного скрипта. @include здесь работает по принципу «matches» из Chrome.
Скрипт тоже обязательно должен быть сохранён в UTF-8.
Этот скрипт добавляет код баннера в код body той страницы, на которой выполняется.
4. В папке с расширением создадим index.html. Это фоновая страница. Мы можем оставить её пустой, потому что фоновых скриптов пока нет и она нам не нужна, но в расширении для оперы она должна быть обязательно.
5. Упакуем расширение в zip-архив. Сменим его расширение с zip на oex.
6. Запустим оперу, зайдём в меню, выберим пункт Дополнения, перетащим туда oex.
7. Проверим, появляются ли баннеры при загрузке страниц.

9. Добавляем кнопку на панель инструментов Opera
На панели инструментов справа-вверху появится кнопка. При нажатии на неё откроется всплывающее окошко с заданной страницей. Всё как в хроме.
Нам понадобится Chrome 20 или новее.
1. Изменим фоновую страницу index.html таким образом

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!doctype html>
<html lang="en">
    <head>
        <script>
            window.addEventListener("load", function(){
                var ToolbarUIItemProperties = {
                    title: "Наша кнопка",
                    icon: "/images/br-icon19.png",
                    popup: {
                        href: "popup/popup.html",
                        width: 300,
                        height: 100
                    }
                }
                opera.contexts.toolbar.addItem(opera.contexts.toolbar.createItem(ToolbarUIItemProperties));
            }, false);
        </script>
    </head>
    <body>
    </body>
</html>

и сохраним.
opera.contexts.toolbar — это класс из Opera API.
У хрома тоже есть API — chrome.*.
2. Создадим подпапки images и popup.
В images создадим картинку, как указано в манифесте.
В popup создадим файл popup.html и запишем в него такой код

Примечание:

в отличие от хрома, размер окошка формируется не через style корневого элемента popup.html, а через width и height, прописанные в ToolbarUIItemProperties в index.html.
3. Чтобы изменения вступили в силу, удалим расширение и установим его обратно.
4. На панели инструментов (слева вверху) появится кнопка с заданной иконкой.
Нажав на кнопку, увидим окошко, в котором будет надпись «Ура!».

10. Добавляем иконку в расширение Opera.
1. Путь к иконке указывается в файле настроек — config.xml.
За него отвечает тэг icon с атрибутом src, в котором указывается относительный путь к иконке (относительно основной папке расширения).
Откроем файл config.xml.
Внутри <widget> добавим строчку

XML
1
<icon src="/images/icon48.png" />

Должно получиться так:

XML
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns="http://www.w3.org/ns/widgets">
    <name>Hello Opera API</name>
    <version>1.0.0.0</version>
    <icon src="/images/icon48.png" />
</widget>

2. Создадим файл icon48.png (это может любая картинка 48×48 пкс) в папке images.
3. Перепакуем и переустановим расширение.
В списке расширений вместо дефолтного значка (сиреневого фрагмента мозаики) будет отображаться наша иконка.


11. Пишем простое расширение Firefox.
12. Добавляем панель инструментов в Firefox.
13. Добавляем иконку в расширение Firefox.

Продолжение следует…
Пока что читаем здесь и экспериментируем.

Пара советов и ссылок на закуску
Конечно, информации из этого топика ещё недостаточно, чтобы написать любое расширение к браузеру Chrome, Firefox или Opera.
Но общее представление о расширениях и особенностях их разработки вы получили.
Поэтому, воспользовавшись данными ссылками в связке с гуглом, Вы при желании сможете углубиться в расширения и писать крупные, уникальные продукты.
Здесь же обещанные магазины расширений.
CHROME
https://developer.chrome.com/extensions/ — официальная документации.
Вот описание в ней контентных скриптов и кнопки browser-action:
https://developer.chrome.com/e… nt_scripts
https://developer.chrome.com/e… wserAction
https://chrome.google.com/webs… ions?hl=ru — магазин.
OPERA
https://addons.opera.com/ru/extensions/ — магазин.
FIREFOX
https://addons.mozilla.org/ru/firefox/ — магазин.

Добавлено через 2 минуты
В процессе написания топика нашёл на форуме баг.
В кодах JSON, XML и др. текст «https://www.cyberforum.ru/images/картинка.png» заменяется на «https://www.cyberforum.ru/images/картинка.png».
То есть если написать

JSON
1
2
3
{
    "48": "ЗДЕСЬ_НЕТ_НИЧЕГОimages/icon48.png"
}

то получится

JSON
1
2
3
{
    "48": "https://www.cyberforum.ru/images/icon48.png"
}

Правда, написав

JSON
1
2
3
{
    "48": "/images/icon48.png"
}

мы получим то, что ожидали. Но иной код от этого может сделаться также нечитабельным, как и из-за добавления «https://www.cyberforum.ru/».



2



How to Write Your Own Browser Extension [Example Project Included]

In this article we will talk about Browser extensions – what they are, how they work, and how you can build your own.

We will finish by actually writing our own extension (Super Fun!) which allows us to copy any code snippet to our clipboard with a click of a single button.

To continue with this article:

  • You need to have a basic understanding of JavaScript.
  • You need the Firefox browser (or any other browser will also work)

What is a Browser Extension?

A browser extension is something you add to your browser which enhances your browsing experience by extending the capacity of your browser.

As an example, think about an ad blocker which you might have installed on your device. This makes your browsing experience better by blocking ads when you surf the web.

Now let’s start by writing a very basic extension.

To begin, we’ll create a folder inside which we create a file named manifest.json.

What is a manifest file?

A manifest file is a must have file in any browser extension. This file contains basic data about our extension like name, version, and so on.

Now inside the manifest.json file copy the following snippet:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
}

How to load the extension file

For Firefox users, follow these steps:

In the address bar, search for this:

about:debugging#/runtime/this-firefox

You will see an option to Load Temporary Add-on. Click on that option and choose the manifest.json file from the directory.

For Chrome users:

In the address bar search for this:

chrome://extensions.
  • Enable Developer Mode and switch into it.
  • Click the Load unpacked button and select the extension directory.

Hurray! You’ve installed the extension successfully. But the extension doesn’t do anything currently. Now let’s add some functionality to our extension. To do this, we’ll edit our manifest.json file like this:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
    {
     "matches":["<all_urls>"],
     "js":["main.js"]
    }
  ]
}

In the above code, we added a content script to manifest.json. Content scripts can manipulate the Document Object Model of the web page. We can inject JS (and CSS) into a web page using a content script.

"matches" contains the list of domains and subdomains where the content script should be added and js is an array of the JS files to be loaded.

Now inside the same directory create a main.js file and add the following code:

alert("The test extension is up and running")

Now reload the extension and when you visit any URLs you will see an alert message.

Don’t forget to reload the extension anytime you edit the code.

How to Customize Your Browser Extension

Now let’s have some more fun with our extension.

What we are going to do now is create a web extension that changes all the images of a webpage we visit to an image we choose.

For this, just add any image to the current directory and change the main.js file to:

console.log("The extension is up and running");

var images = document.getElementsByTagName('img')

for (elt of images){
   elt.src = `${browser.runtime.getURL("pp.jpg")}`
   elt.alt = 'an alt text'
}

Let’s see whats going on here:

var images = document.getElementsByTagName('img')

This line of code selects all the elements in the web page with the img tag .

Then we loop through the array images using a for loop where we change the src attribute of all the img elements to a URL with the help of the runtime.getURL function.

Here pp.jpg is the name of the image file in the current directory in my device.

We need to inform our content script about the pp.jpg file by editing the manifest.json file to:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
   {
    "matches":["<all_urls>"],
    "js":["main.js"]
   }
  ],
  "web_accessible_resources": [
        "pp.jpg"
  ]
}

Then just reload the extension and visit any URL you like. Now you should see all the images being changed to the image which is in your current working directory.

How to add icons to your extension

Add the following code in the manifest.json file:

"icons": {
  "48": "icon-48.png",
  "96": "icon-96.png"
}

How to add a toolbar button to your extension

Now we’ll add a button located in the toolbar of your browser. Users can interact with the extension using this button.

To add a toolbar button, add the following lines to the manifest.json file:

"browser_action":{
   "default_icon":{
     "19":"icon-19.png",
     "38":"icon-38.png"
   }
  }

All the image files should be present in your current directory.

Now, if we reload the extension we should see an icon for our extension in the toolbar of our browser.

How to add listening events for the toolbar button

Maybe we want to do something when a user clicks the button – let’s say we want to open a new tab every time the button is clicked.

For this, we’ll again add the following to the manifest.json file:

"background":{
        "scripts":["background.js"]
  },
  "permissions":[
      "tabs"
  ]

Then we’ll create a new file named background.js in the current working directory and add the following lines in the file:

function openTab(){
    
    var newTab = browser.tabs.create({
        url:'https://twitter.com/abhilekh_gautam',
        active:true
    })
}

browser.browserAction.onClicked.addListener(openTab)

Now reload the extension!

Whenever someone clicks the button, it calls the openTab function which opens a new tab with the URL that links to my twitter profile. Also, the active key, when set to true, makes the newly created tab the current tab.

Note that you can use APIs provided by browsers in the background script. For more about APIs refer to the following article: Javacript APIs.

Now that we’ve learned some of the basics of browser extensions, let’s create an extension that we as developers can use in our daily lives.

Final Project

Alright, now we’re going to write something that will be useful for us in daily life. We’ll create an extension that allows you to copy code snippets from StackOverflow with a single click. So our extension will add a Copy button to the webpage which copies the code to our clipboard.

Demo

demo

First we’ll create a new folder/directory, inside which we’ll add a manifest.json file.

Add the following code to the file:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"copy code",
  "content_scripts":[
    {
     "matches":["*://*.stackoverflow.com/*"],
     "js":["main.js"]
    }
  ]
}

Look at the matches inside the content script – the extension will only work for StackOverflow’s domain and subdomain.

Now create another JavaScript file called main.js in the same directory and add the following lines of code:

var arr =document.getElementsByClassName("s-code-block")

for(let i = 0 ; i < arr.length ; i++){
 var btn = document.createElement("button")
 btn.classList.add("copy_code_button")
 btn.appendChild(document.createTextNode("Copy"))
 arr[i].appendChild(btn)
 //styling the button
 btn.style.position = "relative"
 
 if(arr[i].scrollWidth === arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetHeight)
  btn.style.left = `${arr[i].offsetWidth - 70}px`

  else if(arr[i].scrollWidth != arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetWidth)
   btn.style.left = `${arr[i].offsetWidth - 200}px`
 else 
   btn.style.left = `${arr[i].offsetWidth - 150}px`
  
 if(arr[i].scrollHeight === arr[i].offsetHeight)
   btn.style.bottom = `${arr[i].offsetHeight - 50}px`
   
 else
   btn.style.bottom = `${arr[i].scrollHeight - 50}px`
 //end of styling the button
   
   console.log("Appended")
}

First of all, I selected all the elements with the class name s-code-block – but why? This is because when I inspected StackOverflow’s site I found that all the code snippets were kept in a class with that name.

And then we loop through all those elements and append a button in those elements. Finally, we just position and style the button properly (the styling’s not perfect yet – this is just a start).

When we load the extension using the process we went through above and visit StackOverflow, we should see a copy button.

How to add functionality to the button

Now, when the button is clicked we want the entire snippet to be copied to our clip board. To do this, add the following line of code to the main.js file:

var button = document.querySelectorAll(".copy_code_button")
 button.forEach((elm)=>{
  elm.addEventListener('click',(e)=>{
    navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)
    alert("Copied to Clipboard")
  })
 })

First of all, we select all the buttons we have added to the site using querySelectorAll. Then we listen for the click event whenever the button is clicked.

navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)

The above line of code copies the code to our clipboard. Whenever a snippet is copied we alert the user with the message Copied to clipboard and we are done.

Final Words

Web Extensions can be useful in various way and I hope with the help of this article you will be able to write your own extensions.

All the code can be found in this GitHub repository. Don’t forget to give a pull request anytime you come up with some good styling or a new feature like clipboard history and others.

Happy Coding!



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

How to Write Your Own Browser Extension [Example Project Included]

In this article we will talk about Browser extensions – what they are, how they work, and how you can build your own.

We will finish by actually writing our own extension (Super Fun!) which allows us to copy any code snippet to our clipboard with a click of a single button.

To continue with this article:

  • You need to have a basic understanding of JavaScript.
  • You need the Firefox browser (or any other browser will also work)

What is a Browser Extension?

A browser extension is something you add to your browser which enhances your browsing experience by extending the capacity of your browser.

As an example, think about an ad blocker which you might have installed on your device. This makes your browsing experience better by blocking ads when you surf the web.

Now let’s start by writing a very basic extension.

To begin, we’ll create a folder inside which we create a file named manifest.json.

What is a manifest file?

A manifest file is a must have file in any browser extension. This file contains basic data about our extension like name, version, and so on.

Now inside the manifest.json file copy the following snippet:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
}

How to load the extension file

For Firefox users, follow these steps:

In the address bar, search for this:

about:debugging#/runtime/this-firefox

You will see an option to Load Temporary Add-on. Click on that option and choose the manifest.json file from the directory.

For Chrome users:

In the address bar search for this:

chrome://extensions.
  • Enable Developer Mode and switch into it.
  • Click the Load unpacked button and select the extension directory.

Hurray! You’ve installed the extension successfully. But the extension doesn’t do anything currently. Now let’s add some functionality to our extension. To do this, we’ll edit our manifest.json file like this:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
    {
     "matches":["<all_urls>"],
     "js":["main.js"]
    }
  ]
}

In the above code, we added a content script to manifest.json. Content scripts can manipulate the Document Object Model of the web page. We can inject JS (and CSS) into a web page using a content script.

"matches" contains the list of domains and subdomains where the content script should be added and js is an array of the JS files to be loaded.

Now inside the same directory create a main.js file and add the following code:

alert("The test extension is up and running")

Now reload the extension and when you visit any URLs you will see an alert message.

Don’t forget to reload the extension anytime you edit the code.

How to Customize Your Browser Extension

Now let’s have some more fun with our extension.

What we are going to do now is create a web extension that changes all the images of a webpage we visit to an image we choose.

For this, just add any image to the current directory and change the main.js file to:

console.log("The extension is up and running");

var images = document.getElementsByTagName('img')

for (elt of images){
   elt.src = `${browser.runtime.getURL("pp.jpg")}`
   elt.alt = 'an alt text'
}

Let’s see whats going on here:

var images = document.getElementsByTagName('img')

This line of code selects all the elements in the web page with the img tag .

Then we loop through the array images using a for loop where we change the src attribute of all the img elements to a URL with the help of the runtime.getURL function.

Here pp.jpg is the name of the image file in the current directory in my device.

We need to inform our content script about the pp.jpg file by editing the manifest.json file to:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
   {
    "matches":["<all_urls>"],
    "js":["main.js"]
   }
  ],
  "web_accessible_resources": [
        "pp.jpg"
  ]
}

Then just reload the extension and visit any URL you like. Now you should see all the images being changed to the image which is in your current working directory.

How to add icons to your extension

Add the following code in the manifest.json file:

"icons": {
  "48": "icon-48.png",
  "96": "icon-96.png"
}

How to add a toolbar button to your extension

Now we’ll add a button located in the toolbar of your browser. Users can interact with the extension using this button.

To add a toolbar button, add the following lines to the manifest.json file:

"browser_action":{
   "default_icon":{
     "19":"icon-19.png",
     "38":"icon-38.png"
   }
  }

All the image files should be present in your current directory.

Now, if we reload the extension we should see an icon for our extension in the toolbar of our browser.

How to add listening events for the toolbar button

Maybe we want to do something when a user clicks the button – let’s say we want to open a new tab every time the button is clicked.

For this, we’ll again add the following to the manifest.json file:

"background":{
        "scripts":["background.js"]
  },
  "permissions":[
      "tabs"
  ]

Then we’ll create a new file named background.js in the current working directory and add the following lines in the file:

function openTab(){
    
    var newTab = browser.tabs.create({
        url:'https://twitter.com/abhilekh_gautam',
        active:true
    })
}

browser.browserAction.onClicked.addListener(openTab)

Now reload the extension!

Whenever someone clicks the button, it calls the openTab function which opens a new tab with the URL that links to my twitter profile. Also, the active key, when set to true, makes the newly created tab the current tab.

Note that you can use APIs provided by browsers in the background script. For more about APIs refer to the following article: Javacript APIs.

Now that we’ve learned some of the basics of browser extensions, let’s create an extension that we as developers can use in our daily lives.

Final Project

Alright, now we’re going to write something that will be useful for us in daily life. We’ll create an extension that allows you to copy code snippets from StackOverflow with a single click. So our extension will add a Copy button to the webpage which copies the code to our clipboard.

Demo

demo

First we’ll create a new folder/directory, inside which we’ll add a manifest.json file.

Add the following code to the file:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"copy code",
  "content_scripts":[
    {
     "matches":["*://*.stackoverflow.com/*"],
     "js":["main.js"]
    }
  ]
}

Look at the matches inside the content script – the extension will only work for StackOverflow’s domain and subdomain.

Now create another JavaScript file called main.js in the same directory and add the following lines of code:

var arr =document.getElementsByClassName("s-code-block")

for(let i = 0 ; i < arr.length ; i++){
 var btn = document.createElement("button")
 btn.classList.add("copy_code_button")
 btn.appendChild(document.createTextNode("Copy"))
 arr[i].appendChild(btn)
 //styling the button
 btn.style.position = "relative"
 
 if(arr[i].scrollWidth === arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetHeight)
  btn.style.left = `${arr[i].offsetWidth - 70}px`

  else if(arr[i].scrollWidth != arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetWidth)
   btn.style.left = `${arr[i].offsetWidth - 200}px`
 else 
   btn.style.left = `${arr[i].offsetWidth - 150}px`
  
 if(arr[i].scrollHeight === arr[i].offsetHeight)
   btn.style.bottom = `${arr[i].offsetHeight - 50}px`
   
 else
   btn.style.bottom = `${arr[i].scrollHeight - 50}px`
 //end of styling the button
   
   console.log("Appended")
}

First of all, I selected all the elements with the class name s-code-block – but why? This is because when I inspected StackOverflow’s site I found that all the code snippets were kept in a class with that name.

And then we loop through all those elements and append a button in those elements. Finally, we just position and style the button properly (the styling’s not perfect yet – this is just a start).

When we load the extension using the process we went through above and visit StackOverflow, we should see a copy button.

How to add functionality to the button

Now, when the button is clicked we want the entire snippet to be copied to our clip board. To do this, add the following line of code to the main.js file:

var button = document.querySelectorAll(".copy_code_button")
 button.forEach((elm)=>{
  elm.addEventListener('click',(e)=>{
    navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)
    alert("Copied to Clipboard")
  })
 })

First of all, we select all the buttons we have added to the site using querySelectorAll. Then we listen for the click event whenever the button is clicked.

navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)

The above line of code copies the code to our clipboard. Whenever a snippet is copied we alert the user with the message Copied to clipboard and we are done.

Final Words

Web Extensions can be useful in various way and I hope with the help of this article you will be able to write your own extensions.

All the code can be found in this GitHub repository. Don’t forget to give a pull request anytime you come up with some good styling or a new feature like clipboard history and others.

Happy Coding!



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

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

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

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

👉 Что такое расширение

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

Примеры того, что может сделать расширение: 

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

В этой статье

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

Манифест

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

  • как называется расширение;
  • к чему расширение может получить доступ;
  • какие скрипты будут работать в фоне;
  • как должна выглядеть иконка расширения;
  • что показать или что выполнить, когда пользователь нажмёт на иконку расширения.

Манифест задаёт общие правила для всего расширения, поэтому манифест — единственный обязательный компонент. Можно обойтись без иконок и скриптов, но манифест обязательно должен быть.Каждый манифест хранится в файле manifest.json — создадим пустой файл с таким именем и напишем внутри такое:

{
«name»: «Запускаем снежинки на любом сайте»,
«description»: «Проект журнала Код»,
«version»: «1.0»,
«manifest_version»: 3
}

Первые две строчки — это название и подробное описание расширения. Третья отвечает за номер версии расширения, а последняя говорит браузеру, какая версия манифеста используется в описании. На момент выхода статьи в феврале 2021 года используется третья версия.

Сохраняем файл и всё, расширение готово. Оно ничего не умеет, ничего не делает, зато мы уже можем добавить его в браузер. Для этого запускаем Хром и в адресной строке пишем:

chrome://extensions/

Мы попадаем на страницу, которая нам покажет все установленные расширения:

Делаем своё расширение для браузера за 10 минут

Чтобы добавить своё расширение, в правом верхнем углу включаем режим разработчика, а затем нажимаем «Загрузить распакованное расширение»:

Делаем своё расширение для браузера за 10 минут

Теперь выбираем папку, в которой лежит наш манифест:

Делаем своё расширение для браузера за 10 минут

Отлично, мы только что добавили в браузер новое расширение:

Делаем своё расширение для браузера за 10 минут

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

Чтобы было проще работать и тестировать расширение, закрепим его на панели браузера:

Делаем своё расширение для браузера за 10 минут

Иконки

У расширения есть две иконки, которыми мы можем управлять: 

  1. Картинка в карточке расширения на странице настроек.
  2. Иконка на панели браузера.

Чтобы не рисовать всё с нуля, скачаем папку с иконками из того же руководства Google и положим её в ту же папку, что и манифест:

Теперь добавим иконки в манифест. За картинку в карточке отвечает блок icon, а за иконку на панели —  блок action. Разные размеры картинки нужны для того, чтобы на разных мониторах с любой плотностью пикселей иконки выглядели хорошо:

{
  "name": "Запускаем снежинки на любом сайте",
  "description": "Проект журнала Код",
  "version": "1.0",
  "manifest_version": 3,

  "action": {
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  }
}

Сохраняем манифест, обновляем расширение на странице настроек и смотрим результат:

Добавляем иконки в манифест

Настраиваем разрешения

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

  1. Понять, какая вкладка сейчас активная, чтобы запустить снежинки именно на ней.
  2. Запустить наш скрипт со снежинками.

Чтобы получить доступ к активной вкладке и к запуску скриптов, добавим в манифест такую строку:

"permissions": ["activeTab", "scripting"],

Показываем меню

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

Чтобы сделать всплывающее меню, добавим в манифест в раздел action такую строку:

    "default_popup": "popup.html",

Она означает, что при нажатии на иконку мы увидим рядом с ней мини-страничку, на которой что-то будет.Создадим в той же папке расширения файл popup.html и добавим в него такой код:

<!DOCTYPE html>
<html lang="ru">
  <head>
  	<meta charset="UTF-8">
    <style type="text/css">

    	/* задаём размеры кнопки и размер текста на кнопке  */
    	button {
	      font-size: 12px;
		  height: 40px;
		  width: 80px;
		}
    </style>
  </head>
  <body>
  	<!-- создаём кнопку на странице -->
    <button id="snow">Запустить снежинки</button>
    <!-- подключаем скрипт, который обработает нажатие на эту кнопку -->
    <script src="popup.js"></script>
  </body>
</html>

Чтобы браузер не ругался, что у нас нет файла popup.js, создадим пустой файл с таким названием и положим его в ту же папку:

Показываем меню расширения

Сохраняем манифест, обновляем его на странице настроек и видим, что у нашего расширения появилось меню с кнопкой:

Показываем меню расширения

Запускаем снежинки

Вся магия будет происходить в файле popup.js — откроем его и добавим такой код:

// получаем доступ к кнопке
let snow = document.getElementById("snow");
// когда кнопка нажата — находим активную вкладку и запускаем нужную функцию
snow.addEventListener("click", async () => {
  // получаем доступ к активной вкладке
  let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  // выполняем скрипт
  chrome.scripting.executeScript({
  	// скрипт будет выполняться во вкладке, которую нашли на предыдущем этапе
    target: { tabId: tab.id },
    // вызываем функцию, в которой лежит запуск снежинок
    function: snowFall,
  });
});

// запускаем снег
function snowFall() {
}

Последнее, что нам осталось сделать, — положить в функцию snowFall() полный код скрипта из проекта со снежинками и сохранить файл.

Проверка

В прошлый раз мы не смогли запустить скрипт на любой странице Яндекса — мешала политика безопасности. Теперь всё работает:

Проверяем расширение

Скачать упакованное расширение. Перед установкой его нужно распаковать в любую папку.

Понравилась статья? Поделить с друзьями:
  • Как написать сатановскому евгению яновичу письмо
  • Как написать саранхэ на корейском
  • Как написать свое ранобэ
  • Как написать сапера на питоне
  • Как написать сапер на javascript