@wordpress/block-library 8.19.2 → 8.19.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/cover/edit/inspector-controls.js +1 -1
  3. package/build/cover/edit/inspector-controls.js.map +1 -1
  4. package/build/embed/edit.js +17 -0
  5. package/build/embed/edit.js.map +1 -1
  6. package/build/embed/edit.native.js +17 -0
  7. package/build/embed/edit.native.js.map +1 -1
  8. package/build/image/image.js +2 -2
  9. package/build/image/image.js.map +1 -1
  10. package/build/image/view.js +142 -31
  11. package/build/image/view.js.map +1 -1
  12. package/build/latest-posts/edit.js +6 -2
  13. package/build/latest-posts/edit.js.map +1 -1
  14. package/build/media-text/edit.js +1 -1
  15. package/build/media-text/edit.js.map +1 -1
  16. package/build/navigation/edit/deleted-navigation-warning.js +6 -4
  17. package/build/navigation/edit/deleted-navigation-warning.js.map +1 -1
  18. package/build/navigation/edit/index.js +3 -2
  19. package/build/navigation/edit/index.js.map +1 -1
  20. package/build/navigation/edit/inner-blocks.js +2 -1
  21. package/build/navigation/edit/inner-blocks.js.map +1 -1
  22. package/build/paragraph/edit.js +1 -1
  23. package/build/paragraph/edit.js.map +1 -1
  24. package/build/search/edit.js +12 -10
  25. package/build/search/edit.js.map +1 -1
  26. package/build-module/cover/edit/inspector-controls.js +1 -1
  27. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  28. package/build-module/embed/edit.js +17 -0
  29. package/build-module/embed/edit.js.map +1 -1
  30. package/build-module/embed/edit.native.js +17 -0
  31. package/build-module/embed/edit.native.js.map +1 -1
  32. package/build-module/image/image.js +2 -2
  33. package/build-module/image/image.js.map +1 -1
  34. package/build-module/image/view.js +142 -31
  35. package/build-module/image/view.js.map +1 -1
  36. package/build-module/latest-posts/edit.js +6 -2
  37. package/build-module/latest-posts/edit.js.map +1 -1
  38. package/build-module/media-text/edit.js +1 -1
  39. package/build-module/media-text/edit.js.map +1 -1
  40. package/build-module/navigation/edit/deleted-navigation-warning.js +7 -4
  41. package/build-module/navigation/edit/deleted-navigation-warning.js.map +1 -1
  42. package/build-module/navigation/edit/index.js +3 -2
  43. package/build-module/navigation/edit/index.js.map +1 -1
  44. package/build-module/navigation/edit/inner-blocks.js +2 -1
  45. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  46. package/build-module/paragraph/edit.js +1 -1
  47. package/build-module/paragraph/edit.js.map +1 -1
  48. package/build-module/search/edit.js +12 -10
  49. package/build-module/search/edit.js.map +1 -1
  50. package/build-style/image/style-rtl.css +17 -6
  51. package/build-style/image/style.css +17 -6
  52. package/build-style/navigation-link/style-rtl.css +0 -1
  53. package/build-style/navigation-link/style.css +0 -1
  54. package/build-style/post-featured-image/style-rtl.css +3 -0
  55. package/build-style/post-featured-image/style.css +3 -0
  56. package/build-style/post-template/style-rtl.css +25 -0
  57. package/build-style/post-template/style.css +25 -0
  58. package/build-style/style-rtl.css +46 -7
  59. package/build-style/style.css +46 -7
  60. package/package.json +32 -32
  61. package/src/cover/edit/inspector-controls.js +1 -1
  62. package/src/embed/edit.js +15 -0
  63. package/src/embed/edit.native.js +15 -0
  64. package/src/footnotes/index.php +13 -179
  65. package/src/image/image.js +2 -2
  66. package/src/image/index.php +73 -48
  67. package/src/image/style.scss +23 -6
  68. package/src/image/view.js +151 -48
  69. package/src/latest-posts/edit.js +10 -2
  70. package/src/latest-posts/index.php +18 -8
  71. package/src/media-text/edit.js +1 -1
  72. package/src/navigation/edit/deleted-navigation-warning.js +9 -4
  73. package/src/navigation/edit/index.js +26 -17
  74. package/src/navigation/edit/inner-blocks.js +1 -0
  75. package/src/navigation-link/style.scss +0 -1
  76. package/src/paragraph/edit.js +1 -1
  77. package/src/post-featured-image/style.scss +4 -0
  78. package/src/post-template/style.scss +20 -0
  79. package/src/search/edit.js +16 -10
@@ -39,15 +39,20 @@ function render_block_core_footnotes( $attributes, $content, $block ) {
39
39
  }
40
40
 
41
41
  $wrapper_attributes = get_block_wrapper_attributes();
42
+ $footnote_index = 1;
42
43
 
43
44
  $block_content = '';
44
45
 
45
46
  foreach ( $footnotes as $footnote ) {
47
+ // Translators: %d: Integer representing the number of return links on the page.
48
+ $aria_label = sprintf( __( 'Jump to footnote reference %1$d' ), $footnote_index );
46
49
  $block_content .= sprintf(
47
- '<li id="%1$s">%2$s <a href="#%1$s-link">↩︎</a></li>',
50
+ '<li id="%1$s">%2$s <a href="#%1$s-link" aria-label="%3$s">↩︎</a></li>',
48
51
  $footnote['id'],
49
- $footnote['content']
52
+ $footnote['content'],
53
+ $aria_label
50
54
  );
55
+ ++$footnote_index;
51
56
  }
52
57
 
53
58
  return sprintf(
@@ -68,9 +73,10 @@ function register_block_core_footnotes() {
68
73
  $post_type,
69
74
  'footnotes',
70
75
  array(
71
- 'show_in_rest' => true,
72
- 'single' => true,
73
- 'type' => 'string',
76
+ 'show_in_rest' => true,
77
+ 'single' => true,
78
+ 'type' => 'string',
79
+ 'revisions_enabled' => true,
74
80
  )
75
81
  );
76
82
  }
@@ -84,106 +90,7 @@ function register_block_core_footnotes() {
84
90
  add_action( 'init', 'register_block_core_footnotes' );
85
91
 
86
92
  /**
87
- * Saves the footnotes meta value to the revision.
88
- *
89
- * @since 6.3.0
90
- *
91
- * @param int $revision_id The revision ID.
92
- */
93
- function wp_save_footnotes_meta( $revision_id ) {
94
- $post_id = wp_is_post_revision( $revision_id );
95
-
96
- if ( $post_id ) {
97
- $footnotes = get_post_meta( $post_id, 'footnotes', true );
98
-
99
- if ( $footnotes ) {
100
- // Can't use update_post_meta() because it doesn't allow revisions.
101
- update_metadata( 'post', $revision_id, 'footnotes', wp_slash( $footnotes ) );
102
- }
103
- }
104
- }
105
- add_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' );
106
-
107
- /**
108
- * Keeps track of the revision ID for "rest_after_insert_{$post_type}".
109
- *
110
- * @since 6.3.0
111
- *
112
- * @global int $wp_temporary_footnote_revision_id The footnote revision ID.
113
- *
114
- * @param int $revision_id The revision ID.
115
- */
116
- function wp_keep_footnotes_revision_id( $revision_id ) {
117
- global $wp_temporary_footnote_revision_id;
118
- $wp_temporary_footnote_revision_id = $revision_id;
119
- }
120
- add_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' );
121
-
122
- /**
123
- * This is a specific fix for the REST API. The REST API doesn't update
124
- * the post and post meta in one go (through `meta_input`). While it
125
- * does fix the `wp_after_insert_post` hook to be called correctly after
126
- * updating meta, it does NOT fix hooks such as post_updated and
127
- * save_post, which are normally also fired after post meta is updated
128
- * in `wp_insert_post()`. Unfortunately, `wp_save_post_revision` is
129
- * added to the `post_updated` action, which means the meta is not
130
- * available at the time, so we have to add it afterwards through the
131
- * `"rest_after_insert_{$post_type}"` action.
132
- *
133
- * @since 6.3.0
134
- *
135
- * @global int $wp_temporary_footnote_revision_id The footnote revision ID.
136
- *
137
- * @param WP_Post $post The post object.
138
- */
139
- function wp_add_footnotes_revisions_to_post_meta( $post ) {
140
- global $wp_temporary_footnote_revision_id;
141
-
142
- if ( $wp_temporary_footnote_revision_id ) {
143
- $revision = get_post( $wp_temporary_footnote_revision_id );
144
-
145
- if ( ! $revision ) {
146
- return;
147
- }
148
-
149
- $post_id = $revision->post_parent;
150
-
151
- // Just making sure we're updating the right revision.
152
- if ( $post->ID === $post_id ) {
153
- $footnotes = get_post_meta( $post_id, 'footnotes', true );
154
-
155
- if ( $footnotes ) {
156
- // Can't use update_post_meta() because it doesn't allow revisions.
157
- update_metadata( 'post', $wp_temporary_footnote_revision_id, 'footnotes', wp_slash( $footnotes ) );
158
- }
159
- }
160
- }
161
- }
162
-
163
- add_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' );
164
- add_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' );
165
-
166
- /**
167
- * Restores the footnotes meta value from the revision.
168
- *
169
- * @since 6.3.0
170
- *
171
- * @param int $post_id The post ID.
172
- * @param int $revision_id The revision ID.
173
- */
174
- function wp_restore_footnotes_from_revision( $post_id, $revision_id ) {
175
- $footnotes = get_post_meta( $revision_id, 'footnotes', true );
176
-
177
- if ( $footnotes ) {
178
- update_post_meta( $post_id, 'footnotes', wp_slash( $footnotes ) );
179
- } else {
180
- delete_post_meta( $post_id, 'footnotes' );
181
- }
182
- }
183
- add_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision', 10, 2 );
184
-
185
- /**
186
- * Adds the footnotes field to the revision.
93
+ * Adds the footnotes field to the revisions display.
187
94
  *
188
95
  * @since 6.3.0
189
96
  *
@@ -197,7 +104,7 @@ function wp_add_footnotes_to_revision( $fields ) {
197
104
  add_filter( '_wp_post_revision_fields', 'wp_add_footnotes_to_revision' );
198
105
 
199
106
  /**
200
- * Gets the footnotes field from the revision.
107
+ * Gets the footnotes field from the revision for the revisions screen.
201
108
  *
202
109
  * @since 6.3.0
203
110
  *
@@ -211,76 +118,3 @@ function wp_get_footnotes_from_revision( $revision_field, $field, $revision ) {
211
118
  return get_metadata( 'post', $revision->ID, $field, true );
212
119
  }
213
120
  add_filter( '_wp_post_revision_field_footnotes', 'wp_get_footnotes_from_revision', 10, 3 );
214
-
215
- /**
216
- * The REST API autosave endpoint doesn't save meta, so we can use the
217
- * `wp_creating_autosave` when it updates an exiting autosave, and
218
- * `_wp_put_post_revision` when it creates a new autosave.
219
- *
220
- * @since 6.3.0
221
- *
222
- * @param int|array $autosave The autosave ID or array.
223
- */
224
- function _wp_rest_api_autosave_meta( $autosave ) {
225
- // Ensure it's a REST API request.
226
- if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
227
- return;
228
- }
229
-
230
- $body = rest_get_server()->get_raw_data();
231
- $body = json_decode( $body, true );
232
-
233
- if ( ! isset( $body['meta']['footnotes'] ) ) {
234
- return;
235
- }
236
-
237
- // `wp_creating_autosave` passes the array,
238
- // `_wp_put_post_revision` passes the ID.
239
- $id = is_int( $autosave ) ? $autosave : $autosave['ID'];
240
-
241
- if ( ! $id ) {
242
- return;
243
- }
244
-
245
- update_post_meta( $id, 'footnotes', wp_slash( $body['meta']['footnotes'] ) );
246
- }
247
- // See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L391C1-L391C1.
248
- add_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' );
249
- // See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L398.
250
- // Then https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/revision.php#L367.
251
- add_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' );
252
-
253
- /**
254
- * This is a workaround for the autosave endpoint returning early if the
255
- * revision field are equal. The problem is that "footnotes" is not real
256
- * revision post field, so there's nothing to compare against.
257
- *
258
- * This trick sets the "footnotes" field (value doesn't matter), which will
259
- * cause the autosave endpoint to always update the latest revision. That should
260
- * be fine, it should be ok to update the revision even if nothing changed. Of
261
- * course, this is temporary fix.
262
- *
263
- * @since 6.3.0
264
- *
265
- * @param WP_Post $prepared_post The prepared post object.
266
- * @param WP_REST_Request $request The request object.
267
- *
268
- * See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L365-L384.
269
- * See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L219.
270
- */
271
- function _wp_rest_api_force_autosave_difference( $prepared_post, $request ) {
272
- // We only want to be altering POST requests.
273
- if ( $request->get_method() !== 'POST' ) {
274
- return $prepared_post;
275
- }
276
-
277
- // Only alter requests for the '/autosaves' route.
278
- if ( substr( $request->get_route(), -strlen( '/autosaves' ) ) !== '/autosaves' ) {
279
- return $prepared_post;
280
- }
281
-
282
- $prepared_post->footnotes = '[]';
283
- return $prepared_post;
284
- }
285
-
286
- add_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference', 10, 2 );
@@ -372,10 +372,10 @@ export default function Image( {
372
372
  const lightboxSetting = useSetting( 'lightbox' );
373
373
 
374
374
  const showLightboxToggle =
375
- lightboxSetting === true || lightboxSetting?.allowEditing === true;
375
+ !! lightbox || lightboxSetting?.allowEditing === true;
376
376
 
377
377
  const lightboxChecked =
378
- lightbox?.enabled || ( ! lightbox && lightboxSetting?.enabled );
378
+ !! lightbox?.enabled || ( ! lightbox && !! lightboxSetting?.enabled );
379
379
 
380
380
  const dimensionsControl = (
381
381
  <DimensionsTool
@@ -9,10 +9,11 @@
9
9
  * Renders the `core/image` block on the server,
10
10
  * adding a data-id attribute to the element if core/gallery has added on pre-render.
11
11
  *
12
- * @param array $attributes The block attributes.
13
- * @param string $content The block content.
14
- * @param WP_Block $block The block object.
15
- * @return string Returns the block content with the data-id attribute added.
12
+ * @param array $attributes The block attributes.
13
+ * @param string $content The block content.
14
+ * @param WP_Block $block The block object.
15
+ *
16
+ * @return string The block content with the data-id attribute added.
16
17
  */
17
18
  function render_block_core_image( $attributes, $content, $block ) {
18
19
 
@@ -64,19 +65,25 @@ function render_block_core_image( $attributes, $content, $block ) {
64
65
  }
65
66
 
66
67
  if ( $lightbox_enabled ) {
67
- return block_core_image_render_lightbox( $processor->get_updated_html(), $block->parsed_block );
68
+ // This render needs to happen in a filter with priority 15 to ensure that it
69
+ // runs after the duotone filter and that duotone styles are applied to the image
70
+ // in the lightbox. We also need to ensure that the lightbox works with any plugins
71
+ // that might use filters as well. We can consider removing this in the future if the
72
+ // way the blocks are rendered changes, or if a new kind of filter is introduced.
73
+ add_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15, 2 );
68
74
  }
69
75
 
70
76
  return $processor->get_updated_html();
71
77
  }
72
78
 
73
79
  /**
74
- * Add the lightboxEnabled flag to the block data.
80
+ * Adds the lightboxEnabled flag to the block data.
75
81
  *
76
82
  * This is used to determine whether the lightbox should be rendered or not.
77
83
  *
78
- * @param array $block Block data.
79
- * @return array Filtered block data.
84
+ * @param array $block Block data.
85
+ *
86
+ * @return array Filtered block data.
80
87
  */
81
88
  function block_core_image_get_lightbox_settings( $block ) {
82
89
  // Get the lightbox setting from the block attributes.
@@ -108,43 +115,44 @@ function block_core_image_get_lightbox_settings( $block ) {
108
115
  }
109
116
 
110
117
  /**
111
- * Add the directives and layout needed for the lightbox behavior.
118
+ * Adds the directives and layout needed for the lightbox behavior.
119
+ *
120
+ * @param string $block_content Rendered block content.
121
+ * @param array $block Block object.
112
122
  *
113
- * @param string $block_content Rendered block content.
114
- * @param array $block Block object.
115
- * @return string Filtered block content.
123
+ * @return string Filtered block content.
116
124
  */
117
125
  function block_core_image_render_lightbox( $block_content, $block ) {
118
126
  $processor = new WP_HTML_Tag_Processor( $block_content );
119
127
 
120
128
  $aria_label = __( 'Enlarge image' );
121
129
 
130
+ $processor->next_tag( 'img' );
122
131
  $alt_attribute = $processor->get_attribute( 'alt' );
123
132
 
124
- if ( null !== $alt_attribute ) {
133
+ // An empty alt attribute `alt=""` is valid for decorative images.
134
+ if ( is_string( $alt_attribute ) ) {
125
135
  $alt_attribute = trim( $alt_attribute );
126
136
  }
127
137
 
138
+ // It only makes sense to append the alt text to the button aria-label when the alt text is non-empty.
128
139
  if ( $alt_attribute ) {
129
140
  /* translators: %s: Image alt text. */
130
141
  $aria_label = sprintf( __( 'Enlarge image: %s' ), $alt_attribute );
131
142
  }
132
- $content = $processor->get_updated_html();
133
143
 
134
144
  // Currently, we are only enabling the zoom animation.
135
145
  $lightbox_animation = 'zoom';
136
146
 
137
- // We want to store the src in the context so we can set it dynamically when the lightbox is opened.
138
- $z = new WP_HTML_Tag_Processor( $content );
139
- $z->next_tag( 'img' );
140
-
147
+ // Note: We want to store the `src` in the context so we
148
+ // can set it dynamically when the lightbox is opened.
141
149
  if ( isset( $block['attrs']['id'] ) ) {
142
150
  $img_uploaded_src = wp_get_attachment_url( $block['attrs']['id'] );
143
151
  $img_metadata = wp_get_attachment_metadata( $block['attrs']['id'] );
144
152
  $img_width = $img_metadata['width'];
145
153
  $img_height = $img_metadata['height'];
146
154
  } else {
147
- $img_uploaded_src = $z->get_attribute( 'src' );
155
+ $img_uploaded_src = $processor->get_attribute( 'src' );
148
156
  $img_width = 'none';
149
157
  $img_height = 'none';
150
158
  }
@@ -155,7 +163,7 @@ function block_core_image_render_lightbox( $block_content, $block ) {
155
163
  $scale_attr = false;
156
164
  }
157
165
 
158
- $w = new WP_HTML_Tag_Processor( $content );
166
+ $w = new WP_HTML_Tag_Processor( $block_content );
159
167
  $w->next_tag( 'figure' );
160
168
  $w->add_class( 'wp-lightbox-container' );
161
169
  $w->set_attribute( 'data-wp-interactive', true );
@@ -175,7 +183,8 @@ function block_core_image_render_lightbox( $block_content, $block ) {
175
183
  "imageCurrentSrc": "",
176
184
  "targetWidth": "%s",
177
185
  "targetHeight": "%s",
178
- "scaleAttr": "%s"
186
+ "scaleAttr": "%s",
187
+ "dialogLabel": "%s"
179
188
  }
180
189
  }
181
190
  }',
@@ -183,7 +192,8 @@ function block_core_image_render_lightbox( $block_content, $block ) {
183
192
  $img_uploaded_src,
184
193
  $img_width,
185
194
  $img_height,
186
- $scale_attr
195
+ $scale_attr,
196
+ __( 'Enlarged image' )
187
197
  )
188
198
  );
189
199
  $w->next_tag( 'img' );
@@ -195,19 +205,20 @@ function block_core_image_render_lightbox( $block_content, $block ) {
195
205
  // Wrap the image in the body content with a button.
196
206
  $img = null;
197
207
  preg_match( '/<img[^>]+>/', $body_content, $img );
198
- $button =
199
- '<button
200
- type="button"
201
- aria-haspopup="dialog"
202
- aria-label="' . esc_attr( $aria_label ) . '"
203
- data-wp-on--click="actions.core.image.showLightbox"
204
- data-wp-style--width="context.core.image.imageButtonWidth"
205
- data-wp-style--height="context.core.image.imageButtonHeight"
206
- data-wp-style--left="context.core.image.imageButtonLeft"
207
- data-wp-style--top="context.core.image.imageButtonTop"
208
- >
209
- </button>'
210
- . $img[0];
208
+
209
+ $button =
210
+ $img[0]
211
+ . '<button
212
+ type="button"
213
+ aria-haspopup="dialog"
214
+ aria-label="' . esc_attr( $aria_label ) . '"
215
+ data-wp-on--click="actions.core.image.showLightbox"
216
+ data-wp-style--width="context.core.image.imageButtonWidth"
217
+ data-wp-style--height="context.core.image.imageButtonHeight"
218
+ data-wp-style--left="context.core.image.imageButtonLeft"
219
+ data-wp-style--top="context.core.image.imageButtonTop"
220
+ ></button>';
221
+
211
222
  $body_content = preg_replace( '/<img[^>]+>/', $button, $body_content );
212
223
 
213
224
  // We need both a responsive image and an enlarged image to animate
@@ -215,7 +226,7 @@ function block_core_image_render_lightbox( $block_content, $block ) {
215
226
  // image is a copy of the one in the body, which animates immediately
216
227
  // as the lightbox is opened, while the enlarged one is a full-sized
217
228
  // version that will likely still be loading as the animation begins.
218
- $m = new WP_HTML_Tag_Processor( $content );
229
+ $m = new WP_HTML_Tag_Processor( $block_content );
219
230
  $m->next_tag( 'figure' );
220
231
  $m->add_class( 'responsive-image' );
221
232
  $m->next_tag( 'img' );
@@ -231,7 +242,7 @@ function block_core_image_render_lightbox( $block_content, $block ) {
231
242
  $m->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' );
232
243
  $initial_image_content = $m->get_updated_html();
233
244
 
234
- $q = new WP_HTML_Tag_Processor( $content );
245
+ $q = new WP_HTML_Tag_Processor( $block_content );
235
246
  $q->next_tag( 'figure' );
236
247
  $q->add_class( 'enlarged-image' );
237
248
  $q->next_tag( 'img' );
@@ -247,27 +258,37 @@ function block_core_image_render_lightbox( $block_content, $block ) {
247
258
  $q->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' );
248
259
  $enlarged_image_content = $q->get_updated_html();
249
260
 
250
- $background_color = esc_attr( wp_get_global_styles( array( 'color', 'background' ) ) );
261
+ // If the current theme does NOT have a `theme.json`, or the colors are not defined,
262
+ // we need to set the background color & close button color to some default values
263
+ // because we can't get them from the Global Styles.
264
+ $background_color = '#fff';
265
+ $close_button_color = '#000';
266
+ if ( wp_theme_has_theme_json() ) {
267
+ $global_styles_color = wp_get_global_styles( array( 'color' ) );
268
+ if ( ! empty( $global_styles_color['background'] ) ) {
269
+ $background_color = esc_attr( $global_styles_color['background'] );
270
+ }
271
+ if ( ! empty( $global_styles_color['text'] ) ) {
272
+ $close_button_color = esc_attr( $global_styles_color['text'] );
273
+ }
274
+ }
251
275
 
252
276
  $close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
253
- $close_button_color = esc_attr( wp_get_global_styles( array( 'color', 'text' ) ) );
254
- $dialog_label = $alt_attribute ? esc_attr( $alt_attribute ) : esc_attr__( 'Image' );
255
277
  $close_button_label = esc_attr__( 'Close' );
256
278
 
257
279
  $lightbox_html = <<<HTML
258
280
  <div data-wp-body="" class="wp-lightbox-overlay $lightbox_animation"
259
281
  data-wp-bind--role="selectors.core.image.roleAttribute"
260
- aria-label="$dialog_label"
282
+ data-wp-bind--aria-label="selectors.core.image.dialogLabel"
261
283
  data-wp-class--initialized="context.core.image.initialized"
262
284
  data-wp-class--active="context.core.image.lightboxEnabled"
263
285
  data-wp-class--hideAnimationEnabled="context.core.image.hideAnimationEnabled"
264
- data-wp-bind--aria-hidden="!context.core.image.lightboxEnabled"
265
- aria-hidden="true"
266
- data-wp-bind--aria-modal="context.core.image.lightboxEnabled"
267
- aria-modal="false"
286
+ data-wp-bind--aria-modal="selectors.core.image.ariaModal"
268
287
  data-wp-effect="effects.core.image.initLightbox"
269
288
  data-wp-on--keydown="actions.core.image.handleKeydown"
270
- data-wp-on--mousewheel="actions.core.image.hideLightbox"
289
+ data-wp-on--touchstart="actions.core.image.handleTouchStart"
290
+ data-wp-on--touchmove="actions.core.image.handleTouchMove"
291
+ data-wp-on--touchend="actions.core.image.handleTouchEnd"
271
292
  data-wp-on--click="actions.core.image.hideLightbox"
272
293
  >
273
294
  <button type="button" aria-label="$close_button_label" style="fill: $close_button_color" class="close-button" data-wp-on--click="actions.core.image.hideLightbox">
@@ -275,7 +296,7 @@ function block_core_image_render_lightbox( $block_content, $block ) {
275
296
  </button>
276
297
  <div class="lightbox-image-container">$initial_image_content</div>
277
298
  <div class="lightbox-image-container">$enlarged_image_content</div>
278
- <div class="scrim" style="background-color: $background_color"></div>
299
+ <div class="scrim" style="background-color: $background_color" aria-hidden="true"></div>
279
300
  </div>
280
301
  HTML;
281
302
 
@@ -283,11 +304,13 @@ HTML;
283
304
  }
284
305
 
285
306
  /**
286
- * Ensure that the view script has the `wp-interactivity` dependency.
307
+ * Ensures that the view script has the `wp-interactivity` dependency.
287
308
  *
288
309
  * @since 6.4.0
289
310
  *
290
311
  * @global WP_Scripts $wp_scripts
312
+ *
313
+ * @return void
291
314
  */
292
315
  function block_core_image_ensure_interactivity_dependency() {
293
316
  global $wp_scripts;
@@ -303,6 +326,8 @@ add_action( 'wp_print_scripts', 'block_core_image_ensure_interactivity_dependenc
303
326
 
304
327
  /**
305
328
  * Registers the `core/image` block on server.
329
+ *
330
+ * @return void
306
331
  */
307
332
  function register_block_core_image() {
308
333
  register_block_type_from_metadata(
@@ -154,6 +154,8 @@
154
154
 
155
155
  .wp-lightbox-container {
156
156
  position: relative;
157
+ display: flex;
158
+ flex-direction: column;
157
159
 
158
160
  button {
159
161
  border: none;
@@ -169,6 +171,13 @@
169
171
  outline: 5px auto -webkit-focus-ring-color;
170
172
  outline-offset: 5px;
171
173
  }
174
+
175
+ &:hover,
176
+ &:focus,
177
+ &:not(:hover):not(:active):not(.has-background) {
178
+ background: none;
179
+ border: none;
180
+ }
172
181
  }
173
182
  }
174
183
 
@@ -186,11 +195,23 @@
186
195
 
187
196
  .close-button {
188
197
  position: absolute;
189
- top: calc(env(safe-area-inset-top) + 12.5px);
190
- right: calc(env(safe-area-inset-right) + 12.5px);
198
+ top: calc(env(safe-area-inset-top) + 16px); // equivalent to $grid-unit-20
199
+ right: calc(env(safe-area-inset-right) + 16px); // equivalent to $grid-unit-20
191
200
  padding: 0;
192
201
  cursor: pointer;
193
202
  z-index: 5000000;
203
+ min-width: 40px; // equivalent to $button-size-next-default-40px
204
+ min-height: 40px; // equivalent to $button-size-next-default-40px
205
+ display: flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+
209
+ &:hover,
210
+ &:focus,
211
+ &:not(:hover):not(:active):not(.has-background) {
212
+ background: none;
213
+ border: none;
214
+ }
194
215
  }
195
216
 
196
217
  .lightbox-image-container {
@@ -297,10 +318,6 @@
297
318
  }
298
319
  }
299
320
 
300
- html.wp-has-lightbox-open {
301
- overflow: hidden;
302
- }
303
-
304
321
  @keyframes turn-on-visibility {
305
322
  0% {
306
323
  opacity: 0;