knadh / listmonk

High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.
https://listmonk.app
GNU Affero General Public License v3.0
15.38k stars 1.4k forks source link

Enable Dark mode support in TinyMCE #2073

Open sweetppro opened 1 month ago

sweetppro commented 1 month ago

I have a created Dark Mode theme for my ListMonk install, but the only thing missing is TinyMCE.

It seems it would be quite trivial to add Dark mode support to TinyMCE, as this can be enabled in the initial function: https://www.tiny.cloud/docs/tinymce/latest/customize-ui/

sweetppro commented 1 month ago

It wasnt that difficult to add a quick dark mode style using the Admin Appearance overrides:

css:

.tox-tinymce {
    opacity: 0;
}

.tox-tinymce.show {
    opacity: 1.0;
}

@media (prefers-color-scheme: dark) {
    .tox-tinymce {
            border: 1px solid rgba(71, 71, 71, 0.15) !important;
        }

        .tox-tinymce,
        .tox-editor-container,
        .tox-editor-header {
            filter: invert(100%);
        }

        .tox-edit-area__iframe {
            background-color: transparent !important;
        }
    }

js:

/* add style to tinymce */
if (document.readyState === "complete") startTimer();
else window.addEventListener("load", () => startTimer());

//save elements to array to avoid multiple triggers
var elems = [];
function startTimer() {
  setInterval(checkStyles, 10);
}

function checkStyles() {
  document.querySelectorAll("section.editor textarea").forEach((editor) => {
    if (elems.includes(editor) == false) {
      elems.push(editor);

      var iframeID = editor.id + "_ifr";
      var iframe = document.getElementById(iframeID);

      const iframeDocument =
        iframe.contentDocument || iframe.contentWindow.document;

      const style = iframeDocument.createElement("style");
      style.type = "text/css";

      const customCSS = `@media (prefers-color-scheme: dark) {
            body {
              background-color: #232323;
              color: #fff;
            }
            a {
              color: #4099ff;
            }
          }`;

      style.appendChild(iframeDocument.createTextNode(customCSS));
      iframeDocument.head.appendChild(style);

      //show
      document.querySelectorAll(".tox-tinymce").forEach((editor) => {
        editor.classList.add("show");
      });
    }
  });