hex. * * @var array|null */ private static $palette = null; /** * Parse a CSS colour into [r, g, b, a] or null. * * @param string $value CSS colour. * @return array|null */ public static function parse( $value ) { $value = strtolower( trim( (string) $value ) ); $value = preg_replace( '/\s*!important$/', '', $value ); $named = array( 'black' => '#000000', 'white' => '#ffffff', 'red' => '#ff0000', 'green' => '#008000', 'blue' => '#0000ff', 'yellow' => '#ffff00', 'gray' => '#808080', 'grey' => '#808080', 'silver' => '#c0c0c0', 'orange' => '#ffa500', 'navy' => '#000080', 'purple' => '#800080', 'maroon' => '#800000', 'teal' => '#008080', 'lime' => '#00ff00', 'aqua' => '#00ffff', 'pink' => '#ffc0cb', ); if ( isset( $named[ $value ] ) ) { $value = $named[ $value ]; } if ( preg_match( '/^var\(--wp--preset--color--([a-z0-9-]+)\)$/', $value, $m ) ) { $hex = self::palette_color( $m[1] ); return $hex ? self::parse( $hex ) : null; } if ( preg_match( '/^#([0-9a-f]{3,8})$/', $value, $m ) ) { $hex = $m[1]; if ( 3 === strlen( $hex ) || 4 === strlen( $hex ) ) { $hex = preg_replace( '/(.)/', '$1$1', $hex ); } if ( 6 !== strlen( $hex ) && 8 !== strlen( $hex ) ) { return null; } $a = 8 === strlen( $hex ) ? hexdec( substr( $hex, 6, 2 ) ) / 255 : 1; return array( hexdec( substr( $hex, 0, 2 ) ), hexdec( substr( $hex, 2, 2 ) ), hexdec( substr( $hex, 4, 2 ) ), $a ); } if ( preg_match( '/^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)(?:[\s,\/]+([\d.]+%?))?\s*\)$/', $value, $m ) ) { $a = 1; if ( isset( $m[4] ) && '' !== $m[4] ) { $a = '%' === substr( $m[4], -1 ) ? (float) $m[4] / 100 : (float) $m[4]; } return array( min( 255, (int) $m[1] ), min( 255, (int) $m[2] ), min( 255, (int) $m[3] ), $a ); } return null; } /** * Relative luminance (WCAG). * * @param array $rgb [r, g, b]. * @return float */ public static function luminance( $rgb ) { $c = array(); for ( $i = 0; $i < 3; $i++ ) { $v = $rgb[ $i ] / 255; $c[ $i ] = $v <= 0.03928 ? $v / 12.92 : pow( ( $v + 0.055 ) / 1.055, 2.4 ); } return 0.2126 * $c[0] + 0.7152 * $c[1] + 0.0722 * $c[2]; } /** * Contrast ratio between two colours (1–21), or null if either is unknown or translucent. * * @param string $fg Foreground. * @param string $bg Background. * @return float|null */ public static function ratio( $fg, $bg ) { $a = is_array( $fg ) ? $fg : self::parse( $fg ); $b = is_array( $bg ) ? $bg : self::parse( $bg ); if ( ! $a || ! $b || $a[3] < 1 || $b[3] < 1 ) { return null; } $l1 = self::luminance( $a ); $l2 = self::luminance( $b ); return ( max( $l1, $l2 ) + 0.05 ) / ( min( $l1, $l2 ) + 0.05 ); } /** * Colour for a theme.json palette slug. * * @param string $slug Slug. * @return string|null */ public static function palette_color( $slug ) { if ( null === self::$palette ) { self::$palette = array(); if ( function_exists( 'wp_get_global_settings' ) ) { $palette = wp_get_global_settings( array( 'color', 'palette' ) ); // Order matters: later origins override earlier ones. foreach ( array( 'default', 'theme', 'custom' ) as $origin ) { if ( empty( $palette[ $origin ] ) || ! is_array( $palette[ $origin ] ) ) { continue; } foreach ( $palette[ $origin ] as $entry ) { if ( isset( $entry['slug'], $entry['color'] ) ) { self::$palette[ $entry['slug'] ] = $entry['color']; } } } } /** * Filter the palette used to resolve has-*-color classes. * * @param array $palette slug => colour. */ self::$palette = apply_filters( 'ariaccess_palette', self::$palette ); } return isset( self::$palette[ $slug ] ) ? self::$palette[ $slug ] : null; } /** * Reset the palette cache (tests). */ public static function reset() { self::$palette = null; } }