@wordpress/block-library 8.19.1 → 8.19.3

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 (54) hide show
  1. package/build/image/image.js +1 -1
  2. package/build/image/image.js.map +1 -1
  3. package/build/image/view.js +128 -27
  4. package/build/image/view.js.map +1 -1
  5. package/build/paragraph/edit.js +1 -1
  6. package/build/paragraph/edit.js.map +1 -1
  7. package/build/search/edit.js +12 -10
  8. package/build/search/edit.js.map +1 -1
  9. package/build/social-link/icons/index.js +11 -0
  10. package/build/social-link/icons/index.js.map +1 -1
  11. package/build/social-link/icons/x.js +22 -0
  12. package/build/social-link/icons/x.js.map +1 -0
  13. package/build/social-link/variations.js +8 -0
  14. package/build/social-link/variations.js.map +1 -1
  15. package/build-module/image/image.js +1 -1
  16. package/build-module/image/image.js.map +1 -1
  17. package/build-module/image/view.js +128 -27
  18. package/build-module/image/view.js.map +1 -1
  19. package/build-module/paragraph/edit.js +1 -1
  20. package/build-module/paragraph/edit.js.map +1 -1
  21. package/build-module/search/edit.js +12 -10
  22. package/build-module/search/edit.js.map +1 -1
  23. package/build-module/social-link/icons/index.js +1 -0
  24. package/build-module/social-link/icons/index.js.map +1 -1
  25. package/build-module/social-link/icons/x.js +14 -0
  26. package/build-module/social-link/icons/x.js.map +1 -0
  27. package/build-module/social-link/variations.js +9 -1
  28. package/build-module/social-link/variations.js.map +1 -1
  29. package/build-style/image/style-rtl.css +2 -6
  30. package/build-style/image/style.css +2 -6
  31. package/build-style/navigation/style-rtl.css +4 -4
  32. package/build-style/navigation/style.css +4 -4
  33. package/build-style/navigation-link/style-rtl.css +0 -1
  34. package/build-style/navigation-link/style.css +0 -1
  35. package/build-style/social-links/style-rtl.css +7 -0
  36. package/build-style/social-links/style.css +7 -0
  37. package/build-style/style-rtl.css +13 -11
  38. package/build-style/style.css +13 -11
  39. package/package.json +32 -32
  40. package/src/footnotes/index.php +13 -179
  41. package/src/image/image.js +1 -1
  42. package/src/image/index.php +9 -2
  43. package/src/image/style.scss +2 -6
  44. package/src/image/view.js +137 -44
  45. package/src/navigation/style.scss +4 -4
  46. package/src/navigation-link/style.scss +0 -1
  47. package/src/paragraph/edit.js +1 -1
  48. package/src/search/edit.js +16 -10
  49. package/src/social-link/icons/index.js +1 -0
  50. package/src/social-link/icons/x.js +10 -0
  51. package/src/social-link/index.php +8 -4
  52. package/src/social-link/socials-with-bg.scss +5 -0
  53. package/src/social-link/socials-without-bg.scss +4 -0
  54. package/src/social-link/variations.js +8 -0
@@ -1658,8 +1658,8 @@ h6.has-text-align-left[style*=writing-mode]:where([style*="vertical-lr"]) {
1658
1658
  }
1659
1659
  .wp-lightbox-overlay .close-button {
1660
1660
  position: absolute;
1661
- top: calc(env(safe-area-inset-top) + 12.5px);
1662
- right: calc(env(safe-area-inset-right) + 12.5px);
1661
+ top: calc(env(safe-area-inset-top) + 20px);
1662
+ right: calc(env(safe-area-inset-right) + 20px);
1663
1663
  padding: 0;
1664
1664
  cursor: pointer;
1665
1665
  z-index: 5000000;
@@ -1750,10 +1750,6 @@ h6.has-text-align-left[style*=writing-mode]:where([style*="vertical-lr"]) {
1750
1750
  }
1751
1751
  }
1752
1752
 
1753
- html.wp-has-lightbox-open {
1754
- overflow: hidden;
1755
- }
1756
-
1757
1753
  @keyframes turn-on-visibility {
1758
1754
  0% {
1759
1755
  opacity: 0;
@@ -2418,10 +2414,10 @@ button.wp-block-navigation-item__content {
2418
2414
  background-color: inherit;
2419
2415
  animation: overlay-menu__fade-in-animation 0.1s ease-out;
2420
2416
  animation-fill-mode: forwards;
2421
- padding-top: var(--wp--style--root--padding-top, 2rem);
2422
- padding-right: var(--wp--style--root--padding-right, 2rem);
2423
- padding-bottom: var(--wp--style--root--padding-bottom, 2rem);
2424
- padding-left: var(--wp--style--root--padding-left, 2rem);
2417
+ padding-top: clamp(1rem, var(--wp--style--root--padding-top), 20rem);
2418
+ padding-right: clamp(1rem, var(--wp--style--root--padding-right), 20rem);
2419
+ padding-bottom: clamp(1rem, var(--wp--style--root--padding-bottom), 20rem);
2420
+ padding-left: clamp(1rem, var(--wp--style--root--padding-left), 20em);
2425
2421
  overflow: auto;
2426
2422
  z-index: 100000;
2427
2423
  }
@@ -2598,7 +2594,6 @@ html.has-modal-open {
2598
2594
  }
2599
2595
 
2600
2596
  .wp-block-navigation .wp-block-navigation-item__label {
2601
- word-break: normal;
2602
2597
  overflow-wrap: break-word;
2603
2598
  }
2604
2599
  .wp-block-navigation .wp-block-navigation-item__description {
@@ -3501,6 +3496,10 @@ ul.wp-block-rss.is-grid li {
3501
3496
  background-color: #25d366;
3502
3497
  color: #fff;
3503
3498
  }
3499
+ .wp-block-social-links:not(.is-style-logos-only) .wp-social-link-x {
3500
+ background-color: #000;
3501
+ color: #fff;
3502
+ }
3504
3503
  .wp-block-social-links:not(.is-style-logos-only) .wp-social-link-yelp {
3505
3504
  background-color: #d32422;
3506
3505
  color: #fff;
@@ -3638,6 +3637,9 @@ ul.wp-block-rss.is-grid li {
3638
3637
  .wp-block-social-links.is-style-logos-only .wp-social-link-wordpress {
3639
3638
  color: #3499cd;
3640
3639
  }
3640
+ .wp-block-social-links.is-style-logos-only .wp-social-link-x {
3641
+ color: #000;
3642
+ }
3641
3643
  .wp-block-social-links.is-style-logos-only .wp-social-link-yelp {
3642
3644
  color: #d32422;
3643
3645
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-library",
3
- "version": "8.19.1",
3
+ "version": "8.19.3",
4
4
  "description": "Block library for the WordPress editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,36 +31,36 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.16.0",
34
- "@wordpress/a11y": "^3.42.1",
35
- "@wordpress/api-fetch": "^6.39.1",
36
- "@wordpress/autop": "^3.42.1",
37
- "@wordpress/blob": "^3.42.1",
38
- "@wordpress/block-editor": "^12.10.1",
39
- "@wordpress/blocks": "^12.19.1",
40
- "@wordpress/components": "^25.8.1",
41
- "@wordpress/compose": "^6.19.1",
42
- "@wordpress/core-data": "^6.19.1",
43
- "@wordpress/data": "^9.12.1",
44
- "@wordpress/date": "^4.42.1",
45
- "@wordpress/deprecated": "^3.42.1",
46
- "@wordpress/dom": "^3.42.1",
47
- "@wordpress/element": "^5.19.1",
48
- "@wordpress/escape-html": "^2.42.1",
49
- "@wordpress/hooks": "^3.42.1",
50
- "@wordpress/html-entities": "^3.42.1",
51
- "@wordpress/i18n": "^4.42.1",
52
- "@wordpress/icons": "^9.33.1",
53
- "@wordpress/interactivity": "^2.3.1",
54
- "@wordpress/keycodes": "^3.42.1",
55
- "@wordpress/notices": "^4.10.1",
56
- "@wordpress/primitives": "^3.40.1",
57
- "@wordpress/private-apis": "^0.24.1",
58
- "@wordpress/reusable-blocks": "^4.19.1",
59
- "@wordpress/rich-text": "^6.19.1",
60
- "@wordpress/server-side-render": "^4.19.1",
61
- "@wordpress/url": "^3.43.1",
62
- "@wordpress/viewport": "^5.19.1",
63
- "@wordpress/wordcount": "^3.42.1",
34
+ "@wordpress/a11y": "^3.42.3",
35
+ "@wordpress/api-fetch": "^6.39.3",
36
+ "@wordpress/autop": "^3.42.3",
37
+ "@wordpress/blob": "^3.42.3",
38
+ "@wordpress/block-editor": "^12.10.3",
39
+ "@wordpress/blocks": "^12.19.3",
40
+ "@wordpress/components": "^25.8.3",
41
+ "@wordpress/compose": "^6.19.3",
42
+ "@wordpress/core-data": "^6.19.3",
43
+ "@wordpress/data": "^9.12.3",
44
+ "@wordpress/date": "^4.42.3",
45
+ "@wordpress/deprecated": "^3.42.3",
46
+ "@wordpress/dom": "^3.42.3",
47
+ "@wordpress/element": "^5.19.3",
48
+ "@wordpress/escape-html": "^2.42.3",
49
+ "@wordpress/hooks": "^3.42.3",
50
+ "@wordpress/html-entities": "^3.42.3",
51
+ "@wordpress/i18n": "^4.42.3",
52
+ "@wordpress/icons": "^9.33.3",
53
+ "@wordpress/interactivity": "^2.3.3",
54
+ "@wordpress/keycodes": "^3.42.3",
55
+ "@wordpress/notices": "^4.10.3",
56
+ "@wordpress/primitives": "^3.40.3",
57
+ "@wordpress/private-apis": "^0.24.3",
58
+ "@wordpress/reusable-blocks": "^4.19.3",
59
+ "@wordpress/rich-text": "^6.19.3",
60
+ "@wordpress/server-side-render": "^4.19.3",
61
+ "@wordpress/url": "^3.43.3",
62
+ "@wordpress/viewport": "^5.19.3",
63
+ "@wordpress/wordcount": "^3.42.3",
64
64
  "change-case": "^4.1.2",
65
65
  "classnames": "^2.3.1",
66
66
  "colord": "^2.7.0",
@@ -78,5 +78,5 @@
78
78
  "publishConfig": {
79
79
  "access": "public"
80
80
  },
81
- "gitHead": "4987d16acb5c41b62704dc4f88225acb97ddd698"
81
+ "gitHead": "6256f93c37705d142f75a99f1fc808540ca7dca8"
82
82
  }
@@ -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,7 +372,7 @@ 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
378
  lightbox?.enabled || ( ! lightbox && lightboxSetting?.enabled );
@@ -64,7 +64,12 @@ function render_block_core_image( $attributes, $content, $block ) {
64
64
  }
65
65
 
66
66
  if ( $lightbox_enabled ) {
67
- return block_core_image_render_lightbox( $processor->get_updated_html(), $block->parsed_block );
67
+ // This render needs to happen in a filter with priority 15 to ensure that it
68
+ // runs after the duotone filter and that duotone styles are applied to the image
69
+ // in the lightbox. We also need to ensure that the lightbox works with any plugins
70
+ // that might use filters as well. We can consider removing this in the future if the
71
+ // way the blocks are rendered changes, or if a new kind of filter is introduced.
72
+ add_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15, 2 );
68
73
  }
69
74
 
70
75
  return $processor->get_updated_html();
@@ -267,7 +272,9 @@ function block_core_image_render_lightbox( $block_content, $block ) {
267
272
  aria-modal="false"
268
273
  data-wp-effect="effects.core.image.initLightbox"
269
274
  data-wp-on--keydown="actions.core.image.handleKeydown"
270
- data-wp-on--mousewheel="actions.core.image.hideLightbox"
275
+ data-wp-on--touchstart="actions.core.image.handleTouchStart"
276
+ data-wp-on--touchmove="actions.core.image.handleTouchMove"
277
+ data-wp-on--touchend="actions.core.image.handleTouchEnd"
271
278
  data-wp-on--click="actions.core.image.hideLightbox"
272
279
  >
273
280
  <button type="button" aria-label="$close_button_label" style="fill: $close_button_color" class="close-button" data-wp-on--click="actions.core.image.hideLightbox">
@@ -186,8 +186,8 @@
186
186
 
187
187
  .close-button {
188
188
  position: absolute;
189
- top: calc(env(safe-area-inset-top) + 12.5px);
190
- right: calc(env(safe-area-inset-right) + 12.5px);
189
+ top: calc(env(safe-area-inset-top) + 20px);
190
+ right: calc(env(safe-area-inset-right) + 20px);
191
191
  padding: 0;
192
192
  cursor: pointer;
193
193
  z-index: 5000000;
@@ -297,10 +297,6 @@
297
297
  }
298
298
  }
299
299
 
300
- html.wp-has-lightbox-open {
301
- overflow: hidden;
302
- }
303
-
304
300
  @keyframes turn-on-visibility {
305
301
  0% {
306
302
  opacity: 0;
package/src/image/view.js CHANGED
@@ -17,6 +17,69 @@ const focusableSelectors = [
17
17
  '[tabindex]:not([tabindex^="-"])',
18
18
  ];
19
19
 
20
+ /*
21
+ * Stores a context-bound scroll handler.
22
+ *
23
+ * This callback could be defined inline inside of the store
24
+ * object but it's created externally to avoid confusion about
25
+ * how its logic is called. This logic is not referenced directly
26
+ * by the directives in the markup because the scroll event we
27
+ * need to listen to is triggered on the window; so by defining it
28
+ * outside of the store, we signal that the behavior here is different.
29
+ * If we find a compelling reason to move it to the store, feel free.
30
+ *
31
+ * @type {Function}
32
+ */
33
+ let scrollCallback;
34
+
35
+ /*
36
+ * Tracks whether user is touching screen; used to
37
+ * differentiate behavior for touch and mouse input.
38
+ *
39
+ * @type {boolean}
40
+ */
41
+ let isTouching = false;
42
+
43
+ /*
44
+ * Tracks the last time the screen was touched; used to
45
+ * differentiate behavior for touch and mouse input.
46
+ *
47
+ * @type {number}
48
+ */
49
+ let lastTouchTime = 0;
50
+
51
+ /*
52
+ * Lightbox page-scroll handler: prevents scrolling.
53
+ *
54
+ * This handler is added to prevent scrolling behaviors that
55
+ * trigger content shift while the lightbox is open.
56
+ *
57
+ * It would be better to accomplish this through CSS alone, but
58
+ * using overflow: hidden is currently the only way to do so, and
59
+ * that causes the layout to shift and prevents the zoom animation
60
+ * from working in some cases because we're unable to account for
61
+ * the layout shift when doing the animation calculations. Instead,
62
+ * here we use JavaScript to prevent and reset the scrolling
63
+ * behavior. In the future, we may be able to use CSS or overflow: hidden
64
+ * instead to not rely on JavaScript, but this seems to be the best approach
65
+ * for now that provides the best visual experience.
66
+ *
67
+ * @param {Object} context Interactivity page context?
68
+ */
69
+ function handleScroll( context ) {
70
+ // We can't override the scroll behavior on mobile devices
71
+ // because doing so breaks the pinch to zoom functionality, and we
72
+ // want to allow users to zoom in further on the high-res image.
73
+ if ( ! isTouching && Date.now() - lastTouchTime > 450 ) {
74
+ // We are unable to use event.preventDefault() to prevent scrolling
75
+ // because the scroll event can't be canceled, so we reset the position instead.
76
+ window.scrollTo(
77
+ context.core.image.scrollLeftReset,
78
+ context.core.image.scrollTopReset
79
+ );
80
+ }
81
+ }
82
+
20
83
  store(
21
84
  {
22
85
  state: {
@@ -43,54 +106,49 @@ store(
43
106
 
44
107
  context.core.image.lightboxEnabled = true;
45
108
  setStyles( context, event );
46
- // Hide overflow only when the animation is in progress,
47
- // otherwise the removal of the scrollbars will draw attention
48
- // to itself and look like an error
49
- document.documentElement.classList.add(
50
- 'wp-has-lightbox-open'
109
+
110
+ context.core.image.scrollTopReset =
111
+ window.pageYOffset ||
112
+ document.documentElement.scrollTop;
113
+
114
+ // In most cases, this value will be 0, but this is included
115
+ // in case a user has created a page with horizontal scrolling.
116
+ context.core.image.scrollLeftReset =
117
+ window.pageXOffset ||
118
+ document.documentElement.scrollLeft;
119
+
120
+ // We define and bind the scroll callback here so
121
+ // that we can pass the context and as an argument.
122
+ // We may be able to change this in the future if we
123
+ // define the scroll callback in the store instead, but
124
+ // this approach seems to tbe clearest for now.
125
+ scrollCallback = handleScroll.bind( null, context );
126
+
127
+ // We need to add a scroll event listener to the window
128
+ // here because we are unable to otherwise access it via
129
+ // the Interactivity API directives. If we add a native way
130
+ // to access the window, we can remove this.
131
+ window.addEventListener(
132
+ 'scroll',
133
+ scrollCallback,
134
+ false
51
135
  );
52
136
  },
53
- hideLightbox: async ( { context, event } ) => {
137
+ hideLightbox: async ( { context } ) => {
54
138
  context.core.image.hideAnimationEnabled = true;
55
139
  if ( context.core.image.lightboxEnabled ) {
56
- // If scrolling, wait a moment before closing the lightbox.
57
- if (
58
- context.core.image.lightboxAnimation === 'fade'
59
- ) {
60
- context.core.image.scrollDelta += event.deltaY;
61
- if (
62
- event.type === 'mousewheel' &&
63
- Math.abs(
64
- window.scrollY -
65
- context.core.image.scrollDelta
66
- ) < 10
67
- ) {
68
- return;
69
- }
70
- } else if (
71
- context.core.image.lightboxAnimation === 'zoom'
72
- ) {
73
- // Disable scroll until the zoom animation ends.
74
- // Get the current page scroll position
75
- const scrollTop =
76
- window.pageYOffset ||
77
- document.documentElement.scrollTop;
78
- const scrollLeft =
79
- window.pageXOffset ||
80
- document.documentElement.scrollLeft;
81
- // if any scroll is attempted, set this to the previous value.
82
- window.onscroll = function () {
83
- window.scrollTo( scrollLeft, scrollTop );
84
- };
85
- // Enable scrolling after the animation finishes
86
- setTimeout( function () {
87
- window.onscroll = function () {};
88
- }, 400 );
89
- }
90
-
91
- document.documentElement.classList.remove(
92
- 'wp-has-lightbox-open'
93
- );
140
+ // We want to wait until the close animation is completed
141
+ // before allowing a user to scroll again. The duration of this
142
+ // animation is defined in the styles.scss and depends on if the
143
+ // animation is 'zoom' or 'fade', but in any case we should wait
144
+ // a few milliseconds longer than the duration, otherwise a user
145
+ // may scroll too soon and cause the animation to look sloppy.
146
+ setTimeout( function () {
147
+ window.removeEventListener(
148
+ 'scroll',
149
+ scrollCallback
150
+ );
151
+ }, 450 );
94
152
 
95
153
  context.core.image.lightboxEnabled = false;
96
154
  context.core.image.lastFocusedElement.focus( {
@@ -139,6 +197,27 @@ store(
139
197
  ref,
140
198
  } );
141
199
  },
200
+ handleTouchStart: () => {
201
+ isTouching = true;
202
+ },
203
+ handleTouchMove: ( { context, event } ) => {
204
+ // On mobile devices, we want to prevent triggering the
205
+ // scroll event because otherwise the page jumps around as
206
+ // we reset the scroll position. This also means that closing
207
+ // the lightbox requires that a user perform a simple tap. This
208
+ // may be changed in the future if we find a better alternative
209
+ // to override or reset the scroll position during swipe actions.
210
+ if ( context.core.image.lightboxEnabled ) {
211
+ event.preventDefault();
212
+ }
213
+ },
214
+ handleTouchEnd: () => {
215
+ // We need to wait a few milliseconds before resetting
216
+ // to ensure that pinch to zoom works consistently
217
+ // on mobile devices when the lightbox is open.
218
+ lastTouchTime = Date.now();
219
+ isTouching = false;
220
+ },
142
221
  },
143
222
  },
144
223
  },
@@ -266,6 +345,13 @@ store(
266
345
  }
267
346
  );
268
347
 
348
+ /*
349
+ * Computes styles for the lightbox and adds them to the document.
350
+ *
351
+ * @function
352
+ * @param {Object} context - An Interactivity API context
353
+ * @param {Object} event - A triggering event
354
+ */
269
355
  function setStyles( context, event ) {
270
356
  // The reference img element lies adjacent
271
357
  // to the event target button in the DOM.
@@ -434,6 +520,13 @@ function setStyles( context, event ) {
434
520
  `;
435
521
  }
436
522
 
523
+ /*
524
+ * Debounces a function call.
525
+ *
526
+ * @function
527
+ * @param {Function} func - A function to be called
528
+ * @param {number} wait - The time to wait before calling the function
529
+ */
437
530
  function debounce( func, wait = 50 ) {
438
531
  let timeout;
439
532
  return () => {
@@ -506,10 +506,10 @@ button.wp-block-navigation-item__content {
506
506
  @include reduce-motion("animation");
507
507
 
508
508
  // Try to inherit any root paddings set, so the X can align to a top-right aligned menu.
509
- padding-top: var(--wp--style--root--padding-top, 2rem);
510
- padding-right: var(--wp--style--root--padding-right, 2rem);
511
- padding-bottom: var(--wp--style--root--padding-bottom, 2rem);
512
- padding-left: var(--wp--style--root--padding-left, 2rem);
509
+ padding-top: clamp(1rem, var(--wp--style--root--padding-top), 20rem);
510
+ padding-right: clamp(1rem, var(--wp--style--root--padding-right), 20rem);
511
+ padding-bottom: clamp(1rem, var(--wp--style--root--padding-bottom), 20rem);
512
+ padding-left: clamp(1rem, var(--wp--style--root--padding-left), 20em);
513
513
 
514
514
  // Allow modal to scroll.
515
515
  overflow: auto;
@@ -5,7 +5,6 @@
5
5
  .wp-block-navigation {
6
6
  // This wraps just the innermost text for custom menu items.
7
7
  .wp-block-navigation-item__label {
8
- word-break: normal;
9
8
  overflow-wrap: break-word;
10
9
  }
11
10