"use strict"; // Skip ALL Darkify initialization when this page is running inside a frontend // iframe and the parent site has "Frontend Iframe Dark Mode" turned OFF. // This is the only reliable guard for same-origin embedded pages that have // their own copy of Darkify running — they must not self-initialize dark mode. var _dkf_iframe_disabled = ( window !== window.top && typeof darkify_is_this_admin_panel !== "undefined" && darkify_is_this_admin_panel !== "1" && typeof darkify_enable_frontend_iframe_dark_mode !== "undefined" && darkify_enable_frontend_iframe_dark_mode !== "1" ); let has_process_run_at_least_once = false; let old_transition = ""; let has_background_img_url = false; let darken_level = parseInt(darkify_bg_image_darken_to) / 100; darken_level = darken_level.toFixed(1); let darkify_secondary_bg_color = ""; darkify_init_keyboard_shortcut_listener(); darkify_init_os_mode_change_listener(); const darkify_observer = new MutationObserver(function (mutationsList) { darkify_init_processes(); darkify_process_iframes(); // ✅ darkify proceed iframe }); const elements_class_changed = new MutationObserver((mutationsList) => { if (document.readyState !== "loading") { mutationsList.forEach((mutation) => { const target = mutation.target; if (target.classList.contains("darkify_processed")) { if (!target.hasAttribute("data-darkify_preserved_classes")) { target.dataset.darkify_preserved_classes = target.classList.toString(); } else { if ( target.dataset.darkify_preserved_classes === target.classList.toString() ) { return; } } target.dataset.darkify_preserved_classes = target.classList.toString(); elements_class_changed.disconnect(); target.classList.remove("darkify_processed"); darkify_process_element(target); document .querySelectorAll( "*:not(head, title, link, meta, script, style, defs, filter)", ) .forEach((element) => { elements_class_changed.observe(element, { attributes: true, attributeFilter: ["class"], }); }); } }); } }); const dark_mode_status_changed = new MutationObserver((mutationsList) => { mutationsList.forEach((mutation) => { if (mutation.type === "attributes" && mutation.attributeName === "class") { document .querySelectorAll( "*:not(head, title, link, meta, script, style, defs, filter)", ) .forEach((element) => { if (element.classList.contains("darkify_processed")) { if ( darkify_disallowed_elements.length > 0 && element.matches(darkify_disallowed_elements) ) { return; } if (darkify_enable_bg_image_darken === "1") { darkify_darken_bg_image(element, darken_level); } if ( (darkify_enable_low_image_brightness === "1" || darkify_enable_image_grayscale === "1") && element.nodeName.toLowerCase() === "img" ) { darkify_img_brightness_and_grayscale(element); } if ( darkify_enable_invert_inline_svg === "1" && element.nodeName.toLowerCase() === "svg" ) { darkify_invert_inline_svg(element); } if ( darkify_enable_low_video_brightness === "1" || darkify_enable_video_grayscale === "1" ) { if (element.nodeName.toLowerCase() === "video") { darkify_video_brightness_and_grayscale(element); } if ( element.nodeName.toLowerCase() === "iframe" && element.getAttribute("src") != null ) { const srcAttribute = element.getAttribute("src"); if ( srcAttribute.includes("youtube") || srcAttribute.includes("vimeo") || srcAttribute.includes("dailymotion") ) { darkify_video_brightness_and_grayscale(element); } } } if (element.hasAttribute("data-darkify_alpha_bg")) { darkify_fix_background_color_alpha(element); } } }); } }); }); function darkify_change_state() { if (darkify_is_this_admin_panel === "1") { localStorage.darkify_admin_panel_last_state = document .getElementsByTagName("html")[0] .classList.contains("darkify_dark_mode_enabled") ? "1" : "0"; } else { localStorage.darkify_last_state = document .getElementsByTagName("html")[0] .classList.contains("darkify_dark_mode_enabled") ? "1" : "0"; } } function darkify_switch_trigger() { if (!has_process_run_at_least_once) { darkify_init_processes(); darkify_init_observer(); } const htmlElement = document.getElementsByTagName("html")[0]; if (htmlElement.classList.contains("darkify_dark_mode_enabled")) { htmlElement.classList.remove("darkify_dark_mode_enabled"); } else { htmlElement.classList.add("darkify_dark_mode_enabled"); } darkify_change_state(); darkify_process_iframes(); // ✅ darkify proceed iframe } function darkify_theme_select(theme) { if (!darkify_is_block_editor_context()) return; if (!has_process_run_at_least_once) { darkify_init_processes(); darkify_init_observer(); } const htmlElement = document.documentElement; // ✅ Remove all previous theme classes (IMPORTANT) htmlElement.classList.forEach((cls) => { if (cls.startsWith("darkify-")) { htmlElement.classList.remove(cls); } }); // ✅ Save in localStorage localStorage.darkify_selected_theme = theme; // ✅ Update all select dropdowns darkify_update_theme_selectors(theme); if (darkify_is_this_admin_panel === "1") { if (localStorage.darkify_admin_panel_last_state === "1") { htmlElement.classList.add("darkify_dark_mode_enabled"); htmlElement.classList.add("darkify-" + theme); } else { htmlElement.classList.remove("darkify_dark_mode_enabled"); } } darkify_change_state(); // Apply the new palette to the parent first, then sync iframes so they pick // up the updated variables rather than the previous palette. darkify_apply_palette(theme); darkify_process_iframes(); } document.addEventListener("DOMContentLoaded", function () { if (!darkify_is_block_editor_context()) return; let theme = localStorage.getItem("darkify_selected_theme") || "set1"; darkify_theme_select(theme); }); function darkify_update_theme_selectors(theme) { document .querySelectorAll(".darkify-theme-selector") .forEach(function (select) { if (select.value !== theme) { select.value = theme; } }); } function darkify_is_block_editor_context() { return ( typeof document !== "undefined" && document.body && (document.body.classList.contains("block-editor-page") || document.querySelector(".edit-post-visual-editor") !== null || document.querySelector(".block-editor") !== null) ); } function darkify_restore_selected_theme() { if (!darkify_is_block_editor_context()) return; const storedTheme = localStorage.darkify_selected_theme; if (!storedTheme) return; darkify_update_theme_selectors(storedTheme); darkify_theme_select(storedTheme); } function darkify_apply_palette(theme) { if (!darkify_is_block_editor_context()) return; const palettes = { set1: { bg: "#0F0F0F", secondary_bg: "#171717", text_color: "#BEBEBE", link_color: "#E7E7E7", link_hover_color: "#BEBEBE", input_bg: "#2D2D2D", input_text_color: "#BEBEBE", input_placeholder_color: "#BEBEBE", border_color: "#4A4A4A", btn_text_color: "#BEBEBE", btn_bg: "#4A4A4A", btn_text_hover_color: "#BEBEBE", btn_hover_bg: "#2D2D2D", }, set3: { bg: "#211e3c", secondary_bg: "#302C57", text_color: "#B1BBD8", link_color: "#8071fb", link_hover_color: "#B1BBD8", input_bg: "#2A264D", input_text_color: "#B1BBD8", input_placeholder_color: "#B1BBD8", border_color: "#4E478D", btn_text_color: "#B1BBD8", btn_bg: "#4E478D", btn_text_hover_color: "#B1BBD8", btn_hover_bg: "#2A264D", }, set6: { bg: "#082032", secondary_bg: "#061825", text_color: "#B5D9F3", link_color: "#61bbff", link_hover_color: "#B5D9F3", input_bg: "#0E3755", input_text_color: "#B5D9F3", input_placeholder_color: "#B5D9F3", border_color: "#144E78", btn_text_color: "#B5D9F3", btn_bg: "#144E78", btn_text_hover_color: "#B5D9F3", btn_hover_bg: "#0E3755", }, set9: { bg: "#04261d", secondary_bg: "#021e16", text_color: "#C1D2BB", link_color: "#00d29a", link_hover_color: "#C1D2BB", input_bg: "#073d2f", input_text_color: "#C1D2BB", input_placeholder_color: "#C1D2BB", border_color: "#095541", btn_text_color: "#C1D2BB", btn_bg: "#095541", btn_text_hover_color: "#C1D2BB", btn_hover_bg: "#073d2f", }, set10: { bg: "#171004", secondary_bg: "#211706", text_color: "#E0D2BD", link_color: "#e09525", link_hover_color: "#E0D2BD", input_bg: "#372911", input_text_color: "#E0D2BD", input_placeholder_color: "#E0D2BD", border_color: "#5D4010", btn_text_color: "#E0D2BD", btn_bg: "#5D4010", btn_text_hover_color: "#E0D2BD", btn_hover_bg: "#372911", }, }; const palette = palettes[theme] || palettes["set1"]; document.documentElement.style.setProperty( "--darkify_dark_mode_bg", palette.bg, ); document.documentElement.style.setProperty( "--darkify_dark_mode_secondary_bg", palette.secondary_bg, ); document.documentElement.style.setProperty( "--darkify_dark_mode_text_color", palette.text_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_link_color", palette.link_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_link_hover_color", palette.link_hover_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_input_bg", palette.input_bg, ); document.documentElement.style.setProperty( "--darkify_dark_mode_input_text_color", palette.input_text_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_input_placeholder_color", palette.input_placeholder_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_border_color", palette.border_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_btn_bg", palette.btn_bg, ); document.documentElement.style.setProperty( "--darkify_dark_mode_btn_text_color", palette.btn_text_color, ); document.documentElement.style.setProperty( "--darkify_dark_mode_btn_hover_bg", palette.btn_hover_bg, ); document.documentElement.style.setProperty( "--darkify_dark_mode_btn_text_hover_color", palette.btn_text_hover_color, ); } // --------------------------------------------------------------------------- // Iframe dark mode // // Same-origin iframes are isolated documents: the parent's :root CSS variables, // stylesheet and dark-mode class do not cascade into them. To keep an iframe in // sync with the parent theme we mirror three things into the iframe document: // 1. the darkify_dark_mode_enabled class on // 2. the theme CSS variables (kept live so colour/palette changes propagate) // 3. the plugin stylesheet, plus a run of the element classifier so inner // content (cards, sections, etc.) is darkened, not just
//inputs // Colour changes only need the variables refreshed; the var-driven class rules // then re-theme everything instantly without re-walking the DOM. // --------------------------------------------------------------------------- const DARKIFY_IFRAME_THEME_VARS = [ "--darkify_dark_mode_bg", "--darkify_dark_mode_secondary_bg", "--darkify_dark_mode_text_color", "--darkify_dark_mode_link_color", "--darkify_dark_mode_link_hover_color", "--darkify_dark_mode_input_bg", "--darkify_dark_mode_input_text_color", "--darkify_dark_mode_input_placeholder_color", "--darkify_dark_mode_border_color", "--darkify_dark_mode_btn_bg", "--darkify_dark_mode_btn_text_color", "--darkify_dark_mode_btn_hover_bg", "--darkify_dark_mode_btn_text_hover_color", ]; // Tracks per-iframe-document observers so we don't attach duplicates and can // react to dynamically injected content (e.g. React/SPA pages inside the frame). const darkify_iframe_doc_observers = new WeakMap(); // Tracks per-iframe-document "keep our style last" observers so we attach only // one per document. Keyed on iframeDoc. const darkify_editor_head_watchers = new WeakMap(); // Serialise the parent's current theme variables as a :root {} rule. Computed // style is used so the value reflects the active theme regardless of whether it // was set inline (block editor) or via an inline