*/ class Frontend { /** * The ID of this plugin. * * @since 1.0.0 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * The version of this plugin. * * @since 1.0.0 * @access private * @var string $version The current version of this plugin. */ private $version; public $utils; public $settings; public $external_support; public $unique_id; /** * Initialize the class and set its properties. * * @since 1.0.0 * @param string $plugin_name The name of the plugin. * @param string $version The version of this plugin. */ public function __construct($plugin_name, $version) { $this->plugin_name = $plugin_name; $this->version = $version; $this->utils = new DarkifyUtils($this); $this->external_support = new DarkifyExternalSupport($this); new DarkifyShortcode($this); if (function_exists('wp_rand')) { $this->unique_id = wp_rand(); } // Register unconditionally and gate inside the callback. The constructor // runs at plugin boot (before `init`), so the option read here is always // the SAVED value — deciding registration here means the admin Live // Preview, which swaps in unsaved values only on `init` (see // PreviewRest::maybe_enable_preview), could never show a newly enabled // menu switch until saved. The filter runs at render time, after `init`, // so re-reading the option in the callback sees the preview values. add_filter('wp_nav_menu_items', array($this, 'darkify_switch_in_menu'), 10, 2); add_action('wp_enqueue_scripts', array($this, 'darkify_client_enqueue'), 100); add_action('login_enqueue_scripts', array($this, 'darkify_client_enqueue')); add_action('register_enqueue_scripts', array($this, 'darkify_client_enqueue')); add_action('wp_head', array($this, 'darkify_client_header_script'), 1); add_action('login_head', array($this, 'darkify_client_header_script'), 1); add_action('register_head', array($this, 'darkify_client_header_script'), 1); add_action('wp_footer', array($this, 'darkify_client_footer_script')); add_action('login_footer', array($this, 'darkify_client_footer_script')); add_action('register_footer', array($this, 'darkify_client_footer_script')); add_action('init', array($this, 'darkify_register_switcher_styles'), 5); add_filter('autoptimize_filter_js_exclude', array($this, 'darkify_exclude_js_from_cache_plugins')); } public function darkify_exclude_js_from_cache_plugins($excludes) { $excludes .= ',client_main.js,client_main.min.js'; return $excludes; } public function darkify_register_switcher_styles() { $min = (apply_filters('darkify_dev_mode', false) || WP_DEBUG) ? '' : '.min'; wp_register_style('darkify-client-main', DARKIFY_DIR_URL . 'src/assets/css/client_main' . $min . '.css', array(), DARKIFY_VERSION); wp_register_style('theme-classic', DARKIFY_DIR_URL . 'src/assets/css/switcher/classic' . $min . '.css', array('darkify-client-main'), DARKIFY_VERSION, 'all'); wp_register_style('theme-expand', DARKIFY_DIR_URL . 'src/assets/css/switcher/expand' . $min . '.css', array('darkify-client-main'), DARKIFY_VERSION, 'all'); wp_register_style('theme-inner-moon', DARKIFY_DIR_URL . 'src/assets/css/switcher/inner-moon' . $min . '.css', array('darkify-client-main'), DARKIFY_VERSION, 'all'); wp_register_style('theme-within', DARKIFY_DIR_URL . 'src/assets/css/switcher/within' . $min . '.css', array('darkify-client-main'), DARKIFY_VERSION, 'all'); wp_register_style('theme-orbit', DARKIFY_DIR_URL . 'src/assets/css/switcher/orbit' . $min . '.css', array('darkify-client-main'), DARKIFY_VERSION, 'all'); } function darkify_client_enqueue() { if ($this->darkify_is_dark_mode_allowed()) { $options = get_option('darkify'); $min = (apply_filters('darkify_dev_mode', false) || WP_DEBUG) ? '' : '.min'; wp_enqueue_style('darkify-client-main', DARKIFY_DIR_URL . 'src/assets/css/client_main' . $min . '.css', array(), DARKIFY_VERSION); wp_enqueue_script('darkify-client-main', DARKIFY_DIR_URL . 'src/assets/js/client_main' . $min . '.js', array(), DARKIFY_VERSION); // When "Frontend Iframe Dark Mode" is OFF, use a two-stage inline script // strategy that covers all scenarios — source JS, minified JS, // cross-origin iframes, and same-origin WP pages embedded as iframes. // // ROOT CAUSE: a same-origin WP page loaded inside an