вторник, 15 февраля 2022 г.

Как сделать простое расширение для Chrome. Простой пример из документации. Перевод (вольный).

Расширения - набор файлов, содержащих отдельные, но работающие совместно компоненты.

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


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

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

Создайте файл манифеста.

Работа расширения начинается с его манифеста. Создайте файл с именем manifest.json и скопируйте в него следующий код:

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3

}


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

Откройте страницу управления расширениями chrome://extensions. Можно также найти ее через пункт в меню "Дополнительные инструменты - Расширения".

Включите режим разработчика с помощью переключателя справа.

Нажмите кнопку "Загрузить распакованное расширение" и выберите директорию с нашим расширением.

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

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

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

Регистрация фонового скрипта в манифесте.

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

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3,

  "background": {

    "service_worker": "background.js"

  }

}

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

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

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

// background.js

let color = '#3aa757';

chrome.runtime.onInstalled.addListener(() => {

  chrome.storage.sync.set({ color });

  console.log('Default background color set to %cgreen', `color: ${color}`);

});

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

Добавление разрешения на работу с хранилищем

Большинство API, включая и API для работы с хранилищем, должны быть зарегистрированы в поле "permissions" в манифесте, чтобы расширение могло использовать эти API.

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3,

  "background": {

    "service_worker": "background.js"

  },

  "permissions": ["storage"]

}

Просмотр фонового скрипта в браузере.

Откройте страницу управления расширением и кликните на ссылку перезагрузки с круговой стрелкой. Появится новое поле Отладка страниц с синей ссылкой service worker.

Кликнем на эту ссылку и увидим вывод в консоли от фонового скрипта, "Default background color set to green".


Пользовательский интерфейс расширения.

Расширения могут иметь множество вариантов интерфейса пользователя; в нашем примере мы будем использовать popup - всплывающее окно. Создадим в папке расширения файл popup.html. Наше расширение будет использовать кнопку для изменения фонового цвета страницы. Вот код:

<!DOCTYPE html>

<html>

  <head>

    <link rel="stylesheet" href="button.css">

  </head>

  <body>

    <button id="changeColor"></button>

  </body>

</html>

Как и в случае с фоновым скриптом, этот файл тоже должен быть объявлен в манифесте, чтобы указать браузеру Chrome, что он будет использоваться для вывода всплывающего окна расширения. Чтобы это сделать добавим поле action в манифест и установим в нем свойству default_popup значение с именем нашего скрипта popup.html.

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3,

  "background": {

    "service_worker": "background.js"

  },

  "permissions": ["storage"],

  "action": {

    "default_popup": "popup.html"

  }

}

В нашем файле есть ссылка на внешнюю таблицу стилей button.css. Давайте напишем ее. Создадим файл button.css и добавим код:

button {

  height: 30px;

  width: 30px;

  outline: none;

  margin: 10px;

  border: none;

  border-radius: 2px;

}


button.current {

  box-shadow: 0 0 0 2px white,

              0 0 0 4px black;

}

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

Распакуйте их и поместите в папку расширения. Обновим манифест, чтобы браузер узнал о них.

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3,

  "background": {

    "service_worker": "background.js"

  },

  "permissions": ["storage"],

  "action": {

    "default_popup": "popup.html",

    "default_icon": {

      "16": "/images/get_started16.png",

      "32": "/images/get_started32.png",

      "48": "/images/get_started48.png",

      "128": "/images/get_started128.png"

    }

  }

}

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

{

  "name": "Getting Started Example",

  "description": "Build an Extension!",

  "version": "1.0",

  "manifest_version": 3,

  "background": {

    "service_worker": "background.js"

  },

  "permissions": ["storage"],

  "action": {

    "default_popup": "popup.html",

    "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"

  }

}

По-умолчанию, расширения появляются в меню расширений. Если его закрепить, то появится иконка расширения прямо на панели инструментов браузера.

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

Последний шаг для интерфейса этого окна это изменение цвета кнопки. Создадим для этого скрипт popup.js со следующим кодом и также добавим его в папку расширения:

// Инициализируем кнопку предпочитаемым пользователем цветом

let changeColor = document.getElementById("changeColor");

chrome.storage.sync.get("color", ({ color }) => {

  changeColor.style.backgroundColor = color;

});

Этот код получает элемент кнопки из файла popup.html и запрашивает значение цвета из хранилища. Затем он применяет этот цвет в качестве фонового для самой кнопки. Подключим этот скрипт к странице popup.html.

<!DOCTYPE html>

<html>

  <head>

    <link rel="stylesheet" href="button.css">

  </head>

  <body>

    <button id="changeColor"></button>

    <script src="popup.js"></script>

  </body>

</html>

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

Логика слоев

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

// При нажатии кнопки, инжектируем функцию setPageBackgroundColor в код текущей просматриваемой страницы в браузере.

changeColor.addEventListener("click", async () => {

  let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });


  chrome.scripting.executeScript({

    target: { tabId: tab.id },

    function: setPageBackgroundColor,

  });

});

// Эта функция выполнится как контентный скрипт внутри текущей открытой страницы

function setPageBackgroundColor() {

  chrome.storage.sync.get("color", ({ color }) => {

    document.body.style.backgroundColor = color;

  });

}

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

Нам понадобится добавить разрешение activeTab, чтобы позволить расширению доступ к текущей странице и скриптовое расширение для использования метода executeScript из Scripting API. Добавим их:

{

  "name": "Getting Started Example",

  ...

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

  ...

}

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

Важная заметка!

Расширения не могут инжектировать контентные скрипты на внутренние страницы Chrome, такие как "chrome://extensions" и т.п. Тестируйте его на реальных интернет-сайтах, вроде https://google.com.

Дадим пользователю настройки расширения

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

Начните с создания в папке расширения файла options.html со следующим кодом.

<!DOCTYPE html>

<html>

  <head>

    <link rel="stylesheet" href="button.css">

  </head>

  <body>

    <div id="buttonDiv">

    </div>

    <div>

      <p>Choose a different background color!</p>

    </div>

  </body>

  <script src="options.js"></script>

</html>

Теперь зарегистрируем эту страницу настроек в манифесте:

{

  "name": "Getting Started Example",

  ...

  "options_page": "options.html"

}

Перезагрузим расширение и кликнем на иконке расширения в панели браузера правой кнопкой мыши и выберем пункт Параметры. 

Последний шаг это добавить логику параметров. Создадим файл с именем options.js в папке расширения и добавим в него код:

let page = document.getElementById("buttonDiv");

let selectedClassName = "current";

const presetButtonColors = ["#3aa757", "#e8453c", "#f9bb2d", "#4688f1"];


// обработаем нажатие кнопки окрасив выбранную кнопку и сохраняя выбор

function handleButtonClick(event) {

  // Удалим стиль предыдущего выбранного цвета 

  let current = event.target.parentElement.querySelector(

    `.${selectedClassName}`

  );

  if (current && current !== event.target) {

    current.classList.remove(selectedClassName);

  }


  // Пометим кнопку как выбранную 

  let color = event.target.dataset.color;

  event.target.classList.add(selectedClassName);

  chrome.storage.sync.set({ color });

}


// Добавим кнопку на страницу для каждого предоставляемого цвета

function constructOptions(buttonColors) {

  chrome.storage.sync.get("color", (data) => {

    let currentColor = data.color;

    // для каждого цвета мы ...

    for (let buttonColor of buttonColors) {

      // ... создаем кнопку этого цвета

      let button = document.createElement("button");

      button.dataset.color = buttonColor;

      button.style.backgroundColor = buttonColor;


      // …отмечает кнопку выбранного цвета…

      if (buttonColor === currentColor) {

        button.classList.add(selectedClassName);

      }


      // … и регистрируем обработчик нажатия кнопки

      button.addEventListener("click", handleButtonClick);

      page.appendChild(button);

    }

  });

}


// Инициализируем страницу, соберем настройки цвета

constructOptions(presetButtonColors);

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

На этом простой пример создания расширения завершен.

Эта страница является переводом https://developer.chrome.com/docs/extensions/mv3/getstarted/ с небольшими отступлениями от точного текста.

Комментариев нет:

Отправить комментарий