Как открыть 1000 вкладок
Перейти к содержимому

Как открыть 1000 вкладок

  • автор:

Бесконечное количество вкладок как в Firefox

de4be046-2d95-45ea-8e4b-b57e1382a479-image.png

Хотелось увидеть бесконечное количество вкладок и возможности:

  1. настройки ширины вкладки
  2. прокручивать вкладки влево/вправо при помощи колёсика мышки

Подобное уже реализовано в CentBrowser, но хотелось бы увидеть у вас.

kurai Moderator @vivald1pro
отредактировано

@vivald1pro Сейчас есть какое-то ограничение? Просто никогда не задумывался о таком и даже не пробовал проверить.

Found a bug? Submit bugreport!
Знайшов баґ? Зроби баґрепорт!
Нашёл баг? Отправь багрепорт!
https://vivaldi.com/bugreport/

Nikolay68 @vivald1pro
отредактировано

@vivald1pro, бесконечность — понятие растяжимое. Бесконечное количество вкладок — это примерно сколько?

vivald1pro @Nikolay68
отредактировано

@vivald1pro, бесконечность — понятие растяжимое. Бесконечное количество вкладок — это примерно сколько?

@vivald1pro Сейчас есть какое-то ограничение? Просто никогда не задумывался о таком и даже не пробовал проверить.

тут скорее прокрутка вкладок в лево и в право, а не все вкладки стараются уместится в определённую ширину

kurai Moderator @vivald1pro
отредактировано

тут скорее прокрутка вкладок в лево и в право, а не все вкладки стараются уместится в определённую ширину

Вы имеете в виду, что при достижении максимального количества, которое умещается в экран, вкладки не должны уменьшаться, а должны появляться кнопки прокрутки, как в Total Commander?

Found a bug? Submit bugreport!
Знайшов баґ? Зроби баґрепорт!
Нашёл баг? Отправь багрепорт!
https://vivaldi.com/bugreport/

vivald1pro @kurai
отредактировано vivald1pro

de005d2e-befa-4ff2-b72b-b1410a17c25c-image.png

@kurai
Видео работы множества вкладок, на примере CentBrowser https://yadi.sk/i/dSOiyJ33JA1ksQ
Подобный функционал есть и у Firefox

kurai Moderator @vivald1pro
отредактировано kurai

Видео работы множества вкладок, на примере CentBrowser

Прокручивание колёсиком мыши над панелью вкладок есть в Вивальди.
Меню / Настройки / Вкладки / Группа настроек «Возможности вкладок» / Блок «Переход между вкладками» / Галка «Переключать вкладки прокруткой»

Found a bug? Submit bugreport!
Знайшов баґ? Зроби баґрепорт!
Нашёл баг? Отправь багрепорт!
https://vivaldi.com/bugreport/

vivald1pro @kurai
отредактировано vivald1pro

  1. минимальная ширина вкладки задаётся в настройках
  2. если вкладки не помещаются в окно, то они как бы прячутся слева или справа, как в Firefox и CentBrowser (видео)
  3. навигация (просто прокрутка, а не переключение вкладки колёсиком мыши) по скрытым вкладкам колёсиком мышки (centbrowser), либо как в firefox 2 кнопками слева и справа (на скриншоте)

23e9368d-2fcf-485e-bedf-f25eff57cdb0-image.png

Сейчас всё это выглядит примерно так и открыть ещё 100 вкладок, приведёт к полной неразберихе

Asyl @vivald1pro
отредактировано

@vivald1pro никогда не возникала необходимость открывать много вкладок, но посмотрел на бесконечновкладчатость в центбраузе — да, удобно. Со здешним эскизным видом оно даже лучше будет.

Shpankov Vivaldi Team
отредактировано

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

vivald1pro
отредактировано

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

когда стоит ожидать?
Shpankov Vivaldi Team @vivald1pro
отредактировано

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

когда стоит ожидать? Скоро.
TheDoctorChannel
отредактировано TheDoctorChannel

Господи, чёртовы извращенцы многовкладчики. Вам для этого уже и так дали группы вкладок
51d9f89e-da9c-491f-8033-17a72498d391-image.png
И дали сессии, чтобы можно было отложить что то на потом и вернуться к этому в том виде в котором оно было оставлено
8c1345b1-b560-46e4-9f08-7d0fc706673d-image.png
Нет им ещё нужно всякого барахла напихать в браузер. Пусть разработчики работают над реально недостающими вещами.
Хотя под минимальным размером вкладки подписываюсь, но чтобы этот размер сохранялся в нескольких вкладках до и после активной вкладки, а остальные уменьшали свой размер, как минимум это было бы довольно стильно.

vivald1pro @TheDoctorChannel
отредактировано vivald1pro

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

Много ли у вас открытых вкладок?

У меня в браузере обычно — от 50 до 120. Иногда — 200, в другой раз — 15.

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

Это радикально упростило поиск и чтение статей. И даже волосы мои стали шелковистей. Ну т.е. стал продуктивней.

Откуда берется столько вкладок?

В основном они появляются из Inoreader, иногда из соц-сетей и других ресурсов.
Новые публикации просматриваю раз в неделю-две или реже. Что-то остается открытым, что-то отправляется на потом, но чаще остается открытым.

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

Кроме того, читать сразу несколько статей по одной тематике намного легче, чем каждую статью по отдельности.

Что делает расширение?

Демо-видео вместо тысячи слов.

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

Чтобы вообще найти содержание страницы, используется адаптация Readability.js. Это версия библиотеки, которую Mozilla использует в Firefox, для показа страниц в режиме читателя.

К сожалению, Readability.js далеко не всегда находит содержание страниц. Поэтому для особо популярных ресурсов сделана отдельная предобработка.

Сейчас здесь: Reddit, HackerNews и YouTube.

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

Также есть отдельные ресурсы, страницы которых сортируются только по URL, если таких — больше одной. Это страницы GitHub и GitLab. Т.о. вы получите группировку в соответствии с файловой структурой проектов.

Сделано специально для umputun. Ну почти.

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

В одном случае, это были две статьи, которые совместно подсказали новую идею. Тематика у них была разная, но были общие ключевые слова, поэтому Smart TabS разместил их рядом.

В другом случае, это был браузер для рабочих вопросов. После некоторых подсказок Smart TabS разместил вкладки намного удачней, чем я ожидал, так что работать стало намного проще.

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

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

Например, веб-приложения, почта, соц-сети. По умолчанию, сейчас сюда входят: Facebook, Netflix, Trello, Todoist, Inoreader, Feedly, Gmail и др. сервисы Google.

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

Поддержка браузерами

Расширение сейчас можно поставить для Firefox и Chrome.

Для Safari оно пока не доступно, не смотря на появление WebExtension API в 14-й версии. Там почему-то не добавили поддержку tabs.move(. ), чтобы можно было автоматически перемещать вкладки.

Другие браузеры особе не проверялись, хотя, по идее, для Chromium-based браузеров может быть возможность поставить пакет для Chrome.

P.S.

В этом посте я хотел сосредоточиться на проблеме и ее решении с помощью Smart TabS, так сказать, на публичной стороне вопроса.

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

Как я избавился от тысячи вкладок…

… и опоздал на 3 года. В идеале должно быть так: пользователь запускает браузер, и браузер показывает то, что нужно пользователю. Но пока такого не реализовали приходится пользоваться поисковыми системами. В идеале должно быть так: пользователь открывает поисковую систему, вводит поисковый запрос, и она показывает то, что нужно пользователю. Но пока кнопка «I feel lucky» не так хорошо работает (хотя в последнее время ощутимо движение в этом направлении), приходится иногда переходить по нескольким адресам со страницы поисковой выдачи.

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

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

Мне всегда нужна была кнопка «Нашел», которая бы подчищала за мной последствия поиска (назовём её «I was lucky»). После того, как окунулся в мир расширений для браузеров, я подумал, что это то, что может помочь в данном случае. Так смутно начало появляться желание написать расширение, которое бы решало мои задачи.

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

Первый шаг на пути

Первым делом взялся за настройку инфраструктуры: webpack + babel. И сразу же мне не понравилось, что babel дублировал в каждом модуле код для своих хелперов. Можно было настроить, чтобы он использовал объект babelHelper , но тогда файл с кодом babelHelper нужно было подключать в конфигурации webpack. Хранить такой файл в проекте и указывать его в entry было некрасиво, я сделал плагин для вебпака, который выполнял это за меня автоматически. Потратив много сил на первый шаг и написав ещё немного кода для самого расширения, я немного притормозил.

Плагин
webpack-babel-external-helpers-2:
www.npmjs.com/package/webpack-babel-external-helpers-2

Фундамент

Время шло, а в наличии был только плагин для вебпака, который никак не решал моих задач. И каждый раз, когда я что-то искал и не закрывал вкладки, была мысль: «Хорошо бы доделать то расширение. » Желание росло и росло, и вот, в один прекрасный день, количество переросло в качество.

Самое время рассказать, в чем была основная идея:
Пользователь попадает на страницу поисковой выдачи — СЕРП , мы парсим выдачу, сохраняем себе адреса ссылок, после того, как пользователь перешел по одному из адресов, показываем ему уведомление с остальными адресами и кнопкой «Нашел», чтобы закрыть вкладки.

При переходе на страницу могут быть различные варианты. Самый простой: один запрос — один ответ от сервера (200). Самый сложный: один запрос — несколько серверных перенаправлений (3xx), после чего клиентское перенаправление (с помощью или javascript), сверху ещё и history API. И комбинации между ними, как правило, большинство сайтов попадает в эту категорию.

Простой случай перехода:

Случай простого перехода (ответ 200)

Сложный случай перехода:

Случай сложного перехода (3xx + клиентские перенаправления)

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

В Хроме есть два API, связанных с навигацией: webNavigation и webRequest — каждый со своими событиями. Первый — связывает переходы и UI браузера, последний — нижележащие сетевые запросы. Поэтому, если изменение адреса на странице произошло за счет history API, не будет никаких событий у последнего, а если во время сетевого запроса происходят перенаправления, то первый об этом никак не сообщает. Следовательно, нужно использовать оба АПИ, собирая по щепотке от каждого события каждого АПИ, формировать один логический Переход.

Немного деталей

Как указано в документации, события для webNavigation (wN) выполняются в следующем порядке:

onBeforeNavigate -> onCommitted -> onDOMContentLoaded -> onCompleted 

Интересующие события webRequest (wR):

onBeforeRequest -> [onBeforeRedirect -> onBeforeRequest]* -> onCompleted | onErrorOccurred 

Но между собой события wR и wN не имеют определенного порядка (на аналогичных стадиях запроса), т.е. в каких-то случаях wN.onBeforeNavigate может выполниться раньше wR.onBeforeRequest , в каких-то наоборот. Что немного усложняет логику работы.

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

Развитие

… Вернемся к моменту, когда количество переросло в качество. С начала разработки до этого момента прошло существенное количество времени: браузеры стали поддерживать es6 модули, shadow DOM и другие современные фичи. Для сборки проект переехал на Rollup, плагин в этот раз писать не пришлось. После постройки фундамента — возможности получения информации о любом переходе в любой вкладке, осталось реализовать логику парсинга поддерживаемых СЕРПов и показа уведомлений на связанных страницах.

Первая задача достаточно примитивная: знаем адрес СЕРПа, лезем в содержимое страницы с помощью контент скрипта, получаем интересующие нас данные, сохраняем, ждем, когда пользователь перейдет на одну из страниц, чтобы показать ему уведомление с остальными страницами.

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

Изначально был только один обработчик (он же контроллер), отвечающий за логику при взаимодействии пользователя с поисковыми системами. После чего возникла идея почему бы не показывать уведомления на связанных вкладках, когда пользователь просто переходит по ссылкам, открываемых в новых вкладках. Пришлось переделать логику, сделав ее более универсальной. По аналогии с middleware React/Redux, можно подключать несколько обработчиков Переходов, что в будущем позволит реализовать возможность отключения/включения различных обработчиков в настройках расширения.

Приватность

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

На помощь приходит технология под названием shadow DOM. В вебе не рекомендуется использовать closed mode при создании shadowRoot , потому что в этом нет большого смысла (все равно придется хранить ссылку на элемент shadowRoot где-нибудь, если хочется иметь к нему доступ программно; так же можно переопределить функцию attachShadow , чтобы она создавала shadowRoot в открытом режиме, и тогда скрипты подгруженные после переопределения уже будут пользоваться новой версией функции).

В случае же расширения это не так. Контент скрипты и скрипты страницы живут в параллельных мирах. Скрипты со страницы не имеют доступ к объектам, определенным в контент скриптах, контент скрипты же оперируют с нативной реализацией функций DOM объектов (переопределенная функция скриптом со страницы не имеет эффекта на функцию, с которой работает контент скрипт). Соединяя эти два условия, получаем, что можно создать элемент с закрытым shadowRoot , сохранив ссылку на него в переменной.

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

Трудности перевода

Изначально расширение разрабатывалось только для Google Chrome, но так как WebExtensions API, где-то в голове держал возможность портирования в другие браузеры. А наличие webextension-polyfill вселяло уверенность. Но как бы не так. Полифил для этого расширения принес только возможность использования chrome API с промисами.

Firefox стал разочарованием года. Несоответствие chrome API в Фаерфоксе (Bug 1543647, Bug 1595621) оказалось критичным для работоспособности расширения, можно сказать оно в этом браузере не работает (как положено).

Vivaldi был наиболее близок, но также не обошлось. Событие wN.onCreatedNavigationTarget не возникает, когда пользователь открывает ссылку средней кнопкой мыши или через Shift|Ctrl + левая кнопка мыши, вместо этого в событии wN.onCommitted transitionType == ‘start_page’ , чего нет в chrome API, из-за этого не во всех случаях расширение работает правильно. Так же в Вивальди не работают горячие клавиши для расширений. Что является киллер-фичей в данном случае в Хроме, позволяет намного быстрее переходить по вкладкам и закрывать их, без необходимости использования для этого мышки.

Заключение

В ходе написания кода логика работы показа уведомлений менялась несколько раз, каждый раз упрощаясь. В итоге получилось так, что можно было не городить огород с логическими Переходами, а отлавливать «связанные переходы» пользователя (в событии wN.onCommitted есть флаг transitionType , который указывает из-за чего был переход, во многих случаях он равен «link», означающее что пользователь перешел по ссылке), что значительно бы упростило код и работало во многих случаях, но не во всех.

Так же, не находясь в теме, ожидал большей совместимости с точки зрения webExtensions API. Как всегда — хорошо жить в мире современных браузеров, когда не нужна поддержка старых версий. CSS анимации прекрасная вещь: то, для чего раньше нужно было использовать js библиотеку, теперь делается в несколько строк на css. В расширениях не работают Custom elements, зато работает shadow DOM, позволяющий воспользоваться всеми его возможностями.

Все в порядке, но.

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

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

Если это ваш частный компьютер и вы пытаетесь зайти на сайт, например, из дома — мы рекомендуем вам проверить ваш компьютер на наличие вирусов.

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

  • © 2005-2023, «4PDA». 4PDA® — зарегистрированный товарный знак.

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

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