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
gutenberg / lib / block-supports / settings.php

settings.php in Gutenberg 14.5.2, at lib/block-supports/settings.php

152 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Block level presets support.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Get the class name used on block level presets.
10 *
11 * @access private
12 *
13 * @param array $block Block object.
14 * @return string The unique class name.
15 */
16 function _gutenberg_get_presets_class_name( $block ) {
17 return 'wp-settings-' . md5( serialize( $block ) );
18 }
19
20 /**
21 * Update the block content with block level presets class name.
22 *
23 * @access private
24 *
25 * @param string $block_content Rendered block content.
26 * @param array $block Block object.
27 * @return string Filtered block content.
28 */
29 function _gutenberg_add_block_level_presets_class( $block_content, $block ) {
30 if ( ! $block_content ) {
31 return $block_content;
32 }
33
34 // return early if the block doesn't have support for settings.
35 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
36 if ( ! block_has_support( $block_type, array( '__experimentalSettings' ), false ) ) {
37 return $block_content;
38 }
39
40 // return early if no settings are found on the block attributes.
41 $block_settings = _wp_array_get( $block, array( 'attrs', 'settings' ), null );
42 if ( empty( $block_settings ) ) {
43 return $block_content;
44 }
45
46 $class_name = _gutenberg_get_presets_class_name( $block );
47
48 // Like the layout hook this assumes the hook only applies to blocks with a single wrapper.
49 // Retrieve the opening tag of the first HTML element.
50 $html_element_matches = array();
51 preg_match( '/<[^>]+>/', $block_content, $html_element_matches, PREG_OFFSET_CAPTURE );
52 $first_element = $html_element_matches[0][0];
53 // If the first HTML element has a class attribute just add the new class
54 // as we do on layout and duotone.
55 if ( strpos( $first_element, 'class="' ) !== false ) {
56 $content = preg_replace(
57 '/' . preg_quote( 'class="', '/' ) . '/',
58 'class="' . $class_name . ' ',
59 $block_content,
60 1
61 );
62 } else {
63 // If the first HTML element has no class attribute we should inject the attribute before the attribute at the end.
64 $first_element_offset = $html_element_matches[0][1];
65 $content = substr_replace( $block_content, ' class="' . $class_name . '"', $first_element_offset + strlen( $first_element ) - 1, 0 );
66 }
67
68 return $content;
69 }
70
71 /**
72 * Render the block level presets stylesheet.
73 *
74 * @access private
75 *
76 * @param string|null $pre_render The pre-rendered content. Default null.
77 * @param array $block The block being rendered.
78 *
79 * @return null
80 */
81 function _gutenberg_add_block_level_preset_styles( $pre_render, $block ) {
82 // Return early if the block has not support for descendent block styles.
83 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
84 if ( ! block_has_support( $block_type, array( '__experimentalSettings' ), false ) ) {
85 return null;
86 }
87
88 // return early if no settings are found on the block attributes.
89 $block_settings = _wp_array_get( $block, array( 'attrs', 'settings' ), null );
90 if ( empty( $block_settings ) ) {
91 return null;
92 }
93
94 $class_name = '.' . _gutenberg_get_presets_class_name( $block );
95
96 // the root selector for preset variables needs to target every possible block selector
97 // in order for the general setting to override any bock specific setting of a parent block or
98 // the site root.
99 $variables_root_selector = '*,[class*="wp-block"]';
100 $registry = WP_Block_Type_Registry::get_instance();
101 $blocks = $registry->get_all_registered();
102 foreach ( $blocks as $block_type ) {
103 if (
104 isset( $block_type->supports['__experimentalSelector'] ) &&
105 is_string( $block_type->supports['__experimentalSelector'] )
106 ) {
107 $variables_root_selector .= ',' . $block_type->supports['__experimentalSelector'];
108 }
109 }
110 $variables_root_selector = WP_Theme_JSON_6_1::scope_selector( $class_name, $variables_root_selector );
111
112 // Remove any potentially unsafe styles.
113 $theme_json_shape = WP_Theme_JSON_Gutenberg::remove_insecure_properties(
114 array(
115 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
116 'settings' => $block_settings,
117 )
118 );
119 $theme_json_object = new WP_Theme_JSON_Gutenberg( $theme_json_shape );
120
121 $styles = '';
122
123 // include preset css variables declaration on the stylesheet.
124 $styles .= $theme_json_object->get_stylesheet(
125 array( 'variables' ),
126 null,
127 array(
128 'root_selector' => $variables_root_selector,
129 'scope' => $class_name,
130 )
131 );
132
133 // include preset css classes on the the stylesheet.
134 $styles .= $theme_json_object->get_stylesheet(
135 array( 'presets' ),
136 null,
137 array(
138 'root_selector' => $class_name . ',' . $class_name . ' *',
139 'scope' => $class_name,
140 )
141 );
142
143 if ( ! empty( $styles ) ) {
144 gutenberg_enqueue_block_support_styles( $styles );
145 }
146
147 return null;
148 }
149
150 add_filter( 'render_block', '_gutenberg_add_block_level_presets_class', 10, 2 );
151 add_filter( 'pre_render_block', '_gutenberg_add_block_level_preset_styles', 10, 2 );
152