as raw JSON (like * darkify_allowed_btn_class below), so each value is reduced to a known-safe * shape here: a hex colour or one of the fixed scope keys. Rows missing either * colour are dropped — a half-filled repeater row is the default state of the * field and means nothing to the engine. */ $darkify_color_overrides = array(); if (!empty($options['color_overrides']) && is_array($options['color_overrides'])) { $darkify_override_scopes = array('all', 'text', 'icon', 'background', 'border', 'shadow'); foreach ($options['color_overrides'] as $darkify_override_row) { if (!is_array($darkify_override_row)) { continue; } $darkify_light = isset($darkify_override_row['light_color']) ? DarkifyUtils::sanitize_css_color($darkify_override_row['light_color']) : ''; $darkify_dark = isset($darkify_override_row['dark_color']) ? DarkifyUtils::sanitize_css_color($darkify_override_row['dark_color']) : ''; if (!$darkify_light || !$darkify_dark) { continue; } $darkify_scope = isset($darkify_override_row['override_scope']) ? $darkify_override_row['override_scope'] : 'all'; if (!in_array($darkify_scope, $darkify_override_scopes, true)) { $darkify_scope = 'all'; } $darkify_color_overrides[] = array( 'light_color' => $darkify_light, 'dark_color' => $darkify_dark, 'override_scope' => $darkify_scope, ); } } $invert = isset($options['invert']) ? $options['invert'] : ""; $enable_invert_images = isset($invert['enable_invert_images']) ? $invert['enable_invert_images'] : ""; $invert_images_allowed_urls = !empty($invert['invert_images_allowed_urls']) ? DarkifyUtils::normalize_image_urls($invert['invert_images_allowed_urls']) : ""; if ($invert_images_allowed_urls !== "") { $invert_images_allowed_urls_explode = explode(',', $invert_images_allowed_urls); $invert_images_allowed_urls_arr = json_encode($invert_images_allowed_urls_explode); } else { $invert_images_allowed_urls_arr = "[]"; } $normal_image_replacements = isset($options["image_replacements"][0]['normal_image']) ? $options["image_replacements"][0]['normal_image'] : ''; $dark_image_replacements = isset($options["image_replacements"][0]['dark_image']) ? $options["image_replacements"][0]['dark_image'] : ''; if ($normal_image_replacements || $dark_image_replacements) { $image_replacements = json_encode($options["image_replacements"]); } else { $image_replacements = ""; } // Video Control $video_brightness = isset($options['video_brightness']) ? $options['video_brightness'] : ""; $enable_low_video_brightness = isset($video_brightness['enable_low_video_brightness']) ? $video_brightness['enable_low_video_brightness'] : true; $low_video_brightness_label = isset($video_brightness['low_video_brightness_label']) ? 100 - $video_brightness['low_video_brightness_label'] : 100 - "20"; $video_grayscale = isset($options['video_grayscale']) ? $options['video_grayscale'] : ''; $enable_video_grayscale = isset($video_grayscale['enable_video_grayscale']) ? $video_grayscale['enable_video_grayscale'] : ""; $video_grayscale_label = isset($video_grayscale['video_grayscale_label']) ? $video_grayscale['video_grayscale_label'] : "80"; $normal_video_replacements = isset($options["video_replacements"][0]["normal_video"]) ? $options["video_replacements"][0]["normal_video"] : ''; $dark_video_replacements = isset($options["video_replacements"][0]["dark_video"]) ? $options["video_replacements"][0]["dark_video"] : ''; if ($normal_video_replacements || $dark_video_replacements) { $video_replacements = json_encode($options["video_replacements"]); } else { $video_replacements = "[]"; } if (!is_admin()) { ?> is the de-facto convention a React admin themes itself * off — Tailwind's class strategy, shadcn/ui, and Darkify's own React admin * (`@custom-variant dark (&:is(.dark *))`) all key on exactly this class. * * It used to be added only on Darkify's own SPA pages, which is why a * React-based admin screen from ANOTHER plugin stayed stubbornly light while * the rest of wp-admin went dark: such an app doesn't take its colours from * the cascade at all, it reads design tokens that only switch when `dark` is * present, and that class never arrived. Mirroring Admin Panel Dark Mode * onto it here — on every admin screen, not just ours — lets any app * following the convention inherit the theme with no plugin-specific * handling on either side. * * Setting it in means the very first paint is already dark; the * runtime half of the mirror lives in client_main.js so the admin-bar switch * re-themes those screens live too. The `h.classList.add('dark')` call is * emitted as a static literal in the snippet below. */ /* * `d` gates this FOUC snippet on Admin Panel Dark Mode actually being ON. * It used to be implicit: with the option off this template was never * included on an admin screen. Darkify's own SPA screens now always * include it (so the admin-bar icon can toggle without a reload), so * without this check a stale `darkify_admin_panel_last_state = "1"` would * darken the screen even though the option is off. * * Nested ifs, NOT `s==='1'&&d==='1'`: this whole template is printed * through wp_kses() (see the bottom of the file), whose entity * normalization rewrites a bare `&` to `&` — script content is raw * text, so `&&` would reach the browser as `&&` and kill the * snippet with a SyntaxError. Keep this snippet free of `&` (and `<`). */ /* * Effective admin darkening for THIS screen. Block Editor Dark Mode is * independent of Admin Panel Dark Mode: the block editor darkens when Block * Editor Dark Mode is on even if Admin Panel Dark Mode is off. Reused for the * runtime gate (darkify_admin_panel_dark_enabled) below. */ $darkify_screen = \function_exists('get_current_screen') ? \get_current_screen() : null; $darkify_is_block_editor = $darkify_screen && \method_exists($darkify_screen, 'is_block_editor') && $darkify_screen->is_block_editor(); $darkify_block_editor_dark = !empty($options['block_editor_dark_mode']); $darkify_effective_admin_dark = (!empty($options['enable_admin_panel_dark_mode']) || ($darkify_is_block_editor && $darkify_block_editor_dark)) ? '1' : '0'; $darkify_admin_dark_on = $darkify_effective_admin_dark; ?> array('type' => array(), 'class' => array()), 'script' => array('type' => array(), 'class' => array()) ); echo wp_kses($this->utils->minify_string($output), $tags_allowed_in_output);