Свернуть все папки

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

введите сюда описание изображения

HTML код кнопки открытой папки:

<button class="spoticon-chart-down-16 RootlistItemFolder__arrow RootlistItemFolder__arrow--is-rotated"></button>

HTML код кнопки закрытой папки:

<button class="spoticon-chart-down-16 RootlistItemFolder__arrow"></button>

К классам раскрытых папок всегда добавляется

RootlistItemFolder--is-expanded

Подскажите пожалуйста, как будет выглядеть код на JS, что бы все раскрытые папки свернулись?

P.S. Может быть поможет: Код, блокирующий вообще открытие папок.

    function waitForElement(els, func, timeout = 100) {
    const queries = els.map(el => document.querySelector(el));
    if (queries.every(a => a)) {
        func(queries);
    } else if (timeout > 0) {
        setTimeout(waitForElement, 300, els, func, --timeout);
    }
}

waitForElement([".LeftSidebar__section--rootlist .SidebarList__list"], ([sidebar]) => {
    function shrinkFolders() {
        for (item of sidebar.childNodes) {
            // Only folder item has this class so we don't have to filter by folder first
            if (!item.classList.contains("RootlistItemFolder--is-expanded")) {
                continue;
            }
            
            // Find "expand folder" button and click it to shrink folder
            const button = item.getElementsByTagName("button")[0];
            button.click();
            return;
        }
    }

    new MutationObserver(shrinkFolders)
        .observe(sidebar, {childList: true});
});

P.P.S. В комментариях предложили добавить побольше кода, но там его так много, что выходит каша (ну или я просто не умею правильно копировать HTML). Так что, наверное, лучше скриншотами.

Закрытой папки: введите сюда описание изображения

Открытой папки (всё, что после красной линии - уже вне папки):

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Alexander Lonberg

Можно написать в более читабельном виде с async

// Это оставляем для поиска всего блока
function waitForElement() {
  return new Promise((s) => {
    (function wait() {
      let queries = document.querySelector('.LeftSidebar__section--rootlist .SidebarList__list')
      queries ? s(queries) : setTimeout(wait, 300)
    })()
  })
}

// Запуск всего этого
void async function () {

  // Ждем нахождения всего блока
  const sidebar = await waitForElement()

  // Функция закрытия кнопок
  function shrinkFolders() {

    // [Вариант 1] 
    // Проходимся по всем элементам
    for (let item of sidebar.childNodes) {
      // Проверяем открыта ли папка
      if (!item.classList.contains("RootlistItemFolder--is-expanded")) {
        continue
      }
      // Если открыта и есть кнопка закрываем по одной кнопке
      (item = sidebar.querySelector('button')) && item.click()
      // !!! Вот здесь был указан "return", но при закрытии всех он не нужен
    }

    // [Вариант 2]
    // Смотрим все кнопки с классом + --is-rotated и сразу все закрываем
    // [...sidebar.querySelectorAll('.RootlistItemFolder__arrow--is-rotated')].forEach((e) =>  e.click())

  }
  shrinkFolders()

  // Отслеживание изменений - когда появились новые элементы
  new MutationObserver(shrinkFolders)
    .observe(sidebar, { childList: true })

}()
→ Ссылка