هل يدعم الوضع المظلم التلقائي للتعليقات المضمنة أيضاً؟

I can confirm that the above method still works, but it’d have been nice not to have had to type in code from a screenshot :slight_smile: So, here it is, slightly updated:

Steps

  1. The comments iframe finishes rendering and sends a message to the main browser window, telling it so.
  2. The browser queries its dark/light mode setting and sends back the value into the iframe.
  3. The iframe receives the message, and sets a data-attribute, class, or similar, based on the dark/light mode setting.

Code

  1. Once iframe is loaded, send a notification to the parent window. This needs to be entered on Discourse, under Admin -> Customize -> (select theme) -> Edit CSS/HTML -> Embedded Header.
<script type="text/javascript">
    window.addEventListener("load", (event) => {
        window.parent.postMessage("iframe loaded", "*");
    }, false);
</script>
  1. Handle this incoming trigger in the main window. This code lives in your blog site:
<script type="text/javascript">
  const discourse_url = "https://your.discourse-instance.org";

  // Here, we determine the theme, and send a message to the iframe to let it know what the theme is
  // See below for how we hook up notifyFrameStyle 
  const notifyIFrameOfTheme = () => {
    const iframe = document.getElementById("discourse-embed-frame");
    if (iframe && iframe.contentWindow) {
      iframe.contentWindow.postMessage(
        {
          // Modify the line below to grab dark mode setting, depending on how you store it
          theme: document.documentElement.getAttribute("data-theme")
        },
        discourse_url
      );
    }
  };

  // Call setFrameStyle when we receive the "iframe loaded" message
  const handleMessageListener = (event) => {
    var origin = event.origin;
    if ((origin === discourse_url) && (event.data == "iframe loaded")) {
      notifyIFrameOfTheme();
    }
  };
</script>
  1. In the <script> block from (1), add a listener for the theme message sent by notifyFrameStyle:
    window.addEventListener("message", (event) => {
        const payload = event.data;
        if (payload.theme) {
          // Do something with the theme setting; I set the `data-theme` attribute on the iframe's <html>,
          // but you may want to set a classattribute or similar 
          document.documentElement.setAttribute("data-theme", payload.theme);
        }
    }, false);

Styling

Under Admin -> Customize -> (select theme) -> Edit CSS/HTML -> Embedded CSS, you can now provide CSS for each mode. E.g., you can override the Discourse styling variables:

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

I hope that helps!

6 إعجابات