Как получить все названия классов на HTML-странице?
Мы хотим знать какие именно названия HTML-атрибутов class можно встретить в качестве его значений во всём документе. Как это сделать?
Решение
[...new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort())] или [...new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())]
Данное выражение вернёт нам сортированный массив из уникальных строк, которые являются значениями классов всех элементов в документе.
Как это работает?
Шаг № 1
Сначала мы обращаемся к объекту документа (document), который сформировался на нашей вкладке браузера, после получения строки с данными с сервера. Браузер синтаксически проанализировал строку с HTML-разметкой и при помощи «Объектной Модели Документа» создал для нас специальный JavaScript-объект, который хранит в себе все объекты HTML-элементов.
document
У этого объекта есть целый стандарт, который определяет множество методов и свойств для работы с этим объектом.
Скриншот главной страницы стандарта DOM от 19 декабря 2021 года:

Шаг № 2
Далее есть 2 пути получения всех объектов HTML-элементов:
- Из стандарта DOM мы можем использовать метод querySelectorAll()
- Из стандарта HTML мы можем использовать УСТАРЕВШИЙ атрибут all
Какой из них выбрать — решать вам. На 2022 год оба работают в браузерах.
Разница заключается в том, что в метод querySelectorAll() нужно передавать специальный CSS-селектор, который обозначается строкой со звёздочкой — «*«
document.querySelectorAll('*') или document.all
Второе важное отличие в том, какой объект мы получаем на выходе.
- querySelectorAll(‘*‘), то возвращается объект класса NodeList
- all, то возвращается объект класса HTMLAllCollection
Пример вызова на случайном документе:

Шаг № 3
Стандартные JavaScript-методы экземпляров класса Array не работают с NodeList и HTMLAllCollection. Это значит, что мы не сможем «пробегать» по объектам HTML-элементов и получать(извлекать) нужные нам данные. Нам нужна конвертация в массив для получения полного функционала для манипулирования с объектами HTML-элементов этого документа.
Делается это при помощи spread (…) оператора и литерального объявления массива []:
[...document.querySelectorAll('*')] или [...document.all]
Эти два выражения вернут нам стандартный массив языка JavaScript.

Шаг № 4
Теперь у нас открыта возможность «пробегания» по всем элементам массива для «выдёргивания» значений из нужных свойств объектов HTML-элементов.
Это умеет делать метод map(). Так как нас интересуют значения, которые лежат в классах HTML-элементов, то нам нужно обращаться к такому свойству, которое называется classList.
[...document.querySelectorAll('*')].map(i=>i.classList) или [...document.all].map(i=>i.classList)
Это свойство будет возвращать нам объекты класса DOMTokenList. По сути это те же самые массивы (смотри шаг № 3).

Обратите внимание, что некоторые объекты DOMTokenList будут пустыми. Это нормально т. к. не все HTML-элементы могут иметь свои классы.
Шаг № 5
Нам снова нужна конвертация в массив из объектов DOMTokenList. То есть нам нужно уже сразу возвращать массивы, на каждой итерации функции обратного вызова метода map().
[...document.querySelectorAll('*')].map(i=>[...i.classList]) или [...document.all].map(i=>[...i.classList])

Теперь у нас есть самая удобная структура — массив состоящий только из массивов.
Шаг № 6
Выпаковывание содержимого всех внутренних массивов на один уровень главного массива. Выполнить эту задачу способен метод flat(), который может принять в себя число положительной бесконечности — Infinity. Бесконечность даёт гарантию максимального погружения в глубину массива. До самого дна, если это потребуется.
[...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity) или [...document.all].map(i=>[...i.classList]).flat(Infinity)
Мы получим все названия классов в строковом виде, которые встречаются в текущем документе. Причём некоторые будут повторяться т.к. разные HTML-элементы могут содержать одинаковые значения классов.

Шаг № 7
Сортировка результатов для удобного восприятия итогового массива (и его возможного вывода в графическое представление).
[...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort() или [...document.all].map(i=>[...i.classList]).flat(Infinity).sort()

Шаг № 8
На этом шаге нам нужно избавиться от дублей, чтобы получить только уникальные строковые значения из массива JavaScript. В этом нам поможет конструктор класса Set, который стандартно заложен в ГЛОБАЛЬНОМ объекте языка.
new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort()) или new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())
Нам вернётся объект — экземпляр класса Set.

Шаг № 9
Финальным шагом будет конвертация объекта Set в Array.
[...new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort())] или [...new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())]

Итог
Теперь можно анализировать этот массив для дальнейших манипуляций с кодом своей собственной программы.
Информационные ссылки
JavaScript | Есть ли HTML-класс в DOM-документе?
HTML | Интерфейс HTMLAllCollection
Стандарт HTML — Раздел «2.6.2.1 The HTMLAllCollection interface» — https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlallcollection-interface