--- title: Ваш второй WebExtension slug: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension tags: - Beginner - Example - Guide - WebExtension translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension ---
Если Вы уже прочитали статью Ваш первый WebExtension, то уже представляете, как создавать WebExtension. В этой статье мы напишем более сложное дополнение, которое демонстрирует ещё несколько API.
Дополнение добавляет новую кнопку на панель инструментов Firefox. Когда пользователь кликает по кнопке, мы показываем ему всплывающую панель с предложением выбрать животное. Когда животное выбрано, мы заменяем содержимое текущей страницы на изображение выбранного животного.
Чтобы реализовать это, мы:
Вы можете представить общую структуру дополнения вот так:
Это простое дополнение, но показывает множество основных концепций WebExtensions API:
Вы можете найти полный исходный код дополнения на GitHub.
Чтобы написать это дополнение, Вам нужен Firefox 45 или новее.
Создайте новую директорию и перейдите в неё:
mkdir beastify cd beastify
Теперь создайте файл "manifest.json" и вставьте в него следующее содержимое:
{ "manifest_version": 2, "name": "Beastify", "version": "1.0", "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify", "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify", "icons": { "48": "icons/beasts-48.png" }, "permissions": [ "activeTab" ], "browser_action": { "default_icon": "icons/beasts-32.png", "default_title": "Beastify", "default_popup": "popup/choose_beast.html" }, "web_accessible_resources": [ "beasts/frog.jpg", "beasts/turtle.jpg", "beasts/snake.jpg" ] }
manifest_version
, name
, и version
, являются обязательными и содержат основные мета-данные для дополнения.description
и homepage_url
необязательны, но рекомендуемы: они предоставляют полезную информацию о дополнении.icons
необязательный, но рекомендуемый: позволяет Вам определять иконку для дополнения, которая будет показана в Менеджере Дополнений.permissions
перечисляет разрешения для нужд дополнения. Здесь мы просто спрашиваем разрешения для activeTab
permission.browser_action
задаёт кнопку на панели инструментов. Здесь мы предоставляем три вида информации:
default_icon
это обязательная иконка для кнопкиdefault_title
необязательный заголовок, будет показан в подсказкеdefault_popup
используется, если Вы хотите, чтобы всплывающая панель была показана когда пользователь кликает по кнопке. В нашем примере мы использовали этот ключ и он указывает на HTML файл, подключённый к дополнению.web_accessible_resources
перечисляет файлы, которые мы хотим сделать доступными для веб-страниц. Поскольку дополнение заменяет содержимое страницы на изображения, которые мы упаковали вместе с дополнением, нам нужно сделать эти изображения доступными для страницы.Обратите внимание, что все пути указаны относительно файла manifest.json.
Дополнение должно иметь иконку. Она будет показана рядом с дополнением в Менеджере Дополнений (Вы можете открыть менеджер перейдя по ссылке "about:addons"). Наш manifest.json обещает, что у нас будет иконка для панели инструментов по адресу "icons/beasts-48.png".
Создайте папку "icons" и сохраните там иконку с именем "beasts-48.png". Вы можете использовать иконку из нашего примера, которая взята из набора Aha-Soft’s Free Retina и используется на условиях этой лицензии.
Если Вы выберете свою иконку, она должна быть размером 48x48 пикселей. Вы также можете предоставить иконку размером 96x96 пикселей для дисплеев с высоким разрешением, определив свойство "96"
объекта icons
в файле manifest.json:
"icons": {
"48": "icons/beasts-48.png",
"96": "icons/beasts-96.png"
}
Кнопка панели инструментов также нуждается в иконке, и наш manifest.json обещает, что у нас будет иконка для панели инструментов по адресу "icons/beasts-32.png".
Сохраните иконку с именем "beasts-32.png" в папке "icons". Вы можете использовать иконку из нашего примера, которая взята из набора IconBeast Lite и используется на условиях этой лицензии.
Если Вы не предоставите всплывающую панель, то событие click отправляется в Ваше дополнение, когда пользователь кликает кнопку. Если Вы предоставите всплывающую панель, то событие click не отправляется, зато появляется всплывающая панель. Мы хотим панель, давайте создадим её.
Функция панели - позволить пользователю выбрать одного из трёх зверей.
Создайте новую папку с именем "popup" в корневой папке дополнения. Здесь мы сохраним код для панели. Панель будет состоять из трёх файлов:
choose_beast.html
определяет содержимое панелиchoose_beast.css
стили для содержимогоchoose_beast.js
обрабатывает выбор пользователя, выполняя content script в активной вкладкеHTML выглядит так:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="choose_beast.css"/> </head> <body> <div class="button beast">Frog</div> <div class="button beast">Turtle</div> <div class="button beast">Snake</div> <div class="button clear">Reset</div> <script src="choose_beast.js"></script> </body> </html>
У нас есть элемент для каждого животного. Обратите внимание, что мы подключаем CSS и JS файлы из HTML файла, как на обыкновенной веб-странице.
CSS фиксирует размер всплывающей панели, гарантирует что три варианта заполняют пространство и даёт им основной стиль:
html, body { width: 100px; } .button { margin: 3% auto; padding: 4px; text-align: center; font-size: 1.5em; cursor: pointer; } .beast:hover { background-color: #CFF2F2; } .beast { background-color: #E5F2F2; } .clear { background-color: #FBFBC9; } .clear:hover { background-color: #EAEAC9; }
В JavaScript для всплывающего окна мы обрабатываем события click. Если click был на одном из трёх вариантов наших животных, мы добавляем content script в активную вкладку. После того, как content script загрузится, мы отправляем ему сообщение с выбранным животным:
/* Учитывая имя зверя, получаем URL соответствующего изображения. */ function beastNameToURL(beastName) { switch (beastName) { case "Frog": return browser.extension.getURL("beasts/frog.jpg"); case "Snake": return browser.extension.getURL("beasts/snake.jpg"); case "Turtle": return browser.extension.getURL("beasts/turtle.jpg"); } } /* Слушаем события клика во всплывающей панели. Если кликнули одного из зверей: Добавляем "beastify.js" к активной вкладке. Затем получаем активную вкладку и отправляем сценарию "beastify.js" сообщение, содержащее URL к картинке с выбранным зверем. Если кликнули кнопку, класс которой содержит "clear": Перезагрузить страницу. Закрыть всплывающую панель. Это необходимо, так как content script неисправен после перезагрузки страницы. */ document.addEventListener("click", (e) => { if (e.target.classList.contains("beast")) { var chosenBeast = e.target.textContent; var chosenBeastURL = beastNameToURL(chosenBeast); browser.tabs.executeScript(null, { file: "/content_scripts/beastify.js" }); var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true}); gettingActiveTab.then((tabs) => { browser.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL}); }); } else if (e.target.classList.contains("clear")) { browser.tabs.reload(); window.close(); } });
Скрипт использует три функции WebExtension API:
browser.tabs.executeScript
добавляет content script, найденный по адресу content_scripts/beastify.js", к активной вкладкеbrowser.tabs.query
запрашивает активную вкладкуbrowser.tabs.sendMessage
отправляет сообщение для content script, который работает в активной вкладке. Сообщение содержит URL изображения выбранного зверя.Создайте новую папку с именем "content_scripts" в корневой папке дополнения и создайте в ней новый файл с именем "beastify.js", со следующим кодом:
/* beastify(): * удаляет каждый узел в document.body, * затем вставляет выбранного зверя * затем удаляется как обработчик */ function beastify(request, sender, sendResponse) { removeEverything(); insertBeast(request.beastURL); browser.runtime.onMessage.removeListener(beastify); } /* Удаляет каждый узел в document.body */ function removeEverything() { while (document.body.firstChild) { document.body.firstChild.remove(); } } /* Учитывая URL изображения зверя, создаёт и стилизует узел IMG, указывающий на это изображение, затем вставляет узел в документ. */ function insertBeast(beastURL) { var beastImage = document.createElement("img"); beastImage.setAttribute("src", beastURL); beastImage.setAttribute("style", "width: 100vw"); beastImage.setAttribute("style", "height: 100vh"); document.body.appendChild(beastImage); } /* Назначает beastify() обработчиком сообщений расширения. */ browser.runtime.onMessage.addListener(beastify);
Content script добавляет обработчик к сообщениям от дополнения (в частности как в файле "choose_beast.js" выше). В обработчике скрипт:
document.body
<img>
элемент, указывающий на переданный URL, и вставляет элемент в DOMНаконец, нам нужно подключить изображения животных.
Создайте новую папку с именем "beasts" и добавьте туда три изображения с соответствующими именами. Вы можете получить изображения из GitHub репозитория, или прямо здесь:
Во-первых, дважды проверьте, что у вас все файлы на своих местах:
beastify/ beasts/ frog.jpg snake.jpg turtle.jpg content_scripts/ beastify.js icons/ beasts-32.png beasts-48.png popup/ choose_beast.css choose_beast.html choose_beast.js manifest.json
Начиная с Firefox 45 Вы можете временно установить дополнения с жёсткого диска.
Откройте "about:debugging" в Firefox, кликните "Загрузить временное дополнение", и выберете Ваш файл manifest.json. После этого Вы должны увидеть иконку дополнения на панели инструментов Firefox:
{{EmbedYouTube("sAM78GU4P34")}}
Откройте веб-страницу, затем щёлкните иконку, выберите зверя и посмотрите как страница изменится:
{{EmbedYouTube("YMQXyAQSiE8")}}
Вы можете автоматизировать этап временной установки используя web-ext. Попробуйте это:
cd beastify web-ext run