[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Dark Mode Class 4 * 5 * @package WordPress 6 * @subpackage Twenty_Twenty_One 7 * @since Twenty Twenty-One 1.0 8 */ 9 10 /** 11 * This class is in charge of Dark Mode. 12 */ 13 class Twenty_Twenty_One_Dark_Mode { 14 15 /** 16 * Instantiate the object. 17 * 18 * @since Twenty Twenty-One 1.0 19 */ 20 public function __construct() { 21 22 // Enqueue assets for the block-editor. 23 add_action( 'enqueue_block_editor_assets', array( $this, 'editor_custom_color_variables' ) ); 24 25 // Add styles for dark-mode. 26 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 27 28 // Add scripts for customizer controls. 29 add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) ); 30 31 // Add customizer controls. 32 add_action( 'customize_register', array( $this, 'customizer_controls' ) ); 33 34 // Add HTML classes. 35 add_filter( 'twentytwentyone_html_classes', array( $this, 'html_classes' ) ); 36 37 // Add classes to <body> in the dashboard. 38 add_filter( 'admin_body_class', array( $this, 'admin_body_classes' ) ); 39 40 // Add the switch on the frontend & customizer. 41 add_action( 'wp_footer', array( $this, 'the_switch' ) ); 42 43 // Add the privacy policy content. 44 add_action( 'admin_init', array( $this, 'add_privacy_policy_content' ) ); 45 } 46 47 /** 48 * Editor custom color variables & scripts. 49 * 50 * @since Twenty Twenty-One 1.0 51 * 52 * @return void 53 */ 54 public function editor_custom_color_variables() { 55 if ( ! $this->switch_should_render() ) { 56 return; 57 } 58 $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); 59 $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); 60 if ( $should_respect_color_scheme && Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) > 127 ) { 61 // Add Dark Mode variable overrides. 62 wp_add_inline_style( 63 'twenty-twenty-one-custom-color-overrides', 64 '.is-dark-theme.is-dark-theme .editor-styles-wrapper { --global--color-background: var(--global--color-dark-gray); --global--color-primary: var(--global--color-light-gray); --global--color-secondary: var(--global--color-light-gray); --button--color-text: var(--global--color-background); --button--color-text-hover: var(--global--color-secondary); --button--color-text-active: var(--global--color-secondary); --button--color-background: var(--global--color-secondary); --button--color-background-active: var(--global--color-background); --global--color-border: #9ea1a7; --table--stripes-border-color: rgba(240, 240, 240, 0.15); --table--stripes-background-color: rgba(240, 240, 240, 0.15); }' 65 ); 66 } 67 wp_enqueue_script( 68 'twentytwentyone-dark-mode-support-toggle', 69 get_template_directory_uri() . '/assets/js/dark-mode-toggler.js', 70 array(), 71 '1.0.0', 72 true 73 ); 74 75 wp_enqueue_script( 76 'twentytwentyone-editor-dark-mode-support', 77 get_template_directory_uri() . '/assets/js/editor-dark-mode-support.js', 78 array( 'twentytwentyone-dark-mode-support-toggle' ), 79 '1.0.0', 80 true 81 ); 82 } 83 84 /** 85 * Enqueue scripts and styles. 86 * 87 * @since Twenty Twenty-One 1.0 88 * 89 * @return void 90 */ 91 public function enqueue_scripts() { 92 if ( ! $this->switch_should_render() ) { 93 return; 94 } 95 $url = get_template_directory_uri() . '/assets/css/style-dark-mode.css'; 96 if ( is_rtl() ) { 97 $url = get_template_directory_uri() . '/assets/css/style-dark-mode-rtl.css'; 98 } 99 wp_enqueue_style( 'tt1-dark-mode', $url, array( 'twenty-twenty-one-style' ), wp_get_theme()->get( 'Version' ) ); // @phpstan-ignore-line. Version is always a string. 100 } 101 102 /** 103 * Enqueue scripts for the customizer. 104 * 105 * @since Twenty Twenty-One 1.0 106 * 107 * @return void 108 */ 109 public function customize_controls_enqueue_scripts() { 110 if ( ! $this->switch_should_render() ) { 111 return; 112 } 113 wp_enqueue_script( 114 'twentytwentyone-customize-controls', 115 get_template_directory_uri() . '/assets/js/customize.js', 116 array( 'customize-base', 'customize-controls', 'underscore', 'jquery', 'twentytwentyone-customize-helpers' ), 117 '1.0.0', 118 true 119 ); 120 } 121 122 /** 123 * Register customizer options. 124 * 125 * @since Twenty Twenty-One 1.0 126 * 127 * @param WP_Customize_Manager $wp_customize Theme Customizer object. 128 * @return void 129 */ 130 public function customizer_controls( $wp_customize ) { 131 132 $colors_section = $wp_customize->get_section( 'colors' ); 133 if ( is_object( $colors_section ) ) { 134 $colors_section->title = __( 'Colors & Dark Mode', 'twentytwentyone' ); 135 } 136 137 // Custom notice control. 138 include_once get_theme_file_path( 'classes/class-twenty-twenty-one-customize-notice-control.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound 139 140 $wp_customize->add_setting( 141 'respect_user_color_preference_notice', 142 array( 143 'capability' => 'edit_theme_options', 144 'default' => '', 145 'sanitize_callback' => '__return_empty_string', 146 ) 147 ); 148 149 $wp_customize->add_control( 150 new Twenty_Twenty_One_Customize_Notice_Control( 151 $wp_customize, 152 'respect_user_color_preference_notice', 153 array( 154 'section' => 'colors', 155 'priority' => 100, 156 'active_callback' => static function() { 157 return 127 >= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ); 158 }, 159 ) 160 ) 161 ); 162 163 $wp_customize->add_setting( 164 'respect_user_color_preference', 165 array( 166 'capability' => 'edit_theme_options', 167 'default' => false, 168 'sanitize_callback' => static function( $value ) { 169 return (bool) $value; 170 }, 171 ) 172 ); 173 174 $description = '<p>'; 175 $description .= sprintf( 176 /* translators: %s: Twenty Twenty-One support article URL. */ 177 __( 'Dark Mode is a device setting. If a visitor to your site requests it, your site will be shown with a dark background and light text. <a href="%s">Learn more about Dark Mode.</a>', 'twentytwentyone' ), 178 esc_url( __( 'https://wordpress.org/support/article/twenty-twenty-one/#dark-mode-support', 'twentytwentyone' ) ) 179 ); 180 $description .= '</p>'; 181 $description .= '<p>' . __( 'Dark Mode can also be turned on and off with a button that you can find in the bottom corner of the page.', 'twentytwentyone' ) . '</p>'; 182 183 $wp_customize->add_control( 184 'respect_user_color_preference', 185 array( 186 'type' => 'checkbox', 187 'section' => 'colors', 188 'label' => esc_html__( 'Dark Mode support', 'twentytwentyone' ), 189 'priority' => 110, 190 'description' => $description, 191 'active_callback' => static function( $value ) { 192 return 127 < Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ); 193 }, 194 ) 195 ); 196 197 // Add partial for background_color. 198 $wp_customize->selective_refresh->add_partial( 199 'background_color', 200 array( 201 'selector' => '#dark-mode-toggler', 202 'container_inclusive' => true, 203 'render_callback' => function() { 204 $attrs = ( $this->switch_should_render() ) ? array() : array( 'style' => 'display:none;' ); 205 $this->the_html( $attrs ); 206 }, 207 ) 208 ); 209 } 210 211 /** 212 * Calculate classes for the main <html> element. 213 * 214 * @since Twenty Twenty-One 1.0 215 * 216 * @param string $classes The classes for <html> element. 217 * @return string 218 */ 219 public function html_classes( $classes ) { 220 if ( ! $this->switch_should_render() ) { 221 return $classes; 222 } 223 224 $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); 225 $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); 226 if ( $should_respect_color_scheme && 127 <= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) ) { 227 return ( $classes ) ? ' respect-color-scheme-preference' : 'respect-color-scheme-preference'; 228 } 229 230 return $classes; 231 } 232 233 /** 234 * Adds a class to the <body> element in the editor to accommodate dark-mode. 235 * 236 * @since Twenty Twenty-One 1.0 237 * 238 * @param string $classes The admin body-classes. 239 * @return string 240 */ 241 public function admin_body_classes( $classes ) { 242 if ( ! $this->switch_should_render() ) { 243 return $classes; 244 } 245 246 global $current_screen; 247 if ( empty( $current_screen ) ) { 248 set_current_screen(); 249 } 250 251 if ( $current_screen->is_block_editor() ) { 252 $should_respect_color_scheme = get_theme_mod( 'respect_user_color_preference', false ); 253 $background_color = get_theme_mod( 'background_color', 'D1E4DD' ); 254 255 if ( $should_respect_color_scheme && Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( $background_color ) > 127 ) { 256 $classes .= ' twentytwentyone-supports-dark-theme'; 257 } 258 } 259 260 return $classes; 261 } 262 263 /** 264 * Determine if we want to print the dark-mode switch or not. 265 * 266 * @since Twenty Twenty-One 1.0 267 * 268 * @return bool 269 */ 270 public function switch_should_render() { 271 global $is_IE; 272 return ( 273 get_theme_mod( 'respect_user_color_preference', false ) && 274 ! $is_IE && 275 127 <= Twenty_Twenty_One_Custom_Colors::get_relative_luminance_from_hex( get_theme_mod( 'background_color', 'D1E4DD' ) ) 276 ); 277 } 278 279 /** 280 * Add night/day switch. 281 * 282 * @since Twenty Twenty-One 1.0 283 * 284 * @return void 285 */ 286 public function the_switch() { 287 if ( ! $this->switch_should_render() ) { 288 return; 289 } 290 $this->the_html(); 291 $this->the_script(); 292 } 293 294 /** 295 * Print the dark-mode switch HTML. 296 * 297 * Inspired from https://codepen.io/aaroniker/pen/KGpXZo (MIT-licensed) 298 * 299 * @since Twenty Twenty-One 1.0 300 * 301 * @param array $attrs The attributes to add to our <button> element. 302 * @return void 303 */ 304 public function the_html( $attrs = array() ) { 305 $attrs = wp_parse_args( 306 $attrs, 307 array( 308 'id' => 'dark-mode-toggler', 309 'class' => 'fixed-bottom', 310 'aria-pressed' => 'false', 311 'onClick' => 'toggleDarkMode()', 312 ) 313 ); 314 echo '<button'; 315 foreach ( $attrs as $key => $val ) { 316 echo ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"'; 317 } 318 echo '>'; 319 printf( 320 /* translators: %s: On/Off */ 321 esc_html__( 'Dark Mode: %s', 'twentytwentyone' ), 322 '<span aria-hidden="true"></span>' 323 ); 324 echo '</button>'; 325 ?> 326 <style> 327 #dark-mode-toggler > span { 328 margin-<?php echo is_rtl() ? 'right' : 'left'; ?>: 5px; 329 } 330 #dark-mode-toggler > span::before { 331 content: '<?php esc_attr_e( 'Off', 'twentytwentyone' ); ?>'; 332 } 333 #dark-mode-toggler[aria-pressed="true"] > span::before { 334 content: '<?php esc_attr_e( 'On', 'twentytwentyone' ); ?>'; 335 } 336 <?php if ( is_admin() || wp_is_json_request() ) : ?> 337 .components-editor-notices__pinned ~ .edit-post-visual-editor #dark-mode-toggler { 338 z-index: 20; 339 } 340 .is-dark-theme.is-dark-theme #dark-mode-toggler:not(:hover):not(:focus) { 341 color: var(--global--color-primary); 342 } 343 @media only screen and (max-width: 782px) { 344 #dark-mode-toggler { 345 margin-top: 32px; 346 } 347 } 348 <?php endif; ?> 349 </style> 350 351 <?php 352 } 353 354 /** 355 * Print the dark-mode switch script. 356 * 357 * @since Twenty Twenty-One 1.0 358 * 359 * @return void 360 */ 361 public function the_script() { 362 echo '<script>'; 363 include get_template_directory() . '/assets/js/dark-mode-toggler.js'; // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude 364 echo '</script>'; 365 } 366 367 /** 368 * Adds information to the privacy policy. 369 * 370 * @since Twenty Twenty-One 1.0 371 * 372 * @return void 373 */ 374 public function add_privacy_policy_content() { 375 if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) { 376 return; 377 } 378 $content = '<p class="privacy-policy-tutorial">' . __( 'Twenty Twenty-One uses LocalStorage when Dark Mode support is enabled.', 'twentytwentyone' ) . '</p>' 379 . '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:', 'twentytwentyone' ) . '</strong> ' 380 . __( 'This website uses LocalStorage to save the setting when Dark Mode support is turned on or off.<br> LocalStorage is necessary for the setting to work and is only used when a user clicks on the Dark Mode button.<br> No data is saved in the database or transferred.', 'twentytwentyone' ); 381 wp_add_privacy_policy_content( 'Twenty Twenty-One', wp_kses_post( wpautop( $content, false ) ) ); 382 } 383 384 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Dec 24 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |