Auto Dark Mode for Reddit

Works for desktop

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Auto Dark Mode for Reddit
// @namespace    https://bengrant.dev
// @version      0.3
// @description  Works for desktop
// @author       Avi (https://avi12.com)
// @copyright    2025 Avi (https://avi12.com)
// @license      MIT
// @match        https://www.reddit.com/*
// @icon         https://www.google.com/s2/favicons?domain=reddit.com
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  /**
   * @returns {HTMLButtonElement}
   */
  const getElButtonProfile = () => document.querySelector("button#expand-user-drawer-button");

  // noinspection CssInvalidHtmlTagReference
  /**
   * @returns {HTMLElement}
   */
  const getElDarkToggle = () => document.querySelector("#darkmode-list-item faceplate-switch-input");

  const OBSERVER_OPTIONS = {childList: true, subtree: true};

  function openProfileDrawerAndToggleTheme() {
    const {activeElement} = document;
    const elButtonProfile = getElButtonProfile();
    new MutationObserver((_, observer) => {
      const elDarkToggle = getElDarkToggle();
      if (!elDarkToggle) {
        return;
      }
      const {shadowRoot} = elDarkToggle;
      if (!shadowRoot) {
        return;
      }
      const elDarkToggleInput = shadowRoot.querySelector("input");
      if (!elDarkToggleInput) {
        return;
      }
      observer.disconnect();
      requestAnimationFrame(() => {
        elDarkToggle.click();
        elButtonProfile.click();
        activeElement.focus();
      });
    }).observe(document, OBSERVER_OPTIONS);
    elButtonProfile.click();
  }

  const darkQuery = matchMedia("(prefers-color-scheme: dark)");
  new MutationObserver((_, observer) => {
    if (!getElButtonProfile()) {
      return;
    }

    const themeNew = darkQuery.matches ? "dark" : "light";
    const themeCurrent = document.cookie.match(/theme=([12])/)[1] === "1" ? "light" : "dark";
    const isChangeTheme = themeNew !== themeCurrent;
    observer.disconnect();
    if (!isChangeTheme) {
      return;
    }

    openProfileDrawerAndToggleTheme();
  }).observe(document, OBSERVER_OPTIONS);

  darkQuery.addEventListener("change", () => {
    const elDarkToggle = getElDarkToggle();
    if (elDarkToggle) {
      const {activeElement} = document;
      elDarkToggle.click();
      activeElement.focus();
      return;
    }

    openProfileDrawerAndToggleTheme();
  });
})();