Гнев, торг, принятие. Добавляем GIF в блок комментариев DTF. Часть 1
Hello World! Вот и первая часть дневника разработки расширения для Chrome, которое (если я его не заброшу) добавит интеграцию GIPHY в комментарии DTF.
Сразу хочу отметить:
- Я не разработчик, мой изначальный стек: Hadoop, Hive, PL\SQL, Python, Spark.
- JavaScript для меня новинка и по сути, я учу его по ходу пьесы. Выручает меня лишь понимание принципов программирования.
- Всё делается на чистом энтузиазме и желании прокачать свои умения. Можно считать это исследовательской работой.
День 1. Что ты блин такое Chrome Extension
Для понимания всего происходящего я буду приводить некоторые теоретические моменты в формате — на пальцах.
Глобально расширения в их текущей Manifest V3 реализации состоят из двух частей.
Background Workers — то, что работает в фоне расширения и имеет доступ только к API браузера, т.е. к физической программе. Background Workers не может обращаться к элементам страницы, но может отслеживать действия в самом браузере: изменение вкладки, изменение ссылки, изменение истории, отправка запросов и тд. или же вызывать Content Script.
Content Script — вторая часть, то, что как раз уже может взаимодействовать со страницей, изменять элементы, атрибуты, классы и тд. То есть взаимодействовать с тем, что пользователь видит на сайте.
Покурив документацию поздно вечером, я подумал, что утро вечера мудренее и отправился в День 2.
День 2. С чего начать?
Первым делом было решено озаботиться добавлением кнопки GIF для вызова функционала расширения. Концептуально и на практике выглядит кнопка вот так:
Сразу же стало понятно, что каким-то образом надо впилить кусок вёрстки в элемент формы написания комментария. Но как?
Документация сходу предлагает вариант с использованием такой штуки, как MutationObserver. MutationObserver — интерфейс веб API, который проще говоря позволяет отслеживать изменения каких-то элементов на странице. MutationObserver вызывается в Content Script части, смотрит на определённый элемент страницы и если что-то поменялось, то триггерит какое-то действие.
Я уж было обрадовался, что всё будет просто, но нет, не будет.
И тут я столкнулся с тем, как внутри устроен сам DTF…
День 3-6. Гнев, отрицание, торг, принятие
Думаю не секрет, что DTF не перезагружает всю вкладку целиком при открытии поста, а по сути просто обновляет контент в уже собранных элементах страницы. Стильно, модно, молодёжно, современное по сути веб приложение.
Из этого появилась первая проблема. К чему привязать MutationObserver? Трекать всё тело страницы на изменения не очень то и хотелось, плюс в ходе экспериментов, я просто заваливал Observer в бесконечный цикл, что приводило к перегрузке по памяти. Плюс есть естественные ограничения MutationObserver, ты не можешь наблюдать за всем, что тебе хочется.
А искомый элемент в виде блока комментариев появляется только, если структура сайта пересоберётся под вид открытого поста. Что не мало важно, ещё надо как-то отслеживать переход между постами и не забывать отрисовывать кнопку.
И самый важный момент, MutationObserver возвращает достаточно большой набор мутаций при их обнаружении (т.к. точкой наблюдения является так называемая нода — набор элементов страницы), а значит выполняет что-то на каждый элемент из этого набора, что приводит к дублированию Content Script.
На этом моменте шёл примерно 5-ый день моих изысканий, ничего не получалось и единственная эмоция была вот такой:
Все потуги с MutationObserver не приводили к успеху и знатно бухнув пельменей я решил, что пора курить Background Workers.
День 7. Лучик света в топях Мории
Пельмени сделали своё дело и в какой-то момент меня посетила мысль.
А что если отслеживать физическое изменение ссылки в окне браузера. Ведь это значит, что пользователь как-то взаимодействовал с сайтом.
Продумано, сделано. Так родился Background Workers, который выполняет след. набор действий:
- В фоне отслеживает любое изменение вкладки браузера. Расширение ограничено на работу только с доменном dtf. ru
- Если во вкладке происходит изменение URL в пространстве имён dtf. ru, то формируется запрос к внутреннему API браузера со след. содержимым: изменившийся url и статус его загрузки (он меняется от loading до complete)
- Если такое событие на вкладке произошло, то мы сразу же отправляем данные о состоянии страницы в наш Content Script, который может взаимодействовать с телом страницы.
Тем самым, получилось убить 1 проблему, как трекать какое-то изменение не привязываясь, к изменениям на самой странице (которые могут нам только помешать)
День 8. Наконец-то пилим кнопку
Теперь, когда есть информация о том, что на вкладке сменился URL логичным выглядит для начала сделать проверку: А есть ли вообще элемент с блоком комментариев на странице? Если нет, то просто скипаем и ничего не делаем, а вот если этот блок есть, то наша задача впилить в него новую кнопку.
Обработка ситуации, когда нужного блока нет до ужаса простая, всеми любимая конструкция if else в помощь.
Но как только нужный нам блок на страничке находится, я предпочёл просто вызывать функцию, которая соберёт нам новый кусочек элемента страницы.
Огонь, я научился рисовать или не рисовать кнопку на каждой страничке сайта.
Осталось добавить действие. В JS есть прекрасная вещь как addEventListener. Она позволяет запустить какую либо функцию на какое-то действие с элементом. Т.к. у нас кнопка, то и действие очевидно — click.
По click кнопка срабатывает и на текущий момент открывает GIF заглушку. На этом месте в дальнейшем, должен открыться API GIPHY и после выбора гифки вставлять её в тело сообщения комментария.
Но это будет только в будущем …
Демонстрация работы на текущий момент (есть пока не закрытая проблема с ожидаем дозагрузки страницы, поэтому на отрисовку кнопки выставлен таймаут в 5 секунд, ну тупо ждём пока страница дособерётся)
И помните, что я не разработчик: )