Пишем расширение для google chrome
Написать расширение для google chrome несложно. Но при написании первого раширения могут возникнуть (и возникают) вопросы. Большинство мануалов по написанию первого расширения расчитаны на использования манифеста первой версии, поддержка которого в скором будущем прекратится.
- Как составлять манифест v.2
- Как работать с удаленными ресурсами
- Как работать с cookies
- Как работать с local storage
- Как работать с уведомлениями
Введение
- Должен иметь поле для добавления события (дата, время, событие)
- Должен отображать все задачи на текущий день, отсортированные по времени
- Все прошедшие события должен отображать зачеркнутыми
- Должен иметь поле для ввода времени, за сколько надо показывать уведомление, а так же чекбокс разрешающий и запрещающий показывать уведомления
- За указанное время до события должен отображать уведомление о приближающемся событии
Манифест
Начнем создавать расширение с самого начала, то есть с манифеста. Манифест – это тот самый файл, в котром прописываются все параметры расширения. Название, описание, версия, разрешение на доступ к сайтам, разрешение на использование кук, уведомлений, локального хранилища. В общем, манифест – это мозг расширения. Создаем файл manifest.json. Манифест – единственный файл, который должен иметь заранее предопределенное имя, все остальные файлы можно будет называть как угодно. В этом файле есть три обязательных поля:
manifest.json
- Версия манифеста должна быть целочисленной, то есть должна писаться как 2, а не “2”.
- Версия расширения должна быть строковой, но содержать только числа и точки, то есть “1.0” — хорошо, а 1.0 и “0.9 beta” — плохо.
С обязательными полями – все, перейдем к созданию всплывающего окна расширения. Для того, чтобы по нажатию на пиктограмму, открывалось окно, необходимо добавить в манифест поле “browser_action”
manifest.json
Теперь создадим всплывающее окно. Это обычная html страница, которая может быть любого размера и цвета, никаких фокусов. Назовем файл “popup.html”. Создать этот файл мало – его надо указать в манифесте. Так мы и сделали: «default_popup»: «popup.html».
Добавление расширения в браузер
Теперь пришло время проверить работоспособность нашего расширния. Для этого загрузим расширение в браузер. Открываем в хроме меню расширений. Ставим птицу на “Developer mode”.
После этого появятся три кнопки. Нажимаем “Load unpacked extension. ”. Выбираем папку с файлами расширения. После этого появится наше расширение. Если все правильно, то по нажатию на иконку – повится окно: 
Подключение скриптов
Теперь можно приступить к интересному. Подключим два javascript файла. Первый – popup.js, второй – jquery. С первым проблем не возникнет, но jquery будем подключать не локальный, а удаленный, взятый по адресу ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js. Проблемы возникнут от того, что по умолчанию расширение не имеет доступа к сторонним ресурсам. Чтобы получить доступ, надо его указать в манифесте. Доступ к чему-либо указывается в поле “permissions”. Так же, для удаленных скриптов и css надо указывать доступные удаленные ресурсы.
manifest.json
Теперь подключим эти скрипты в popup.html
Storage
При помощи storage в хроме можно хранить пользовательские данные. И именно в storage наше расширение и будет хранить грядущие события. На то есть две причины. Во-первых, данные, хранищиеся в storage можно синхронизировать, если залогиниться в браузере. А во-вторых, данные можно хранить не только в виде строки, как в cookies, а в любом виде, то есть можно хранить и массивы и объекты. Чтобы это заработало, откроем доступ к storage в манифесте.
manifest.json
Теперь переделаем всплавающее окно. Во всплывающем окне будет поле с сегодняшней датой, три инпута для даты, времени и описания нового события, кнопка для добавления нового события, а так же список всех событий на сегодня.
И сразу же добавим отображение даты в блоке #today_date.
Выглядеть должно так: 
Итак, при нажатии на кнопку “+” у нас должно добавляться событие. Вначале файла объявим глобальную переменную storage – объект для работы с storage, а так же глобальный массив tasks для хранения событий.
Функция валидации проверяет, что дата записана в формате d.m.yyyy, а время в формате hh:mm, а так же, что в описании события не меньше трех символов.
С добавлением разобрались, переходим к получению событий на сегодня. Для этого надо получить все события из базы, выбираем из всех только сегодняшние события и сортируем их по времени по возрастанию.
Функция getTodayTasks() возвращает из общего списка только события с сегодняшней датой.
Функция sortTasks() сортирует события по возрастанию времени.
Уведомления
Пришло время настроить отображение уведомлений на экране. Добавим во всплывающее окно специальный чекбокс. Если этот чекбокс будет отмечен – уведомлениея будут показываться, если не будет отмечен – не будут. Так же добавим текстовый инпут. Цифра в этом инпуте будет показывать, за какое время до событя будет показываться уведомление. То есть если у нас событие назначено на 19:00, в этом текстовом инпуте будет 5, значит в 18:55 появится уведомление. Добавим в popup.html код с этими инпутами

Теперь давайте разберемся с тем, как это будет работать. При нажатии на чекбокс, будет проверяться его атрибут checked, значение атрибута будет записываться в cookie “show_notifications”. Перейдем к текстовому инпуту. По изменению его значения, новое значение будет валидироваться, если оно целочисленное и не больше 120, записываем новое значение в cookie “when_to_notify”.
Но для того, чтобы у нас это заработало, надо открыть доступ к cookies. Для этого заходим в manifest.json и добавляем в “permissions”
manifest.json
Теперь можно приступать к скрипту. Заходим в popup.js. Для начала установим первоначальные значения в инпутах. По-умолчанию чекбокс не отмечен, то есть уведомления не показываются, а время равно 0. При клике на чекбокс, будет меняться значение cookie “show_notifications”. При изменении значения в тектовом поле, будет меняться значение cookie “when_to_notify”.
Рассмотрим подробнее функции. Начнем с функций работы с cookies. В данном случае были взяты готовые функции с w3schools.com.
Разберемся с функцией setCheckbox(). Она получает cookie “show_notifications” и проверяет, если полученное значение равно “true”(текстовое, да), то параметр checked у чекбокса true, иначе false.
Теперь рассмотрим setWhenToNotify(). Она принимает новое значение таймера. Если это значение – целочисленное и не больше 120 минут, то в cookie “when_to_notify” устанавливается новое значение. Если переменная не прошла эту валидацию, то в инпут возвращается предыдущее значение из cookies “when_to_notify”.
Перейдем к самим уведомлениям. Для этого откроем доступ к уведомлениям и подключим фоновый background.js. Нужно подключить именно фоновый файл, так как если уведомления вызывать из popup.js, то уведомления будут появляться только если открыто всплывающее окно.
manifest.json
Последняя строчка дает доступ к удаленному файлу. Дело в том, что картинка, которая отображается в уведомлении обязательно должна быть доступна расширению удаленно. В данном случае файл локальный, но доступ открывать все равно надо. Теперь возьмемся за background.js. Объявим переменную storage и пустой массив tasks. Далее раз в минуту скрипт будет получать список сегодняшних событий и получать из них список задач, которые должны произойти через указанное время. После этого для каждой такой задачи будет показано уведомление.
background.js
Функции getTodayTasks() и getCookie() взяты из popup.js. Так что начнем разбор с функции getNextTask(). Функция сравнивает текущее время и время события, если оно равно тому значению, которое хранится в cookie “when_to_notify”, то в массив next дописывается строка из времени события и его описания. После проверки всех событий возвращет массив next.
background.js
Функция show() показывает уведомление с заданным текстом.
background.js
Результатом работы этого скрипта будет такое вот уведомление: 
Послесловие
Как и обещано, в конце статьи у нас есть готовое расширение-органайзер для Google Chrome.
Теперь добавим расширение в Chrome Web Store. Загружать надо расширение, запакованное в .zip-архив. Для начала заходим в Web Store. Для этого заходим в хроме на вкладку “Приложения” и нажимаем кнопку “Web Strore”
Теперь заходим в меню. Для этого нажимаем шестиренку и открываем “Developer dashboard”
Нажимаем большую кнопку “Add new item”. После этого надо будет выбрать zip-архив с расширением нажать “upload”
Далее надо заполнить небольшую форму с описанием расширения. Теперь есть выбор либо сохранить расширение в черновил либо опубликовать. Просто так опубликовать его не получится так как регистрация в Web Store стоит 5 $. Плату за регистрацию надо платить один раз для аккаунта, а не для каждого расширения. После оплаты появляется позможность опубликовать расширение, но и тут надо быть готовым к тому, что его будут валидировать несколько дней.
Делаем своё расширение для браузера за 10 минут
В конце 2020 года мы делали проект со снежинками — писали специальный скрипт, который запускал падающий снег на сайтах. Если бы мы хотели сделать такой снег на любом своём сайте, это не составило бы труда: добавляешь скрипт в код страницы, и готово.
А вот на чужих сайтах была проблема. Скрипт нужно было вставлять через консоль. А если на сайте была настроена политика безопасности, которая запрещает запуск внешних скриптов, то магия не срабатывала.
Сегодня мы это исправим — сделаем расширение для браузера, которое может запускать любой скрипт на любой странице. Мы охватим принцип, на основе которого вы сможете сделать собственные расширения, в том числе намного более сложные.
Что такое расширение
Расширение для Chrome — это небольшая программа, которая выполняется внутри браузера и помогает расширить возможности сайтов. Сила расширения в том, что оно может выполняться прямо из меню браузера и не зависит от политик безопасности.
Примеры того, что может сделать расширение:
- Сохранить ваши пароли и другие личные данные,
- Выдрать из страницы скрытые данные (например, ссылку на скачивание музыки).
- Менять что-то на странице, например, отключать рекламу, переводить текст, удалять ненужное.
- Собирать статистику вашей работы в интернете.
- Подключаться к другим сервисам (почте, чатам, файлообменникам) и взаимодействовать с ними из браузера.
В этой статье
Мы сделаем самое простое расширение для браузера Chrome, которое позволит запускать скрипт со снежинками на любом сайте, независимо от настроенной политики безопасности. Для этого воспользуемся официальным руководством Google по созданию расширений.
Манифест
В каждом расширении для браузера должен быть манифест — документ, в котором написано:
- как называется расширение;
- к чему расширение может получить доступ;
- какие скрипты будут работать в фоне;
- как должна выглядеть иконка расширения;
- что показать или что выполнить, когда пользователь нажмёт на иконку расширения.
Манифест задаёт общие правила для всего расширения, поэтому манифест — единственный обязательный компонент. Можно обойтись без иконок и скриптов, но манифест обязательно должен быть.Каждый манифест хранится в файле manifest.json — создадим пустой файл с таким именем и напишем внутри такое:
<
«name»: «Запускаем снежинки на любом сайте»,
«description»: «Проект журнала Код»,
«version»: «1.0»,
«manifest_version»: 3
>
Первые две строчки — это название и подробное описание расширения. Третья отвечает за номер версии расширения, а последняя говорит браузеру, какая версия манифеста используется в описании. На момент выхода статьи в феврале 2021 года используется третья версия.
Сохраняем файл и всё, расширение готово. Оно ничего не умеет, ничего не делает, зато мы уже можем добавить его в браузер. Для этого запускаем Хром и в адресной строке пишем:
Мы попадаем на страницу, которая нам покажет все установленные расширения:

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

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

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

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

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

Настраиваем разрешения
Разрешения — это то, что браузер позволяет делать расширению со страницами и с их содержимым. Для запуска снежинок нам нужно сделать две вещи:
- Понять, какая вкладка сейчас активная, чтобы запустить снежинки именно на ней.
- Запустить наш скрипт со снежинками.
Чтобы получить доступ к активной вкладке и к запуску скриптов, добавим в манифест такую строку:
«permissions»: [«activeTab», «scripting»],
Показываем меню
Если мы сейчас нажмём на иконку расширения на панели браузера, то ничего не призойдёт, потому что мы ничего не запрограммировали. Исправим это — сделаем так, чтобы при нажатии расширение показывало кнопку запуска. Когда расширение будет уметь больше, вместо одной кнопки можно будет показать целое меню.
Чтобы сделать всплывающее меню, добавим в манифест в раздел action такую строку:
Она означает, что при нажатии на иконку мы увидим рядом с ней мини-страничку, на которой что-то будет.Создадим в той же папке расширения файл popup.html и добавим в него такой код:
Чтобы браузер не ругался, что у нас нет файла popup.js , создадим пустой файл с таким названием и положим его в ту же папку:

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

Запускаем снежинки
Вся магия будет происходить в файле popup.js — откроем его и добавим такой код:
Последнее, что нам осталось сделать, — положить в функцию snowFall() полный код скрипта из проекта со снежинками и сохранить файл.
Проверка
В прошлый раз мы не смогли запустить скрипт на любой странице Яндекса — мешала политика безопасности. Теперь всё работает:

Скачать упакованное расширение. Перед установкой его нужно распаковать в любую папку.
Как сделать расширение для браузера или первое расширение для Chrome
Google предоставляет подробную документацию о том, как сделать расширение для браузера Chrome. И помните, что браузерное расширения — это просто HTML, CSS и JavaScript. Вы можете добавлять библиотеки и фреймворки или разрабатывать код «старомодным» способом.
Настройка
Что нужно знать:
- Обратные вызовы;
- Таймауты;
- Инструменты разработчика Chrome.
При создании расширений под Chrome используется большое количество обратных вызовов. Поэтому перед началом я рекомендую освежить в памяти эту тему.

При создании расширения я не учла, что одновременно буду работать с тремя таймерами. И я сэкономила бы много времени, если бы уделила внимание их организации и ознакомлению с документацией.
Обратите внимание, что это руководство описывает только создание собственного пользовательского окна. Но не редактирование существующих окон или вкладок.
Документация
- Руководство Google по расширениям браузера .
- Руководство по началу работы .
- Обзор по расширениям Chrome .
Файл manifest.json предоставляет браузеру информацию о расширении. В том числе о том, где расположены файлы и иконки расширения, а также данные для доступа к API. Вот как выглядел мой файл manifest.json :

Изображение, которое описывает архитектуру расширения.

Файл background.js является обработчиком событий расширения. Он постоянно прослушивает события браузера, которые вы передаете через Chrome Extension API . Google говорит, что эффективный фоновый скрипт загружается только тогда, когда он необходим, и выгружается, когда простаивает.
Popup — это маленькое окно, которое появляется при клике по иконке расширения в меню Chrome. Оно состоит из разметки и скрипта. Вы можете указать браузеру, где его найти, в разделе manifest.json — page_action: < "default_popup": FILE_NAME_HERE >.
Страница параметров является именно тем, что ожидается. На ней отображаются настраиваемые параметры, выводимые пользователю, только когда он кликает правой кнопкой мыши в меню Chrome и выбирают пункт «Параметры» для расширения. Эта страница также состоит из разметки и скриптов. Вы можете указать браузеру, где ее найти, в разделе options_page: FILE_NAME_HERE файла manifest.json.
Content scripts — это крипты, которые будут взаимодействовать с любыми окнами или вкладками, открытыми пользователем. Они также будут взаимодействовать с вкладками и окнами, открытыми расширением.
Отладка
Перед началом не забудьте ознакомиться с руководством по отладке !
Как и в любом другом окне Chrome, в расширении вы можете использовать и встроенные инструменты разработчика.
Например, при тестировании расширения я получила ошибку “This request exceeds the MAX_WRITE_OPERATIONS_PER_HOUR quota”. Оказывается, существуют ограничения на синхронизацию хранимой информации .
Еще одна ошибка, которую я продолжала получать: “Alarm delay is less than minimum of 1 minutes. In released .crx, alarm “ ALARM_NAME_HERE” will fire in approximately 1 minutes” . Оказывается, есть минимальные интервалы времени для предупреждений .
Старые добрые console.log действительно могут помочь с обратными вызовами и прослушивателями!

Я добавила кучу «console.log», пытаясь убрать предупреждения.
Функционал Eye Rest
Что за расширение я создала? Оно позволяет отдохнуть глазам в течение двадцати секунд каждые двадцать минут.
Схема работы расширения:
- Если расширение работает,
- Если пользователь не нажал кнопку «Пауза» во всплывающем окне,
- Если счетчик во всплывающем окне достиг отметки 00:00, ТОГДА
- Открывается новое окно с HTML-таймером, И
- Начинается 20-секундный обратный отсчет в HTML-таймере, И
- Сбрасывается счетчик всплывающего окна на 20:00.
- Закрыть это окно и повторить цикл заново.
Звучит довольно просто, но эти таймеры запутали меня. Чтобы понять суть проблемы, посетите репозиторий GitHub для Eye Rest .
Теперь рассмотрим API, который я использовала для создания этого расширения.
Таймеры
Таймеры Chrome — это в основном setTimeout и setInterval. Для получения дополнительной информации, ознакомьтесь с документацией .
Одно интересное замечание о таймерах в Chrome — они работают постоянно. Так как освобождение ресурсов памяти реализовано здесь плохо. В этом я убедилась, когда использовала метод clearAll для удаления таймеров, созданных при предыдущих загрузках или установках расширения. Единственный способ решения данной проблемы – указывать уникальное имя таймера каждый раз, когда загружается расширение. А также сбрасывать другие таймеры без этого уникального имени.
Фоновые скрипты
В своем расширении Eye Rest используется два фоновых скрипта: прослушиватель событий и файл вспомогательных функций .
Я хотела, чтобы фоновый скрипт очищал все существующие таймеры, создавал новый таймер и добавлял оставшееся время до истечения таймера в локальное хранилище сразу после загрузки расширения.
Чтобы сделать функцию clearAndCreateAlarm доступной для фонового скрипта, я добавила первый элемент helpers.js в background> scripts в файле manifest.json.
Я также хотела, чтобы скрипт всплывающего окна делал то же самое, когда пользователь отключал функционал расширения. Чтобы сделать функцию доступной для всплывающего окна, я размещаю вспомогательный скрипт в HTML-файле вплывающего окна.
Другие API
Windows
Для создания окна таймера используется Windows API . Этот процесс инициируется фоновым скриптом . Я передаю timer.html , type, size, position и другие визуальные опции как параметр URL.
Хранилище
Чтобы передавать информацию между фоновым скриптом и скриптом всплывающего окна, используйте хранилище Chrome или локальное . Одним из преимуществ использования локального хранилища является отсутствие лимитов на операции записи.
Обратный отсчет должен изменяться каждую секунду. Он довольно сложный, и для этого нужно много записей. Вот почему я выбрала вариант локального хранилища. Вы можете увидеть, как я получаю и устанавливаю эти переменные в скриптах Background, Helper и Popup. Найдите в коде date, nextAlarmTime и isPaused.
Declarative Content
Declarative Content API позволяет вывести страницу расширения на основе несколько типов сопоставлений без необходимости получать права доступа к хосту Поэтому он нужен нам, чтобы расширение работало в браузере!
Я реализовала это в моем фоновом скрипте . Всплывающее окно расширения должно отображать на каждой просматриваемой странице в браузере.
Расширение

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

И вот как оно выглядит с новыми стилями.

А вот как выглядят окно таймера и всплывающее окно!
Публикация
Публикация расширения стандартизирована : архивируете файлы, создаете новую или используете существующую учетную запись Google Developer, загружаете файлы, добавляете некоторые данные и платите 5 долларов США. После этого ваше расширение будет доступно в магазине Chrome. Мое расширение теперь доступно для установки .
Заключение
Создание этого расширения Chrome стоило мне боли в плечах и уставших глаз. Но теперь Eye Rest может напоминать мне, что нужно делать перерыв каждые 20 минут.
Пожалуйста, оставьте ваши мнения по текущей теме статьи. За комментарии, отклики, подписки, лайки, дизлайки низкий вам поклон!
Дайте знать, что вы думаете по этой теме статьи в комментариях. За комментарии, отклики, лайки, дизлайки, подписки огромное вам спасибо!