Автоматическая тёмная тема и для встроенных комментариев?

Я могу подтвердить, что описанный выше метод всё ещё работает, но было бы приятнее не вводить код вручную со скриншота :slight_smile: Вот он, с небольшими обновлениями:

Шаги

  1. iframe комментариев завершает рендеринг и отправляет сообщение в главное окно браузера, уведомляя об этом.
  2. Браузер запрашивает настройку тёмного/светлого режима и возвращает это значение в iframe.
  3. iframe получает сообщение и устанавливает data-атрибут, класс или аналогичный элемент в зависимости от настройки тёмного/светлого режима.

Код

  1. После загрузки iframe отправьте уведомление родительскому окну. Этот код нужно добавить на Discourse в разделе Admin -> Customize -> (выберите тему) -> Edit CSS/HTML -> Embedded Header.
<script type="text/javascript">
    window.addEventListener("load", (event) => {
        window.parent.postMessage("iframe loaded", "*");
    }, false);
</script>
  1. Обработайте этот входящий триггер в главном окне. Этот код размещается на вашем сайте блога:
<script type="text/javascript">
  const discourse_url = "https://your.discourse-instance.org";

  // Здесь мы определяем тему и отправляем сообщение в iframe, чтобы сообщить ей о выбранной теме
  // Ниже показано, как подключить notifyFrameStyle
  const notifyIFrameOfTheme = () => {
    const iframe = document.getElementById("discourse-embed-frame");
    if (iframe && iframe.contentWindow) {
      iframe.contentWindow.postMessage(
        {
          // Измените строку ниже, чтобы получить настройку тёмного режима в зависимости от способа её хранения
          theme: document.documentElement.getAttribute("data-theme")
        },
        discourse_url
      );
    }
  };

  // Вызываем setFrameStyle при получении сообщения "iframe loaded"
  const handleMessageListener = (event) => {
    var origin = event.origin;
    if ((origin === discourse_url) && (event.data == "iframe loaded")) {
      notifyIFrameOfTheme();
    }
  };
</script>
  1. В блоке <script> из шага (1) добавьте слушатель для сообщения о теме, отправленного notifyFrameStyle:
    window.addEventListener("message", (event) => {
        const payload = event.data;
        if (payload.theme) {
          // Выполните действие с настройкой темы; я устанавливаю атрибут `data-theme` на теге <html> внутри iframe,
          // но вы можете установить класс или аналогичный атрибут
          document.documentElement.setAttribute("data-theme", payload.theme);
        }
    }, false);

Стилизация

В разделе Admin -> Customize -> (выберите тему) -> Edit CSS/HTML -> Embedded CSS вы теперь можете предоставить CSS для каждого режима. Например, можно переопределить переменные стилей Discourse:

html[data-theme="dark"] {
  --primary: #ced6dd;
  --primary-low: #48566b;
  --secondary: #14181e;
  --tertiary: #2b7e8d;
}

Надеюсь, это поможет!

6 лайков