Как написать расширение для chrome
Перейти к содержимому

Как написать расширение для chrome

  • автор:

Создаём расширение для Chrome

Хотите написать расширение для Chrome, но не знаете, с чего начать? Читайте это руководство с нуля до подготовки к публикации скрипта содержимого. Здесь применяются фреймворк CSS TailWind и универсальный упаковщик Parcel.js, решаются проблемы переопределения стиля страницы и перезагрузки расширения. Весь код вы найдёте в конце.

Написать расширение для Chrome непросто. Это не то же самое, что разработка веб-приложения: не хочется перегружать браузер оверхедом JS, ведь расширения работают одновременно с сайтами. Более того, у нас нет инструментов упаковки или отладки из привычных фреймворков.

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

В этом руководстве мы напишем расширение для Сhrome с помощью Parcel.js для упаковки и просмотра результатов, а также TailwindCSS для оформления. Кроме того, мы отделим стилизацию расширения от веб-сайта, чтобы избежать конфликта CSS.

Есть несколько типов расширений для Chrome, достойных упоминания:

  • Скрипты содержимого. Наиболее распространённый тип. Они запускаются в контексте веб-страницы и могут изменять её. Именно такое расширение мы и будем создавать.
  • Выпадающее окно (popup). Использует иконку справа от адресной строки, чтобы открыть окно с каким-то HTML.
  • UI с опциями. Пользовательский интерфейс для настройки параметров в качестве расширения. Получить доступ к нему можно, щелкнув правой кнопкой мыши по значку расширения и выбрав пункт “Параметры” или перейдя на страницу расширения из списка расширений Chrome: chrome://extensions .
  • Расширение DevTools. Добавляет функциональность в инструменты разработчика. Оно может добавлять новые панели интерфейса, взаимодействовать с проверяемой страницей, получать информацию о сетевых запросах и многое другое — документация Google Chrome.

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

Упаковываем расширение с Parcel.js V2

Parcel.js — это упаковщик веб-приложений, не требующий конфигурации. Входным может быть файл любого типа, упаковщик прост в использовании и работает с любыми приложениями, включая расширения Chrome. Создаём папку demo-extension . Удостоверьтесь, что у вас установлены yarn или npm . Здесь будем работать с yarn . Установим Parcel как локальную зависимость и создадим папку src

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

Каждому браузерному расширению необходим файл манифеста. Именно там мы определяем версию и метаданные расширения, а также скрипты, которые в нём работают. Контент, фон, всплывающее окна, разрешения, если они нужны и так далее. Вы найдёте полное описание файла манифеста в документации Chrome: https://developer.chrome.com/extensions/manifest. Давайте двинемся дальше и добавим в src файл manifest.json с такими строками:

Прежде чем углубиться в детали работы расширения Chrome, установим и настроим TailwindCSS.

Подключаем TailwindCSS

TailwindCSS — это CSS-фреймворк, применяющий служебные классы низкого уровня для создания переиспользуемых и настраиваемых компонентов интерфейса. Tailwind устанавливается двумя способами, самый распространённый — установка с помощью NPM. Кроме того, сразу же стоит добавить autoprefixer и postcss-import :

Они нужны, чтобы добавить префиксы поставщиков к стилям и иметь возможность писать конструкции @import "tailwindcss/base" , импортируя файлы Tailwind прямо из node_modules .

Теперь, когда всё установлено, давайте создадим файл postcss.config.js в корневом каталоге. Этот файл — конфигурация для PostCSS. Вставим в него такой код:

Порядок плагинов здесь имеет значение! Это всё, что нужно, чтобы начать использовать TailwindCSS в вашем расширении. Начинаем. Создадим файл style.css в папке src и импортируем в него стили Tailwind:

Очищаем CSS с помощью PurgeCSS

Убедимся, что мы импортируем только те стили, которые используем, включив очистку. Создадим конфигурационный файл Tailwind, запустив такую команду:

Теперь у нас есть tailwind.config.js . Чтобы удалить неиспользуемый CSS, добавляем пути ко всем нашим файлам JS в поле конфигурации purge :

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

Включаем горячую перезагрузку

Chrome не перезагружает файлы при внесении изменении, то есть нам нужно нажимать кнопку “Перезагрузить” на странице расширений каждый раз, когда мы хотим посмотреть на результат. К счастью, есть пакет NPM для автоматической перезагрузки:

Чтобы использовать его, создадим файл background.js в папке src и импортируем в этот файл crx-hotreload :

Наконец, добавим указатель на background.js в manifest.json , чтобы он мог работать с нашим расширением: горячая перезагрузка в продакшне отключена по умолчанию:

Достаточно конфигураций. Давайте создадим небольшую форму-скрипт в расширении.

Типы скриптов расширения Chrome

Как уже упоминалось, у расширений Chrome есть несколько типов скриптов:

  • Скрипты содержимого — это сценарии, которые выполняются в контексте посещаемой веб-страницы. Вы можете запустить любой код JavaScript, в противном случае доступный на любой обычной веб-странице, включая доступ к DOM и манипулирование им.
  • Фоновые скрипты — это место, где вы можете реагировать на события браузера с доступом к API расширения.

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

Создадим файл content-script.js в папке src . И добавим HTML-форму в только что созданный файл:

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

Теневой DOM — мощная техника инкапсуляции стилей: область применения стиля ограничивается теневым деревом. Таким образом ничего не просачивается на веб-страницу. Кроме того, внешние стили не переопределяют содержимое дерева, хотя переменные CSS всё ещё доступны.

Теневой хост — это любой элемент DOM, к которому мы хотели бы присоединить теневое дерево. Теневой корень — это то, что возвращается из attachShadow , а его содержимое — то, что визуализируется.

Будьте осторожны: единственный способ стилизовать содержимое теневого дерева — встроить стили. Parcel V2 из коробки есть функция, благодаря которой вы можете импортировать содержимое одного пакета и использовать его в качестве скомпилированного текста внутри ваших файлов JavaScript. Именно это мы и сделали со своим пакетом style.css . Parcel заменит его во время упаковки.

Теперь мы можем автоматически встроить CSS в Shadow DOM во время сборки. Конечно, мы должны сообщить браузеру о файле content-script.js , в котором встраивается style.css . Для этого включаем скрипт содержимого в манифест. Обратите внимание на секцию content-scripts ниже первого блока:

Чтобы обслуживать наше расширение, добавим несколько скриптов к package.json :

Наконец, запускаем yarn watch , переходим в chrome://extensions и убеждаемся, что в правом верхнем углу страницы включен режим разработчика. Нажмите на кнопку “Загрузить распакованный” и выберите папку dist в разделе demo-extension .

Если вы получили ошибку Error: Bundles must have unique filePaths , ее можно исправить, просто удалив main из package.json .

Подготовка к публикации

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

Если у вас ещё не установлен zip, пожалуйста, выполните команду:

  • На MacOS: brew install zip .
  • На Linux: sudo apt install zip .
  • На Windows: powershell Compress-Archive -Path .\\dist\\ -Destination .\\chrome-extension.zip .

Теперь всё, что остается, — это отправиться в Chrome Web Store Developer Dashboard — панель управления разработчика, чтобы настроить учетную запись и опубликовать своё расширение.

Заключение

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

Создание расширения браузера Google Chrome для извлечения всех изображений web-страницы. Часть 1

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

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

Мы создадим расширение, которое называется Image Grabber. Оно будет содержать интерфейс для подключения к web-странице и для извлечения из нее информации о всех изображениях. Далее, при нажатии на кнопку «GRAB NOW» список абсолютных URL этих изображений будет скопирован в буфер обмена. В этом процессе вы познакомитесь с фундаментальными строительными блоками, которые в дальнейшем можно будет использовать для создания других расширений.

Расширения, создаваемые таким образом для браузера Chrome совместимы с другими браузерами, основанными на движке Chromium и могут быть установлены, например, в Yandex-браузер или Opera.

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

Это только первая часть истории. Во второй части я покажу, как расширить интерфейс, чтобы выгрузить все или выбранные изображения в виде ZIP-архива, а также, как опубликовать свое расширение в Chrome Web Store.

Базовая структура расширения

Расширение Google Chrome — это web-приложение, содержащее любое количество HTML-страниц, файлов CSS и изображений, а также, файл manifest.json, который определяет как расширение выглядит и работает. Все эти файлы должны быть в одной папке.

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

Здесь только manifest_version должен быть равен 3. Остальные поля заполняются произвольно в зависимости от назначения расширения: name — название расширения, description — краткое описание, version — версия. Остальные параметры мы будем заполнять по ходу разработки интерфейса. Полный список параметров manifest.json можно найти в официальной документации.

Папка с одним файлом manifest.json — это минимальное расширение, которое может быть установлено в Google Chrome и запущено. Оно ничего не будет делать, однако именно с установки нужно начинать. Поэтому создайте папку image_grabber, затем добавьте в нее текстовый файл manifest.json с содержимым приведенным выше.

Установка расширения

В процессе разработки расширения, оно представляет собой папку с файлами. В терминологии Google Chrome это называется «unpacked extension». После завершения разработки, его нужно упаковать в ZIP-архив и загрузить в Chrome Web Store, откуда оно потом может быть установлено в браузер.

Однако на этапе разработки, «unpacked extension» тоже можно установить, просто как папку с файлами. Для этого нужно ввести chrome://extensions в браузере, чтобы открыть Chrome Extensions Manager:

Это покажет список уже установленных расширений. Чтобы устанавливать в него «unpacked extensions», включите флажок «Developer mode» в правом верхнем углу. После этого должна отобразиться панель управления расширениями.

Затем нажмите первую кнопку Load unpacked и укажите папку, в которой находится расширение с файлом manifest.json. В нашем случае это папка image_grabber. Расширение должно отобразиться в списке:

Эта панель должна показывать данные расширения такие как имя, описание и версию, ранее указанные в manifest.json, а также уникальный идентификатор, присвоенный этому расширению. Каждый раз после изменения manifest.json и файлов, непосредственно указанных в нем, нужно обновлять расширение в браузере, нажимая на кнопку «Reload«:

Чтобы запустить и использовать установленное расширение в браузере, нажмите кнопку Extensions на панели инструментов Google Chrome рядом с URL и найдите «Image Grabber» в списке установленных расширений:

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

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

Добавление иконок

Параметр icons файла manifest.json принимает объект JavaScript, ключами которого являются размеры иконок, а значениями пути к файлам с этими иконками. Иконка это картинка с расширением PNG (для прозрачности). Расширение должно иметь иконки разных размеров: 16×16, 32×32, 48×48 и 128×128. Я создал иконки для всех этих размеров и поместил их в папку «icons» внутри папки с расширением. Сделайте то же самое. Имена файлов могут быть любыми:

Как видно, здесь указаны относительные пути к файлам в папке icons.

После изменения manifest.json нажмите кнопку «Reload» на панели расширения Image Grabber в Chrome Extensions Manager, чтобы обновить установленное расширение. Если все сделано как описано выше, то картинка на кнопке расширения должна измениться:

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

Создание интерфейса расширения

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

В фоне, при запуске расширения и при дальнейшей его работе

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

Расширение может использовать обе эти возможности одновременно.

Чтобы запускать действия в фоне, нужно создать Javascript-файл и указать путь к нему в параметре «background» файла manifest.json. Этот скрипт может содержать функции обработчики различных событий браузера и жизненного цикла самого расширения. Background-скрипт слушает эти события и запускает написанные для них функции обработчики.

Однако в этом расширении мы этим пользоваться не будем и параметр «background» останется пустым. Он присутствует только для того, чтобы показать что это возможно и что данный файл manifest.json может использоваться для создания расширений любого типа. Однако расширение Image Grabber выполняет действия только когда пользователь нажимает кнопку «GRAB NOW» из интерфейса.

Соответственно мы создадим интерфейс для расширения. Интерфейс расширения это фактически Web-сайт, состоящий из HTML-страниц с элементами управления, CSS-таблиц стилей и скриптов, которые реагируют на события элементов управления из этих HTML-страниц и выполняют определенные действия, используя в частности API расширений Google Chrome.

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

Здесь определено, что основное действие (action) расширения это всплывающее окно (popup), которое содержит страницу popup.html.

Теперь создайте файл popup.html с заголовком Image Grabber и кнопкой «GRAB NOW» и поместите его в папку с расширением:

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

Чтобы увидеть, что изменилось, снова обновите расширение в Chrome Extensions Manager. Если все было сделано как написано выше, то при нажатии на иконку расширения будет появляться содержимое файла popup.html во всплывающем окне:

Работает!! Но выглядит не очень. Теперь нужно стилизовать этот интерфейс с помощью CSS.

Создайте файл popup.css со следующим содержимым и поместите его в папку с расширением:

Этот файл определяет стили для кнопки и для body всей страницы: все содержимое выровнено по центру, а также, ширина содержимого будет 200 пикселей.

Добавьте ссылку на файл с этими стилями в popup.html:

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

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

Чтобы придать интерфейсу завершенность, добавим JavaScript-код, который будет реагировать на нажатия кнопки «GRAB NOW«. Создайте файл popup.js в папке с расширением со следующим содержимым:

и добавьте ссылку на этот файл в popup.html:

Таким образом мы добавили событие onClick для кнопки с идентификатором «grabBtn«. Теперь, при нажатии на кнопку «GRAB NOW» в интерфейсе, должно появляться предупреждение «CLICKED».

В результате мы имеем такую файловую систему расширения:

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

Теперь реализуем бизнес логику расширения: при нажатии на кнопку «GRAB NOW» расширение должно извлечь список путей ко всем картинкам текущей страницы в браузере и скопировать этот список в буфер обмена.

Функция «GRAB NOW»

Используя Javascript в расширении можно делать все то же самое, что и при использовании JavaScript на web-сайте, например открывать различные web-страницы из текущей или делать AJAX HTTP-запросы к различным серверам. Но в дополнении к этому, Javascript-код в расширении браузера может использовать различные API Chrome для взаимодействия с компонентами самого браузера. Большинство этих API доступно через пространство имен chrome . В частности, расширение Image Grabber будет использовать следующие API:

chrome.tabs — Chrome Tabs API. Будет использоваться для доступа к активной вкладке браузера.

chrome.scripting — Chrome Scripting API. Будет использоваться для внедрения кода JavaScript на web-страницу активной вкладки и для исполнения этого кода в контексте этой страницы.

Получение необходимых разрешений

По умолчанию, из соображений безопасности, расширение Chrome не имеет доступа ко всем API браузера. Необходимо запросить этот доступ через механизм разрешений. Для этого нужно указать список требуемых разрешений в параметре permissions в файле manifest.json. Существует множество различных разрешений, которые описаны здесь: https://developer.chrome.com/docs/extensions/mv3/declare_permissions/. Для Image Grabber нужно указать следующие из них:

activeTab — разрешение для получения доступа к текущей вкладке браузера.

scripting — разрешение для получения доступа к Chrome Scripting API для исполнения скриптов в контексте Web-страницы, открытой в браузере.

Добавьте эти разрешения в параметр permissions в файле manifest.json:

и обновите расширение в Chrome Extensions Manager.

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

Получение информации об активной вкладке браузера

Для получения информации о вкладках браузера используется функция chrome.tabs.query , которая определена следующим образом:

queryObject — объект запроса в котором указываются параметры поиска нужных вкладок.

callback — функция обратного вызова, которая выполняется после выполнения этого запроса. В нее передается массив tabs , содержащий все найденные вкладки, соответствующие критерию запроса. Каждый элемент этого массива — это объект типа Tab , содержащий информацию о вкладке, включая ее уникальный идентификатор. Этот идентификатор будет использоваться для исполнения Javascript-кода на этой вкладке.

Здесь я не буду полностью описывать синтаксис queryObject , а также все поля возвращаемых объектов Tabs . Эту информацию можно найти в официальной документации по chrome.tabs : https://developer.chrome.com/docs/extensions/reference/tabs/.

Для расширения Image Grabber нужно получить только активную вкладку. Для этой цели queryObject должен быть определен как: .

Теперь давайте изменим код обработчика нажатия кнопки grabBtn в popup.js чтобы он получал активную вкладку и ее идентификатор, когда пользователь нажимает на кнопку «GRAB NOW» в интерфейсе расширения:

Этот код выполняет запрос ко всем вкладкам, которые активны. Может быть только одна такая вкладка, поэтому к ней можно обратиться как tabs[0] . Если такая вкладка существует, то функция отображает ее id, а если не существует, то показывает сообщение об ошибке.

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

Извлечение изображений из текущей страницы

Расширение может взаимодействовать с открытыми страницами с помощью интерфейса Chrome Scripting API, доступного через chrome.scripting . В частности, мы будем использовать функцию для внедрения своего кода в текущую web-страницу и для исполнения этого кода в ее контексте. При запуске этот код будет иметь доступ к DOM-дереву этой страницы и сможет делать нужные нам действия с любыми HTML-тэгами.

Для внедрения скрипта в страницу Web-браузера используется функция executeScript , определенная следующим образом:

Рассмотрим ее параметры.

injectSpec

Это объект типа ScriptInjection. В нем определяется какой Javascript-код, в какую web-страницу и каким образом внедрить. В частности, в параметре target указывается идентификатор вкладки браузера со страницей, которая нам нужна. Мы получили его ранее. Остальные параметры указывают каким образом передать скрипт на эту страницу. Возможно использовать следующие параметры для передачи скрипта:

files — указывается список путей к JS-файлам, которые нужно внедрить, относительно корневой папки расширения

func — указывается Javascript-функция, которую нужно внедрить. Функция должна быть предварительно написана.

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

В итоге injectSpec будет определен следующим образом:

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

Саму функцию grabImages мы напишем чуть позже.

callback

Это функция обратного вызова, которая будет вызвана после того, как внедренный скрипт исполнится на странице и во всех ее фреймах. В качестве параметра в ней будет массив результатов, которые вернула функция grabImages для каждого фрейма (возможно это будет всего один элемент, если фреймов нет). Каждый элемент этого массива — это объект типа InjectionResult. Он в частности содержит свойство result . Именно оно содержит то, что возвращает функция grabImages, т.е. список URL-ов.

Теперь соберем все вместе в следующем коде:

Функция grabImages может быть определена следующим образом:

Здесь все просто: получаем список DOM-элементов <img> и извлекаем свойство src каждого из них в итоговый массив. Считаю нужным напомнить, что объект document , указанный в этой функции указывает на содержимое не той HTML-страницы, где находится функция grabImages , а удаленной web-страницы, в которую эта функция будет внедрена.

После того как данная функция выполнится в каждом фрейме, результаты будут объединены в единый массив и переданы в функцию onResult . Эта функция может быть определена следующим образом:

Следует упомянуть что не все вкладки браузера — это вкладки с web-страницами. Например, может быть вкладка свойств браузера. Страницы на таких вкладках не имеют свойства document . В этом случае функция grabImages не выполнится и не вернет результатов. Этот случай обрабатывается в самом начале функции. Затем массив массивов результатов объединяется в единый плоский массив используя концепцию map/reduce, затем функция window.navigator.clipboard используется, чтобы скопировать его в буфер обмена. Предварительно массив результатов преобразовывается в строку, разделенную символом перевода строки.

Завершающие штрихи

Здесь я описал только незначительную часть Chrome Scripting API и описал только в контексте данного расширения. Полная документация по Chrome Scripting API доступна здесь: https://developer.chrome.com/docs/extensions/reference/scripting/.

Теперь немного почистим код. Здесь я считаю нужным часть функции обработчика grabBtn, которая выполняет chrome.scripting.executeScript вынести в отдельную функцию execScript . В результате файл popup.js выглядит так:

Заключение

Теперь, если нажать по иконке расширения Image Grabber и затем кликнуть кнопку GRAB NOW, то в буфере обмена будет список URL-ов всех изображений текущей web-страницы. Можно вставить его в любой текстовый редактор.

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

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

Пишем расширение под Google Chrome

В связи с последними тенденциями в вебе (в том числе и недавний запуск webstore), возникла идея попрактиковаться в написании плагина под Google Chrome. Решил написать плагин, который бы показывал цитаты с сайта Forismatic.com, после прочтения статьи о написании аналогичного апплета для gnome.

Требования:

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

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

/.config/chromium/Default/Extensions (используется Chromium на Ubuntu).

Весь исходный код моего расширения доступен на гитхабе.

Получать цитаты будем с помощью api forismatic.com в формате json.

Меняем lang на выбранный язык, а параметр key произвольно.

Теперь перейдём непосредственно к созданию приложения Необходимо создать такую структуру:

  • _locales/en/messages.json #для перевода на английский язык
  • _locales/ru/messages.json #для перевода на русский язык
  • background.html #файл, который выполняется при запуске плагина
  • functions.js #небольшая библиотечка написанных функций
  • icon.png #В связи с запуском webstore рекомендую использовать иконки по-качественней
  • manifest.json #файл описания плагина
  • options.html #html-файл настроек

Сначала создаём файлы переводы.

_locales/en/messages.json

_locales/ru/messages.json

Теперь можно описать расширение в манифесте

manifest.json

Параметр default_locale определяет стандартную локаль.

Параметр name описывает имя расширения. Мы его задаём в зависимости от языка, используя ранее описанную переменную в файлах локализации extName, предварительно обернув её: MSG_extName Также поступим и с параметром description. Кстати, при отображении расширения на https://chrome.google.com/extensions/ или на https://chrome.google.com/webstore будет тоже подставляться значение в зависимости от выбранного языка.

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

Параметры background_page и options_page указывают на страницу, выполняющуюся в фоне, и страницу настроек. В параметре permissions передаем массив, в котором описываем, что может делать расширение. Мы включили доступ к уведомлениям (notifications) и доступ к сайту api (http://api.forismatic.com/*).

С параметром icons всё понятно.

Библиотека функций для javascript

functions.js

options.html

Cкрипт, который помогает упаковывать расширение:

zip.sh

Теперь можно запустить плагин в браузере: Tools » Расширения » Загрузить распакованное расширение Должно появиться всплывающее окно с цитатой. Можно зайти в настройки, сменить язык. При сохранении, должная появиться цитата на другом языке.

Как сделать расширение для Google Chrome и немного улучшить UX на главной странице почты

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

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

Больше года назад я заметил, что ссылки «Входящие» и «Написать письмо» на главной странице почты, которой я часто пользуюсь, стали открываться в новом окне. По ответу эксперта стало понятно, что придется привыкать к этому спорному нововведению.

Я привыкнуть не смог: каждый раз возвращаться и закрывать вкладку браузера неудобно. Так появилась идея простого расширения для Chrome, которое вернет прежнее поведение при открытии Входящих и написании нового письма.

SimilarWeb показывает 1,141 млрд посещений главной страницы за август. Если хотя бы 10% из них приходится на десктопный браузер и целевое действие, то это 141 млн открытых вкладок в месяц. На возврат и закрытие вкладки уходит не меньше секунды. Получается, мы собираемся сэкономить 31,5 тысячи человеко-часов в месяц.

Приготовим минимальный стартовый набор.

1. Создайте папку проекта. Назовите ее именем вашего расширения.

2. Создайте javascript-файл, в котором будет реализована логика приложения. Я назвал его app.js.

3. Добавьте в созданный файл команду для тестирования: вывод строки в консоль или в диалоговое окно браузера.

4. Создайте manifest.json – служебный файл, который должен быть в каждом расширении.

Обязательные параметры, должны быть в каждом manifest.json:

manifest_version – целое число, обозначает версию формата манифеста. Для современных версий браузера значение равно 2;

name – название расширения, до 45 символов. К названию стоит подойти ответственно – оно отображается в магазине, при установке и на странице управления расширениями (chrome://extensions);

description – простой текст, до 132 символов. Отображается в магазине и на странице управления расширениями;

icons – список из иконок расширения;

5. Подготовьте иконку в формате png размером 128х128 пикселей и положите ее в папку проекта. Эта версия отображается при установке и в магазине расширений. Рекомендуют также добавить иконку размером 48х48 пикселей – она отображается на странице управления расширениями. И можно добавить версию 16х16 пикселей, которая будет использоваться как фавикон.

К этому моменту в нашем проекте есть иконка расширения, manifest.json со служебной информацией и app.js, в котором позже появится код приложения.

Примечание: расширение может состоять из нескольких JS-файлов, HTML-верстки и CSS-стилей.

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

1. Войдите в свой аккаунт в браузере Chrome.

2. Перейдете на страницу chrome://extensions.

3. В правом верхнем углу включите Режим разработчика.

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

5. В новой вкладке браузера откройте любую веб-страницу. Отлично, работает!

Теперь мы готовы добавить полезное действие.

Проверим код ссылок «Входящие» и «Написать письмо» на странице почты с помощью инструментов разработчика браузера. Нажимаем правую кнопку на ссылке и выбираем Посмотреть код. Видно, что ссылки открываются в новой вкладке из-за атрибута target=”_blank”.

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

1. В app.js сохраните ссылки в переменные:

Здесь мы выбираем элементы по их идентификатору (id).

2. Если такие ссылки найдены, удалите у них атрибут target.

Похоже, этого кода достаточно для решения проблемы.

Заодно давайте пропишем в manifest.json правило, по которому расширение будет запускать наш скрипт только на целевой странице. Для этого в параметре content_scripts в ключе matches пропишем конкретный URL:

Звездочку в конце URL я поставил, чтобы скрипт срабатывал на всех страницах, начинающихся с https://mail.ru/.

Кстати, после обновления расширения стоит обновить версию и в manifest.json:

После внесения правок важно обновить расширение в браузере. Для этого нажмите на стрелку на странице управления расширениями (chrome://extensions/).

Готово! Проверим расширение в боевых условиях.

Открываем целевую страницу и переходим по ссылкам «Входящие» и «Написать письмо». Победа! Ссылки открываются в той же вкладке, как в старые добрые времена.

Этот шаг необязательный. Во-первых, возможно, вы не хотите делать доступным для всех свое расширение. А во-вторых, возможно, не захотите платить за это $5. Такой регистрационный сбор должен оплатить разработчик Chrome Web Store.

  1. Создайте zip-архив с файлами проекта.
  2. Зарегистрируйтесь как разработчик Chrome Web Store. Для этого войдите в консоль разработчика под своим аккаунтом Chrome, примите условия соглашения и Политику конфиденциальности.
  3. Оплатите регистрационный сбор $5. Оплатить можно картой, как в обычных интернет-магазинах.
  4. На дашборде разработчика в разделе Аккаунт добавьте адрес электронной почты. Без этого не получится отправить расширение на проверку.
  5. В личном кабинет разработчика нажмите Добавить продукт и загрузите zip-архив проекта.
  6. В разделе Описание продукта заполните описание расширения, выберите категорию и язык. Добавьте хотя бы один скриншот расширения.
  7. В разделе Конфиденциальность коротко опишите единственное назначение расширения, обоснование для использования разрешения и отметьте, что не используете разрешение «удаленный код».
  8. В разделе Цель и распространение задайте, кому будет доступно расширение.
  9. Нажмите Отправить на проверку в правом верхнем углу.

Это всё. Остается ждать результат проверки, которая может занять несколько недель.

Я отправил расширение на проверку параллельно с публикацией статьи. Как только получу ответ, добавлю комментарий со ссылкой на опубликованное расширение.

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

И всё это ради 5 (3) строк кода?

По поводу самой идеи, а не инструкции по написанию расширений:
Чтобы не создавать каждый раз новое расширение для незначительных правок для каждого сайта, на котором Вам что-то захочется подправить под себя, достаточно один раз установить расширение Tampermonkey и делать это для сотни сайтов быстро и удобно в три клика (открыть меню -> создать скрипт -> сохранить).

Всё это ради решения проблемы. В данном случае получилось решить её с помощью нескольких строк кода.

один раз установить расширение Tampermonkey

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

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

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

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

Скорее всего я бы выбрал вариант автономного приложения с использованием сетевого API бесплатных сервисов (чтобы это смог повторить каждый), либо просто парсинга, с информативной иконкой с числовым показателем и уведомлениями (Notifications API).

Идеальным вариантом для демонстрации, как мне кажется, было бы расширение для мониторинга конкретной информации (входящие e-mail, доступные билеты, баланс на счёте, начало трансляций и так далее) с информативными image/text-уведомлениями.

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

UPD. Расширение опубликовано в Chrome Web Store. На почту никакое уведомление не приходило, поэтому сложно сказать, сколько времени заняла проверка.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *