| @@ -47,11 +47,11 @@ | ||
| 47 | 47 | * 'core/featured-image' => 'blue-orange', |
| 48 | 48 | * … |
| 49 | 49 | * ] |
| 50 | 50 | * |
| 51 | - * @var ?array<string, string> | |
| 51 | + * @var array | |
| 52 | 52 | */ |
| 53 | - private static $global_styles_block_names; | |
| 53 | + private static $global_styles_block_names = array(); | |
| 54 | 54 | |
| 55 | 55 | /** |
| 56 | 56 | * An array of duotone filter data from global, theme, and custom presets. |
| 57 | 57 | * |
| @@ -67,11 +67,11 @@ | ||
| 67 | 67 | * ], |
| 68 | 68 | * … |
| 69 | 69 | * ] |
| 70 | 70 | * |
| 71 | - * @var ?array<string, array<string, string|string[]>> | |
| 71 | + * @var array | |
| 72 | 72 | */ |
| 73 | - private static $global_styles_presets; | |
| 73 | + private static $global_styles_presets = array(); | |
| 74 | 74 | |
| 75 | 75 | /** |
| 76 | 76 | * All of the duotone filter data from presets for CSS custom properties on |
| 77 | 77 | * the page. |
| @@ -475,9 +475,9 @@ | ||
| 475 | 475 | |
| 476 | 476 | $slug = self::get_slug_from_attribute( $duotone_attr ); |
| 477 | 477 | $filter_id = self::get_filter_id( $slug ); |
| 478 | 478 | |
| 479 | - return array_key_exists( $filter_id, self::get_all_global_styles_presets() ); | |
| 479 | + return array_key_exists( $filter_id, self::$global_styles_presets ); | |
| 480 | 480 | } |
| 481 | 481 | |
| 482 | 482 | /** |
| 483 | 483 | * Get the CSS variable name for a duotone preset. |
| @@ -645,43 +645,41 @@ | ||
| 645 | 645 | |
| 646 | 646 | /** |
| 647 | 647 | * Get the CSS selector for a block type. |
| 648 | 648 | * |
| 649 | - * @param WP_Block_Type $block_type Block type to check for support. | |
| 649 | + * @param string $block_name The block name. | |
| 650 | 650 | * |
| 651 | - * @return string|null The CSS selector. Null if there is no support or the $block_type is not a WP_Block_Type. | |
| 651 | + * @return ?string The CSS selector or null if there is no support. | |
| 652 | 652 | */ |
| 653 | - private static function get_selector( $block_type ) { | |
| 654 | - if ( ! ( $block_type instanceof WP_Block_Type ) ) { | |
| 655 | - return null; | |
| 656 | - } | |
| 653 | + private static function get_selector( $block_name ) { | |
| 654 | + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name ); | |
| 657 | 655 | |
| 658 | - /* | |
| 659 | - * Backward compatibility with `supports.color.__experimentalDuotone` | |
| 660 | - * is provided via the `block_type_metadata_settings` filter. If | |
| 661 | - * `supports.filter.duotone` has not been set and the experimental | |
| 662 | - * property has been, the experimental property value is copied into | |
| 663 | - * `supports.filter.duotone`. | |
| 664 | - */ | |
| 665 | - $duotone_support = block_has_support( $block_type, array( 'filter', 'duotone' ) ); | |
| 666 | - if ( ! $duotone_support ) { | |
| 667 | - return null; | |
| 668 | - } | |
| 656 | + if ( $block_type && $block_type instanceof WP_Block_Type ) { | |
| 657 | + // Backwards compatibility with `supports.color.__experimentalDuotone` | |
| 658 | + // is provided via the `block_type_metadata_settings` filter. If | |
| 659 | + // `supports.filter.duotone` has not been set and the experimental | |
| 660 | + // property has been, the experimental property value is copied into | |
| 661 | + // `supports.filter.duotone`. | |
| 662 | + $duotone_support = $block_type->supports['filter']['duotone'] ?? false; | |
| 663 | + if ( ! $duotone_support ) { | |
| 664 | + return null; | |
| 665 | + } | |
| 669 | 666 | |
| 670 | - /* | |
| 671 | - * If the experimental duotone support was set, that value is to be | |
| 672 | - * treated as a selector and requires scoping. | |
| 673 | - */ | |
| 674 | - $experimental_duotone = $block_type->supports['color']['__experimentalDuotone'] ?? false; | |
| 675 | - if ( $experimental_duotone ) { | |
| 676 | - $root_selector = wp_get_block_css_selector( $block_type ); | |
| 677 | - return is_string( $experimental_duotone ) | |
| 678 | - ? WP_Theme_JSON::scope_selector( $root_selector, $experimental_duotone ) | |
| 679 | - : $root_selector; | |
| 667 | + // If the experimental duotone support was set, that value is to be | |
| 668 | + // treated as a selector and requires scoping. | |
| 669 | + $experimental_duotone = $block_type->supports['color']['__experimentalDuotone'] ?? false; | |
| 670 | + if ( $experimental_duotone ) { | |
| 671 | + $root_selector = wp_get_block_css_selector( $block_type ); | |
| 672 | + return is_string( $experimental_duotone ) | |
| 673 | + ? WP_Theme_JSON_Gutenberg::scope_selector( $root_selector, $experimental_duotone ) | |
| 674 | + : $root_selector; | |
| 675 | + } | |
| 676 | + | |
| 677 | + // Regular filter.duotone support uses filter.duotone selectors with fallbacks. | |
| 678 | + return wp_get_block_css_selector( $block_type, array( 'filter', 'duotone' ), true ); | |
| 680 | 679 | } |
| 681 | 680 | |
| 682 | - // Regular filter.duotone support uses filter.duotone selectors with fallbacks. | |
| 683 | - return wp_get_block_css_selector( $block_type, array( 'filter', 'duotone' ), true ); | |
| 681 | + return null; | |
| 684 | 682 | } |
| 685 | 683 | |
| 686 | 684 | /** |
| 687 | 685 | * Enqueue a block CSS declaration for the page. |
| @@ -732,10 +730,9 @@ | ||
| 732 | 730 | * @param string $duotone_selector The block's duotone selector. e.g. '.wp-block-image img'. |
| 733 | 731 | * @param string $filter_value The filter CSS value. e.g. 'url(#wp-duotone-blue-orange)' or 'unset'. |
| 734 | 732 | */ |
| 735 | 733 | private static function enqueue_global_styles_preset( $filter_id, $duotone_selector, $filter_value ) { |
| 736 | - $global_styles_presets = self::get_all_global_styles_presets(); | |
| 737 | - if ( ! array_key_exists( $filter_id, $global_styles_presets ) ) { | |
| 734 | + if ( ! array_key_exists( $filter_id, self::$global_styles_presets ) ) { | |
| 738 | 735 | $error_message = sprintf( |
| 739 | 736 | /* translators: %s: duotone filter ID */ |
| 740 | 737 | __( 'The duotone id "%s" is not registered in theme.json settings', 'gutenberg' ), |
| 741 | 738 | $filter_id |
| @@ -742,10 +739,10 @@ | ||
| 742 | 739 | ); |
| 743 | 740 | _doing_it_wrong( __METHOD__, $error_message, '6.3.0' ); |
| 744 | 741 | return; |
| 745 | 742 | } |
| 746 | - self::$used_global_styles_presets[ $filter_id ] = $global_styles_presets[ $filter_id ]; | |
| 747 | - self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $global_styles_presets[ $filter_id ] ); | |
| 743 | + self::$used_global_styles_presets[ $filter_id ] = self::$global_styles_presets[ $filter_id ]; | |
| 744 | + self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, self::$global_styles_presets[ $filter_id ] ); | |
| 748 | 745 | } |
| 749 | 746 | |
| 750 | 747 | /** |
| 751 | 748 | * Registers the style and colors block attributes for block types that support it. |
| @@ -754,11 +751,16 @@ | ||
| 754 | 751 | * |
| 755 | 752 | * @param WP_Block_Type $block_type Block Type. |
| 756 | 753 | */ |
| 757 | 754 | public static function register_duotone_support( $block_type ) { |
| 758 | - // Previous `color.__experimentalDuotone` support flag is migrated | |
| 759 | - // to `filter.duotone` via `block_type_metadata_settings` filter. | |
| 760 | - if ( block_has_support( $block_type, array( 'filter', 'duotone' ), null ) ) { | |
| 755 | + $has_duotone_support = false; | |
| 756 | + if ( $block_type instanceof WP_Block_Type ) { | |
| 757 | + // Previous `color.__experimentalDuotone` support flag is migrated | |
| 758 | + // to `filter.duotone` via `block_type_metadata_settings` filter. | |
| 759 | + $has_duotone_support = $block_type->supports['filter']['duotone'] ?? null; | |
| 760 | + } | |
| 761 | + | |
| 762 | + if ( $has_duotone_support ) { | |
| 761 | 763 | if ( ! $block_type->attributes ) { |
| 762 | 764 | $block_type->attributes = array(); |
| 763 | 765 | } |
| 764 | 766 | |
| @@ -774,21 +776,14 @@ | ||
| 774 | 776 | * Get all possible duotone presets from global and theme styles and store as slug => [ colors array ] |
| 775 | 777 | * We only want to process this one time. On block render we'll access and output only the needed presets for that page. |
| 776 | 778 | * |
| 777 | 779 | * @since 6.3.0 |
| 778 | - * | |
| 779 | - * @return array<string, array<string, string|string[]>> An array of global styles presets, keyed on the filter ID. | |
| 780 | 780 | */ |
| 781 | - private static function get_all_global_styles_presets() { | |
| 782 | - if ( isset( self::$global_styles_presets ) ) { | |
| 783 | - return self::$global_styles_presets; | |
| 784 | - } | |
| 785 | - | |
| 781 | + public static function set_global_styles_presets() { | |
| 786 | 782 | // Get the per block settings from the theme.json. |
| 787 | 783 | $tree = gutenberg_get_global_settings(); |
| 788 | 784 | $presets_by_origin = $tree['color']['duotone'] ?? array(); |
| 789 | 785 | |
| 790 | - self::$global_styles_presets = array(); | |
| 791 | 786 | foreach ( $presets_by_origin as $presets ) { |
| 792 | 787 | foreach ( $presets as $preset ) { |
| 793 | 788 | $filter_id = self::get_filter_id( _wp_to_kebab_case( $preset['slug'] ) ); |
| 794 | 789 | |
| @@ -794,44 +789,21 @@ | ||
| 794 | 789 | |
| 795 | 790 | self::$global_styles_presets[ $filter_id ] = $preset; |
| 796 | 791 | } |
| 797 | 792 | } |
| 798 | - | |
| 799 | - return self::$global_styles_presets; | |
| 800 | 793 | } |
| 801 | 794 | |
| 802 | 795 | /** |
| 803 | - * Ensure all possible duotone presets are ready. | |
| 804 | - * This function is deprecated, as it's no longer necessary to handle this manually. | |
| 805 | - * It is kept to ensure external users of this method don't break. | |
| 806 | - * | |
| 807 | - * @since 6.3.0 | |
| 808 | - * @deprecated | |
| 809 | - */ | |
| 810 | - public static function set_global_styles_presets() { | |
| 811 | - _deprecated_function( __METHOD__, 'Gutenberg 22.5.0' ); | |
| 812 | - self::get_all_global_styles_presets(); | |
| 813 | - } | |
| 814 | - | |
| 815 | - /** | |
| 816 | 796 | * Scrape all block names from global styles and store in self::$global_styles_block_names |
| 817 | 797 | * |
| 818 | 798 | * @since 6.3.0 |
| 819 | - * | |
| 820 | - * @return null|array<string, string> An array of global style block slugs, keyed on the block name. | |
| 821 | 799 | */ |
| 822 | - private static function get_all_global_style_block_names() { | |
| 823 | - if ( isset( self::$global_styles_block_names ) ) { | |
| 824 | - return self::$global_styles_block_names; | |
| 825 | - } | |
| 826 | - | |
| 800 | + public static function set_global_style_block_names() { | |
| 827 | 801 | // Get the per block settings from the theme.json. |
| 828 | 802 | $tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data(); |
| 829 | 803 | $block_nodes = $tree->get_styles_block_nodes(); |
| 830 | 804 | $theme_json = $tree->get_raw_data(); |
| 831 | 805 | |
| 832 | - self::$global_styles_block_names = array(); | |
| 833 | - | |
| 834 | 806 | foreach ( $block_nodes as $block_node ) { |
| 835 | 807 | // This block definition doesn't include any duotone settings. Skip it. |
| 836 | 808 | if ( empty( $block_node['duotone'] ) ) { |
| 837 | 809 | continue; |
| @@ -855,52 +827,34 @@ | ||
| 855 | 827 | if ( $slug && $slug !== $duotone_attr ) { |
| 856 | 828 | self::$global_styles_block_names[ $block_node['name'] ] = $slug; |
| 857 | 829 | } |
| 858 | 830 | } |
| 859 | - | |
| 860 | - return self::$global_styles_block_names; | |
| 861 | 831 | } |
| 862 | 832 | |
| 863 | 833 | /** |
| 864 | - * Ensure all possible global style block names are ready. | |
| 865 | - * This function is deprecated, as it's no longer necessary to handle this manually. | |
| 866 | - * It is kept to ensure external users of this method don't break. | |
| 867 | - * | |
| 868 | - * @since 6.3.0 | |
| 869 | - * @deprecated | |
| 870 | - */ | |
| 871 | - public static function set_global_style_block_names() { | |
| 872 | - _deprecated_function( __METHOD__, 'Gutenberg 22.5.0' ); | |
| 873 | - self::get_all_global_style_block_names(); | |
| 874 | - } | |
| 875 | - | |
| 876 | - /** | |
| 877 | 834 | * Render out the duotone CSS styles and SVG. |
| 878 | 835 | * |
| 879 | 836 | * @since 6.3.0 |
| 880 | 837 | * |
| 881 | - * @param string $block_content Rendered block content. | |
| 882 | - * @param array $block Block object. | |
| 883 | - * @param WP_Block $wp_block The block instance. | |
| 884 | - * @return string Filtered block content. | |
| 838 | + * @param string $block_content Rendered block content. | |
| 839 | + * @param array $block Block object. | |
| 840 | + * @return string Filtered block content. | |
| 885 | 841 | */ |
| 886 | - public static function render_duotone_support( $block_content, $block, $wp_block ) { | |
| 887 | - if ( ! $block['blockName'] ) { | |
| 842 | + public static function render_duotone_support( $block_content, $block ) { | |
| 843 | + if ( null === $block['blockName'] ) { | |
| 888 | 844 | return $block_content; |
| 889 | 845 | } |
| 890 | - $duotone_selector = self::get_selector( $wp_block->block_type ); | |
| 891 | 846 | |
| 892 | - if ( ! $duotone_selector ) { | |
| 893 | - return $block_content; | |
| 894 | - } | |
| 847 | + $duotone_selector = self::get_selector( $block['blockName'] ); | |
| 895 | 848 | |
| 896 | - $global_styles_block_names = self::get_all_global_style_block_names(); | |
| 897 | - | |
| 898 | 849 | // The block should have a duotone attribute or have duotone defined in its theme.json to be processed. |
| 899 | 850 | $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] ); |
| 900 | - $has_global_styles_duotone = array_key_exists( $block['blockName'], $global_styles_block_names ); | |
| 851 | + $has_global_styles_duotone = array_key_exists( $block['blockName'], self::$global_styles_block_names ); | |
| 901 | 852 | |
| 902 | - if ( ! $has_duotone_attribute && ! $has_global_styles_duotone ) { | |
| 853 | + if ( | |
| 854 | + ! $duotone_selector || | |
| 855 | + ( ! $has_duotone_attribute && ! $has_global_styles_duotone ) | |
| 856 | + ) { | |
| 903 | 857 | return $block_content; |
| 904 | 858 | } |
| 905 | 859 | |
| 906 | 860 | // Generate the pieces needed for rendering a duotone to the page. |
| @@ -943,9 +897,9 @@ | ||
| 943 | 897 | // SVG filter and block CSS. |
| 944 | 898 | self::enqueue_custom_filter( $filter_id, $duotone_selector, $filter_value, $filter_data ); |
| 945 | 899 | } |
| 946 | 900 | } elseif ( $has_global_styles_duotone ) { |
| 947 | - $slug = $global_styles_block_names[ $block['blockName'] ]; // e.g. 'blue-orange'. | |
| 901 | + $slug = self::$global_styles_block_names[ $block['blockName'] ]; // e.g. 'blue-orange'. | |
| 948 | 902 | $filter_id = self::get_filter_id( $slug ); // e.g. 'wp-duotone-filter-blue-orange'. |
| 949 | 903 | $filter_value = self::get_css_var( $slug ); // e.g. 'var(--wp--preset--duotone--blue-orange)'. |
| 950 | 904 | |
| 951 | 905 | // CSS custom property, SVG filter, and block CSS. |
| @@ -953,9 +907,9 @@ | ||
| 953 | 907 | } |
| 954 | 908 | |
| 955 | 909 | // Like the layout hook, this assumes the hook only applies to blocks with a single wrapper. |
| 956 | 910 | $tags = new WP_HTML_Tag_Processor( $block_content ); |
| 957 | - if ( $tags->next_tag() && isset( $filter_id ) ) { | |
| 911 | + if ( $tags->next_tag() ) { | |
| 958 | 912 | $tags->add_class( $filter_id ); |
| 959 | 913 | } |
| 960 | 914 | |
| 961 | 915 | return $tags->get_updated_html(); |
| @@ -986,10 +940,11 @@ | ||
| 986 | 940 | |
| 987 | 941 | $tags->set_bookmark( 'wrapper-div' ); |
| 988 | 942 | $tags->next_tag(); |
| 989 | 943 | |
| 990 | - foreach ( $tags->class_list() as $classname ) { | |
| 991 | - if ( str_starts_with( $classname, 'wp-duotone' ) ) { | |
| 944 | + $inner_classnames = explode( ' ', $tags->get_attribute( 'class' ) ); | |
| 945 | + foreach ( $inner_classnames as $classname ) { | |
| 946 | + if ( 0 === strpos( $classname, 'wp-duotone' ) ) { | |
| 992 | 947 | $tags->remove_class( $classname ); |
| 993 | 948 | $tags->seek( 'wrapper-div' ); |
| 994 | 949 | $tags->add_class( $classname ); |
| 995 | 950 | break; |
| @@ -1061,10 +1016,9 @@ | ||
| 1061 | 1016 | * @param array $settings The block editor settings from the `block_editor_settings_all` filter. |
| 1062 | 1017 | * @return array The editor settings with duotone SVGs and CSS custom properties. |
| 1063 | 1018 | */ |
| 1064 | 1019 | public static function add_editor_settings( $settings ) { |
| 1065 | - $global_styles_presets = self::get_all_global_styles_presets(); | |
| 1066 | - if ( ! empty( $global_styles_presets ) ) { | |
| 1020 | + if ( ! empty( self::$global_styles_presets ) ) { | |
| 1067 | 1021 | if ( ! isset( $settings['styles'] ) ) { |
| 1068 | 1022 | $settings['styles'] = array(); |
| 1069 | 1023 | } |
| 1070 | 1024 | |
| @@ -1069,9 +1023,9 @@ | ||
| 1069 | 1023 | } |
| 1070 | 1024 | |
| 1071 | 1025 | $settings['styles'][] = array( |
| 1072 | 1026 | // For the editor we can add all of the presets by default. |
| 1073 | - 'assets' => self::get_svg_definitions( $global_styles_presets ), | |
| 1027 | + 'assets' => self::get_svg_definitions( self::$global_styles_presets ), | |
| 1074 | 1028 | // The 'svgs' type is new in 6.3 and requires the corresponding JS changes in the EditorStyles component to work. |
| 1075 | 1029 | '__unstableType' => 'svgs', |
| 1076 | 1030 | // These styles not generated by global styles, so this must be false or they will be stripped out in gutenberg_get_block_editor_settings. |
| 1077 | 1031 | 'isGlobalStyles' => false, |
| @@ -1078,9 +1032,9 @@ | ||
| 1078 | 1032 | ); |
| 1079 | 1033 | |
| 1080 | 1034 | $settings['styles'][] = array( |
| 1081 | 1035 | // For the editor we can add all of the presets by default. |
| 1082 | - 'css' => self::get_global_styles_presets( $global_styles_presets ), | |
| 1036 | + 'css' => self::get_global_styles_presets( self::$global_styles_presets ), | |
| 1083 | 1037 | // This must be set and must be something other than 'theme' or they will be stripped out in the post editor <Editor> component. |
| 1084 | 1038 | '__unstableType' => 'presets', |
| 1085 | 1039 | // These styles are no longer generated by global styles, so this must be false or they will be stripped out in gutenberg_get_block_editor_settings. |
| 1086 | 1040 | 'isGlobalStyles' => false, |