Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Это расширение я написал для себя, столкнувшись с проблемой отсутствия подобной функциональности искаропки. Но тем не менее, считаю, что оно могло бы быть полезным не только мне лично. Желающих подробностей прошу под кат.
С чего вообще возникла эта идея?
Достаточно значительную часть своего времени я провожу в различных соцсетях. Нет, у меня еще осталась личная жизнь (С Саус Парк), но при этом я зарегистрирован и состою во многих форумах, сетях, группах, чатах и т.п. — где по необходимости, а где из-за хобби и для досуга / развлечения. В каждой группе присутствует свой состав участников, и в процессе взаимодействия формируется различное отношение к ним — кого-то хочется добавить в друзья, а кого-то в игнор. При этом интерфейсы различных соцсетей предлагают разный набор возможностей и средств для этого — многие форумы не показывают содержание постов пользователей из черного списка, но показывают их наличие и ответы на них, Телеграм вообще не имеет никаких подобных возможностей, а тот же ВКонтакте позволяет добавить пользователей как в друзья так и в черный список, но логика работы этой функциональности лично меня не устроила.
Далее продолжу применительно к сети ВКонтакте, потому что именно с ней у меня остро возникла необходимость что-то делать. При добавлении пользователя в черный список, блокируется возможность данному пользователю отправлять вам личные сообщения. И, насколько я знаю, это всё. Посты пользователя так же видны во всех группах, на всех страницах, во всех тредах и комментариях, списках лайков и т.п. Более того, визуально этот пользователь никак не отличается от остальных (впрочем, как и пользователи, которые у вас в друзьях). В результате нередко в токсичные группы неприятно заходить, поскольку приходится выискивать нужную и конструктивную информацию среди спама и агрессивных сообщений.
Анализируя различные варианты того, что я могу сделать с этой ситуацией (в конце концов, яжпрограммист), я остановился на идее создания расширения для Chrome.
Во-первых, потому что я редко использую отдельные специализированные приложения для чего-либо, когда есть альтернатива в виде веб-интерфейса. Все эти ваши Зумы, ВКонтакте, Точки/Тиньковы и прочие, имя им легион, я открываю через браузер. В том числе и потому, что я не настолько активно пользуюсь смартфоном, а больше десктопом — с удобным большим монитором, хорошей клавиатурой и мышью. А устанавливать отдельные приложения для каждой ерунды считаю излишним, только Телеграм у меня удостоился этой чести.
И во-вторых, альтернативные варианты типа анализа и фильтрации входящего траффика на низком уровне и прочая подобная жесть показалась мне слишком несоразмерной изначальной задаче. А вот идея с браузерным расширением выглядела как то, что надо. Не взирая на то, что я до этого вообще не имел дела с браузерным апи и вообще ни разу не джаваскриптер и даже не фронтендер.
В результате через несколько дней у меня уже было рабочее расширение, полностью решающее мою задачу. Позволю себе упомянуть некоторые технические моменты, возникшие в процессе реализации, и методы их решения. Поанализировав код html страниц, которые отдает ВКонтакте, я выявил критерии, по которым определенные элементы можно отнести к типу «проверяемых на возможное изменение отображения» — это посты, ответы, объявления, элементы списка поставивших лайки и т.п. Часть из этих элементов имела говорящие сами за себя уникальные айдишники типа
post_1213312431...
другая часть не имела айдишников вообще, зато имела достаточный набор css классов, по которому можно было однозначно идентифицировать эти элементы. Далее, через рекурсивный обход дерева подчиненных элементов в глубину находится первый элемент, содержащий аватар и ссылку на страницу пользователя, содержащую его уникальный айдишник. После этого анализируется, присутствует ли данный айдишник в черном списке, и если да, то ко всему родительскому элементу применяется любое желаемое стилевое оформление — например, в стартовом скрине КПДВ выбрано
opacity = 0.15
исключительно для большей наглядности, в рабочем варианте у меня стоит
display = 'none'
.Далее надо реализовать интерфейс добавления пользователей в черный список. Выше я упомянул как ищется аватарка пользователя с его айдишником, так вот когда элемент аватарки найден, он стилистически оформляется как кнопка (добавляются фон и границы) и вешается листенер на событие клика по нему. Тут надо упомянуть, что код расширения и код страницы выполняются в разных окружениях, и между собой имеют только достаточно ограниченные варианты взаимодействия (посылка сообщений и т.п.), но доступ к DOM элементам страницы как на чтение так и на запись у расширения есть, поэтому можно легко подменять/назначать свои обработчики событий дополнительно или вместо тех, которые назначены кодом страницы. Подозреваю, что можно сделать более вариантивно, и показывать выпадающий список с действиями по клику на аватар — пререйти настраницу пользователя, добавить его в ЧС или что-то еще, но я выбрал простой вариант — по клику на аватар пользователь сразу добавляется в ЧС :) Если надо перейти на страницу — почти везде рядом с аватарами присутствую текстовые имена-ники пользователей, которые работают как ссылки на их страницы, поэтому никаких ограничений интерфейса не возникает.
Вот скрин того, как это выглядит визуально (при выделении прозрачностью):
Хранение черного списка для простоты реализовано в Local storage, но очевидно, что это вопрос непринципиальный — можно хоть в Global storage хранить, хоть вообще на своем сервере с апи по добавлению/проверке айдишника пользователя.
Ну и на закуску — страница ВКонтакте динамическая, обновляется по вебсокету в том числе без каких-либо активных действий пользователя. Но тут нам на помощь приходит волшебный объект
MutationObserver
, который автоматически следит за любыми назначенными изменениями страницы и даже предоставляет список добавленных элементов addedNodes
. Итого, для расширения достаточно запустить код фильтрации всего контента при загрузке страницы (настраивается в манифесте во время какого события жизненного цикла запускать код) и далее отрабатывать его на всех добавленных элементах, которые любезно предоставит нам MutationObserver
.Вот и всё. Весь кот расширения — один файл в 100 строк. Дешево, сердито и практично! Пользователь, единожды добавленный в черный список, не показывается больше вообще нигде — в любой группе, любом посте, ответе, личных сообщениях, списке поставивших лайки и т.п. где он появляется, расширение тут же назначает ему
display = 'none'
. И жить становится легче и приятней :)ЗЫ: кот проекта лежит на отечетсвенном аналоге гитхаба — gitflic.ru/project/ivana/vk-filter потому что сейчас такое дело, что гитхаб/гитлаб в любое время может превратиться в тыкву, да и ВКонтакте тоже отечественный сервис, так что все сходится :) Только проект с кодом не имеет публичный доступ — эта функцинальность пока закрыта для использования на gitflic. Если подскажете удобный отечественный аналог гитхаба с публичными проектами, то возможно перенесу туда. Но выж тоже программисты, а там всего 100 строк кода, и выше имхо я более чем подробно расписал его работу, можете легко реализовать сами при желании :)
ЗЗЫ: оставляйте ваш ценный фидбек в комментах, критикуйте. Только вы же поняли, что в описанной выше логике работы расширения я нигде не опирался на апи ВКонтакте (хоть и выбрал его в списке хабов, потому что имхо очень близкая тема), поэтому его очень легко расширить и на Телеграм, и на… в общем, на всё :)