PluginProbe
Gutenberg / 14.5.2
Gutenberg v14.5.2
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
← All changes | lib/block-supports/elements.php +60 -24 12.6.0 → 14.5.2 View file →
@@ -5,17 +5,33 @@
5 5 * @package gutenberg
6 6 */
7 7
8 8 /**
9 - * Render the elements stylesheet.
9 + * Get the elements class names.
10 10 *
11 + * @param array $block Block object.
12 + * @return string The unique class name.
13 + */
14 +function gutenberg_get_elements_class_name( $block ) {
15 + return 'wp-elements-' . md5( serialize( $block ) );
16 +}
17 +
18 +/**
19 + * Update the block content with elements class names.
20 + *
11 21 * @param string $block_content Rendered block content.
12 22 * @param array $block Block object.
13 23 * @return string Filtered block content.
14 24 */
15 25 function gutenberg_render_elements_support( $block_content, $block ) {
26 + if ( ! $block_content ) {
27 + return $block_content;
28 + }
16 29
17 - if ( ! $block_content ) {
30 + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
31 + $skip_link_color_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'color', 'link' );
32 +
33 + if ( $skip_link_color_serialization ) {
18 34 return $block_content;
19 35 }
20 36
21 37 $link_color = null;
@@ -32,20 +48,10 @@
32 48 if ( null === $link_color ) {
33 49 return $block_content;
34 50 }
35 51
36 - $class_name = 'wp-elements-' . uniqid();
52 + $class_name = gutenberg_get_elements_class_name( $block );
37 53
38 - if ( strpos( $link_color, 'var:preset|color|' ) !== false ) {
39 - // Get the name from the string and add proper styles.
40 - $index_to_splice = strrpos( $link_color, '|' ) + 1;
41 - $link_color_name = substr( $link_color, $index_to_splice );
42 - $link_color = "var(--wp--preset--color--$link_color_name)";
43 - }
44 - $link_color_declaration = esc_html( safecss_filter_attr( "color: $link_color" ) );
45 -
46 - $style = "<style>.$class_name a{" . $link_color_declaration . ";}</style>\n";
47 -
48 54 // Like the layout hook this assumes the hook only applies to blocks with a single wrapper.
49 55 // Retrieve the opening tag of the first HTML element.
50 56 $html_element_matches = array();
51 57 preg_match( '/<[^>]+>/', $block_content, $html_element_matches, PREG_OFFSET_CAPTURE );
@@ -51,9 +57,9 @@
51 57 preg_match( '/<[^>]+>/', $block_content, $html_element_matches, PREG_OFFSET_CAPTURE );
52 58 $first_element = $html_element_matches[0][0];
53 59 // If the first HTML element has a class attribute just add the new class
54 60 // as we do on layout and duotone.
55 - if ( strpos( $first_element, 'class="' ) !== false ) {
61 + if ( str_contains( $first_element, 'class="' ) ) {
56 62 $content = preg_replace(
57 63 '/' . preg_quote( 'class="', '/' ) . '/',
58 64 'class="' . $class_name . ' ',
59 65 $block_content,
@@ -64,20 +70,50 @@
64 70 $first_element_offset = $html_element_matches[0][1];
65 71 $content = substr_replace( $block_content, ' class="' . $class_name . '"', $first_element_offset + strlen( $first_element ) - 1, 0 );
66 72 }
67 73
68 - // Ideally styles should be loaded in the head, but blocks may be parsed
69 - // after that, so loading in the footer for now.
70 - // See https://core.trac.wordpress.org/ticket/53494.
71 - add_action(
72 - 'wp_footer',
73 - function () use ( $style ) {
74 - echo $style;
75 - }
74 + return $content;
75 +}
76 +
77 +/**
78 + * Render the elements stylesheet.
79 + *
80 + * In the case of nested blocks we want the parent element styles to be rendered before their descendants.
81 + * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant:
82 + * we want the descendant style to take priority, and this is done by loading it after, in DOM order.
83 + *
84 + * @param string|null $pre_render The pre-rendered content. Default null.
85 + * @param array $block The block being rendered.
86 + *
87 + * @return null
88 + */
89 +function gutenberg_render_elements_support_styles( $pre_render, $block ) {
90 + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
91 + $element_block_styles = isset( $block['attrs']['style']['elements'] ) ? $block['attrs']['style']['elements'] : null;
92 +
93 + /*
94 + * For now we only care about link color.
95 + */
96 + $skip_link_color_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'color', 'link' );
97 +
98 + if ( $skip_link_color_serialization ) {
99 + return null;
100 + }
101 + $class_name = gutenberg_get_elements_class_name( $block );
102 + $link_block_styles = isset( $element_block_styles['link'] ) ? $element_block_styles['link'] : null;
103 +
104 + gutenberg_style_engine_get_styles(
105 + $link_block_styles,
106 + array(
107 + 'selector' => ".$class_name a",
108 + 'context' => 'block-supports',
109 + )
76 110 );
77 111
78 - return $content;
112 + return null;
79 113 }
80 114
81 -// Remove WordPress core filter to avoid rendering duplicate elements stylesheet.
115 +// Remove WordPress core filters to avoid rendering duplicate elements stylesheet & attaching classes twice.
82 116 remove_filter( 'render_block', 'wp_render_elements_support', 10, 2 );
117 +remove_filter( 'pre_render_block', 'wp_render_elements_support_styles', 10, 2 );
83 118 add_filter( 'render_block', 'gutenberg_render_elements_support', 10, 2 );
119 +add_filter( 'pre_render_block', 'gutenberg_render_elements_support_styles', 10, 2 );