PluginProbe
Gutenberg / 23.7.2
Gutenberg v23.7.2
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 7.4.0 All 402 releases
gutenberg / lib / block-supports / position.php

position.php in Gutenberg 23.7.2, at lib/block-supports/position.php

149 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Position block support flag.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Registers the style block attribute for block types that support it.
10 *
11 * @param WP_Block_Type $block_type Block Type.
12 */
13 function gutenberg_register_position_support( $block_type ) {
14 $has_position_support = block_has_support( $block_type, array( 'position' ), false );
15
16 // Set up attributes and styles within that if needed.
17 if ( ! $block_type->attributes ) {
18 $block_type->attributes = array();
19 }
20
21 if ( $has_position_support && ! array_key_exists( 'style', $block_type->attributes ) ) {
22 $block_type->attributes['style'] = array(
23 'type' => 'object',
24 );
25 }
26 }
27
28 /**
29 * Renders position styles to the block wrapper.
30 *
31 * @param string $block_content Rendered block content.
32 * @param array $block Block object.
33 * @return string Filtered block content.
34 */
35 function gutenberg_render_position_support( $block_content, $block ) {
36 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
37 $has_position_support = block_has_support( $block_type, array( 'position' ), false );
38
39 if (
40 ! $has_position_support ||
41 empty( $block['attrs']['style']['position'] )
42 ) {
43 return $block_content;
44 }
45
46 $global_settings = gutenberg_get_global_settings();
47 $theme_has_sticky_support = $global_settings['position']['sticky'] ?? false;
48 $theme_has_fixed_support = $global_settings['position']['fixed'] ?? false;
49
50 // Only allow output for position types that the theme supports.
51 $allowed_position_types = array();
52 if ( true === $theme_has_sticky_support ) {
53 $allowed_position_types[] = 'sticky';
54 }
55 if ( true === $theme_has_fixed_support ) {
56 $allowed_position_types[] = 'fixed';
57 }
58
59 $style_attribute = $block['attrs']['style'] ?? null;
60 $class_name = wp_unique_id( 'wp-container-' );
61 $selector = ".$class_name";
62 $position_styles = array();
63 $position_type = $style_attribute['position']['type'] ?? '';
64 $wrapper_classes = array();
65
66 if (
67 in_array( $position_type, $allowed_position_types, true )
68 ) {
69 $wrapper_classes[] = $class_name;
70 $wrapper_classes[] = 'is-position-' . $position_type;
71 $sides = array( 'top', 'right', 'bottom', 'left' );
72
73 foreach ( $sides as $side ) {
74 $side_value = $style_attribute['position'][ $side ] ?? null;
75 if ( null !== $side_value ) {
76 /*
77 * For fixed or sticky top positions,
78 * ensure the value includes an offset for the logged in admin bar.
79 */
80 if (
81 'top' === $side &&
82 ( 'fixed' === $position_type || 'sticky' === $position_type )
83 ) {
84 // Ensure 0 values can be used in `calc()` calculations.
85 if ( '0' === $side_value || 0 === $side_value ) {
86 $side_value = '0px';
87 }
88
89 // Ensure current side value also factors in the height of the logged in admin bar.
90 $side_value = "calc($side_value + var(--wp-admin--admin-bar--position-offset, 0px))";
91 }
92
93 $position_styles[] =
94 array(
95 'selector' => $selector,
96 'declarations' => array(
97 $side => $side_value,
98 ),
99 );
100 }
101 }
102
103 $position_styles[] =
104 array(
105 'selector' => $selector,
106 'declarations' => array(
107 'position' => $position_type,
108 'z-index' => '10', // TODO: Replace hard-coded z-index value with a z-index preset approach in theme.json.
109 ),
110 );
111 }
112
113 if ( ! empty( $position_styles ) ) {
114 /*
115 * Add to the style engine store to enqueue and render position styles.
116 */
117 gutenberg_style_engine_get_stylesheet_from_css_rules(
118 $position_styles,
119 array(
120 'context' => 'block-supports',
121 'prettify' => false,
122 )
123 );
124
125 // Inject class name to block container markup.
126 $content = new WP_HTML_Tag_Processor( $block_content );
127 $content->next_tag();
128 foreach ( $wrapper_classes as $class ) {
129 $content->add_class( $class );
130 }
131 return (string) $content;
132 }
133
134 return $block_content;
135 }
136
137 // Register the block support. (overrides core one).
138 WP_Block_Supports::get_instance()->register(
139 'position',
140 array(
141 'register_attribute' => 'gutenberg_register_position_support',
142 )
143 );
144
145 if ( function_exists( 'wp_render_position_support' ) ) {
146 remove_filter( 'render_block', 'wp_render_position_support' );
147 }
148 add_filter( 'render_block', 'gutenberg_render_position_support', 10, 2 );
149