From 80997a41931ef96613db9102642d5cba5520c6c1 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Mon, 28 Aug 2023 10:25:27 +1000 Subject: [PATCH 01/56] Mobile Release v1.101.2 (#53936) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Release script: Update react-native-editor version to 1.101.0 * Release script: Update with changes from 'npm run core preios' * Update `react-native-editor` CHANGELOG * Remove incorrect CHANGELOG entry The iOS focus loop will be included in 1.100.2. I've updated the CHANGELOG accordingly. * Release script: Update react-native-editor version to 1.101.1 * Release script: Update with changes from '$PRE_IOS_COMMAND' * fix: Dynamic bottom sheet height (#53608) Stretching this content with flex appears to be necessary after upgrading React Native or refactoring the bottom sheet height animation. Refactor: 0411df13e1e8b832d8011e4fafe34436cd8fc773 Upgrade: c2957aa08de7e574d030f167ed8c5731c89e37af * fix: Optional chaining to handle undefined title (#53721) This PR adds safety checks for the `title` property within `reusableBlock`. By using optional chaining, the code now gracefully handles scenarios where `title` might be undefined, preventing a TypeError from being thrown. * Update CHANGELOG * Release script: Update react-native-editor version to 1.101.2 * Release script: Update with changes from 'npm run core preios' * [Mobile] - Fix Voice Over and assistive keyboards (#53895) * AztecView - Replace usage of TouchableWithoutFeedback with Pressable - This fixes the current React Native regression with VoiceOver and assistive keyboards * Patch React Native's TextInput component to avoid passing the recently introduced accessibilityState prop which causes issues with assistive keyboards * Updates snapshots: Fule, Audio blocks and Search component after changing the AztecView component to use Pressable * Update AztecView's Pressable with changing its accessible prop to false * Update Changelog --------- Co-authored-by: Siobhan Co-authored-by: David Calhoun Co-authored-by: Gerardo --- packages/react-native-editor/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index be8e0d33eaccc6..b8b7df73520cbc 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -19,6 +19,9 @@ For each user feature we should also add a importance categorization label to i - [**] Display outline around selected Social Link block [#53377] - [**] Fixes font customization not getting updated on iOS [#53391] +## 1.101.2 +- [**] Fix Voice Over and assistive keyboards [#53895] + ## 1.101.1 - [**] Fix the dynamic height when opening/closing navigation screens within the bottom sheet. [https://github.com/WordPress/gutenberg/pull/53608] From 1db3a34cb842878276714251afc7229816ef6251 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 28 Aug 2023 13:01:46 +1200 Subject: [PATCH 02/56] Cover block: fix exception when adding video background (#53961) --- .../block-library/src/cover/edit/index.js | 4 +- packages/block-library/src/cover/shared.js | 45 ++++++++++--------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/packages/block-library/src/cover/edit/index.js b/packages/block-library/src/cover/edit/index.js index 8409d33a2e1caf..932281b1ab6f1b 100644 --- a/packages/block-library/src/cover/edit/index.js +++ b/packages/block-library/src/cover/edit/index.js @@ -151,8 +151,10 @@ function CoverEdit( { const setMedia = attributesFromMedia( setAttributes, dimRatio ); const onSelectMedia = async ( newMedia ) => { + // Only pass the url to getCoverIsDark if the media is an image as video is not handled. + const newUrl = newMedia?.type === 'image' ? newMedia.url : undefined; const isDarkSetting = await getCoverIsDark( - newMedia.url, + newUrl, dimRatio, overlayColor.color ); diff --git a/packages/block-library/src/cover/shared.js b/packages/block-library/src/cover/shared.js index 1b9fdc0e566807..72a42c0d5c70b8 100644 --- a/packages/block-library/src/cover/shared.js +++ b/packages/block-library/src/cover/shared.js @@ -167,26 +167,31 @@ export async function getCoverIsDark( url, dimRatio = 50, overlayColor ) { .toRgb(); if ( url ) { - const imgCrossOrigin = applyFilters( - 'media.crossOrigin', - undefined, - url - ); - const { - value: [ r, g, b, a ], - } = await retrieveFastAverageColor().getColorAsync( url, { - // Previously the default color was white, but that changed - // in v6.0.0 so it has to be manually set now. - defaultColor: [ 255, 255, 255, 255 ], - // Errors that come up don't reject the promise, so error - // logging has to be silenced with this option. - silent: process.env.NODE_ENV === 'production', - crossOrigin: imgCrossOrigin, - } ); - // FAC uses 0-255 for alpha, but colord expects 0-1. - const media = { r, g, b, a: a / 255 }; - const composite = compositeSourceOver( overlay, media ); - return colord( composite ).isDark(); + try { + const imgCrossOrigin = applyFilters( + 'media.crossOrigin', + undefined, + url + ); + const { + value: [ r, g, b, a ], + } = await retrieveFastAverageColor().getColorAsync( url, { + // Previously the default color was white, but that changed + // in v6.0.0 so it has to be manually set now. + defaultColor: [ 255, 255, 255, 255 ], + // Errors that come up don't reject the promise, so error + // logging has to be silenced with this option. + silent: process.env.NODE_ENV === 'production', + crossOrigin: imgCrossOrigin, + } ); + // FAC uses 0-255 for alpha, but colord expects 0-1. + const media = { r, g, b, a: a / 255 }; + const composite = compositeSourceOver( overlay, media ); + return colord( composite ).isDark(); + } catch ( error ) { + // If there's an error, just assume the image is dark. + return true; + } } // Assume a white background because it isn't easy to get the actual From 6c2a629d47197dfa229739135c13eb6a147f7ca3 Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 28 Aug 2023 11:36:23 +1000 Subject: [PATCH 03/56] Date: add relative time translations for moment.js (#53931) * Overwriting wp-date script string to include new relateTime translations * Making the translator comments clearer because some languages change the case of indefinite articles * LINTY LINTY SPACEY SPACEY * comma comma comma comma comma chameleon * Move global inside check * Remove useless assignment * It's better to add this to lib/compat/wordpress-6.4/script-loader.php as it reflects the intended destination in Core and also communicates compatibility. --- lib/compat/wordpress-6.4/script-loader.php | 98 ++++++++++++++++++++++ lib/load.php | 1 + 2 files changed, 99 insertions(+) create mode 100644 lib/compat/wordpress-6.4/script-loader.php diff --git a/lib/compat/wordpress-6.4/script-loader.php b/lib/compat/wordpress-6.4/script-loader.php new file mode 100644 index 00000000000000..ac1b01700511f3 --- /dev/null +++ b/lib/compat/wordpress-6.4/script-loader.php @@ -0,0 +1,98 @@ +query( 'wp-date', 'registered' ) ) { + global $wp_locale; + // Calculate the timezone abbr (EDT, PST) if possible. + $timezone_string = get_option( 'timezone_string', 'UTC' ); + $timezone_abbr = ''; + + if ( ! empty( $timezone_string ) ) { + $timezone_date = new DateTime( 'now', new DateTimeZone( $timezone_string ) ); + $timezone_abbr = $timezone_date->format( 'T' ); + } + $scripts->registered['wp-date']->extra['after'] = array( + false, + sprintf( + 'wp.date.setSettings( %s );', + wp_json_encode( + array( + 'l10n' => array( + 'locale' => get_user_locale(), + 'months' => array_values( $wp_locale->month ), + 'monthsShort' => array_values( $wp_locale->month_abbrev ), + 'weekdays' => array_values( $wp_locale->weekday ), + 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), + 'meridiem' => (object) $wp_locale->meridiem, + 'relative' => array( + /* translators: %s: Duration. */ + 'future' => __( '%s from now', 'default' ), + /* translators: %s: Duration. */ + 'past' => __( '%s ago', 'default' ), + /* translators: One second from or to a particular datetime, e.g., "a second ago" or "a second from now". */ + 's' => __( 'a second', 'default' ), + /* translators: %s: Duration in seconds from or to a particular datetime, e.g., "4 seconds ago" or "4 seconds from now". */ + 'ss' => __( '%d seconds', 'default' ), + /* translators: One minute from or to a particular datetime, e.g., "a minute ago" or "a minute from now". */ + 'm' => __( 'a minute', 'default' ), + /* translators: %s: Duration in minutes from or to a particular datetime, e.g., "4 minutes ago" or "4 minutes from now". */ + 'mm' => __( '%d minutes', 'default' ), + /* translators: %s: One hour from or to a particular datetime, e.g., "an hour ago" or "an hour from now". */ + 'h' => __( 'an hour', 'default' ), + /* translators: %s: Duration in hours from or to a particular datetime, e.g., "4 hours ago" or "4 hours from now". */ + 'hh' => __( '%d hours', 'default' ), + /* translators: %s: One day from or to a particular datetime, e.g., "a day ago" or "a day from now". */ + 'd' => __( 'a day', 'default' ), + /* translators: %s: Duration in days from or to a particular datetime, e.g., "4 days ago" or "4 days from now". */ + 'dd' => __( '%d days', 'default' ), + /* translators: %s: One month from or to a particular datetime, e.g., "a month ago" or "a month from now". */ + 'M' => __( 'a month', 'default' ), + /* translators: %s: Duration in months from or to a particular datetime, e.g., "4 months ago" or "4 months from now". */ + 'MM' => __( '%d months', 'default' ), + /* translators: %s: One year from or to a particular datetime, e.g., "a year ago" or "a year from now". */ + 'y' => __( 'a year', 'default' ), + /* translators: %s: Duration in years from or to a particular datetime, e.g., "4 years ago" or "4 years from now". */ + 'yy' => __( '%d years', 'default' ), + ), + 'startOfWeek' => (int) get_option( 'start_of_week', 0 ), + ), + 'formats' => array( + /* translators: Time format, see https://www.php.net/manual/datetime.format.php */ + 'time' => get_option( 'time_format', __( 'g:i a', 'gutenberg' ) ), + /* translators: Date format, see https://www.php.net/manual/datetime.format.php */ + 'date' => get_option( 'date_format', __( 'F j, Y', 'gutenberg' ) ), + /* translators: Date/Time format, see https://www.php.net/manual/datetime.format.php */ + 'datetime' => __( 'F j, Y g:i a', 'default' ), + /* translators: Abbreviated date/time format, see https://www.php.net/manual/datetime.format.php */ + 'datetimeAbbreviated' => __( 'M j, Y g:i a', 'default' ), + ), + 'timezone' => array( + 'offset' => (float) get_option( 'gmt_offset', 0 ), + 'string' => $timezone_string, + 'abbr' => $timezone_abbr, + ), + ) + ) + ), + ); + } +} + +add_action( 'wp_default_scripts', 'gutenberg_update_wp_date_settings' ); + diff --git a/lib/load.php b/lib/load.php index 1db219dd681976..6560ef566d444b 100644 --- a/lib/load.php +++ b/lib/load.php @@ -122,6 +122,7 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.4 compat. require __DIR__ . '/compat/wordpress-6.4/blocks.php'; require __DIR__ . '/compat/wordpress-6.4/block-patterns.php'; +require __DIR__ . '/compat/wordpress-6.4/script-loader.php'; // Experimental features. require __DIR__ . '/experimental/block-editor-settings-mobile.php'; From dc061938197a1616a4256a7dc9ce919a641d69bd Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Mon, 28 Aug 2023 14:58:20 +1000 Subject: [PATCH 04/56] [RNMobile] Remove third-party dependency on react-native-hsv-color-picker (#53329) * Add hsv color picker components * Update Saturation Picker from source * Update Hue Picker from source * Update hsv-color-picker imports * Remove third-party dependency package react-native-hsv-color-picker * Update hsv-color-picker styles * Update CHANGELOG * Add tinycolor2 package * Remove dependency on tinycolor2 from hsv-color-picker * Remove tinycolor package reference * Revert empty change on initial editor html * Update hsv-color-picker container style * Add color-picker integration test * Update packages/components/src/color-picker/style.native.scss Co-authored-by: David Calhoun * Update packages/react-native-editor/CHANGELOG.md Co-authored-by: David Calhoun * Update Color Picker code style and test formatting * Update hsv-color-picker test ID * Remove color picker test Removes Color Picker test in favor of testing the color picker in a deeper editor tree, like Cover block * Update saturation picker imports --------- Co-authored-by: David Calhoun --- package-lock.json | 29 --- .../src/cover/test/edit.native.js | 6 +- .../color-picker/hsv-color-picker.native.js | 88 ++++++++ .../src/color-picker/hue-picker.native.js | 194 ++++++++++++++++++ .../src/color-picker/index.native.js | 3 +- .../color-picker/saturation-picker.native.js | 163 +++++++++++++++ .../src/color-picker/style.native.scss | 23 +++ packages/react-native-editor/CHANGELOG.md | 5 +- packages/react-native-editor/package.json | 1 - 9 files changed, 474 insertions(+), 38 deletions(-) create mode 100644 packages/components/src/color-picker/hsv-color-picker.native.js create mode 100644 packages/components/src/color-picker/hue-picker.native.js create mode 100644 packages/components/src/color-picker/saturation-picker.native.js diff --git a/package-lock.json b/package-lock.json index 9c62dde7f6eb89..98b0e5ebc2aea9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45968,15 +45968,6 @@ "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz", "integrity": "sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ==" }, - "node_modules/react-native-hsv-color-picker": { - "version": "1.0.1-wp-5", - "resolved": "https://raw.githubusercontent.com/wordpress-mobile/react-native-hsv-color-picker/v1.0.1-wp-5/react-native-hsv-color-picker-1.0.1-wp-5.tgz", - "integrity": "sha512-c8N3p7hPC3mN97hzloWG2s333JY2UuFlrEps5Njm1o1EHBKJAsPI5vKWBcdaFn68OKyQPdiEIV4A5lpDz9XNuw==", - "dependencies": { - "react-native-linear-gradient": "2.7.3", - "tinycolor2": "^1.4.1" - } - }, "node_modules/react-native-linear-gradient": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.7.3.tgz", @@ -50922,11 +50913,6 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -55943,7 +55929,6 @@ "react-native-fast-image": "8.5.11", "react-native-gesture-handler": "2.10.2", "react-native-get-random-values": "1.4.0", - "react-native-hsv-color-picker": "https://raw.githubusercontent.com/wordpress-mobile/react-native-hsv-color-picker/v1.0.1-wp-5/react-native-hsv-color-picker-1.0.1-wp-5.tgz", "react-native-linear-gradient": "2.7.3", "react-native-modal": "13.0.1", "react-native-prompt-android": "https://raw.githubusercontent.com/wordpress-mobile/react-native-prompt-android/v1.0.0-wp-4/react-native-prompt-android-1.0.0-wp-4.tgz", @@ -68199,7 +68184,6 @@ "react-native-fast-image": "8.5.11", "react-native-gesture-handler": "2.10.2", "react-native-get-random-values": "1.4.0", - "react-native-hsv-color-picker": "https://raw.githubusercontent.com/wordpress-mobile/react-native-hsv-color-picker/v1.0.1-wp-5/react-native-hsv-color-picker-1.0.1-wp-5.tgz", "react-native-linear-gradient": "2.7.3", "react-native-modal": "13.0.1", "react-native-prompt-android": "https://raw.githubusercontent.com/wordpress-mobile/react-native-prompt-android/v1.0.0-wp-4/react-native-prompt-android-1.0.0-wp-4.tgz", @@ -93750,14 +93734,6 @@ "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz", "integrity": "sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ==" }, - "react-native-hsv-color-picker": { - "version": "https://raw.githubusercontent.com/wordpress-mobile/react-native-hsv-color-picker/v1.0.1-wp-5/react-native-hsv-color-picker-1.0.1-wp-5.tgz", - "integrity": "sha512-c8N3p7hPC3mN97hzloWG2s333JY2UuFlrEps5Njm1o1EHBKJAsPI5vKWBcdaFn68OKyQPdiEIV4A5lpDz9XNuw==", - "requires": { - "react-native-linear-gradient": "2.7.3", - "tinycolor2": "^1.4.1" - } - }, "react-native-linear-gradient": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.7.3.tgz", @@ -97337,11 +97313,6 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, - "tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/packages/block-library/src/cover/test/edit.native.js b/packages/block-library/src/cover/test/edit.native.js index d5dffb3161a52a..8ca3d40967a27b 100644 --- a/packages/block-library/src/cover/test/edit.native.js +++ b/packages/block-library/src/cover/test/edit.native.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { Image, Pressable } from 'react-native'; +import { Image } from 'react-native'; import { getEditorHtml, initializeEditor, @@ -12,7 +12,6 @@ import { getBlock, openBlockSettings, } from 'test/helpers'; -import HsvColorPicker from 'react-native-hsv-color-picker'; /** * WordPress dependencies @@ -541,9 +540,6 @@ describe( 'color settings', () => { } ); it( 'displays the hex color value in the custom color picker', async () => { - HsvColorPicker.mockImplementation( ( props ) => { - return ; - } ); const screen = await initializeEditor( { initialHtml: COVER_BLOCK_PLACEHOLDER_HTML, } ); diff --git a/packages/components/src/color-picker/hsv-color-picker.native.js b/packages/components/src/color-picker/hsv-color-picker.native.js new file mode 100644 index 00000000000000..46499c94df5b3e --- /dev/null +++ b/packages/components/src/color-picker/hsv-color-picker.native.js @@ -0,0 +1,88 @@ +/** + * External dependencies + */ +import { View, Dimensions } from 'react-native'; + +/** + * WordPress dependencies + */ +import { useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import HuePicker from './hue-picker'; +import SaturationValuePicker from './saturation-picker'; +import styles from './style.native.scss'; + +const HsvColorPicker = ( props ) => { + const maxWidth = Dimensions.get( 'window' ).width - 32; + const satValPickerRef = useRef( null ); + + const { + containerStyle = {}, + currentColor, + huePickerContainerStyle = {}, + huePickerBorderRadius = 0, + huePickerHue = 0, + huePickerBarWidth = maxWidth, + huePickerBarHeight = 12, + huePickerSliderSize = 24, + onHuePickerDragStart, + onHuePickerDragMove, + onHuePickerDragEnd, + onHuePickerDragTerminate, + onHuePickerPress, + satValPickerContainerStyle = {}, + satValPickerBorderRadius = 0, + satValPickerSize = { width: maxWidth, height: 200 }, + satValPickerSliderSize = 24, + satValPickerHue = 0, + satValPickerSaturation = 1, + satValPickerValue = 1, + onSatValPickerDragStart, + onSatValPickerDragMove, + onSatValPickerDragEnd, + onSatValPickerDragTerminate, + onSatValPickerPress, + } = props; + + return ( + + + + + ); +}; + +export default HsvColorPicker; diff --git a/packages/components/src/color-picker/hue-picker.native.js b/packages/components/src/color-picker/hue-picker.native.js new file mode 100644 index 00000000000000..d7d391e1837656 --- /dev/null +++ b/packages/components/src/color-picker/hue-picker.native.js @@ -0,0 +1,194 @@ +/** + * External dependencies + */ +import { Animated, View, PanResponder } from 'react-native'; +import LinearGradient from 'react-native-linear-gradient'; + +/** + * WordPress dependencies + */ +import React, { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import styles from './style.scss'; + +export default class HuePicker extends Component { + constructor( props ) { + super( props ); + this.hueColors = [ + '#ff0000', + '#ffff00', + '#00ff00', + '#00ffff', + '#0000ff', + '#ff00ff', + '#ff0000', + ]; + this.sliderX = new Animated.Value( + ( props.barHeight * props.hue ) / 360 + ); + this.panResponder = PanResponder.create( { + onStartShouldSetPanResponder: () => true, + onStartShouldSetPanResponderCapture: () => true, + onMoveShouldSetPanResponder: () => true, + onMoveShouldSetPanResponderCapture: () => true, + onPanResponderGrant: ( evt, gestureState ) => { + const { onPress } = this.props; + this.dragStartValue = this.computeHueValuePress( evt ); + + if ( onPress ) { + onPress( { + hue: this.computeHueValuePress( evt ), + nativeEvent: evt.nativeEvent, + } ); + } + + this.fireDragEvent( 'onDragStart', gestureState ); + }, + onPanResponderMove: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragMove', gestureState ); + }, + onPanResponderTerminationRequest: () => true, + onPanResponderRelease: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragEnd', gestureState ); + }, + onPanResponderTerminate: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragTerminate', gestureState ); + }, + onShouldBlockNativeResponder: () => true, + } ); + } + + componentDidUpdate( prevProps ) { + const { hue = 0, barWidth = 200, sliderSize = 24 } = this.props; + const borderWidth = sliderSize / 10; + if ( prevProps.hue !== hue || prevProps.barWidth !== barWidth ) { + this.sliderX.setValue( + ( ( barWidth - sliderSize + borderWidth ) * hue ) / 360 + ); + } + } + + normalizeValue( value ) { + if ( value < 0 ) return 0; + if ( value > 1 ) return 1; + return value; + } + + getContainerStyle() { + const { + sliderSize = 24, + barHeight = 12, + containerStyle = {}, + } = this.props; + const paddingLeft = sliderSize / 2; + const paddingTop = + sliderSize - barHeight > 0 ? ( sliderSize - barHeight ) / 2 : 0; + return [ + styles[ 'hsv-container' ], + containerStyle, + { + paddingTop, + paddingBottom: paddingTop, + paddingLeft, + paddingRight: paddingLeft, + }, + ]; + } + + computeHueValueDrag( gestureState ) { + const { dx } = gestureState; + const { barWidth = 200 } = this.props; + const { dragStartValue } = this; + const diff = dx / barWidth; + const updatedHue = + this.normalizeValue( dragStartValue / 360 + diff ) * 360; + return updatedHue; + } + + computeHueValuePress( event ) { + const { nativeEvent } = event; + const { locationX } = nativeEvent; + const { barWidth = 200 } = this.props; + const updatedHue = this.normalizeValue( locationX / barWidth ) * 360; + return updatedHue; + } + + fireDragEvent( eventName, gestureState ) { + const { [ eventName ]: event } = this.props; + if ( event ) { + event( { + hue: this.computeHueValueDrag( gestureState ), + gestureState, + } ); + } + } + + firePressEvent( event ) { + const { onPress } = this.props; + if ( onPress ) { + onPress( { + hue: this.computeHueValuePress( event ), + nativeEvent: event.nativeEvent, + } ); + } + } + + render() { + const { hueColors } = this; + const { + sliderSize = 24, + barWidth = 200, + barHeight = 12, + borderRadius = 0, + } = this.props; + const borderWidth = sliderSize / 10; + return ( + + + + + + + ); + } +} diff --git a/packages/components/src/color-picker/index.native.js b/packages/components/src/color-picker/index.native.js index 1dfd2353cad1cc..a2fee512ce26ff 100644 --- a/packages/components/src/color-picker/index.native.js +++ b/packages/components/src/color-picker/index.native.js @@ -2,7 +2,6 @@ * External dependencies */ import { View, Text, TouchableWithoutFeedback, Platform } from 'react-native'; -import HsvColorPicker from 'react-native-hsv-color-picker'; import { colord, extend } from 'colord'; import namesPlugin from 'colord/plugins/names'; /** @@ -17,6 +16,7 @@ import { Icon, check, close } from '@wordpress/icons'; * Internal dependencies */ import styles from './style.scss'; +import HsvColorPicker from './hsv-color-picker.native.js'; extend( [ namesPlugin ] ); @@ -122,6 +122,7 @@ function ColorPicker( { <> true, + onStartShouldSetPanResponderCapture: () => true, + onMoveShouldSetPanResponder: () => true, + onMoveShouldSetPanResponderCapture: () => true, + onPanResponderGrant: ( evt, gestureState ) => { + const { onPress } = this.props; + const { saturation, value } = this.computeSatValPress( evt ); + this.dragStartValue = { + saturation, + value, + }; + + if ( onPress ) { + onPress( { + ...this.computeSatValPress( evt ), + nativeEvent: evt.nativeEvent, + } ); + } + + this.fireDragEvent( 'onDragStart', gestureState ); + }, + onPanResponderMove: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragMove', gestureState ); + }, + onPanResponderTerminationRequest: () => true, + onPanResponderRelease: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragEnd', gestureState ); + }, + onPanResponderTerminate: ( evt, gestureState ) => { + this.fireDragEvent( 'onDragTerminate', gestureState ); + }, + onShouldBlockNativeResponder: () => true, + } ); + } + + normalizeValue( value ) { + if ( value < 0 ) return 0; + if ( value > 1 ) return 1; + return value; + } + + computeSatValDrag( gestureState ) { + const { dx, dy } = gestureState; + const { size } = this.props; + const { saturation, value } = this.dragStartValue; + const diffx = dx / size.width; + const diffy = dy / size.height; + return { + saturation: this.normalizeValue( saturation + diffx ), + value: this.normalizeValue( value - diffy ), + }; + } + + computeSatValPress( event ) { + const { nativeEvent } = event; + const { locationX, locationY } = nativeEvent; + const { size } = this.props; + return { + saturation: this.normalizeValue( locationX / size.width ), + value: 1 - this.normalizeValue( locationY / size.height ), + }; + } + + fireDragEvent( eventName, gestureState ) { + const { [ eventName ]: event } = this.props; + if ( event ) { + event( { + ...this.computeSatValDrag( gestureState ), + gestureState, + } ); + } + } + + render() { + const { + size, + sliderSize = 24, + hue = 0, + value = 1, + saturation = 1, + containerStyle = {}, + borderRadius = 0, + currentColor, + } = this.props; + + return ( + + + + + + + + + ); + } +} diff --git a/packages/components/src/color-picker/style.native.scss b/packages/components/src/color-picker/style.native.scss index 9932830e4e313d..248a464ae4ad82 100644 --- a/packages/components/src/color-picker/style.native.scss +++ b/packages/components/src/color-picker/style.native.scss @@ -62,3 +62,26 @@ .pickerPointer { height: 16px; } + +.hsv-container { + justify-content: center; + align-items: center; +} + +.gradient-gontainer { + overflow: hidden; +} + +.saturation-slider { + top: 0; + left: 0; + position: absolute; + border-color: $white; +} + +.hue-slider { + position: absolute; + background-color: #fff; + box-shadow: 0 7px 10px rgba(0, 0, 0, 0.5); + z-index: 5; +} diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index b8b7df73520cbc..40793756cb2ce0 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -10,20 +10,21 @@ For each user feature we should also add a importance categorization label to i --> ## Unreleased +- [**] Replace third-party dependency react-native-hsv-color-picker with first-party code [#53329] - [*] Search Control - Prevent calling TextInput's methods when undefined [#53745] - [*] Improve horizontal rule styles to avoid invisible lines [#53883] - [*] Fix horizontal rule style extensions [#53917] ## 1.102.0 - [*] Display custom color value in mobile Cover Block color picker [#51414] -- [**] Display outline around selected Social Link block [#53377] +- [**] Display outline around selected Social Link block [#51414] - [**] Fixes font customization not getting updated on iOS [#53391] ## 1.101.2 - [**] Fix Voice Over and assistive keyboards [#53895] ## 1.101.1 -- [**] Fix the dynamic height when opening/closing navigation screens within the bottom sheet. [https://github.com/WordPress/gutenberg/pull/53608] +- [**] Fix the dynamic height when opening/closing navigation screens within the bottom sheet. [https://github.com/WordPress/gutenberg/pull/53608] ## 1.101.0 - [*] Remove visual gap in mobile toolbar when a Gallery block is selected [#52966] diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 9329554e5cf0f9..e312b57a17d155 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -61,7 +61,6 @@ "react-native-fast-image": "8.5.11", "react-native-gesture-handler": "2.10.2", "react-native-get-random-values": "1.4.0", - "react-native-hsv-color-picker": "https://raw.githubusercontent.com/wordpress-mobile/react-native-hsv-color-picker/v1.0.1-wp-5/react-native-hsv-color-picker-1.0.1-wp-5.tgz", "react-native-linear-gradient": "2.7.3", "react-native-modal": "13.0.1", "react-native-prompt-android": "https://raw.githubusercontent.com/wordpress-mobile/react-native-prompt-android/v1.0.0-wp-4/react-native-prompt-android-1.0.0-wp-4.tgz", From 4316be5fa8513003ebb5dbae36c793ab4885bee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeff=20Chi=20=E6=9D=B0=E5=A4=AB=E8=BF=9F?= Date: Mon, 28 Aug 2023 09:19:20 +0200 Subject: [PATCH 05/56] Make mid size parameter settable for Query Pagination block. (#51216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add attribute & context „midSize“ to pagination block. * Add and use QueryPaginationMidSizeControl in PaginationBlock. * React to new „midSize“ context in pagination numbers block. * Adjust unit tests. * Fix php errors from partial line commits. * Remove unneeded React import. * Move midSize control to query pagination numbers * Fix incorrect partial php commit * Get midSize param from attributes not context * Re-add missing array definition line * Update help description. * Remove unnecessary formatting changes * Fix formatting issue. * Move mid size control from own file into edit.js * Only pass mid_size if set; also for inherit query * Fix space alignment * Increase last pagination number to justify … gap * Rebuild test --- docs/reference-guides/core-blocks.md | 2 +- .../src/query-pagination-numbers/block.json | 6 ++ .../src/query-pagination-numbers/edit.js | 80 +++++++++++++++---- .../src/query-pagination-numbers/index.php | 9 ++- .../core__query-pagination-numbers.json | 4 +- .../blocks/core__query__deprecated-3.json | 4 +- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index c666802aa117aa..fde7f405558cc1 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -705,7 +705,7 @@ Displays a list of page numbers for pagination ([Source](https://github.com/Word - **Category:** theme - **Parent:** core/query-pagination - **Supports:** color (background, gradients, ~~text~~), typography (fontSize, lineHeight), ~~html~~, ~~reusable~~ -- **Attributes:** +- **Attributes:** midSize ## Previous Page diff --git a/packages/block-library/src/query-pagination-numbers/block.json b/packages/block-library/src/query-pagination-numbers/block.json index f00b2993a75f63..09b001c94dbf51 100644 --- a/packages/block-library/src/query-pagination-numbers/block.json +++ b/packages/block-library/src/query-pagination-numbers/block.json @@ -7,6 +7,12 @@ "parent": [ "core/query-pagination" ], "description": "Displays a list of page numbers for pagination", "textdomain": "default", + "attributes": { + "midSize": { + "type": "number", + "default": 2 + } + }, "usesContext": [ "queryId", "query" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/query-pagination-numbers/edit.js b/packages/block-library/src/query-pagination-numbers/edit.js index 3832f673ea1248..eb83204b2cca2b 100644 --- a/packages/block-library/src/query-pagination-numbers/edit.js +++ b/packages/block-library/src/query-pagination-numbers/edit.js @@ -1,25 +1,73 @@ /** * WordPress dependencies */ -import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; +import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; +import { PanelBody, RangeControl } from '@wordpress/components'; const createPaginationItem = ( content, Tag = 'a', extraClass = '' ) => ( - { content } + + { content } + ); -const previewPaginationNumbers = () => ( - <> - { createPaginationItem( 1 ) } - { createPaginationItem( 2 ) } - { createPaginationItem( 3, 'span', 'current' ) } - { createPaginationItem( 4 ) } - { createPaginationItem( 5 ) } - { createPaginationItem( '...', 'span', 'dots' ) } - { createPaginationItem( 8 ) } - -); +const previewPaginationNumbers = ( midSize ) => { + const paginationItems = []; + + // First set of pagination items. + for ( let i = 1; i <= midSize; i++ ) { + paginationItems.push( createPaginationItem( i ) ); + } + + // Current pagination item. + paginationItems.push( + createPaginationItem( midSize + 1, 'span', 'current' ) + ); + + // Second set of pagination items. + for ( let i = 1; i <= midSize; i++ ) { + paginationItems.push( createPaginationItem( midSize + 1 + i ) ); + } + + // Dots. + paginationItems.push( createPaginationItem( '...', 'span', 'dots' ) ); + + // Last pagination item. + paginationItems.push( createPaginationItem( midSize * 2 + 3 ) ); + + return <>{ paginationItems }; +}; -export default function QueryPaginationNumbersEdit() { - const paginationNumbers = previewPaginationNumbers(); - return
{ paginationNumbers }
; +export default function QueryPaginationNumbersEdit( { + attributes, + setAttributes, +} ) { + const { midSize } = attributes; + const paginationNumbers = previewPaginationNumbers( + parseInt( midSize, 10 ) + ); + return ( + <> + + + { + setAttributes( { + midSize: parseInt( value, 10 ), + } ); + } } + min={ 0 } + max={ 5 } + withInputField={ false } + /> + + +
{ paginationNumbers }
+ + ); } diff --git a/packages/block-library/src/query-pagination-numbers/index.php b/packages/block-library/src/query-pagination-numbers/index.php index 60fe85efa1f8dc..c37a4ae9fac7e2 100644 --- a/packages/block-library/src/query-pagination-numbers/index.php +++ b/packages/block-library/src/query-pagination-numbers/index.php @@ -22,6 +22,7 @@ function render_block_core_query_pagination_numbers( $attributes, $content, $blo $wrapper_attributes = get_block_wrapper_attributes(); $content = ''; global $wp_query; + $mid_size = isset( $block->attributes['midSize'] ) ? (int) $block->attributes['midSize'] : null; if ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ) { // Take into account if we have set a bigger `max page` // than what the query has. @@ -30,7 +31,10 @@ function render_block_core_query_pagination_numbers( $attributes, $content, $blo 'prev_next' => false, 'total' => $total, ); - $content = paginate_links( $paginate_args ); + if ( null !== $mid_size ) { + $paginate_args['mid_size'] = $mid_size; + } + $content = paginate_links( $paginate_args ); } else { $block_query = new WP_Query( build_query_vars_from_query_block( $block, $page ) ); // `paginate_links` works with the global $wp_query, so we have to @@ -45,6 +49,9 @@ function render_block_core_query_pagination_numbers( $attributes, $content, $blo 'total' => $total, 'prev_next' => false, ); + if ( null !== $mid_size ) { + $paginate_args['mid_size'] = $mid_size; + } if ( 1 !== $page ) { /** * `paginate_links` doesn't use the provided `format` when the page is `1`. diff --git a/test/integration/fixtures/blocks/core__query-pagination-numbers.json b/test/integration/fixtures/blocks/core__query-pagination-numbers.json index e5ef189320be2f..16ac2fb469f98a 100644 --- a/test/integration/fixtures/blocks/core__query-pagination-numbers.json +++ b/test/integration/fixtures/blocks/core__query-pagination-numbers.json @@ -2,7 +2,9 @@ { "name": "core/query-pagination-numbers", "isValid": true, - "attributes": {}, + "attributes": { + "midSize": 2 + }, "innerBlocks": [] } ] diff --git a/test/integration/fixtures/blocks/core__query__deprecated-3.json b/test/integration/fixtures/blocks/core__query__deprecated-3.json index bb9a9de34a4b78..d41ce2c5c826b7 100644 --- a/test/integration/fixtures/blocks/core__query__deprecated-3.json +++ b/test/integration/fixtures/blocks/core__query__deprecated-3.json @@ -100,7 +100,9 @@ { "name": "core/query-pagination-numbers", "isValid": true, - "attributes": {}, + "attributes": { + "midSize": 2 + }, "innerBlocks": [] }, { From 640150aedcaac50493b9614c4be28bcc60a01c5c Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Mon, 28 Aug 2023 10:36:11 +0200 Subject: [PATCH 06/56] Interactivity API: router with region-based client-side navigation (#53733) * Add router with region-based client-side navigation * Add changelog * Interactivity API: merge new server-side rendered context on client-side navigation (#53853) * Add failing test * Fix the test * Add changelog * Fix lint error * Fix changelog placement * Interactivity API: Support for the `data-wp-key` directive (#53844) * Add failing test * Fix test using key * Replace key with data-wp-key * Refactor test a bit * Add changelog * Add docs * Remove unnecessary paragraph * Fix lint error * Interactivity API: Fix non stable context reference on client side navigation (#53876) * Add failing test * Fix the test * Refactor addPostWithBlock util * Add tests for router regions --------- Co-authored-by: David Arenas --- .../directive-context/render.php | 13 ++ .../directive-context/view.js | 35 ++++- .../directive-key/block.json | 14 ++ .../directive-key/render.php | 18 +++ .../interactive-blocks/directive-key/view.js | 23 ++++ .../router-regions/block.json | 14 ++ .../router-regions/render.php | 89 ++++++++++++ .../interactive-blocks/router-regions/view.js | 43 ++++++ packages/interactivity/CHANGELOG.md | 6 + .../interactivity/docs/2-api-reference.md | 26 ++++ packages/interactivity/src/directives.js | 40 +++--- packages/interactivity/src/hooks.js | 1 + packages/interactivity/src/hydration.js | 22 --- packages/interactivity/src/index.js | 9 +- packages/interactivity/src/router.js | 127 ++++++++++++++++++ .../specs/interactivity/directive-key.spec.ts | 34 +++++ .../interactivity/directives-context.spec.ts | 27 ++++ .../fixtures/interactivity-utils.ts | 21 ++- .../interactivity/router-regions.spec.ts | 100 ++++++++++++++ 19 files changed, 611 insertions(+), 51 deletions(-) create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-key/block.json create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-key/render.php create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-key/view.js create mode 100644 packages/e2e-tests/plugins/interactive-blocks/router-regions/block.json create mode 100644 packages/e2e-tests/plugins/interactive-blocks/router-regions/render.php create mode 100644 packages/e2e-tests/plugins/interactive-blocks/router-regions/view.js delete mode 100644 packages/interactivity/src/hydration.js create mode 100644 packages/interactivity/src/router.js create mode 100644 test/e2e/specs/interactivity/directive-key.spec.ts create mode 100644 test/e2e/specs/interactivity/router-regions.spec.ts diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php index a9b0402d1b094e..e64686e02d5581 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php @@ -119,3 +119,16 @@ + +
+
+
+ + + + +
diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-context/view.js b/packages/e2e-tests/plugins/interactive-blocks/directive-context/view.js index 46483aaa2ea53d..1bab3946a3d4b5 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-context/view.js +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-context/view.js @@ -1,5 +1,19 @@ ( ( { wp } ) => { - const { store } = wp.interactivity; + const { store, navigate } = wp.interactivity; + + const html = ` +
+
+
+ + + + +
`; store( { derived: { @@ -17,6 +31,25 @@ toggleContextText: ( { context } ) => { context.text = context.text === 'Text 1' ? 'Text 2' : 'Text 1'; }, + toggleText: ( { context } ) => { + context.text = "changed dynamically"; + }, + addNewText: ( { context } ) => { + context.newText = 'some new text'; + }, + navigate: () => { + navigate( window.location, { + force: true, + html, + } ); + }, + asyncNavigate: async ({ context }) => { + await navigate( window.location, { + force: true, + html, + } ); + context.newText = 'changed from async action'; + } }, } ); } )( window ); diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-key/block.json b/packages/e2e-tests/plugins/interactive-blocks/directive-key/block.json new file mode 100644 index 00000000000000..0cbdd065e63a1d --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-key/block.json @@ -0,0 +1,14 @@ +{ + "apiVersion": 2, + "name": "test/directive-key", + "title": "E2E Interactivity tests - directive key", + "category": "text", + "icon": "heart", + "description": "", + "supports": { + "interactivity": true + }, + "textdomain": "e2e-interactivity", + "viewScript": "directive-key-view", + "render": "file:./render.php" +} diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-key/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-key/render.php new file mode 100644 index 00000000000000..07c6e4e3de161d --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-key/render.php @@ -0,0 +1,18 @@ + + +
+
    +
  • 2
  • +
  • 3
  • +
+ +
diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-key/view.js b/packages/e2e-tests/plugins/interactive-blocks/directive-key/view.js new file mode 100644 index 00000000000000..a155dec99e0aa9 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-key/view.js @@ -0,0 +1,23 @@ +( ( { wp } ) => { + const { store, navigate } = wp.interactivity; + + const html = ` +
+
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
+
`; + + store( { + actions: { + navigate: () => { + navigate( window.location, { + force: true, + html, + } ); + }, + }, + } ); +} )( window ); diff --git a/packages/e2e-tests/plugins/interactive-blocks/router-regions/block.json b/packages/e2e-tests/plugins/interactive-blocks/router-regions/block.json new file mode 100644 index 00000000000000..44cc260d87d3f6 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/router-regions/block.json @@ -0,0 +1,14 @@ +{ + "apiVersion": 2, + "name": "test/router-regions", + "title": "E2E Interactivity tests - router regions", + "category": "text", + "icon": "heart", + "description": "", + "supports": { + "interactivity": true + }, + "textdomain": "e2e-interactivity", + "viewScript": "router-regions-view", + "render": "file:./render.php" +} diff --git a/packages/e2e-tests/plugins/interactive-blocks/router-regions/render.php b/packages/e2e-tests/plugins/interactive-blocks/router-regions/render.php new file mode 100644 index 00000000000000..db6e75709f9792 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/router-regions/render.php @@ -0,0 +1,89 @@ + + +
+

Region 1

+
+

not hydrated

+

content from page

+ + + + + Next + + Back + +
+
+ +
+

not hydrated

+
+ + +
+

Region 2

+
+

not hydrated

+

content from page

+ + + +
+
+

not hydrated

+
+ +
+

Nested region

+
+

content from page

+
+
+
+
+
diff --git a/packages/e2e-tests/plugins/interactive-blocks/router-regions/view.js b/packages/e2e-tests/plugins/interactive-blocks/router-regions/view.js new file mode 100644 index 00000000000000..296c77d3ee7b38 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/router-regions/view.js @@ -0,0 +1,43 @@ +( ( { wp } ) => { + /** + * WordPress dependencies + */ + const { store, navigate } = wp.interactivity; + + store( { + state: { + region1: { + text: 'hydrated' + }, + region2: { + text: 'hydrated' + }, + counter: { + value: 0, + }, + }, + actions: { + router: { + navigate: async ( { event: e } ) => { + e.preventDefault(); + await navigate( e.target.href ); + }, + back: () => history.back(), + }, + counter: { + increment: ( { state, context } ) => { + if ( context.counter ) { + context.counter.value += 1; + } else { + state.counter.value += 1; + } + }, + init: ( { context } ) => { + if ( context.counter ) { + context.counter.value = context.counter.initialValue; + } + } + }, + }, + } ); +} )( window ); diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 6bff5ea1f4dea4..63da342d030a56 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +### Enhancements + +- Support keys using `data-wp-key`. ([#53844](https://github.com/WordPress/gutenberg/pull/53844)) +- Merge new server-side rendered context on client-side navigation. ([#53853](https://github.com/WordPress/gutenberg/pull/53853)) +- Support region-based client-side navigation. ([#53733](https://github.com/WordPress/gutenberg/pull/53733)) + ## 2.1.0 (2023-08-16) ### New Features diff --git a/packages/interactivity/docs/2-api-reference.md b/packages/interactivity/docs/2-api-reference.md index 64a4adf19b3dc0..828de4379c0269 100644 --- a/packages/interactivity/docs/2-api-reference.md +++ b/packages/interactivity/docs/2-api-reference.md @@ -22,6 +22,7 @@ DOM elements are connected to data stored in the state & context through directi - [`wp-on`](#wp-on) ![](https://img.shields.io/badge/EVENT_HANDLERS-afd2e3.svg) - [`wp-effect`](#wp-effect) ![](https://img.shields.io/badge/SIDE_EFFECTS-afd2e3.svg) - [`wp-init`](#wp-init) ![](https://img.shields.io/badge/SIDE_EFFECTS-afd2e3.svg) + - [`wp-key`](#wp-key) ![](https://img.shields.io/badge/TEMPLATING-afd2e3.svg) - [Values of directives are references to store properties](#values-of-directives-are-references-to-store-properties) - [The store](#the-store) - [Elements of the store](#elements-of-the-store) @@ -449,6 +450,31 @@ store( { The `wp-init` can return a function. If it does, the returned function will run when the element is removed from the DOM. +#### `wp-key` + + +The `wp-key` directive assigns a unique key to an element to help the Interactivity API identify it when iterating through arrays of elements. This becomes important if your array elements can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen key value helps the Interactivity API infer what exactly has changed in the array, allowing it to make the correct updates to the DOM. + +The key should be a string that uniquely identifies the element among its siblings. Typically it is used on repeated elements like list items. For example: + +```html +
    +
  • Item 1
  • +
  • Item 2
  • +
+``` + +But it can also be used on other elements: + +```html + +``` + +When the list is re-rendered, the Interactivity API will match elements by their keys to determine if an item was added/removed/reordered. Elements without keys might be recreated unnecessarily. + ### Values of directives are references to store properties The value assigned to a directive is a string pointing to a specific state, selector, action, or effect. *Using a Namespace is highly recommended* to define these elements of the store. diff --git a/packages/interactivity/src/directives.js b/packages/interactivity/src/directives.js index 16789bd9da0522..1b7a82be38cfaa 100644 --- a/packages/interactivity/src/directives.js +++ b/packages/interactivity/src/directives.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { useContext, useMemo, useEffect } from 'preact/hooks'; +import { useContext, useMemo, useEffect, useRef } from 'preact/hooks'; import { deepSignal, peek } from 'deepsignal'; /** @@ -14,18 +14,16 @@ import { directive } from './hooks'; const isObject = ( item ) => item && typeof item === 'object' && ! Array.isArray( item ); -const mergeDeepSignals = ( target, source ) => { +const mergeDeepSignals = ( target, source, overwrite ) => { for ( const k in source ) { - if ( typeof peek( target, k ) === 'undefined' ) { - target[ `$${ k }` ] = source[ `$${ k }` ]; - } else if ( - isObject( peek( target, k ) ) && - isObject( peek( source, k ) ) - ) { + if ( isObject( peek( target, k ) ) && isObject( peek( source, k ) ) ) { mergeDeepSignals( target[ `$${ k }` ].peek(), - source[ `$${ k }` ].peek() + source[ `$${ k }` ].peek(), + overwrite ); + } else if ( overwrite || typeof peek( target, k ) === 'undefined' ) { + target[ `$${ k }` ] = source[ `$${ k }` ]; } } }; @@ -36,20 +34,24 @@ export default () => { 'context', ( { directives: { - context: { default: context }, + context: { default: newContext }, }, props: { children }, - context: inherited, + context: inheritedContext, } ) => { - const { Provider } = inherited; - const inheritedValue = useContext( inherited ); - const value = useMemo( () => { - const localValue = deepSignal( context ); - mergeDeepSignals( localValue, inheritedValue ); - return localValue; - }, [ context, inheritedValue ] ); + const { Provider } = inheritedContext; + const inheritedValue = useContext( inheritedContext ); + const currentValue = useRef( deepSignal( {} ) ); + currentValue.current = useMemo( () => { + const newValue = deepSignal( newContext ); + mergeDeepSignals( newValue, inheritedValue ); + mergeDeepSignals( currentValue.current, newValue, true ); + return currentValue.current; + }, [ newContext, inheritedValue ] ); - return { children }; + return ( + { children } + ); }, { priority: 5 } ); diff --git a/packages/interactivity/src/hooks.js b/packages/interactivity/src/hooks.js index 448060caf2b2e0..d5b019300fed1a 100644 --- a/packages/interactivity/src/hooks.js +++ b/packages/interactivity/src/hooks.js @@ -205,6 +205,7 @@ options.vnode = ( vnode ) => { if ( vnode.props.__directives ) { const props = vnode.props; const directives = props.__directives; + if ( directives.key ) vnode.key = directives.key.default; delete props.__directives; const priorityLevels = getPriorityLevels( directives ); if ( priorityLevels.length > 0 ) { diff --git a/packages/interactivity/src/hydration.js b/packages/interactivity/src/hydration.js deleted file mode 100644 index e5a8e5128a1d14..00000000000000 --- a/packages/interactivity/src/hydration.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * External dependencies - */ -import { hydrate } from 'preact'; -/** - * Internal dependencies - */ -import { toVdom, hydratedIslands } from './vdom'; -import { createRootFragment } from './utils'; -import { directivePrefix } from './constants'; - -export const init = async () => { - document - .querySelectorAll( `[data-${ directivePrefix }-interactive]` ) - .forEach( ( node ) => { - if ( ! hydratedIslands.has( node ) ) { - const fragment = createRootFragment( node.parentNode, node ); - const vdom = toVdom( node ); - hydrate( vdom, fragment ); - } - } ); -}; diff --git a/packages/interactivity/src/index.js b/packages/interactivity/src/index.js index a3b942dc482be6..88e81e6f5877c0 100644 --- a/packages/interactivity/src/index.js +++ b/packages/interactivity/src/index.js @@ -2,20 +2,17 @@ * Internal dependencies */ import registerDirectives from './directives'; -import { init } from './hydration'; +import { init } from './router'; import { rawStore, afterLoads } from './store'; export { store } from './store'; export { directive } from './hooks'; +export { navigate, prefetch } from './router'; export { h as createElement } from 'preact'; export { useEffect, useContext, useMemo } from 'preact/hooks'; export { deepSignal } from 'deepsignal'; -/** - * Initialize the Interactivity API. - */ -registerDirectives(); - document.addEventListener( 'DOMContentLoaded', async () => { + registerDirectives(); await init(); afterLoads.forEach( ( afterLoad ) => afterLoad( rawStore ) ); } ); diff --git a/packages/interactivity/src/router.js b/packages/interactivity/src/router.js new file mode 100644 index 00000000000000..cc7925e2fc3981 --- /dev/null +++ b/packages/interactivity/src/router.js @@ -0,0 +1,127 @@ +/** + * External dependencies + */ +import { hydrate, render } from 'preact'; +/** + * Internal dependencies + */ +import { toVdom, hydratedIslands } from './vdom'; +import { createRootFragment } from './utils'; +import { directivePrefix } from './constants'; + +// The cache of visited and prefetched pages. +const pages = new Map(); + +// Keep the same root fragment for each interactive region node. +const regionRootFragments = new WeakMap(); +const getRegionRootFragment = ( region ) => { + if ( ! regionRootFragments.has( region ) ) { + regionRootFragments.set( + region, + createRootFragment( region.parentElement, region ) + ); + } + return regionRootFragments.get( region ); +}; + +// Helper to remove domain and hash from the URL. We are only interesting in +// caching the path and the query. +const cleanUrl = ( url ) => { + const u = new URL( url, window.location ); + return u.pathname + u.search; +}; + +// Fetch a new page and convert it to a static virtual DOM. +const fetchPage = async ( url, { html } ) => { + try { + if ( ! html ) { + const res = await window.fetch( url ); + if ( res.status !== 200 ) return false; + html = await res.text(); + } + const dom = new window.DOMParser().parseFromString( html, 'text/html' ); + return regionsToVdom( dom ); + } catch ( e ) { + return false; + } +}; + +// Return an object with VDOM trees of those HTML regions marked with a +// `navigation-id` directive. +const regionsToVdom = ( dom ) => { + const regions = {}; + const attrName = `data-${ directivePrefix }-navigation-id`; + dom.querySelectorAll( `[${ attrName }]` ).forEach( ( region ) => { + const id = region.getAttribute( attrName ); + regions[ id ] = toVdom( region ); + } ); + + return { regions }; +}; + +// Prefetch a page. We store the promise to avoid triggering a second fetch for +// a page if a fetching has already started. +export const prefetch = ( url, options = {} ) => { + url = cleanUrl( url ); + if ( options.force || ! pages.has( url ) ) { + pages.set( url, fetchPage( url, options ) ); + } +}; + +// Render all interactive regions contained in the given page. +const renderRegions = ( page ) => { + const attrName = `data-${ directivePrefix }-navigation-id`; + document.querySelectorAll( `[${ attrName }]` ).forEach( ( region ) => { + const id = region.getAttribute( attrName ); + const fragment = getRegionRootFragment( region ); + render( page.regions[ id ], fragment ); + } ); +}; + +// Navigate to a new page. +export const navigate = async ( href, options = {} ) => { + const url = cleanUrl( href ); + prefetch( url, options ); + const page = await pages.get( url ); + if ( page ) { + renderRegions( page ); + window.history[ options.replace ? 'replaceState' : 'pushState' ]( + {}, + '', + href + ); + } else { + window.location.assign( href ); + } +}; + +// Listen to the back and forward buttons and restore the page if it's in the +// cache. +window.addEventListener( 'popstate', async () => { + const url = cleanUrl( window.location ); // Remove hash. + const page = pages.has( url ) && ( await pages.get( url ) ); + if ( page ) { + renderRegions( page ); + } else { + window.location.reload(); + } +} ); + +// Initialize the router with the initial DOM. +export const init = async () => { + document + .querySelectorAll( `[data-${ directivePrefix }-interactive]` ) + .forEach( ( node ) => { + if ( ! hydratedIslands.has( node ) ) { + const fragment = getRegionRootFragment( node ); + const vdom = toVdom( node ); + hydrate( vdom, fragment ); + } + } ); + + // Cache the current regions. + pages.set( + cleanUrl( window.location ), + Promise.resolve( regionsToVdom( document ) ) + ); +}; diff --git a/test/e2e/specs/interactivity/directive-key.spec.ts b/test/e2e/specs/interactivity/directive-key.spec.ts new file mode 100644 index 00000000000000..b780100b92a6dc --- /dev/null +++ b/test/e2e/specs/interactivity/directive-key.spec.ts @@ -0,0 +1,34 @@ +/** + * Internal dependencies + */ +import { test, expect } from './fixtures'; + +test.describe( 'data-wp-key', () => { + test.beforeAll( async ( { interactivityUtils: utils } ) => { + await utils.activatePlugins(); + await utils.addPostWithBlock( 'test/directive-key' ); + } ); + + test.beforeEach( async ( { interactivityUtils: utils, page } ) => { + await page.goto( utils.getLink( 'test/directive-key' ) ); + } ); + + test.afterAll( async ( { interactivityUtils: utils } ) => { + await utils.deactivatePlugins(); + await utils.deleteAllPosts(); + } ); + + test( 'should keep the elements when adding items to the start of the array', async ( { + page, + } ) => { + // Add a number to the node so we can check later that it is still there. + await page + .getByTestId( 'first-item' ) + .evaluate( ( n ) => ( ( n as any )._id = 123 ) ); + await page.getByTestId( 'navigate' ).click(); + const id = await page + .getByTestId( 'second-item' ) + .evaluate( ( n ) => ( n as any )._id ); + expect( id ).toBe( 123 ); + } ); +} ); diff --git a/test/e2e/specs/interactivity/directives-context.spec.ts b/test/e2e/specs/interactivity/directives-context.spec.ts index 5c74e8054bf19d..f94784865cb757 100644 --- a/test/e2e/specs/interactivity/directives-context.spec.ts +++ b/test/e2e/specs/interactivity/directives-context.spec.ts @@ -162,4 +162,31 @@ test.describe( 'data-wp-context', () => { await expect( element ).toHaveText( 'Text 1' ); await expect( element ).toHaveAttribute( 'value', 'Text 1' ); } ); + + test( 'should replace values on navigation', async ( { page } ) => { + const element = page.getByTestId( 'navigation text' ); + await expect( element ).toHaveText( 'first page' ); + await page.getByTestId( 'toggle text' ).click(); + await expect( element ).toHaveText( 'changed dynamically' ); + await page.getByTestId( 'navigate' ).click(); + await expect( element ).toHaveText( 'second page' ); + } ); + + test( 'should preserve the previous context values', async ( { page } ) => { + const element = page.getByTestId( 'navigation new text' ); + await expect( element ).toHaveText( '' ); + await page.getByTestId( 'add new text' ).click(); + await expect( element ).toHaveText( 'some new text' ); + await page.getByTestId( 'navigate' ).click(); + await expect( element ).toHaveText( 'some new text' ); + } ); + + test( 'should maintain the same context reference on async actions', async ( { + page, + } ) => { + const element = page.getByTestId( 'navigation new text' ); + await expect( element ).toHaveText( '' ); + await page.getByTestId( 'async navigate' ).click(); + await expect( element ).toHaveText( 'changed from async action' ); + } ); } ); diff --git a/test/e2e/specs/interactivity/fixtures/interactivity-utils.ts b/test/e2e/specs/interactivity/fixtures/interactivity-utils.ts index 9d83c93650d403..fc0dc4b30d664e 100644 --- a/test/e2e/specs/interactivity/fixtures/interactivity-utils.ts +++ b/test/e2e/specs/interactivity/fixtures/interactivity-utils.ts @@ -3,6 +3,11 @@ */ import type { RequestUtils } from '@wordpress/e2e-test-utils-playwright'; +type AddPostWithBlockOptions = { + alias?: string; + attributes?: Record< string, any >; +}; + export default class InteractivityUtils { links: Map< string, string >; requestUtils: RequestUtils; @@ -28,15 +33,25 @@ export default class InteractivityUtils { return url.href; } - async addPostWithBlock( blockName: string ) { + async addPostWithBlock( + name: string, + { attributes, alias }: AddPostWithBlockOptions = {} + ) { + const block = attributes + ? `${ name } ${ JSON.stringify( attributes ) }` + : name; + + if ( ! alias ) alias = block; + const payload = { - content: ``, + content: ``, status: 'publish' as 'publish', date_gmt: '2023-01-01T00:00:00', }; const { link } = await this.requestUtils.createPost( payload ); - this.links.set( blockName, link ); + this.links.set( alias, link ); + return this.getLink( alias ); } async deleteAllPosts() { diff --git a/test/e2e/specs/interactivity/router-regions.spec.ts b/test/e2e/specs/interactivity/router-regions.spec.ts new file mode 100644 index 00000000000000..cbe66b7bd1b217 --- /dev/null +++ b/test/e2e/specs/interactivity/router-regions.spec.ts @@ -0,0 +1,100 @@ +/** + * Internal dependencies + */ +import { test, expect } from './fixtures'; + +test.describe( 'Router regions', () => { + test.beforeAll( async ( { interactivityUtils: utils } ) => { + await utils.activatePlugins(); + const next = await utils.addPostWithBlock( 'test/router-regions', { + alias: 'router regions - page 2', + attributes: { page: 2 }, + } ); + await utils.addPostWithBlock( 'test/router-regions', { + alias: 'router regions - page 1', + attributes: { page: 1, next }, + } ); + } ); + + test.beforeEach( async ( { interactivityUtils: utils, page } ) => { + await page.goto( utils.getLink( 'router regions - page 1' ) ); + } ); + + test.afterAll( async ( { interactivityUtils: utils } ) => { + await utils.deactivatePlugins(); + await utils.deleteAllPosts(); + } ); + + test( 'should be the only part hydrated', async ( { page } ) => { + const region1Text = page.getByTestId( 'region-1-text' ); + const region2Text = page.getByTestId( 'region-2-text' ); + const noRegionText1 = page.getByTestId( 'no-region-text-1' ); + const noRegionText2 = page.getByTestId( 'no-region-text-2' ); + + await expect( region1Text ).toHaveText( 'hydrated' ); + await expect( region2Text ).toHaveText( 'hydrated' ); + await expect( noRegionText1 ).toHaveText( 'not hydrated' ); + await expect( noRegionText2 ).toHaveText( 'not hydrated' ); + } ); + + test( 'should update after navigation', async ( { page } ) => { + const region1Ssr = page.getByTestId( 'region-1-ssr' ); + const region2Ssr = page.getByTestId( 'region-2-ssr' ); + + await expect( region1Ssr ).toHaveText( 'content from page 1' ); + await expect( region2Ssr ).toHaveText( 'content from page 1' ); + + await page.getByTestId( 'next' ).click(); + + await expect( region1Ssr ).toHaveText( 'content from page 2' ); + await expect( region2Ssr ).toHaveText( 'content from page 2' ); + + await page.getByTestId( 'back' ).click(); + + await expect( region1Ssr ).toHaveText( 'content from page 1' ); + await expect( region2Ssr ).toHaveText( 'content from page 1' ); + } ); + + test( 'should preserve state across pages', async ( { page } ) => { + const counter = page.getByTestId( 'state-counter' ); + await expect( counter ).toHaveText( '0' ); + + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '3' ); + + await page.getByTestId( 'next' ).click(); + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '6' ); + + await page.getByTestId( 'back' ).click(); + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '9' ); + } ); + + test( 'should preserve context across pages', async ( { page } ) => { + const counter = page.getByTestId( 'context-counter' ); + await expect( counter ).toHaveText( '0' ); + + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '3' ); + + await page.getByTestId( 'next' ).click(); + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '6' ); + + await page.getByTestId( 'back' ).click(); + await counter.click( { clickCount: 3, delay: 50 } ); + await expect( counter ).toHaveText( '9' ); + } ); + + test( 'can be nested', async ( { page } ) => { + const nestedRegionSsr = page.getByTestId( 'nested-region-ssr' ); + await expect( nestedRegionSsr ).toHaveText( 'content from page 1' ); + + await page.getByTestId( 'next' ).click(); + await expect( nestedRegionSsr ).toHaveText( 'content from page 2' ); + + await page.getByTestId( 'back' ).click(); + await expect( nestedRegionSsr ).toHaveText( 'content from page 1' ); + } ); +} ); From 12c60c785c2a34dce782b5f674b58ed54a8eaca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Walb=C3=B8=20Johnsg=C3=A5rd?= Date: Mon, 28 Aug 2023 11:00:06 +0200 Subject: [PATCH 07/56] Icons: Fix invalid namespaces (#53955) * Icons: Fix invalid XML namespace * Update CHANGELOG.md --- .../block-editor/src/components/color-style-selector/index.js | 2 +- packages/icons/CHANGELOG.md | 4 ++++ packages/icons/src/library/align-justify.js | 2 +- packages/icons/src/library/custom-link.js | 2 +- packages/icons/src/library/map-marker.js | 2 +- packages/icons/src/library/post-content.js | 2 +- packages/icons/src/library/title.js | 2 +- 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/color-style-selector/index.js b/packages/block-editor/src/components/color-style-selector/index.js index 957e3adc400e67..4a76a1da8369e2 100644 --- a/packages/block-editor/src/components/color-style-selector/index.js +++ b/packages/block-editor/src/components/color-style-selector/index.js @@ -13,7 +13,7 @@ import { DOWN } from '@wordpress/keycodes'; import deprecated from '@wordpress/deprecated'; const ColorSelectorSVGIcon = () => ( - + ); diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index 3a4df4e364c856..7ce0c1bbfa3ffb 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fix + +- Fixed invalid XML namespace on `alignJustify`, `customLink`, `mapMarker`, `postContent` and `title` ([#53955](https://github.com/WordPress/gutenberg/pull/53955)). + ## 9.31.0 (2023-08-16) ## 9.30.0 (2023-08-10) diff --git a/packages/icons/src/library/align-justify.js b/packages/icons/src/library/align-justify.js index 9fee191c0a71e2..f79a8bf06d5b2f 100644 --- a/packages/icons/src/library/align-justify.js +++ b/packages/icons/src/library/align-justify.js @@ -4,7 +4,7 @@ import { SVG, Path } from '@wordpress/primitives'; const alignJustify = ( - + ); diff --git a/packages/icons/src/library/custom-link.js b/packages/icons/src/library/custom-link.js index 27a5d24a71083e..b7aa7c309aaeb8 100644 --- a/packages/icons/src/library/custom-link.js +++ b/packages/icons/src/library/custom-link.js @@ -4,7 +4,7 @@ import { SVG, Path } from '@wordpress/primitives'; const customLink = ( - + ); diff --git a/packages/icons/src/library/map-marker.js b/packages/icons/src/library/map-marker.js index f142d17d352af2..52fa68e9590c3a 100644 --- a/packages/icons/src/library/map-marker.js +++ b/packages/icons/src/library/map-marker.js @@ -4,7 +4,7 @@ import { SVG, Path } from '@wordpress/primitives'; const mapMarker = ( - + ); diff --git a/packages/icons/src/library/post-content.js b/packages/icons/src/library/post-content.js index 4f9d6ce56ed83f..6047a5ad368f6b 100644 --- a/packages/icons/src/library/post-content.js +++ b/packages/icons/src/library/post-content.js @@ -4,7 +4,7 @@ import { SVG, Path } from '@wordpress/primitives'; const postContent = ( - + ); diff --git a/packages/icons/src/library/title.js b/packages/icons/src/library/title.js index d70f2fd52f6199..cf77753bc35f89 100644 --- a/packages/icons/src/library/title.js +++ b/packages/icons/src/library/title.js @@ -4,7 +4,7 @@ import { SVG, Path } from '@wordpress/primitives'; const title = ( - + ); From a9252ece268e0a458016d65d302440c46db9b044 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 28 Aug 2023 13:05:14 +0100 Subject: [PATCH 08/56] Always render the fallback Popover anchor within the Popover's parent element (#53982) --- packages/components/src/popover/index.tsx | 15 ++++++----- .../dot-tip/test/__snapshots__/index.js.snap | 2 +- .../nux/src/components/dot-tip/test/index.js | 26 ++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/components/src/popover/index.tsx b/packages/components/src/popover/index.tsx index c9cec1a5a565e0..21f81e0f09e807 100644 --- a/packages/components/src/popover/index.tsx +++ b/packages/components/src/popover/index.tsx @@ -569,17 +569,20 @@ const UnforwardedPopover = ( if ( shouldRenderWithinSlot ) { content = { content }; + } else if ( ! inline ) { + content = createPortal( content, getPopoverFallbackContainer() ); } - if ( ! hasAnchor ) { - content = { content }; - } - - if ( shouldRenderWithinSlot || inline ) { + if ( hasAnchor ) { return content; } - return createPortal( content, getPopoverFallbackContainer() ); + return ( + <> + + { content } + + ); }; /** diff --git a/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap b/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap index bfdb68b78cf578..29a743a5316de3 100644 --- a/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap +++ b/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap @@ -5,7 +5,7 @@ exports[`DotTip should render correctly 1`] = ` aria-label="Editor tips" class="components-popover nux-dot-tip is-positioned" role="dialog" - style="position: absolute; top: 0px; left: 0px; opacity: 0; transform: translateX(0px) translateY(0px) translateX(-2em) scale(0) translateZ(0); transform-origin: 0% 50% 0;" + style="position: absolute; top: 0px; left: 0px; opacity: 1; transform: none; transform-origin: 0% 50% 0;" tabindex="-1" >
{}; - describe( 'DotTip', () => { beforeEach( () => { jest.useFakeTimers(); @@ -20,26 +18,26 @@ describe( 'DotTip', () => { jest.useRealTimers(); } ); - it( 'should not render anything if invisible', async () => { + it( 'should not render anything if invisible', () => { render( It looks like you’re writing a letter. Would you like help? ); - await act( () => Promise.resolve() ); - expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument(); } ); it( 'should render correctly', async () => { render( - + It looks like you’re writing a letter. Would you like help? ); - await act( () => Promise.resolve() ); + await waitFor( () => + expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover() + ); expect( screen.getByRole( 'dialog' ) ).toMatchSnapshot(); } ); @@ -51,12 +49,14 @@ describe( 'DotTip', () => { const onDismiss = jest.fn(); render( - + It looks like you’re writing a letter. Would you like help? ); - await act( () => Promise.resolve() ); + await waitFor( () => + expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover() + ); await user.click( screen.getByRole( 'button', { name: 'Got it' } ) ); @@ -70,12 +70,14 @@ describe( 'DotTip', () => { const onDisable = jest.fn(); render( - + It looks like you’re writing a letter. Would you like help? ); - await act( () => Promise.resolve() ); + await waitFor( () => + expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover() + ); await user.click( screen.getByRole( 'button', { name: 'Disable tips' } ) From f2b1fc525f9a8b77a679d86b7b68c2dec8f31be9 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Mon, 28 Aug 2023 18:00:08 +0300 Subject: [PATCH 09/56] [Commands]: Add toggle list view command in site editor (#53983) --- .../hooks/commands/use-edit-mode-commands.js | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index 5b4f02eda8b4cd..6079c01773be78 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -14,6 +14,7 @@ import { blockDefault, code, keyboard, + listView, } from '@wordpress/icons'; import { useCommandLoader } from '@wordpress/commands'; import { decodeEntities } from '@wordpress/html-entities'; @@ -198,21 +199,27 @@ function useEditUICommands() { setIsListViewOpened, switchEditorMode, } = useDispatch( editSiteStore ); - const { canvasMode, editorMode, activeSidebar, showBlockBreadcrumbs } = - useSelect( - ( select ) => ( { - canvasMode: unlock( select( editSiteStore ) ).getCanvasMode(), - editorMode: select( editSiteStore ).getEditorMode(), - activeSidebar: select( - interfaceStore - ).getActiveComplementaryArea( editSiteStore.name ), - showBlockBreadcrumbs: select( preferencesStore ).get( - 'core/edit-site', - 'showBlockBreadcrumbs' - ), - } ), - [] - ); + const { + canvasMode, + editorMode, + activeSidebar, + showBlockBreadcrumbs, + isListViewOpen, + } = useSelect( ( select ) => { + const { isListViewOpened, getEditorMode } = select( editSiteStore ); + return { + canvasMode: unlock( select( editSiteStore ) ).getCanvasMode(), + editorMode: getEditorMode(), + activeSidebar: select( interfaceStore ).getActiveComplementaryArea( + editSiteStore.name + ), + showBlockBreadcrumbs: select( preferencesStore ).get( + 'core/edit-site', + 'showBlockBreadcrumbs' + ), + isListViewOpen: isListViewOpened(), + }; + }, [] ); const { openModal } = useDispatch( interfaceStore ); const { get: getPreference } = useSelect( preferencesStore ); const { set: setPreference, toggle } = useDispatch( preferencesStore ); @@ -341,6 +348,16 @@ function useEditUICommands() { }, } ); + commands.push( { + name: 'core/toggle-list-view', + label: __( 'Toggle list view' ), + icon: listView, + callback: ( { close } ) => { + setIsListViewOpened( ! isListViewOpen ); + close(); + }, + } ); + return { isLoading: false, commands, From 3a86baa5ec37c3480e7c6449cf5630f4178164b0 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 28 Aug 2023 11:50:35 -0400 Subject: [PATCH 10/56] Mobile Release v1.102.1 (#53946) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Release script: Update react-native-editor version to 1.102.0 * Release script: Update with changes from 'npm run core preios' * Bump version in package-lock.json * Update CHANGELOG to reflect latest release * Fix PR reference in CHANGELOG entry * Release script: Update react-native-editor version to 1.102.1 * Release script: Update with changes from 'npm run core preios' * [Mobile] - Fix Voice Over and assistive keyboards (#53895) * AztecView - Replace usage of TouchableWithoutFeedback with Pressable - This fixes the current React Native regression with VoiceOver and assistive keyboards * Patch React Native's TextInput component to avoid passing the recently introduced accessibilityState prop which causes issues with assistive keyboards * Updates snapshots: Fule, Audio blocks and Search component after changing the AztecView component to use Pressable * Update AztecView's Pressable with changing its accessible prop to false * docs: Add change log entry --------- Co-authored-by: Gio Lodi Co-authored-by: Siobhan Co-authored-by: Gerardo Pacheco --- package-lock.json | 6 +++--- packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/CHANGELOG.md | 5 ++++- packages/react-native-editor/ios/Podfile.lock | 8 ++++---- packages/react-native-editor/package.json | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98b0e5ebc2aea9..a5a0c340849e65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55869,7 +55869,7 @@ }, "packages/react-native-aztec": { "name": "@wordpress/react-native-aztec", - "version": "1.102.0", + "version": "1.102.1", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/element": "file:../element", @@ -55882,7 +55882,7 @@ }, "packages/react-native-bridge": { "name": "@wordpress/react-native-bridge", - "version": "1.102.0", + "version": "1.102.1", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/react-native-aztec": "file:../react-native-aztec" @@ -55893,7 +55893,7 @@ }, "packages/react-native-editor": { "name": "@wordpress/react-native-editor", - "version": "1.102.0", + "version": "1.102.1", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index a994c4a1cf0055..5b2c1b19adeaf5 100644 --- a/packages/react-native-aztec/package.json +++ b/packages/react-native-aztec/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-aztec", - "version": "1.102.0", + "version": "1.102.1", "description": "Aztec view for react-native.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json index ef9a381402aba5..ef36503a2ddbec 100644 --- a/packages/react-native-bridge/package.json +++ b/packages/react-native-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-bridge", - "version": "1.102.0", + "version": "1.102.1", "description": "Native bridge library used to integrate the block editor into a native App.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 40793756cb2ce0..f38723e92153cc 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -15,9 +15,12 @@ For each user feature we should also add a importance categorization label to i - [*] Improve horizontal rule styles to avoid invisible lines [#53883] - [*] Fix horizontal rule style extensions [#53917] +## 1.102.1 +- [**] Fix Voice Over and assistive keyboards [#53895] + ## 1.102.0 - [*] Display custom color value in mobile Cover Block color picker [#51414] -- [**] Display outline around selected Social Link block [#51414] +- [**] Display outline around selected Social Link block [#53377] - [**] Fixes font customization not getting updated on iOS [#53391] ## 1.101.2 diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index 6a6d35459071c9..170a7561517537 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - ReactCommon/turbomodule/core (= 0.71.11) - fmt (6.2.1) - glog (0.3.5) - - Gutenberg (1.102.0): + - Gutenberg (1.102.1): - React-Core (= 0.71.11) - React-CoreModules (= 0.71.11) - React-RCTImage (= 0.71.11) @@ -394,7 +394,7 @@ PODS: - React-RCTImage - RNSVG (13.9.0): - React-Core - - RNTAztecView (1.102.0): + - RNTAztecView (1.102.1): - React-Core - WordPress-Aztec-iOS (~> 1.19.8) - SDWebImage (5.11.1): @@ -577,7 +577,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: f07662560742d82a5b73cee116c70b0b49bcc220 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - Gutenberg: b4e5ee6c4271083049b46e31f98ab076e3d6a21a + Gutenberg: 656841784dff643159705b6f22e11b4149696e8c libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: f6187ec763637e6a57f5728dd9a3bdabc6d6b4e0 @@ -620,7 +620,7 @@ SPEC CHECKSUMS: RNReanimated: df2567658c01135f9ff4709d372675bcb9fd1d83 RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789 RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 - RNTAztecView: 660cdb1f9469ca251684c261f2bd0c700a1cc64e + RNTAztecView: f6bc15f12a0c97e22a7c5ed1c2c5e4e9e93e65b7 SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d WordPress-Aztec-iOS: 7d11d598f14c82c727c08b56bd35fbeb7dafb504 diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index e312b57a17d155..b57486f9bdf2b6 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-editor", - "version": "1.102.0", + "version": "1.102.1", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 58f5e9a6a972d16aeca13693ce863bcedaf342b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Aug 2023 01:54:36 +0200 Subject: [PATCH 11/56] Update translation domains (#53995) --- lib/compat/wordpress-6.4/script-loader.php | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/compat/wordpress-6.4/script-loader.php b/lib/compat/wordpress-6.4/script-loader.php index ac1b01700511f3..a81a1122f47fe4 100644 --- a/lib/compat/wordpress-6.4/script-loader.php +++ b/lib/compat/wordpress-6.4/script-loader.php @@ -42,41 +42,41 @@ function gutenberg_update_wp_date_settings( $scripts ) { 'meridiem' => (object) $wp_locale->meridiem, 'relative' => array( /* translators: %s: Duration. */ - 'future' => __( '%s from now', 'default' ), + 'future' => __( '%s from now', 'gutenberg' ), /* translators: %s: Duration. */ - 'past' => __( '%s ago', 'default' ), + 'past' => __( '%s ago', 'gutenberg' ), /* translators: One second from or to a particular datetime, e.g., "a second ago" or "a second from now". */ - 's' => __( 'a second', 'default' ), + 's' => __( 'a second', 'gutenberg' ), /* translators: %s: Duration in seconds from or to a particular datetime, e.g., "4 seconds ago" or "4 seconds from now". */ - 'ss' => __( '%d seconds', 'default' ), + 'ss' => __( '%d seconds', 'gutenberg' ), /* translators: One minute from or to a particular datetime, e.g., "a minute ago" or "a minute from now". */ - 'm' => __( 'a minute', 'default' ), + 'm' => __( 'a minute', 'gutenberg' ), /* translators: %s: Duration in minutes from or to a particular datetime, e.g., "4 minutes ago" or "4 minutes from now". */ - 'mm' => __( '%d minutes', 'default' ), + 'mm' => __( '%d minutes', 'gutenberg' ), /* translators: %s: One hour from or to a particular datetime, e.g., "an hour ago" or "an hour from now". */ - 'h' => __( 'an hour', 'default' ), + 'h' => __( 'an hour', 'gutenberg' ), /* translators: %s: Duration in hours from or to a particular datetime, e.g., "4 hours ago" or "4 hours from now". */ - 'hh' => __( '%d hours', 'default' ), + 'hh' => __( '%d hours', 'gutenberg' ), /* translators: %s: One day from or to a particular datetime, e.g., "a day ago" or "a day from now". */ - 'd' => __( 'a day', 'default' ), + 'd' => __( 'a day', 'gutenberg' ), /* translators: %s: Duration in days from or to a particular datetime, e.g., "4 days ago" or "4 days from now". */ - 'dd' => __( '%d days', 'default' ), + 'dd' => __( '%d days', 'gutenberg' ), /* translators: %s: One month from or to a particular datetime, e.g., "a month ago" or "a month from now". */ - 'M' => __( 'a month', 'default' ), + 'M' => __( 'a month', 'gutenberg' ), /* translators: %s: Duration in months from or to a particular datetime, e.g., "4 months ago" or "4 months from now". */ - 'MM' => __( '%d months', 'default' ), + 'MM' => __( '%d months', 'gutenberg' ), /* translators: %s: One year from or to a particular datetime, e.g., "a year ago" or "a year from now". */ - 'y' => __( 'a year', 'default' ), + 'y' => __( 'a year', 'gutenberg' ), /* translators: %s: Duration in years from or to a particular datetime, e.g., "4 years ago" or "4 years from now". */ - 'yy' => __( '%d years', 'default' ), + 'yy' => __( '%d years', 'gutenberg' ), ), 'startOfWeek' => (int) get_option( 'start_of_week', 0 ), ), 'formats' => array( /* translators: Time format, see https://www.php.net/manual/datetime.format.php */ - 'time' => get_option( 'time_format', __( 'g:i a', 'gutenberg' ) ), + 'time' => get_option( 'time_format', __( 'g:i a', 'default' ) ), /* translators: Date format, see https://www.php.net/manual/datetime.format.php */ - 'date' => get_option( 'date_format', __( 'F j, Y', 'gutenberg' ) ), + 'date' => get_option( 'date_format', __( 'F j, Y', 'default' ) ), /* translators: Date/Time format, see https://www.php.net/manual/datetime.format.php */ 'datetime' => __( 'F j, Y g:i a', 'default' ), /* translators: Abbreviated date/time format, see https://www.php.net/manual/datetime.format.php */ From 902a30071f52f9ac8222963ba0c046ae6d07e600 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 29 Aug 2023 12:04:30 +0200 Subject: [PATCH 12/56] Interactivity API: Update `data-wp-bind` directive logic (#54003) * Add undefined and null to the removeAttribute This should be done in a separate PR. * Adding first test cases (WIP) * Add comment * Remove unnecessary comment * Update test cases * Fix bind useEffect logic * Update changelog * Add type and comments to matrix entries * Fix phpcs errors --------- Co-authored-by: Luis Herranz --- .../directive-bind/render.php | 40 +++++ .../interactive-blocks/directive-bind/view.js | 11 ++ packages/interactivity/CHANGELOG.md | 1 + packages/interactivity/src/directives.js | 43 ++++- .../interactivity/directive-bind.spec.ts | 167 +++++++++++++++++- 5 files changed, 252 insertions(+), 10 deletions(-) diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-bind/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-bind/render.php index e4580f8cf02fd1..a94eb20bfa6d54 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-bind/render.php +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-bind/render.php @@ -56,4 +56,44 @@ > Some Text

+ + '{ "value": false }', + 'true' => '{ "value": true }', + 'null' => '{ "value": null }', + 'undef' => '{ "__any": "any" }', + 'emptyString' => '{ "value": "" }', + 'anyString' => '{ "value": "any" }', + 'number' => '{ "value": 10 }', + ); + ?> + + $context ) : ?> +
+ Red dot + + +
+
diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-bind/view.js b/packages/e2e-tests/plugins/interactive-blocks/directive-bind/view.js index 0cd590f184cc85..cbe562f5e25499 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-bind/view.js +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-bind/view.js @@ -18,6 +18,17 @@ state.show = ! state.show; state.width += foo.bar; }, + toggleValue: ( { context } ) => { + const previousValue = ( 'previousValue' in context ) + ? context.previousValue + // Any string works here; we just want to toggle the value + // to ensure Preact renders the same we are hydrating in the + // first place. + : 'tacocat'; + + context.previousValue = context.value; + context.value = previousValue; + } }, } ); } )( window ); diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 63da342d030a56..62515115484fa2 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -7,6 +7,7 @@ - Support keys using `data-wp-key`. ([#53844](https://github.com/WordPress/gutenberg/pull/53844)) - Merge new server-side rendered context on client-side navigation. ([#53853](https://github.com/WordPress/gutenberg/pull/53853)) - Support region-based client-side navigation. ([#53733](https://github.com/WordPress/gutenberg/pull/53733)) +- Improve `data-wp-bind` hydration to match Preact's logic. ([#54003](https://github.com/WordPress/gutenberg/pull/54003)) ## 2.1.0 (2023-08-16) diff --git a/packages/interactivity/src/directives.js b/packages/interactivity/src/directives.js index 1b7a82be38cfaa..0fd532debc7753 100644 --- a/packages/interactivity/src/directives.js +++ b/packages/interactivity/src/directives.js @@ -222,19 +222,46 @@ export default () => { // on the hydration, so we have to do it manually. It doesn't need // deps because it only needs to do it the first time. useEffect( () => { + const el = element.ref.current; + + // We set the value directly to the corresponding + // HTMLElement instance property excluding the following + // special cases. + // We follow Preact's logic: https://github.com/preactjs/preact/blob/ea49f7a0f9d1ff2c98c0bdd66aa0cbc583055246/src/diff/props.js#L110-L129 + if ( + attribute !== 'width' && + attribute !== 'height' && + attribute !== 'href' && + attribute !== 'list' && + attribute !== 'form' && + // Default value in browsers is `-1` and an empty string is + // cast to `0` instead + attribute !== 'tabIndex' && + attribute !== 'download' && + attribute !== 'rowSpan' && + attribute !== 'colSpan' && + attribute in el + ) { + try { + el[ attribute ] = + result === null || result === undefined + ? '' + : result; + return; + } catch ( err ) {} + } // aria- and data- attributes have no boolean representation. // A `false` value is different from the attribute not being // present, so we can't remove it. // We follow Preact's logic: https://github.com/preactjs/preact/blob/ea49f7a0f9d1ff2c98c0bdd66aa0cbc583055246/src/diff/props.js#L131C24-L136 - if ( result === false && attribute[ 4 ] !== '-' ) { - element.ref.current.removeAttribute( attribute ); + if ( + result !== null && + result !== undefined && + ( result !== false || attribute[ 4 ] === '-' ) + ) { + el.setAttribute( attribute, result ); } else { - element.ref.current.setAttribute( - attribute, - result === true && attribute[ 4 ] !== '-' - ? '' - : result - ); + el.removeAttribute( attribute ); } }, [] ); } ); diff --git a/test/e2e/specs/interactivity/directive-bind.spec.ts b/test/e2e/specs/interactivity/directive-bind.spec.ts index 67ee1232a6798e..401bbcd6b24ddf 100644 --- a/test/e2e/specs/interactivity/directive-bind.spec.ts +++ b/test/e2e/specs/interactivity/directive-bind.spec.ts @@ -37,12 +37,12 @@ test.describe( 'data-wp-bind', () => { test( 'add missing checked at hydration', async ( { page } ) => { const el = page.getByTestId( 'add missing checked at hydration' ); - await expect( el ).toHaveAttribute( 'checked', '' ); + await expect( el ).toBeChecked(); } ); test( 'remove existing checked at hydration', async ( { page } ) => { const el = page.getByTestId( 'remove existing checked at hydration' ); - await expect( el ).not.toHaveAttribute( 'checked', '' ); + await expect( el ).not.toBeChecked(); } ); test( 'update existing checked', async ( { page } ) => { @@ -93,4 +93,167 @@ test.describe( 'data-wp-bind', () => { await expect( el ).toHaveAttribute( 'aria-expanded', 'true' ); await expect( el ).toHaveAttribute( 'data-some-value', 'true' ); } ); + + test.describe( 'attribute hydration', () => { + /** + * Data structure to define a hydration test case. + */ + type MatrixEntry = { + /** + * Test ID of the element (the `data-testid` attr). + */ + testid: string; + /** + * Name of the attribute being hydrated. + */ + name: string; + /** + * Array of different values to test. + */ + values: Record< + /** + * The type of value we are hydrating. E.g., false is `false`, + * undef is `undefined`, emptyString is `''`, etc. + */ + string, + [ + /** + * Value that the attribute should contain after hydration. + * If the attribute is missing, this value is `null`. + */ + attributeValue: any, + /** + * Value that the HTMLElement instance property should + * contain after hydration. + */ + entityPropValue: any + ] + >; + }; + + const matrix: MatrixEntry[] = [ + { + testid: 'image', + name: 'width', + values: { + false: [ null, 5 ], + true: [ 'true', 5 ], + null: [ null, 5 ], + undef: [ null, 5 ], + emptyString: [ '', 5 ], + anyString: [ 'any', 5 ], + number: [ '10', 10 ], + }, + }, + { + testid: 'input', + name: 'name', + values: { + false: [ 'false', 'false' ], + true: [ 'true', 'true' ], + null: [ '', '' ], + undef: [ '', '' ], + emptyString: [ '', '' ], + anyString: [ 'any', 'any' ], + number: [ '10', '10' ], + }, + }, + { + testid: 'input', + name: 'value', + values: { + false: [ null, 'false' ], + true: [ null, 'true' ], + null: [ null, '' ], + undef: [ null, '' ], + emptyString: [ null, '' ], + anyString: [ null, 'any' ], + number: [ null, '10' ], + }, + }, + { + testid: 'input', + name: 'disabled', + values: { + false: [ null, false ], + true: [ '', true ], + null: [ null, false ], + undef: [ null, false ], + emptyString: [ null, false ], + anyString: [ '', true ], + number: [ '', true ], + }, + }, + { + testid: 'input', + name: 'aria-disabled', + values: { + false: [ 'false', undefined ], + true: [ 'true', undefined ], + null: [ null, undefined ], + undef: [ null, undefined ], + emptyString: [ '', undefined ], + anyString: [ 'any', undefined ], + number: [ '10', undefined ], + }, + }, + ]; + + for ( const { testid, name, values } of matrix ) { + test( `${ name } is correctly hydrated for different values`, async ( { + page, + } ) => { + for ( const type in values ) { + const [ attrValue, propValue ] = values[ type ]; + + const container = page.getByTestId( `hydrating ${ type }` ); + const el = container.getByTestId( testid ); + const toggle = container.getByTestId( 'toggle value' ); + + const hydratedAttr = await el.getAttribute( name ); + const hydratedProp = await el.evaluate( + ( node, propName ) => ( node as any )[ propName ], + name + ); + expect( [ type, hydratedAttr ] ).toEqual( [ + type, + attrValue, + ] ); + expect( [ type, hydratedProp ] ).toEqual( [ + type, + propValue, + ] ); + + // Only check the rendered value if the new value is not + // `undefined` and the attibute is neither `value` nor + // `disabled` because Preact doesn't update the attribute + // for those cases. + // See https://github.com/preactjs/preact/blob/099c38c6ef92055428afbc116d18a6b9e0c2ea2c/src/diff/index.js#L471-L494 + if ( + type === 'undef' && + ( name === 'value' || name === 'undefined' ) + ) { + return; + } + + await toggle.click( { clickCount: 2, delay: 50 } ); + + // Values should be the same as before. + const renderedAttr = await el.getAttribute( name ); + const renderedProp = await el.evaluate( + ( node, propName ) => ( node as any )[ propName ], + name + ); + expect( [ type, renderedAttr ] ).toEqual( [ + type, + attrValue, + ] ); + expect( [ type, renderedProp ] ).toEqual( [ + type, + propValue, + ] ); + } + } ); + } + } ); } ); From a7350b052e166d28d202f855ff49abc6891ec2c2 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 29 Aug 2023 11:12:45 +0100 Subject: [PATCH 13/56] Pass entire link value on new tab toggle (#53949) --- packages/block-editor/src/components/link-control/index.js | 6 +----- .../block-editor/src/components/link-control/test/index.js | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 9d9e6f4e188d42..ac1ec660934a3a 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -422,11 +422,7 @@ function LinkControl( { settings={ settings?.filter( ( { id } ) => id === 'opensInNewTab' ) } - onChange={ ( { opensInNewTab } ) => { - onChange( { - opensInNewTab, - } ); - } } + onChange={ onChange } /> ); } diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index 4e3e9f45e4dea2..f8e9aedcbd5bd5 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -1789,6 +1789,7 @@ describe( 'Addition Settings UI', () => { expect( mockOnChange ).toHaveBeenCalledTimes( 1 ); expect( mockOnChange ).toHaveBeenCalledWith( { + ...selectedLink, opensInNewTab: true, } ); } ); From db18bf38335e8ede8fd05072081533e3de8f3228 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Tue, 29 Aug 2023 10:29:41 +0000 Subject: [PATCH 14/56] Bump plugin version to 16.5.1 --- gutenberg.php | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index bc848f9b628dd1..d42b0a09017c07 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.1 * Requires PHP: 7.0 - * Version: 16.5.0 + * Version: 16.5.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index a5a0c340849e65..059180e5c24bab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gutenberg", - "version": "16.5.0", + "version": "16.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gutenberg", - "version": "16.5.0", + "version": "16.5.1", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { diff --git a/package.json b/package.json index 915268be932368..a4131bca556d9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "16.5.0", + "version": "16.5.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From 470730ffac91c15904cfd2f97b4c20b3dbaf6b9a Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 29 Aug 2023 12:57:44 +0200 Subject: [PATCH 15/56] Interactivity API: add Slot and Fill directives (#53958) * Add undefined and null to the removeAttribute This should be done in a separate PR. * Adding first test cases (WIP) * Add comment * Remove unnecessary comment * Update test cases * Fix bind useEffect logic * Update changelog * Add type and comments to matrix entries * Fix phpcs errors * Copy current implementation * Refactor data-wp-slot * Add slot and fill tests * Add changelog * Fix changelog --------- Co-authored-by: Luis Herranz --- .../directive-slots/block.json | 14 ++ .../directive-slots/render.php | 67 +++++++ .../directive-slots/view.js | 18 ++ packages/interactivity/CHANGELOG.md | 4 + packages/interactivity/src/directives.js | 69 +++++++ packages/interactivity/src/slots.js | 38 ++++ .../interactivity/directive-slots.spec.ts | 186 ++++++++++++++++++ 7 files changed, 396 insertions(+) create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-slots/block.json create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-slots/render.php create mode 100644 packages/e2e-tests/plugins/interactive-blocks/directive-slots/view.js create mode 100644 packages/interactivity/src/slots.js create mode 100644 test/e2e/specs/interactivity/directive-slots.spec.ts diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-slots/block.json b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/block.json new file mode 100644 index 00000000000000..f79f89a6e81b8a --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/block.json @@ -0,0 +1,14 @@ +{ + "apiVersion": 2, + "name": "test/directive-slots", + "title": "E2E Interactivity tests - directive slots", + "category": "text", + "icon": "heart", + "description": "", + "supports": { + "interactivity": true + }, + "textdomain": "e2e-interactivity", + "viewScript": "directive-slots-view", + "render": "file:./render.php" +} diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-slots/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/render.php new file mode 100644 index 00000000000000..5c1558d35403d3 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/render.php @@ -0,0 +1,67 @@ + +
+
+
[1]
+
[2]
+
[3]
+
[4]
+
[5]
+
+ +
+ initial +
+ +
+ + + + + + +
+
diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-slots/view.js b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/view.js new file mode 100644 index 00000000000000..ab5b39379f3a84 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-slots/view.js @@ -0,0 +1,18 @@ +( ( { wp } ) => { + const { store } = wp.interactivity; + + store( { + state: { + slot: '' + }, + actions: { + changeSlot: ( { state, event } ) => { + state.slot = event.target.dataset.slot; + }, + updateSlotText: ( { context } ) => { + const n = context.text[1]; + context.text = `[${n} updated]`; + }, + }, + } ); +} )( window ); diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 62515115484fa2..6a4565f3ad1833 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -9,6 +9,10 @@ - Support region-based client-side navigation. ([#53733](https://github.com/WordPress/gutenberg/pull/53733)) - Improve `data-wp-bind` hydration to match Preact's logic. ([#54003](https://github.com/WordPress/gutenberg/pull/54003)) +### New Features + +- Add new directives that implement the Slot and Fill pattern: `data-wp-slot-provider`, `data-wp-slot` and `data-wp-fill`. ([#53958](https://github.com/WordPress/gutenberg/pull/53958)) + ## 2.1.0 (2023-08-16) ### New Features diff --git a/packages/interactivity/src/directives.js b/packages/interactivity/src/directives.js index 0fd532debc7753..f0a3d7e32e09e1 100644 --- a/packages/interactivity/src/directives.js +++ b/packages/interactivity/src/directives.js @@ -10,6 +10,7 @@ import { deepSignal, peek } from 'deepsignal'; import { createPortal } from './portals'; import { useSignalEffect } from './utils'; import { directive } from './hooks'; +import { SlotProvider, Slot, Fill } from './slots'; const isObject = ( item ) => item && typeof item === 'object' && ! Array.isArray( item ); @@ -305,4 +306,72 @@ export default () => { } ); } ); + + // data-wp-slot + directive( + 'slot', + ( { + directives: { + slot: { default: slot }, + }, + props: { children }, + element, + } ) => { + const name = typeof slot === 'string' ? slot : slot.name; + const position = slot.position || 'children'; + + if ( position === 'before' ) { + return ( + <> + + { children } + + ); + } + if ( position === 'after' ) { + return ( + <> + { children } + + + ); + } + if ( position === 'replace' ) { + return { children }; + } + if ( position === 'children' ) { + element.props.children = ( + { element.props.children } + ); + } + }, + { priority: 4 } + ); + + // data-wp-fill + directive( + 'fill', + ( { + directives: { + fill: { default: fill }, + }, + props: { children }, + evaluate, + context, + } ) => { + const contextValue = useContext( context ); + const slot = evaluate( fill, { context: contextValue } ); + return { children }; + }, + { priority: 4 } + ); + + // data-wp-slot-provider + directive( + 'slot-provider', + ( { props: { children } } ) => ( + { children } + ), + { priority: 4 } + ); }; diff --git a/packages/interactivity/src/slots.js b/packages/interactivity/src/slots.js new file mode 100644 index 00000000000000..e8bc6ddfa368f5 --- /dev/null +++ b/packages/interactivity/src/slots.js @@ -0,0 +1,38 @@ +/** + * External dependencies + */ +import { createContext } from 'preact'; +import { useContext, useEffect } from 'preact/hooks'; +import { signal } from '@preact/signals'; + +const slotsContext = createContext(); + +export const Fill = ( { slot, children } ) => { + const slots = useContext( slotsContext ); + + useEffect( () => { + if ( slot ) { + slots.value = { ...slots.value, [ slot ]: children }; + return () => { + slots.value = { ...slots.value, [ slot ]: null }; + }; + } + }, [ slots, slot, children ] ); + + return !! slot ? null : children; +}; + +export const SlotProvider = ( { children } ) => { + return ( + // TODO: We can change this to use deepsignal once this PR is merged. + // https://github.com/luisherranz/deepsignal/pull/38 + + { children } + + ); +}; + +export const Slot = ( { name, children } ) => { + const slots = useContext( slotsContext ); + return slots.value[ name ] || children; +}; diff --git a/test/e2e/specs/interactivity/directive-slots.spec.ts b/test/e2e/specs/interactivity/directive-slots.spec.ts new file mode 100644 index 00000000000000..d93e50f767215f --- /dev/null +++ b/test/e2e/specs/interactivity/directive-slots.spec.ts @@ -0,0 +1,186 @@ +/** + * Internal dependencies + */ +import { test, expect } from './fixtures'; + +test.describe( 'data-wp-slot', () => { + test.beforeAll( async ( { interactivityUtils: utils } ) => { + await utils.activatePlugins(); + await utils.addPostWithBlock( 'test/directive-slots' ); + } ); + + test.beforeEach( async ( { interactivityUtils: utils, page } ) => { + await page.goto( utils.getLink( 'test/directive-slots' ) ); + } ); + + test.afterAll( async ( { interactivityUtils: utils } ) => { + await utils.deactivatePlugins(); + await utils.deleteAllPosts(); + } ); + + test( 'should render the fill in its children by default', async ( { + page, + } ) => { + const slot1 = page.getByTestId( 'slot-1' ); + const slots = page.getByTestId( 'slots' ); + const fillContainer = page.getByTestId( 'fill-container' ); + + await page.getByTestId( 'slot-1-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + await expect( slot1.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slot1 ).toHaveText( 'fill inside slot 1' ); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + 'fill inside slot 1', + '[2]', + '[3]', + '[4]', + '[5]', + ] ); + } ); + + test( 'should render the fill before if specified', async ( { page } ) => { + const slot2 = page.getByTestId( 'slot-2' ); + const slots = page.getByTestId( 'slots' ); + const fillContainer = page.getByTestId( 'fill-container' ); + + await page.getByTestId( 'slot-2-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + await expect( slot2 ).toHaveText( '[2]' ); + await expect( slots.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + 'fill inside slots', + '[2]', + '[3]', + '[4]', + '[5]', + ] ); + } ); + + test( 'should render the fill after if specified', async ( { page } ) => { + const slot3 = page.getByTestId( 'slot-3' ); + const slots = page.getByTestId( 'slots' ); + const fillContainer = page.getByTestId( 'fill-container' ); + + await page.getByTestId( 'slot-3-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + await expect( slot3 ).toHaveText( '[3]' ); + await expect( slots.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + '[2]', + '[3]', + 'fill inside slots', + '[4]', + '[5]', + ] ); + } ); + + test( 'should render the fill in its children if specified', async ( { + page, + } ) => { + const slot4 = page.getByTestId( 'slot-4' ); + const slots = page.getByTestId( 'slots' ); + const fillContainer = page.getByTestId( 'fill-container' ); + + await page.getByTestId( 'slot-4-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + await expect( slot4.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slot4 ).toHaveText( 'fill inside slot 4' ); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + '[2]', + '[3]', + 'fill inside slot 4', + '[5]', + ] ); + } ); + + test( 'should be replaced by the fill if specified', async ( { page } ) => { + const slot5 = page.getByTestId( 'slot-5' ); + const slots = page.getByTestId( 'slots' ); + const fillContainer = page.getByTestId( 'fill-container' ); + + await page.getByTestId( 'slot-5-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + await expect( slot5 ).not.toBeVisible(); + await expect( slots.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + '[2]', + '[3]', + '[4]', + 'fill inside slots', + ] ); + } ); + + test( 'should keep the fill in its original position if no slot matches', async ( { + page, + } ) => { + const fillContainer = page.getByTestId( 'fill-container' ); + await expect( fillContainer.getByTestId( 'fill' ) ).toBeVisible(); + + await page.getByTestId( 'slot-1-button' ).click(); + + await expect( fillContainer ).toBeEmpty(); + + await page.getByTestId( 'reset' ).click(); + + await expect( fillContainer.getByTestId( 'fill' ) ).toBeVisible(); + } ); + + test( 'should not be re-mounted when adding the fill before', async ( { + page, + } ) => { + const slot2 = page.getByTestId( 'slot-2' ); + const slots = page.getByTestId( 'slots' ); + + await expect( slot2 ).toHaveText( '[2]' ); + + await slot2.click(); + + await expect( slot2 ).toHaveText( '[2 updated]' ); + + await page.getByTestId( 'slot-2-button' ).click(); + + await expect( slots.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + 'fill inside slots', + '[2 updated]', + '[3]', + '[4]', + '[5]', + ] ); + } ); + + test( 'should not be re-mounted when adding the fill after', async ( { + page, + } ) => { + const slot3 = page.getByTestId( 'slot-3' ); + const slots = page.getByTestId( 'slots' ); + + await expect( slot3 ).toHaveText( '[3]' ); + + await slot3.click(); + + await expect( slot3 ).toHaveText( '[3 updated]' ); + + await page.getByTestId( 'slot-3-button' ).click(); + + await expect( slots.getByTestId( 'fill' ) ).toBeVisible(); + await expect( slots.locator( 'css= > *' ) ).toHaveText( [ + '[1]', + '[2]', + '[3 updated]', + 'fill inside slots', + '[4]', + '[5]', + ] ); + } ); +} ); From 1231506986f8d261637f163a823aa7a4ecb6254f Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 29 Aug 2023 20:32:20 +0900 Subject: [PATCH 16/56] Fix: indicator style when block moving mode (#53972) --- packages/block-editor/src/components/block-list/content.scss | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index a163ddaa789551..52f26217730773 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -85,7 +85,6 @@ .block-editor-block-list__block.is-highlighted, .block-editor-block-list__block.is-highlighted ~ .is-multi-selected, &.is-navigate-mode .block-editor-block-list__block.is-selected, - & .is-block-moving-mode.block-editor-block-list__block.has-child-selected, .block-editor-block-list__block:not([contenteditable]):focus { outline: none; @@ -113,8 +112,6 @@ // Moving blocks using keyboard (Ellipsis > Move). & .is-block-moving-mode.block-editor-block-list__block.is-selected { - box-shadow: none; - outline: none; &::after { content: ""; @@ -130,6 +127,8 @@ top: -$default-block-margin * 0.5; border-radius: $radius-block-ui; border-top: 4px solid $gray-400; + bottom: auto; + box-shadow: none; } } From df40f46dfc836cac1cfe263875c0a66ba71031d3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter <96308+ockham@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:49:35 +0200 Subject: [PATCH 17/56] Auto-inserting blocks: Add block inspector panel (#52969) Add a new panel (tentatively named "Plugins") to the block inspector that lists blocks that are slated for auto-insertion next to that block, and provide toggles to insert (or remove) them. Co-authored-by: Carlos Bravo --- lib/experimental/auto-inserting-blocks.php | 95 ++++++- lib/experimental/editor-settings.php | 4 + .../src/hooks/auto-inserting-blocks.js | 232 ++++++++++++++++++ packages/block-editor/src/hooks/index.js | 1 + packages/blocks/src/api/registration.js | 12 + 5 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 packages/block-editor/src/hooks/auto-inserting-blocks.js diff --git a/lib/experimental/auto-inserting-blocks.php b/lib/experimental/auto-inserting-blocks.php index 90f3bdf15e509d..f4a650e110bf92 100644 --- a/lib/experimental/auto-inserting-blocks.php +++ b/lib/experimental/auto-inserting-blocks.php @@ -64,6 +64,31 @@ function gutenberg_auto_insert_block( $inserted_block, $relative_position, $anch }; } +/** + * Add auto-insertion information to a block type's controller. + * + * @param array $inserted_block_type The type of block to insert. + * @param string $position The position relative to the anchor block. + * Can be 'before', 'after', 'first_child', or 'last_child'. + * @param string $anchor_block_type The auto-inserted block will be inserted next to instances of this block type. + * @return callable A filter for the `rest_prepare_block_type` hook that adds an `auto_insert` field to the network response. + */ +function gutenberg_add_auto_insert_field_to_block_type_controller( $inserted_block_type, $position, $anchor_block_type ) { + return function( $response, $block_type ) use ( $inserted_block_type, $position, $anchor_block_type ) { + if ( $block_type->name !== $inserted_block_type ) { + return $response; + } + + $data = $response->get_data(); + if ( ! isset( $data['auto_insert'] ) ) { + $data['auto_insert'] = array(); + } + $data['auto_insert'][ $anchor_block_type ] = $position; + $response->set_data( $data ); + return $response; + }; +} + /** * Register blocks for auto-insertion, based on their block.json metadata. * @@ -113,6 +138,37 @@ function gutenberg_register_auto_inserted_blocks( $settings, $metadata ) { $settings['auto_insert'][ $anchor_block_name ] = $mapped_position; } + // Copied from `get_block_editor_server_block_settings()`. + $fields_to_pick = array( + 'api_version' => 'apiVersion', + 'title' => 'title', + 'description' => 'description', + 'icon' => 'icon', + 'attributes' => 'attributes', + 'provides_context' => 'providesContext', + 'uses_context' => 'usesContext', + 'selectors' => 'selectors', + 'supports' => 'supports', + 'category' => 'category', + 'styles' => 'styles', + 'textdomain' => 'textdomain', + 'parent' => 'parent', + 'ancestor' => 'ancestor', + 'keywords' => 'keywords', + 'example' => 'example', + 'variations' => 'variations', + ); + // Add `auto_insert` to the list of fields to pick. + $fields_to_pick['auto_insert'] = 'autoInsert'; + + $exposed_settings = array_intersect_key( $settings, $fields_to_pick ); + + // TODO: Make work for blocks registered via direct call to gutenberg_register_auto_inserted_block(). + wp_add_inline_script( + 'wp-blocks', + 'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( array( $inserted_block_name => $exposed_settings ) ) . ');' + ); + return $settings; } add_filter( 'block_type_metadata_settings', 'gutenberg_register_auto_inserted_blocks', 10, 2 ); @@ -135,7 +191,7 @@ function gutenberg_register_auto_inserted_blocks( $settings, $metadata ) { * @return void */ function gutenberg_register_auto_inserted_block( $inserted_block, $position, $anchor_block ) { - $inserted_block = array( + $inserted_block_array = array( 'blockName' => $inserted_block, 'attrs' => array(), 'innerHTML' => '', @@ -143,8 +199,19 @@ function gutenberg_register_auto_inserted_block( $inserted_block, $position, $an 'innerBlocks' => array(), ); - $inserter = gutenberg_auto_insert_block( $inserted_block, $position, $anchor_block ); + $inserter = gutenberg_auto_insert_block( $inserted_block_array, $position, $anchor_block ); add_filter( 'gutenberg_serialize_block', $inserter, 10, 1 ); + + /* + * The block-types REST API controller uses objects of the `WP_Block_Type` class, which are + * in turn created upon block type registration. However, that class does not contain + * an `auto_insert` property (and is not easily extensible), so we have to use a different + * mechanism to communicate to the controller which blocks have been registered for + * auto-insertion. We're doing so here (i.e. upon block registration), by adding a filter to + * the controller's response. + */ + $controller_extender = gutenberg_add_auto_insert_field_to_block_type_controller( $inserted_block, $position, $anchor_block ); + add_filter( 'rest_prepare_block_type', $controller_extender, 10, 2 ); } /** @@ -256,3 +323,27 @@ function gutenberg_serialize_block( $block ) { function gutenberg_serialize_blocks( $blocks ) { return implode( '', array_map( 'gutenberg_serialize_block', $blocks ) ); } + +/** + * Register the `auto_insert` field for the block-types REST API controller. + * + * @return void + */ +function gutenberg_register_auto_insert_rest_field() { + register_rest_field( + 'block-type', + 'auto_insert', + array( + 'schema' => array( + 'description' => __( 'Block types that may be automatically inserted near this block and the associated relative position where they are inserted.', 'gutenberg' ), + 'patternProperties' => array( + '^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$' => array( + 'type' => 'string', + 'enum' => array( 'before', 'after', 'first_child', 'last_child' ), + ), + ), + ), + ) + ); +} +add_action( 'rest_api_init', 'gutenberg_register_auto_insert_rest_field' ); diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index c09b5cde0f16bc..a9b7b18e75a5f1 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -30,6 +30,10 @@ function gutenberg_enable_experiments() { if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' ); } + + if ( $gutenberg_experiments && array_key_exists( 'gutenberg-auto-inserting-blocks', $gutenberg_experiments ) ) { + wp_add_inline_script( 'wp-block-editor', 'window.__experimentalAutoInsertingBlocks = true', 'before' ); + } } add_action( 'admin_init', 'gutenberg_enable_experiments' ); diff --git a/packages/block-editor/src/hooks/auto-inserting-blocks.js b/packages/block-editor/src/hooks/auto-inserting-blocks.js new file mode 100644 index 00000000000000..266d9dd55fa674 --- /dev/null +++ b/packages/block-editor/src/hooks/auto-inserting-blocks.js @@ -0,0 +1,232 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { addFilter } from '@wordpress/hooks'; +import { Fragment } from '@wordpress/element'; +import { PanelBody, ToggleControl } from '@wordpress/components'; +import { createHigherOrderComponent } from '@wordpress/compose'; +import { createBlock, store as blocksStore } from '@wordpress/blocks'; +import { useDispatch, useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { InspectorControls } from '../components'; +import { store as blockEditorStore } from '../store'; + +function AutoInsertingBlocksControl( props ) { + const { autoInsertedBlocksForCurrentBlock, groupedAutoInsertedBlocks } = + useSelect( + ( select ) => { + const { getBlockTypes } = select( blocksStore ); + const _autoInsertedBlocksForCurrentBlock = + getBlockTypes()?.filter( + ( { autoInsert } ) => + autoInsert && props.blockName in autoInsert + ); + + // Group by block namespace (i.e. prefix before the slash). + const _groupedAutoInsertedBlocks = + _autoInsertedBlocksForCurrentBlock?.reduce( + ( groups, block ) => { + const [ namespace ] = block.name.split( '/' ); + if ( ! groups[ namespace ] ) { + groups[ namespace ] = []; + } + groups[ namespace ].push( block ); + return groups; + }, + {} + ); + + return { + autoInsertedBlocksForCurrentBlock: + _autoInsertedBlocksForCurrentBlock, + groupedAutoInsertedBlocks: _groupedAutoInsertedBlocks, + }; + }, + [ props.blockName ] + ); + + const { + autoInsertedBlockClientIds, + blockIndex, + rootClientId, + innerBlocksLength, + } = useSelect( + ( select ) => { + const { getBlock, getBlockIndex, getBlockRootClientId } = + select( blockEditorStore ); + const _rootClientId = getBlockRootClientId( props.clientId ); + + const _autoInsertedBlockClientIds = + autoInsertedBlocksForCurrentBlock.reduce( + ( clientIds, block ) => { + const relativePosition = + block?.autoInsert?.[ props.blockName ]; + let candidates; + + switch ( relativePosition ) { + case 'before': + case 'after': + // Any of the current block's siblings (with the right block type) qualifies + // as an auto-inserted block (inserted `before` or `after` the current one), + // as the block might've been auto-inserted and then moved around a bit by the user. + candidates = + getBlock( _rootClientId )?.innerBlocks; + break; + + case 'first_child': + case 'last_child': + // Any of the current block's child blocks (with the right block type) qualifies + // as an auto-inserted first or last child block, as the block might've been + // auto-inserted and then moved around a bit by the user. + candidates = getBlock( + props.clientId + ).innerBlocks; + break; + } + + const autoInsertedBlock = candidates?.find( + ( { name } ) => name === block.name + ); + + if ( autoInsertedBlock ) { + clientIds[ block.name ] = + autoInsertedBlock.clientId; + } + + // TOOD: If no auto-inserted block was found in any of its designated locations, + // we want to check if it's present elsewhere in the block tree. + // If it is, we'd consider it manually inserted and would want to remove the + // corresponding toggle from the block inspector panel. + + return clientIds; + }, + {} + ); + + return { + blockIndex: getBlockIndex( props.clientId ), + innerBlocksLength: getBlock( props.clientId )?.innerBlocks + ?.length, + rootClientId: _rootClientId, + autoInsertedBlockClientIds: _autoInsertedBlockClientIds, + }; + }, + [ autoInsertedBlocksForCurrentBlock, props.blockName, props.clientId ] + ); + + const { insertBlock, removeBlock } = useDispatch( blockEditorStore ); + + if ( ! autoInsertedBlocksForCurrentBlock.length ) { + return null; + } + + const insertBlockIntoDesignatedLocation = ( block, relativePosition ) => { + switch ( relativePosition ) { + case 'before': + case 'after': + insertBlock( + block, + relativePosition === 'after' ? blockIndex + 1 : blockIndex, + rootClientId, // Insert as a child of the current block's parent + false + ); + break; + + case 'first_child': + case 'last_child': + insertBlock( + block, + // TODO: It'd be great if insertBlock() would accept negative indices for insertion. + relativePosition === 'first_child' ? 0 : innerBlocksLength, + props.clientId, // Insert as a child of the current block. + false + ); + break; + } + }; + + return ( + + + { Object.keys( groupedAutoInsertedBlocks ).map( ( vendor ) => { + return ( + +

{ vendor }

+ { groupedAutoInsertedBlocks[ vendor ].map( + ( block ) => { + // TODO: Display block icon. + // + + const checked = + block.name in + autoInsertedBlockClientIds; + + return ( + { + if ( ! checked ) { + // Create and insert block. + const relativePosition = + block.autoInsert[ + props.blockName + ]; + insertBlockIntoDesignatedLocation( + createBlock( + block.name + ), + relativePosition + ); + return; + } + + // Remove block. + const clientId = + autoInsertedBlockClientIds[ + block.name + ]; + removeBlock( clientId, false ); + } } + /> + ); + } + ) } +
+ ); + } ) } +
+
+ ); +} + +export const withAutoInsertingBlocks = createHigherOrderComponent( + ( BlockEdit ) => { + return ( props ) => { + const blockEdit = ; + return ( + <> + { blockEdit } + + + ); + }; + }, + 'withAutoInsertingBlocks' +); + +if ( window?.__experimentalAutoInsertingBlocks ) { + addFilter( + 'editor.BlockEdit', + 'core/auto-inserting-blocks/with-inspector-control', + withAutoInsertingBlocks + ); +} diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index 6834d859d25453..5e18c6a309d693 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -22,6 +22,7 @@ import './metadata'; import './metadata-name'; import './behaviors'; import './custom-fields'; +import './auto-inserting-blocks'; export { useCustomSides } from './dimensions'; export { useLayoutClasses, useLayoutStyles } from './layout'; diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index bf866b7a2143ba..702582ff6489e8 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -180,6 +180,17 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { serverSideBlockDefinitions[ blockName ].selectors = definitions[ blockName ].selectors; } + + if ( + serverSideBlockDefinitions[ blockName ] + .__experimentalAutoInsert === undefined && + definitions[ blockName ].__experimentalAutoInsert + ) { + serverSideBlockDefinitions[ + blockName + ].__experimentalAutoInsert = + definitions[ blockName ].__experimentalAutoInsert; + } continue; } @@ -219,6 +230,7 @@ function getBlockSettingsFromMetadata( { textdomain, ...metadata } ) { 'styles', 'example', 'variations', + '__experimentalAutoInsert', ]; const settings = Object.fromEntries( From 2653b5e4f29c703a7ea52ebdc62dc254e4dc1dae Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 29 Aug 2023 08:12:17 -0400 Subject: [PATCH 18/56] test: Automate mobile editor tests (#53991) * test: Remove duplicative tests These are covered by: `packages/block-library/src/social-links/test/edit.native.js` * test: Social Links sets a link URL Assert the fundamental functionality of setting a URL for a Social Link link. --- .../src/embed/embed-link-settings.native.js | 1 - .../src/embed/test/index.native.js | 18 +-- .../src/social-link/test/index.native.js | 132 ------------------ .../src/social-links/test/edit.native.js | 30 ++++ .../link-settings-navigation.native.js | 2 +- 5 files changed, 40 insertions(+), 143 deletions(-) delete mode 100644 packages/block-library/src/social-link/test/index.native.js diff --git a/packages/block-library/src/embed/embed-link-settings.native.js b/packages/block-library/src/embed/embed-link-settings.native.js index ad4152c2fe19a8..9c3fbffc8a196b 100644 --- a/packages/block-library/src/embed/embed-link-settings.native.js +++ b/packages/block-library/src/embed/embed-link-settings.native.js @@ -90,7 +90,6 @@ const EmbedLinkSettings = ( { onDismiss={ onDismiss } setAttributes={ onSetAttributes } options={ linkSettingsOptions } - testID="embed-edit-url-modal" withBottomSheet={ withBottomSheet } showIcon /> diff --git a/packages/block-library/src/embed/test/index.native.js b/packages/block-library/src/embed/test/index.native.js index c2e65bcef35c41..b13b86b40d3fd3 100644 --- a/packages/block-library/src/embed/test/index.native.js +++ b/packages/block-library/src/embed/test/index.native.js @@ -241,7 +241,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -259,7 +259,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -299,7 +299,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -338,7 +338,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -359,7 +359,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -400,7 +400,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -584,7 +584,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -623,7 +623,7 @@ describe( 'Embed block', () => { // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); await waitForModalVisible( embedEditURLModal ); @@ -804,7 +804,7 @@ describe( 'Embed block', () => { // Dismiss the edit URL modal. const embedEditURLModal = editor.getByTestId( - 'embed-edit-url-modal' + 'link-settings-navigation' ); fireEvent( embedEditURLModal, 'backdropPress' ); fireEvent( embedEditURLModal, MODAL_DISMISS_EVENT ); diff --git a/packages/block-library/src/social-link/test/index.native.js b/packages/block-library/src/social-link/test/index.native.js deleted file mode 100644 index 4ad7611e72045d..00000000000000 --- a/packages/block-library/src/social-link/test/index.native.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * External dependencies - */ -import { fireEvent, initializeEditor, waitFor, within } from 'test/helpers'; -/** - * WordPress dependencies - */ -import { registerCoreBlocks } from '@wordpress/block-library'; -import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; - -const unregisterBlocks = () => { - const blocks = getBlockTypes(); - - blocks.forEach( ( { name } ) => unregisterBlockType( name ) ); -}; - -describe( '', () => { - beforeAll( () => { - registerCoreBlocks(); - } ); - - afterAll( () => { - unregisterBlocks(); - } ); - - /** - * GIVEN an EDITOR is displayed; - * WHEN a SOCIAL ICONS BLOCK is selected from the BLOCK INSERTER; - */ - it( 'should display WORDPRESS, FACEBOOK, TWITTER, INSTAGRAM by default.', async () => { - // Arrange - const subject = await initializeEditor( {} ); - - // Act - fireEvent.press( - await waitFor( () => subject.getByLabelText( 'Add block' ) ) - ); - fireEvent.changeText( - await waitFor( () => - subject.getByPlaceholderText( 'Search blocks' ) - ), - 'social icons' - ); - fireEvent.press( - await subject.findByLabelText( 'Social Icons block' ) - ); - const [ socialIconsBlock ] = subject.getAllByLabelText( - /Social Icons Block. Row 1/ - ); - fireEvent( - within( socialIconsBlock ).getByTestId( 'block-list-wrapper' ), - 'layout', - { nativeEvent: { layout: { width: 100 } } } - ); - - // Assert - expect( - await waitFor( () => - subject.getByLabelText( /WordPress social icon/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByLabelText( /Facebook social icon/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByLabelText( /Twitter social icon/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByLabelText( /Instagram social icon/ ) - ) - ).toBeDefined(); - } ); - - /** - * GIVEN an EDITOR is displayed; - * WHEN a SOCIAL ICONS BLOCK is selected from the BLOCK INSERTER; - */ - it( `should display WORDPRESS with a URL set by default - AND should display FACEBOOK, TWITTER, INSTAGRAM with NO URL set by default.`, async () => { - // Arrange - const subject = await initializeEditor( {} ); - - // Act - fireEvent.press( - await waitFor( () => subject.getByLabelText( 'Add block' ) ) - ); - fireEvent.changeText( - await waitFor( () => - subject.getByPlaceholderText( 'Search blocks' ) - ), - 'social icons' - ); - fireEvent.press( - await subject.findByLabelText( 'Social Icons block' ) - ); - const [ socialIconsBlock ] = subject.getAllByLabelText( - /Social Icons Block. Row 1/ - ); - fireEvent( - within( socialIconsBlock ).getByTestId( 'block-list-wrapper' ), - 'layout', - { nativeEvent: { layout: { width: 100 } } } - ); - - // Assert - expect( - await waitFor( () => - subject.getByA11yHint( /WordPress has URL set/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByA11yHint( /Facebook has no URL set/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByA11yHint( /Twitter has no URL set/ ) - ) - ).toBeDefined(); - expect( - await waitFor( () => - subject.getByA11yHint( /Instagram has no URL set/ ) - ) - ).toBeDefined(); - } ); -} ); diff --git a/packages/block-library/src/social-links/test/edit.native.js b/packages/block-library/src/social-links/test/edit.native.js index 48fefaadaec8c0..a4ac5246979aa3 100644 --- a/packages/block-library/src/social-links/test/edit.native.js +++ b/packages/block-library/src/social-links/test/edit.native.js @@ -3,12 +3,14 @@ */ import { addBlock, + dismissModal, fireEvent, getEditorHtml, initializeEditor, within, getBlock, waitFor, + waitForModalVisible, } from 'test/helpers'; /** @@ -197,4 +199,32 @@ describe( 'Social links block', () => { expect( getEditorHtml() ).toMatchSnapshot(); } ); + + it( "should set a icon's URL", async () => { + const screen = await initializeEditor(); + await addBlock( screen, 'Social Icons' ); + fireEvent.press( screen.getByLabelText( 'Facebook social icon' ) ); + fireEvent.press( screen.getByLabelText( 'Add link to Facebook' ) ); + + await waitForModalVisible( + screen.getByTestId( 'link-settings-navigation' ) + ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Add URL' ), + 'https://facebook.com' + ); + dismissModal( screen.getByTestId( 'link-settings-navigation' ) ); + + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " + + " + ` ); + } ); } ); diff --git a/packages/components/src/mobile/link-settings/link-settings-navigation.native.js b/packages/components/src/mobile/link-settings/link-settings-navigation.native.js index 7f82ca49a96769..375dae450fbcef 100644 --- a/packages/components/src/mobile/link-settings/link-settings-navigation.native.js +++ b/packages/components/src/mobile/link-settings/link-settings-navigation.native.js @@ -23,7 +23,7 @@ function LinkSettingsNavigation( props ) { isVisible={ props.isVisible } onClose={ props.onClose } onDismiss={ props.onDismiss } - testID={ props.testID } + testID="link-settings-navigation" hideHeader hasNavigation > From 935be24b5e828d4e91effdb45267965a740cdc73 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 29 Aug 2023 08:12:34 -0400 Subject: [PATCH 19/56] test: Social Icons (#54001) * test: Export Social Icons block name Enable e2e tests for the Social Icons block by reference. * refactor: Log local Appium server start status Mitigate confusion regarding the local Appium server status. --- .../__device-tests__/helpers/appium-local-start.js | 12 +++++++++++- .../__device-tests__/pages/editor-page.js | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/react-native-editor/__device-tests__/helpers/appium-local-start.js b/packages/react-native-editor/__device-tests__/helpers/appium-local-start.js index 12d00ed09b92ee..a8e62b6b1f67f0 100644 --- a/packages/react-native-editor/__device-tests__/helpers/appium-local-start.js +++ b/packages/react-native-editor/__device-tests__/helpers/appium-local-start.js @@ -3,4 +3,14 @@ */ const { start } = require( './appium-local.js' ); -start( { flags: '--allow-cors' } ); +start( { flags: '--allow-cors' } ).then( + () => { + // eslint-disable-next-line no-console + console.log( 'INFO: Appium server started successfully' ); + }, + ( error ) => { + // eslint-disable-next-line no-console + console.error( error ); + process.exit( 1 ); + } +); diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index cf5b7879c88192..8e2bc02d657b9a 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -1024,6 +1024,7 @@ const blockNames = { paragraph: 'Paragraph', search: 'Search', separator: 'Separator', + socialIcons: 'Social Icons', spacer: 'Spacer', verse: 'Verse', shortcode: 'Shortcode', From 0074c5a5001873047567162899a6f84f0b455563 Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 29 Aug 2023 21:25:41 +0900 Subject: [PATCH 20/56] Post Editor: Fix browser console error when changing device preview mode (#53969) --- packages/edit-post/src/components/visual-editor/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 88fc233e0f74d4..fb764b967e67d5 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -180,7 +180,8 @@ export default function VisualEditor( { styles } ) { const desktopCanvasStyles = { height: '100%', width: '100%', - margin: 0, + marginLeft: 'auto', + marginRight: 'auto', display: 'flex', flexFlow: 'column', // Default background color so that grey From 3a7404dd80067715da65caffb7f830b3ca218617 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Tue, 29 Aug 2023 12:28:48 +0000 Subject: [PATCH 21/56] Update Changelog for 16.5.1 --- changelog.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/changelog.txt b/changelog.txt index 32f3469b9d6d35..40c6e315feac6f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,26 @@ == Changelog == += 16.5.1 = + + + +## Changelog + +### Bug Fixes + +#### Block Editor +- Pass entire link value on toggle of setting on Link Preview. ([53949](https://github.com/WordPress/gutenberg/pull/53949)) + + + + +## Contributors + +The following contributors merged PRs in this release: + +@getdave + + = 16.5.0 = From a8eead850002d971cdfe1d9a511a4cd6e52dafa2 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Tue, 29 Aug 2023 15:54:54 +0300 Subject: [PATCH 22/56] [Commands]: Fix block editor commands availability (#53994) --- .../components/use-block-commands/index.js | 160 ++++++++---------- 1 file changed, 73 insertions(+), 87 deletions(-) diff --git a/packages/block-editor/src/components/use-block-commands/index.js b/packages/block-editor/src/components/use-block-commands/index.js index cb325438deca73..184c33714e7103 100644 --- a/packages/block-editor/src/components/use-block-commands/index.js +++ b/packages/block-editor/src/components/use-block-commands/index.js @@ -131,23 +131,6 @@ const useActionsCommands = () => { useSelect( blocksStore ); const blocks = getBlocksByClientId( clientIds ); - const rootClientId = getBlockRootClientId( clientIds[ 0 ] ); - - const canDuplicate = blocks.every( ( block ) => { - return ( - !! block && - hasBlockSupport( block.name, 'multiple', true ) && - canInsertBlockType( block.name, rootClientId ) - ); - } ); - - const canInsertDefaultBlock = canInsertBlockType( - getDefaultBlockName(), - rootClientId - ); - - const canMove = canMoveBlocks( clientIds, rootClientId ); - const canRemove = canRemoveBlocks( clientIds, rootClientId ); const { removeBlocks, @@ -160,42 +143,6 @@ const useActionsCommands = () => { selectBlock, } = useDispatch( blockEditorStore ); - const onDuplicate = () => { - if ( ! canDuplicate ) { - return; - } - return duplicateBlocks( clientIds, true ); - }; - const onRemove = () => { - if ( ! canRemove ) { - return; - } - return removeBlocks( clientIds, true ); - }; - const onAddBefore = () => { - if ( ! canInsertDefaultBlock ) { - return; - } - const clientId = Array.isArray( clientIds ) ? clientIds[ 0 ] : clientId; - insertBeforeBlock( clientId ); - }; - const onAddAfter = () => { - if ( ! canInsertDefaultBlock ) { - return; - } - const clientId = Array.isArray( clientIds ) - ? clientIds[ clientIds.length - 1 ] - : clientId; - insertAfterBlock( clientId ); - }; - const onMoveTo = () => { - if ( ! canMove ) { - return; - } - setNavigationMode( true ); - selectBlock( clientIds[ 0 ] ); - setBlockMovingClientId( clientIds[ 0 ] ); - }; const onGroup = () => { if ( ! blocks.length ) { return; @@ -229,6 +176,21 @@ const useActionsCommands = () => { return { isLoading: false, commands: [] }; } + const rootClientId = getBlockRootClientId( clientIds[ 0 ] ); + const canInsertDefaultBlock = canInsertBlockType( + getDefaultBlockName(), + rootClientId + ); + const canDuplicate = blocks.every( ( block ) => { + return ( + !! block && + hasBlockSupport( block.name, 'multiple', true ) && + canInsertBlockType( block.name, rootClientId ) + ); + } ); + const canRemove = canRemoveBlocks( clientIds, rootClientId ); + const canMove = canMoveBlocks( clientIds, rootClientId ); + const commands = [ { name: 'ungroup', @@ -242,49 +204,73 @@ const useActionsCommands = () => { callback: onGroup, icon: group, }, - { - name: 'move-to', - label: __( 'Move to' ), - callback: onMoveTo, - icon: move, - }, - { - name: 'add-after', - label: __( 'Add after' ), - callback: onAddAfter, - icon: add, - }, - { - name: 'add-before', - label: __( 'Add before' ), - callback: onAddBefore, - icon: add, - }, - { + ]; + if ( canInsertDefaultBlock ) { + commands.push( + { + name: 'add-after', + label: __( 'Add after' ), + callback: () => { + const clientId = Array.isArray( clientIds ) + ? clientIds[ clientIds.length - 1 ] + : clientId; + insertAfterBlock( clientId ); + }, + icon: add, + }, + { + name: 'add-before', + label: __( 'Add before' ), + callback: () => { + const clientId = Array.isArray( clientIds ) + ? clientIds[ 0 ] + : clientId; + insertBeforeBlock( clientId ); + }, + icon: add, + } + ); + } + if ( canRemove ) { + commands.push( { name: 'remove', label: __( 'Remove' ), - callback: onRemove, + callback: () => removeBlocks( clientIds, true ), icon: remove, - }, - { + } ); + } + if ( canDuplicate ) { + commands.push( { name: 'duplicate', label: __( 'Duplicate' ), - callback: onDuplicate, + callback: () => duplicateBlocks( clientIds, true ), icon: copy, - }, - ].map( ( { name, label, callback, icon } ) => { - return { - name: 'core/block-editor/action-' + name, - label, - icon, + } ); + } + if ( canMove ) { + commands.push( { + name: 'move-to', + label: __( 'Move to' ), + callback: () => { + setNavigationMode( true ); + selectBlock( clientIds[ 0 ] ); + setBlockMovingClientId( clientIds[ 0 ] ); + }, + icon: move, + } ); + } + + return { + isLoading: false, + commands: commands.map( ( command ) => ( { + ...command, + name: 'core/block-editor/action-' + command.name, callback: ( { close } ) => { - callback(); + command.callback(); close(); }, - }; - } ); - - return { isLoading: false, commands }; + } ) ), + }; }; export const useBlockCommands = () => { From 4f6d1b39350f31e242a573da64dea93175beaa74 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Tue, 29 Aug 2023 08:30:55 -0700 Subject: [PATCH 23/56] Fix query loop bugs by correctly relying on the main query and removing problematic workaround (#49904) * Use global main query directly so that global query loop works as expected. * Remove hack to enforce query loop as it causes problems, and the loop needs to be handled in block templates instead. * Maintain fix from #43198. * Clarify logic with comment. * Add test coverage. --- .../block-library/src/post-content/index.php | 6 -- .../src/post-featured-image/index.php | 6 -- .../block-library/src/post-template/index.php | 13 ++- phpunit/blocks/render-post-template-test.php | 86 +++++++++++++++++++ 4 files changed, 98 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/post-content/index.php b/packages/block-library/src/post-content/index.php index 2be1ef77b3b856..dd84574fdea658 100644 --- a/packages/block-library/src/post-content/index.php +++ b/packages/block-library/src/post-content/index.php @@ -35,12 +35,6 @@ function render_block_core_post_content( $attributes, $content, $block ) { $seen_ids[ $post_id ] = true; - // Check is needed for backward compatibility with third-party plugins - // that might rely on the `in_the_loop` check; calling `the_post` sets it to true. - if ( ! in_the_loop() && have_posts() ) { - the_post(); - } - // When inside the main loop, we want to use queried object // so that `the_preview` for the current post can apply. // We force this behavior by omitting the third argument (post ID) from the `get_the_content`. diff --git a/packages/block-library/src/post-featured-image/index.php b/packages/block-library/src/post-featured-image/index.php index 6cb4110ee000e6..67c889b0befa51 100644 --- a/packages/block-library/src/post-featured-image/index.php +++ b/packages/block-library/src/post-featured-image/index.php @@ -19,12 +19,6 @@ function render_block_core_post_featured_image( $attributes, $content, $block ) } $post_ID = $block->context['postId']; - // Check is needed for backward compatibility with third-party plugins - // that might rely on the `in_the_loop` check; calling `the_post` sets it to true. - if ( ! in_the_loop() && have_posts() ) { - the_post(); - } - $is_link = isset( $attributes['isLink'] ) && $attributes['isLink']; $size_slug = isset( $attributes['sizeSlug'] ) ? $attributes['sizeSlug'] : 'post-thumbnail'; $attr = get_block_core_post_featured_image_border_attributes( $attributes ); diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index 88b7c27f1c66f9..d72e66ce65350d 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -50,7 +50,18 @@ function render_block_core_post_template( $attributes, $content, $block ) { $use_global_query = ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ); if ( $use_global_query ) { global $wp_query; - $query = clone $wp_query; + + /* + * If already in the main query loop, duplicate the query instance to not tamper with the main instance. + * Since this is a nested query, it should start at the beginning, therefore rewind posts. + * Otherwise, the main query loop has not started yet and this block is responsible for doing so. + */ + if ( in_the_loop() ) { + $query = clone $wp_query; + $query->rewind_posts(); + } else { + $query = $wp_query; + } } else { $query_args = build_query_vars_from_query_block( $block, $page ); $query = new WP_Query( $query_args ); diff --git a/phpunit/blocks/render-post-template-test.php b/phpunit/blocks/render-post-template-test.php index 13b5623cdd5dda..95a90f12ca3e24 100644 --- a/phpunit/blocks/render-post-template-test.php +++ b/phpunit/blocks/render-post-template-test.php @@ -70,4 +70,90 @@ public function test_rendering_post_template() { str_replace( array( "\n", "\t" ), '', $markup ) ); } + + /** + * Tests that the `core/post-template` block triggers the main query loop when rendering within a corresponding + * `core/query` block. + */ + public function test_rendering_post_template_with_main_query_loop() { + global $wp_query, $wp_the_query; + + // Query block with post template block. + $content = ''; + $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; + + $expected = '
    '; + $expected .= '
  • '; + $expected .= '

    ' . self::$post->post_title . '

    '; + $expected .= '
  • '; + $expected .= '
'; + + // Set main query to single post. + $wp_query = new WP_Query( array( 'p' => self::$post->ID ) ); + $wp_the_query = $wp_query; + + // Register test block to log `in_the_loop()` results. + $in_the_loop_logs = array(); + register_block_type( + 'test/in-the-loop-logger', + array( + 'render_callback' => static function() use ( &$in_the_loop_logs ) { + $in_the_loop_logs[] = in_the_loop(); + return ''; + }, + ) + ); + + $output = do_blocks( $content ); + $this->assertSame( $expected, $output, 'Unexpected parsed blocks content' ); + $this->assertSame( array( true ), $in_the_loop_logs, 'Unexpected in_the_loop() result' ); + } + + /** + * Tests that the `core/post-template` block does not tamper with the main query loop when rendering within a post + * as the main query loop has already been started. In this case, the main query object needs to be cloned to + * prevent an infinite loop. + */ + public function test_rendering_post_template_with_main_query_loop_already_started() { + global $wp_query, $wp_the_query; + + // Query block with post template block. + $content = ''; + $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; + + $expected = '
    '; + $expected .= '
  • '; + $expected .= '

    ' . self::$post->post_title . '

    '; + $expected .= '
  • '; + $expected .= '
'; + + // Update the post's content to have a query block for the same query as the main query. + wp_update_post( + array( + 'ID' => self::$post->ID, + 'post_content' => $content, + 'post_content_filtered' => $content, + ) + ); + + // Set main query to single post. + $wp_query = new WP_Query( array( 'p' => self::$post->ID ) ); + $wp_the_query = $wp_query; + + // Get post content within main query loop. + $output = ''; + while ( $wp_query->have_posts() ) { + $wp_query->the_post(); + + $output = get_echo( 'the_content' ); + } + + $this->assertSame( $expected, $output, 'Unexpected parsed post content' ); + } } From 2db2dc038e37f6965098951171fe05ff11a5ee2d Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Wed, 30 Aug 2023 01:29:35 +0900 Subject: [PATCH 24/56] Patterns: Disable the preview option button when editing (#53913) * Don't show the preview options button when editing patterns * Refactor with FOCUSABLE_ENTITIES * Use disabled view icon * Use isEnabled prop * Also set 'disableOpenOnArrowDown' * Fix e2e test * Use `toBeDisabled` --------- Co-authored-by: George Mamadashvili --- .../src/components/preview-options/index.js | 2 + .../block-editor/site-editor-canvas.js | 2 +- .../src/components/header-edit-mode/index.js | 69 ++++++++++--------- .../block-editor => utils}/constants.js | 0 test/e2e/specs/site-editor/style-book.spec.js | 2 +- 5 files changed, 39 insertions(+), 36 deletions(-) rename packages/edit-site/src/{components/block-editor => utils}/constants.js (100%) diff --git a/packages/block-editor/src/components/preview-options/index.js b/packages/block-editor/src/components/preview-options/index.js index c22109e7359d1d..9f5f820c4edcb2 100644 --- a/packages/block-editor/src/components/preview-options/index.js +++ b/packages/block-editor/src/components/preview-options/index.js @@ -33,6 +33,7 @@ export default function PreviewOptions( { const toggleProps = { className: 'block-editor-post-preview__button-toggle', disabled: ! isEnabled, + __experimentalIsFocusable: ! isEnabled, children: viewLabel, }; const menuProps = { @@ -53,6 +54,7 @@ export default function PreviewOptions( { menuProps={ menuProps } icon={ deviceIcons[ deviceType.toLowerCase() ] } label={ label || __( 'Preview' ) } + disableOpenOnArrowDown={ ! isEnabled } > { ( renderProps ) => ( <> diff --git a/packages/edit-site/src/components/block-editor/site-editor-canvas.js b/packages/edit-site/src/components/block-editor/site-editor-canvas.js index 6693a1380ac83f..2fc77e1ee1a403 100644 --- a/packages/edit-site/src/components/block-editor/site-editor-canvas.js +++ b/packages/edit-site/src/components/block-editor/site-editor-canvas.js @@ -27,7 +27,7 @@ import EditorCanvas from './editor-canvas'; import EditorCanvasContainer from '../editor-canvas-container'; import useSiteEditorSettings from './use-site-editor-settings'; import { store as editSiteStore } from '../../store'; -import { FOCUSABLE_ENTITIES } from './constants'; +import { FOCUSABLE_ENTITIES } from '../../utils/constants'; import { unlock } from '../../lock-unlock'; import PageContentFocusManager from '../page-content-focus-manager'; diff --git a/packages/edit-site/src/components/header-edit-mode/index.js b/packages/edit-site/src/components/header-edit-mode/index.js index 23b7adc1bc757c..da682e995defd3 100644 --- a/packages/edit-site/src/components/header-edit-mode/index.js +++ b/packages/edit-site/src/components/header-edit-mode/index.js @@ -45,6 +45,7 @@ import { useHasEditorCanvasContainer, } from '../editor-canvas-container'; import { unlock } from '../../lock-unlock'; +import { FOCUSABLE_ENTITIES } from '../../utils/constants'; const { useShouldContextualToolbarShow } = unlock( blockEditorPrivateApis ); @@ -156,8 +157,7 @@ export default function HeaderEditMode() { const hasDefaultEditorCanvasView = ! useHasEditorCanvasContainer(); - const isFocusMode = - templateType === 'wp_template_part' || templateType === 'wp_navigation'; + const isFocusMode = FOCUSABLE_ENTITIES.includes( templateType ); /* translators: button label text should, if possible, be under 16 characters. */ const longLabel = _x( @@ -313,39 +313,40 @@ export default function HeaderEditMode() { variants={ toolbarVariants } transition={ toolbarTransition } > - { ! isFocusMode && hasDefaultEditorCanvasView && ( -
+ - - { ( { onClose } ) => ( - - - { __( 'View site' ) } - - { - /* translators: accessibility text */ - __( '(opens in a new tab)' ) - } - - - - ) } - -
- ) } + { ( { onClose } ) => ( + + + { __( 'View site' ) } + + { + /* translators: accessibility text */ + __( '(opens in a new tab)' ) + } + + + + ) } + + { ! isDistractionFree && ( diff --git a/packages/edit-site/src/components/block-editor/constants.js b/packages/edit-site/src/utils/constants.js similarity index 100% rename from packages/edit-site/src/components/block-editor/constants.js rename to packages/edit-site/src/utils/constants.js diff --git a/test/e2e/specs/site-editor/style-book.spec.js b/test/e2e/specs/site-editor/style-book.spec.js index 47001a48edbd10..eeaa1270f3ff9e 100644 --- a/test/e2e/specs/site-editor/style-book.spec.js +++ b/test/e2e/specs/site-editor/style-book.spec.js @@ -42,7 +42,7 @@ test.describe( 'Style Book', () => { ).not.toBeVisible(); await expect( page.locator( 'role=button[name="View"i]' ) - ).not.toBeVisible(); + ).toBeDisabled(); } ); test( 'should have tabs containing block examples', async ( { page } ) => { From 2436169504eae1e4dd67a28e6437b464190185ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Walb=C3=B8=20Johnsg=C3=A5rd?= Date: Tue, 29 Aug 2023 18:39:49 +0200 Subject: [PATCH 25/56] PaletteEdit: Fix component height (#54000) * PaletteEdit: Fix item height * Update CHANGELOG.md --- packages/components/CHANGELOG.md | 1 + packages/components/src/palette-edit/styles.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 4017491e46de67..eb52028535f893 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -11,6 +11,7 @@ ### Bug Fix - `SandBox`: Fix the cleanup method in useEffect ([#53796](https://github.com/WordPress/gutenberg/pull/53796)). +- `PaletteEdit`: Fix the height of the `PaletteItems`. Don't rely on styles only present in the block editor ([#54000](https://github.com/WordPress/gutenberg/pull/54000)). ### Internal diff --git a/packages/components/src/palette-edit/styles.js b/packages/components/src/palette-edit/styles.js index e04aa1840028ff..72e6bff97e4a29 100644 --- a/packages/components/src/palette-edit/styles.js +++ b/packages/components/src/palette-edit/styles.js @@ -42,7 +42,6 @@ export const NameInputControl = styled( InputControl )` export const PaletteItem = styled( View )` padding: 3px 0 3px ${ space( 3 ) }; - height: calc( 40px - ${ CONFIG.borderWidth } ); border: 1px solid ${ CONFIG.surfaceBorderColor }; border-bottom-color: transparent; &:first-of-type { From abfe3c6013bb811a0f5bf9d61a62c709c81c80c3 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Tue, 29 Aug 2023 19:29:30 +0200 Subject: [PATCH 26/56] Query block: client-side pagination (#53812) * Add router with region-based client-side navigation * Add changelog * Initial version working * Only add supports.interactivity and enqueue the view.js file if the "Enhanced Pagination" option is enabled * Interactivity API: merge new server-side rendered context on client-side navigation (#53853) * Add failing test * Fix the test * Add changelog * Fix lint error * Fix changelog placement * Interactivity API: Support for the `data-wp-key` directive (#53844) * Add failing test * Fix test using key * Replace key with data-wp-key * Refactor test a bit * Add changelog * Add docs * Remove unnecessary paragraph * Fix lint error * Interactivity API: Fix non stable context reference on client side navigation (#53876) * Add failing test * Fix the test * Add basic accessibility (announcement + focus) * Add basic loading animation Co-authored-by: David Arenas * Only enqueue styles if they are needed * Add missing CSS props on aria-live element Apparently, some screen readers don't read elements that don't have width and height. * Fix two typos * Update fixture * Simplify loaded text * Move navigation announce style to a class --------- Co-authored-by: David Arenas Co-authored-by: David Arenas --- docs/reference-guides/core-blocks.md | 2 +- .../src/post-template/block.json | 3 +- .../block-library/src/post-template/index.php | 10 +- .../src/query-pagination-next/block.json | 8 +- .../src/query-pagination-next/index.php | 23 ++++- .../src/query-pagination-numbers/block.json | 2 +- .../src/query-pagination-numbers/index.php | 22 ++++- .../src/query-pagination-previous/block.json | 8 +- .../src/query-pagination-previous/index.php | 21 +++- packages/block-library/src/query/block.json | 11 ++- .../query/edit/inspector-controls/index.js | 49 +++++++++- .../src/query/edit/query-content.js | 1 + packages/block-library/src/query/index.php | 95 ++++++++++++++++++- packages/block-library/src/query/style.scss | 63 ++++++++++++ packages/block-library/src/query/view.js | 82 ++++++++++++++++ .../fixtures/blocks/core__query.json | 3 +- 16 files changed, 380 insertions(+), 23 deletions(-) create mode 100644 packages/block-library/src/query/style.scss create mode 100644 packages/block-library/src/query/view.js diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index fde7f405558cc1..0f25cead8b07a9 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -665,7 +665,7 @@ An advanced block that allows displaying post types based on different query par - **Name:** core/query - **Category:** theme - **Supports:** align (full, wide), layout, ~~html~~ -- **Attributes:** namespace, query, queryId, tagName +- **Attributes:** enhancedPagination, namespace, query, queryId, tagName ## No results diff --git a/packages/block-library/src/post-template/block.json b/packages/block-library/src/post-template/block.json index 1f0d4677e67278..48804de75d2cae 100644 --- a/packages/block-library/src/post-template/block.json +++ b/packages/block-library/src/post-template/block.json @@ -13,7 +13,8 @@ "queryContext", "displayLayout", "templateSlug", - "previewPostType" + "previewPostType", + "enhancedPagination" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index d72e66ce65350d..e616939514a682 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -43,8 +43,9 @@ function block_core_post_template_uses_featured_image( $inner_blocks ) { * @return string Returns the output of the query, structured using the layout defined by the block's inner blocks. */ function render_block_core_post_template( $attributes, $content, $block ) { - $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; + $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; + $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; // Use global query if needed. $use_global_query = ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ); @@ -120,7 +121,10 @@ function render_block_core_post_template( $attributes, $content, $block ) { // Wrap the render inner blocks in a `li` element with the appropriate post classes. $post_classes = implode( ' ', get_post_class( 'wp-block-post' ) ); - $content .= '
  • ' . $block_content . '
  • '; + + $inner_block_directives = $enhanced_pagination ? ' data-wp-key="post-template-item-' . $post_id . '"' : ''; + + $content .= '' . $block_content . ''; } /* diff --git a/packages/block-library/src/query-pagination-next/block.json b/packages/block-library/src/query-pagination-next/block.json index 60d44d7ca17b54..95b1169dc992fd 100644 --- a/packages/block-library/src/query-pagination-next/block.json +++ b/packages/block-library/src/query-pagination-next/block.json @@ -12,7 +12,13 @@ "type": "string" } }, - "usesContext": [ "queryId", "query", "paginationArrow", "showLabel" ], + "usesContext": [ + "queryId", + "query", + "paginationArrow", + "showLabel", + "enhancedPagination" + ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/query-pagination-next/index.php b/packages/block-library/src/query-pagination-next/index.php index f0ded727ee8a9a..83c177c6fb0a9f 100644 --- a/packages/block-library/src/query-pagination-next/index.php +++ b/packages/block-library/src/query-pagination-next/index.php @@ -15,9 +15,10 @@ * @return string Returns the next posts link for the query pagination. */ function render_block_core_query_pagination_next( $attributes, $content, $block ) { - $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; - $max_page = isset( $block->context['query']['pages'] ) ? (int) $block->context['query']['pages'] : 0; + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; + $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; + $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + $max_page = isset( $block->context['query']['pages'] ) ? (int) $block->context['query']['pages'] : 0; $wrapper_attributes = get_block_wrapper_attributes(); $show_label = isset( $block->context['showLabel'] ) ? (bool) $block->context['showLabel'] : true; @@ -61,6 +62,22 @@ function render_block_core_query_pagination_next( $attributes, $content, $block } wp_reset_postdata(); // Restore original Post Data. } + + if ( $enhanced_pagination ) { + $p = new WP_HTML_Tag_Processor( $content ); + if ( $p->next_tag( + array( + 'tag_name' => 'a', + 'class_name' => 'wp-block-query-pagination-next', + ) + ) ) { + $p->set_attribute( 'data-wp-key', 'query-pagination-next' ); + $p->set_attribute( 'data-wp-on--click', 'actions.core.query.navigate' ); + $p->set_attribute( 'data-wp-on--mouseenter', 'actions.core.query.prefetch' ); + $content = $p->get_updated_html(); + } + } + return $content; } diff --git a/packages/block-library/src/query-pagination-numbers/block.json b/packages/block-library/src/query-pagination-numbers/block.json index 09b001c94dbf51..f05e269d2ece20 100644 --- a/packages/block-library/src/query-pagination-numbers/block.json +++ b/packages/block-library/src/query-pagination-numbers/block.json @@ -13,7 +13,7 @@ "default": 2 } }, - "usesContext": [ "queryId", "query" ], + "usesContext": [ "queryId", "query", "enhancedPagination" ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/query-pagination-numbers/index.php b/packages/block-library/src/query-pagination-numbers/index.php index c37a4ae9fac7e2..98098533adac7d 100644 --- a/packages/block-library/src/query-pagination-numbers/index.php +++ b/packages/block-library/src/query-pagination-numbers/index.php @@ -15,9 +15,10 @@ * @return string Returns the pagination numbers for the Query. */ function render_block_core_query_pagination_numbers( $attributes, $content, $block ) { - $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; - $max_page = isset( $block->context['query']['pages'] ) ? (int) $block->context['query']['pages'] : 0; + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; + $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; + $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + $max_page = isset( $block->context['query']['pages'] ) ? (int) $block->context['query']['pages'] : 0; $wrapper_attributes = get_block_wrapper_attributes(); $content = ''; @@ -84,9 +85,24 @@ function render_block_core_query_pagination_numbers( $attributes, $content, $blo wp_reset_postdata(); // Restore original Post Data. $wp_query = $prev_wp_query; } + if ( empty( $content ) ) { return ''; } + + if ( $enhanced_pagination ) { + $p = new WP_HTML_Tag_Processor( $content ); + while ( $p->next_tag( + array( + 'tag_name' => 'a', + 'class_name' => 'page-numbers', + ) + ) ) { + $p->set_attribute( 'data-wp-on--click', 'actions.core.query.navigate' ); + } + $content = $p->get_updated_html(); + } + return sprintf( '
    %2$s
    ', $wrapper_attributes, diff --git a/packages/block-library/src/query-pagination-previous/block.json b/packages/block-library/src/query-pagination-previous/block.json index d13442f831c972..fbaac543c1da35 100644 --- a/packages/block-library/src/query-pagination-previous/block.json +++ b/packages/block-library/src/query-pagination-previous/block.json @@ -12,7 +12,13 @@ "type": "string" } }, - "usesContext": [ "queryId", "query", "paginationArrow", "showLabel" ], + "usesContext": [ + "queryId", + "query", + "paginationArrow", + "showLabel", + "enhancedPagination" + ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/query-pagination-previous/index.php b/packages/block-library/src/query-pagination-previous/index.php index 5665506598f813..a580880f0f04c8 100644 --- a/packages/block-library/src/query-pagination-previous/index.php +++ b/packages/block-library/src/query-pagination-previous/index.php @@ -15,8 +15,9 @@ * @return string Returns the previous posts link for the query. */ function render_block_core_query_pagination_previous( $attributes, $content, $block ) { - $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; + $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; + $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; $wrapper_attributes = get_block_wrapper_attributes(); $show_label = isset( $block->context['showLabel'] ) ? (bool) $block->context['showLabel'] : true; @@ -49,6 +50,22 @@ function render_block_core_query_pagination_previous( $attributes, $content, $bl $label ); } + + if ( $enhanced_pagination ) { + $p = new WP_HTML_Tag_Processor( $content ); + if ( $p->next_tag( + array( + 'tag_name' => 'a', + 'class_name' => 'wp-block-query-pagination-previous', + ) + ) ) { + $p->set_attribute( 'data-wp-key', 'query-pagination-previous' ); + $p->set_attribute( 'data-wp-on--click', 'actions.core.query.navigate' ); + $p->set_attribute( 'data-wp-on--mouseenter', 'actions.core.query.prefetch' ); + $content = $p->get_updated_html(); + } + } + return $content; } diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index e4b78b585be0e5..d30eccf3765792 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -34,17 +34,24 @@ }, "namespace": { "type": "string" + }, + "enhancedPagination": { + "type": "boolean", + "default": false } }, "providesContext": { "queryId": "queryId", "query": "query", - "displayLayout": "displayLayout" + "displayLayout": "displayLayout", + "enhancedPagination": "enhancedPagination" }, "supports": { "align": [ "wide", "full" ], "html": false, "layout": true }, - "editorStyle": "wp-block-query-editor" + "editorStyle": "wp-block-query-editor", + "style": "wp-block-query", + "viewScript": "file:./view.min.js" } diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js index 5244a888312552..492f276ccf6151 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -17,7 +17,8 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { debounce } from '@wordpress/compose'; -import { useEffect, useState, useCallback } from '@wordpress/element'; +import { useEffect, useState, useCallback, useRef } from '@wordpress/element'; +import { speak } from '@wordpress/a11y'; /** * Internal dependencies @@ -40,8 +41,8 @@ import { const { BlockInfo } = unlock( blockEditorPrivateApis ); export default function QueryInspectorControls( props ) { - const { attributes, setQuery, setDisplayLayout } = props; - const { query, displayLayout } = attributes; + const { attributes, setQuery, setDisplayLayout, setAttributes } = props; + const { query, displayLayout, enhancedPagination } = attributes; const { order, orderBy, @@ -123,6 +124,18 @@ export default function QueryInspectorControls( props ) { isControlAllowed( allowedControls, 'parents' ) && isPostTypeHierarchical; + const enhancedPaginationNotice = __( + 'Enhanced Pagination might cause interactive blocks within the Post Template to stop working. Disable it if you experience any issues.' + ); + + const isFirstRender = useRef( true ); // Don't speak on first render. + useEffect( () => { + if ( ! isFirstRender.current && enhancedPagination ) { + speak( enhancedPaginationNotice ); + } + isFirstRender.current = false; + }, [ enhancedPagination, enhancedPaginationNotice ] ); + const showFiltersPanel = showTaxControl || showAuthorControl || @@ -280,6 +293,36 @@ export default function QueryInspectorControls( props ) { ) } + + + + setAttributes( { + enhancedPagination: !! value, + } ) + } + /> + { enhancedPagination && ( +
    + + { enhancedPaginationNotice } + +
    + ) } +
    +
    ); } diff --git a/packages/block-library/src/query/edit/query-content.js b/packages/block-library/src/query/edit/query-content.js index 1d795dd646d48d..89c6efa2809795 100644 --- a/packages/block-library/src/query/edit/query-content.js +++ b/packages/block-library/src/query/edit/query-content.js @@ -109,6 +109,7 @@ export default function QueryContent( { attributes={ attributes } setQuery={ updateQuery } setDisplayLayout={ updateDisplayLayout } + setAttributes={ setAttributes } /> next_tag() ) { + // Add the necessary directives. + $p->set_attribute( 'data-wp-interactive', true ); + $p->set_attribute( 'data-wp-navigation-id', 'query-' . $attributes['queryId'] ); + $p->set_attribute( + 'data-wp-context', + wp_json_encode( array( 'core' => array( 'query' => (object) array() ) ) ) + ); + $content = $p->get_updated_html(); + + // Mark the block as interactive. + $block->block_type->supports['interactivity'] = true; + + // Add a div to announce messages using `aria-live`. + $last_div_position = strripos( $content, '' ); + $content = substr_replace( + $content, + '
    +
    ', + $last_div_position, + 0 + ); + + // Use state to send translated strings. + wp_store( + array( + 'state' => array( + 'core' => array( + 'query' => array( + 'loadingText' => __( 'Loading page, please wait.' ), + 'loadedText' => __( 'Page Loaded.' ), + ), + ), + ), + ) + ); + } + } + + $view_asset = 'wp-block-query-view'; + if ( ! wp_script_is( $view_asset ) ) { + $script_handles = $block->block_type->view_script_handles; + // If the script is not needed, and it is still in the `view_script_handles`, remove it. + if ( ! $attributes['enhancedPagination'] && in_array( $view_asset, $script_handles, true ) ) { + $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_asset ) ); + } + // If the script is needed, but it was previously removed, add it again. + if ( $attributes['enhancedPagination'] && ! in_array( $view_asset, $script_handles, true ) ) { + $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_asset ) ); + } + } + + $style_asset = 'wp-block-query'; + if ( ! wp_style_is( $style_asset ) ) { + $style_handles = $block->block_type->style_handles; + // If the styles are not needed, and they are still in the `style_handles`, remove them. + if ( ! $attributes['enhancedPagination'] && in_array( $style_asset, $style_handles, true ) ) { + $block->block_type->style_handles = array_diff( $style_handles, array( $style_asset ) ); + } + // If the styles are needed, but they were previously removed, add them again. + if ( $attributes['enhancedPagination'] && ! in_array( $style_asset, $style_handles, true ) ) { + $block->block_type->style_handles = array_merge( $style_handles, array( $style_asset ) ); + } + } + + return $content; +} + /** * Registers the `core/query` block on the server. */ function register_block_core_query() { register_block_type_from_metadata( - __DIR__ . '/query' + __DIR__ . '/query', + array( + 'render_callback' => 'render_block_core_query', + ) ); } add_action( 'init', 'register_block_core_query' ); diff --git a/packages/block-library/src/query/style.scss b/packages/block-library/src/query/style.scss new file mode 100644 index 00000000000000..c560018056d7f0 --- /dev/null +++ b/packages/block-library/src/query/style.scss @@ -0,0 +1,63 @@ +.wp-block-query__enhanced-pagination-animation { + position: fixed; + top: 0; + left: 0; + margin: 0; + padding: 0; + width: 100vw; + max-width: 100vw !important; + height: 4px; + background-color: var(--wp--preset--color--primary, #000); + opacity: 0; + + &.start-animation { + animation: + wp-block-query__enhanced-pagination-start-animation + 30s + cubic-bezier(0, 1, 0, 1) + infinite; + } + + &.finish-animation { + animation: + wp-block-query__enhanced-pagination-finish-animation + 300ms + ease-in; + } +} + +@keyframes wp-block-query__enhanced-pagination-start-animation { + 0% { + transform: scaleX(0); + transform-origin: 0% 0%; + opacity: 1; + } + 100% { + transform: scaleX(1); + transform-origin: 0% 0%; + opacity: 1; + } +} + +@keyframes wp-block-query__enhanced-pagination-finish-animation { + 0% { + opacity: 1; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.wp-block-query__enhanced-pagination-navigation-announce { + position: absolute; + clip: rect(0, 0, 0, 0); + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + border: 0; +} diff --git a/packages/block-library/src/query/view.js b/packages/block-library/src/query/view.js new file mode 100644 index 00000000000000..cbd5573e05c6f9 --- /dev/null +++ b/packages/block-library/src/query/view.js @@ -0,0 +1,82 @@ +/** + * WordPress dependencies + */ +import { store, navigate, prefetch } from '@wordpress/interactivity'; + +const isValidLink = ( ref ) => + ref && + ref instanceof window.HTMLAnchorElement && + ref.href && + ( ! ref.target || ref.target === '_self' ) && + ref.origin === window.location.origin; + +const isValidEvent = ( event ) => + event.button === 0 && // left clicks only + ! event.metaKey && // open in new tab (mac) + ! event.ctrlKey && // open in new tab (windows) + ! event.altKey && // download + ! event.shiftKey && + ! event.defaultPrevented; + +store( { + selectors: { + core: { + query: { + startAnimation: ( { context } ) => + context.core.query.animation === 'start', + finishAnimation: ( { context } ) => + context.core.query.animation === 'finish', + }, + }, + }, + actions: { + core: { + query: { + navigate: async ( { event, ref, context, state } ) => { + if ( isValidLink( ref ) && isValidEvent( event ) ) { + event.preventDefault(); + + const id = ref.closest( '[data-wp-navigation-id]' ) + .dataset.wpNavigationId; + + // Don't announce the navigation immediately, wait 300 ms. + const timeout = setTimeout( () => { + context.core.query.message = + state.core.query.loadingText; + context.core.query.animation = 'start'; + }, 300 ); + + await navigate( ref.href ); + + // Dismiss loading message if it hasn't been added yet. + clearTimeout( timeout ); + + // Announce that the page has been loaded. If the message is the + // same, we use a no-break space similar to the @wordpress/a11y + // package: https://github.com/WordPress/gutenberg/blob/c395242b8e6ee20f8b06c199e4fc2920d7018af1/packages/a11y/src/filter-message.js#L20-L26 + context.core.query.message = + state.core.query.loadedText + + ( context.core.query.message === + state.core.query.loadedText + ? '\u00A0' + : '' ); + + context.core.query.animation = 'finish'; + + // Focus the first anchor of the Query block. + document + .querySelector( + `[data-wp-navigation-id=${ id }] a[href]` + ) + ?.focus(); + } + }, + prefetch: async ( { ref } ) => { + if ( isValidLink( ref ) ) { + await prefetch( ref.href ); + } + }, + }, + }, + }, +} ); diff --git a/test/integration/fixtures/blocks/core__query.json b/test/integration/fixtures/blocks/core__query.json index fb545c16ea6953..b050aaa2b5b1fd 100644 --- a/test/integration/fixtures/blocks/core__query.json +++ b/test/integration/fixtures/blocks/core__query.json @@ -18,7 +18,8 @@ "taxQuery": null, "parents": [] }, - "tagName": "div" + "tagName": "div", + "enhancedPagination": false }, "innerBlocks": [] } From 5dbe0da79971af4aa38641630a32f7814d50c159 Mon Sep 17 00:00:00 2001 From: margolisj <1588194+margolisj@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:20:53 -0400 Subject: [PATCH 27/56] RichTextValue: improve types (#54002) * Do not accept undefined start/end properties in RichTextValue * Accept null value to WPFormat --- packages/rich-text/src/register-format-type.js | 18 +++++++++--------- packages/rich-text/src/types.ts | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/rich-text/src/register-format-type.js b/packages/rich-text/src/register-format-type.js index a3ca5b64903f9f..b2dd048d79e6fb 100644 --- a/packages/rich-text/src/register-format-type.js +++ b/packages/rich-text/src/register-format-type.js @@ -9,15 +9,15 @@ import { store as richTextStore } from './store'; /** * @typedef {Object} WPFormat * - * @property {string} name A string identifying the format. Must be - * unique across all registered formats. - * @property {string} tagName The HTML tag this format will wrap the - * selection with. - * @property {boolean} interactive Whether format makes content interactive or not. - * @property {string} [className] A class to match the format. - * @property {string} title Name of the format. - * @property {Function} edit Should return a component for the user to - * interact with the new registered format. + * @property {string} name A string identifying the format. Must be + * unique across all registered formats. + * @property {string} tagName The HTML tag this format will wrap the + * selection with. + * @property {boolean} interactive Whether format makes content interactive or not. + * @property {string | null} [className] A class to match the format. + * @property {string} title Name of the format. + * @property {Function} edit Should return a component for the user to + * interact with the new registered format. */ /** diff --git a/packages/rich-text/src/types.ts b/packages/rich-text/src/types.ts index 1e4725260c27e0..5ef595fcdb7615 100644 --- a/packages/rich-text/src/types.ts +++ b/packages/rich-text/src/types.ts @@ -1,5 +1,5 @@ /** - * Stores the type of a rich rext format, such as core/bold. + * Stores the type of a rich text format, such as core/bold. */ export type RichTextFormat = { type: @@ -26,6 +26,6 @@ export type RichTextValue = { text: string; formats: Array< RichTextFormatList >; replacements: Array< RichTextFormat >; - start: number | undefined; - end: number | undefined; + start: number; + end: number; }; From 8c165c19e59760f50a0abd2b2b187f279992f874 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Wed, 30 Aug 2023 10:20:17 +1000 Subject: [PATCH 28/56] [RNMobile] Add block outline to all Social Link blocks when selected (#54011) * Update native block outline component to outline all social-link blocks * Remove unneeded container style prop * Update CHANGELOG --- .../src/components/block-list/block-outline.native.js | 7 +++++-- packages/block-library/src/social-link/edit.native.js | 2 +- packages/block-library/src/social-link/editor.native.scss | 4 ---- packages/react-native-editor/CHANGELOG.md | 1 + 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block-outline.native.js b/packages/block-editor/src/components/block-list/block-outline.native.js index 753b16f94a7557..83c6a58bac365f 100644 --- a/packages/block-editor/src/components/block-list/block-outline.native.js +++ b/packages/block-editor/src/components/block-list/block-outline.native.js @@ -13,7 +13,7 @@ import { usePreferredColorSchemeStyle } from '@wordpress/compose'; */ import styles from './block.scss'; -const BLOCKS_WITH_OUTLINE = [ 'core/social-link', 'core/missing' ]; +const TEXT_BLOCKS_WITH_OUTLINE = [ 'core/missing' ]; function BlockOutline( { blockCategory, @@ -22,7 +22,9 @@ function BlockOutline( { isSelected, name, } ) { - const textBlockWithOutline = BLOCKS_WITH_OUTLINE.includes( name ); + const textBlockWithOutline = TEXT_BLOCKS_WITH_OUTLINE.includes( name ); + const socialBlockWithOutline = name.includes( 'core/social-link' ); + const hasBlockTextCategory = blockCategory === 'text' && ! textBlockWithOutline; const hasBlockMediaCategory = @@ -47,6 +49,7 @@ function BlockOutline( { ( ( hasBlockTextCategory && hasInnerBlocks ) || ( ! hasBlockTextCategory && hasInnerBlocks ) || ( ! hasBlockTextCategory && isRootList ) || + socialBlockWithOutline || textBlockWithOutline ); return ( diff --git a/packages/block-library/src/social-link/edit.native.js b/packages/block-library/src/social-link/edit.native.js index 856c6aa704a4e6..cdfca2cb17abd5 100644 --- a/packages/block-library/src/social-link/edit.native.js +++ b/packages/block-library/src/social-link/edit.native.js @@ -158,7 +158,7 @@ const SocialLinkEdit = ( { ); return ( - + { isSelected && ( <> diff --git a/packages/block-library/src/social-link/editor.native.scss b/packages/block-library/src/social-link/editor.native.scss index f54d3aa4847755..be0919d2c33fb6 100644 --- a/packages/block-library/src/social-link/editor.native.scss +++ b/packages/block-library/src/social-link/editor.native.scss @@ -1,9 +1,5 @@ @import "./socials-with-bg.scss"; -.container { - margin: $block-selected-margin; -} - .linkSettingsPanel { padding-left: 0; padding-right: 0; diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index f38723e92153cc..7cb02a4848dd64 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -14,6 +14,7 @@ For each user feature we should also add a importance categorization label to i - [*] Search Control - Prevent calling TextInput's methods when undefined [#53745] - [*] Improve horizontal rule styles to avoid invisible lines [#53883] - [*] Fix horizontal rule style extensions [#53917] +- [*] Add block outline to all Social Link blocks when selected [#54011] ## 1.102.1 - [**] Fix Voice Over and assistive keyboards [#53895] From 4cd832016762791b1bfb2651cca148a0d0642996 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:49:59 +1000 Subject: [PATCH 29/56] BlockList: Ensure element styles (and svg) are always appended at the end of the document (#53859) * BlockList: Ensure element styles are always output at the end of the document * Remove hidden attribute so that Duotone still works in FF --- packages/block-editor/src/components/block-list/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 6b20789fa919e0..a9d5f15f12f81b 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -104,7 +104,6 @@ function Root( { className, ...settings } ) { ref: useMergeRefs( [ useBlockSelectionClearer(), useInBetweenInserter(), - setElement, useTypingObserver(), ] ), className: classnames( 'is-root-container', className, { @@ -119,6 +118,8 @@ function Root( { className, ...settings } ) {
    + { /* Ensure element and layout styles are always at the end of the document */ } +
    ); From 324e9b33f5b4a168da41e19c2ead021992435d4f Mon Sep 17 00:00:00 2001 From: Dominik Schilling Date: Wed, 30 Aug 2023 09:05:13 +0200 Subject: [PATCH 30/56] Simplify check for no posts in query-no-results block (#53772) --- packages/block-library/src/query-no-results/index.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/block-library/src/query-no-results/index.php b/packages/block-library/src/query-no-results/index.php index 4342ba57cccbd7..a6f4bd14d01972 100644 --- a/packages/block-library/src/query-no-results/index.php +++ b/packages/block-library/src/query-no-results/index.php @@ -32,14 +32,10 @@ function render_block_core_query_no_results( $attributes, $content, $block ) { $query = new WP_Query( $query_args ); } - if ( $query->have_posts() ) { + if ( $query->post_count > 0 ) { return ''; } - if ( ! $use_global_query ) { - wp_reset_postdata(); - } - $classes = ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) ? 'has-link-color' : ''; $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) ); return sprintf( From 6ede5e222ecb8002ba8d344443631a31ca43dc03 Mon Sep 17 00:00:00 2001 From: Mitchell Austin Date: Wed, 30 Aug 2023 01:24:10 -0700 Subject: [PATCH 31/56] Migrate shortcut help e2e tests to Playwright (#53832) * Migrate test case * Migrate test case * Use Role locators * Update to have tests pass locally - swap pressKeyWithModifier for pressKeys - use locator assertions - remove some extraneous steps in latter tests - cleanup comments * Combine tests * Locate platform-agnostically * Locate more rolefully * Assert focus return --------- Co-authored-by: alvitazwar <55917380+alvitazwar@users.noreply.github.com> --- .../editor/various/shortcut-help.test.js | 47 ------------------- .../editor/various/shortcut-help.spec.js | 42 +++++++++++++++++ 2 files changed, 42 insertions(+), 47 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/various/shortcut-help.test.js create mode 100644 test/e2e/specs/editor/various/shortcut-help.spec.js diff --git a/packages/e2e-tests/specs/editor/various/shortcut-help.test.js b/packages/e2e-tests/specs/editor/various/shortcut-help.test.js deleted file mode 100644 index 838a3edac2a2a4..00000000000000 --- a/packages/e2e-tests/specs/editor/various/shortcut-help.test.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * WordPress dependencies - */ -import { - createNewPost, - clickOnMoreMenuItem, - clickOnCloseModalButton, - pressKeyWithModifier, -} from '@wordpress/e2e-test-utils'; - -describe( 'keyboard shortcut help modal', () => { - beforeAll( async () => { - await createNewPost(); - } ); - - it( 'displays the shortcut help modal when opened using the menu item in the more menu', async () => { - await clickOnMoreMenuItem( 'Keyboard shortcuts' ); - const shortcutHelpModalElements = await page.$$( - '.edit-post-keyboard-shortcut-help-modal' - ); - expect( shortcutHelpModalElements ).toHaveLength( 1 ); - } ); - - it( 'closes the shortcut help modal when the close icon is clicked', async () => { - await clickOnCloseModalButton(); - const shortcutHelpModalElements = await page.$$( - '.edit-post-keyboard-shortcut-help-modal' - ); - expect( shortcutHelpModalElements ).toHaveLength( 0 ); - } ); - - it( 'displays the shortcut help modal when opened using the shortcut key (access+h)', async () => { - await pressKeyWithModifier( 'access', 'h' ); - const shortcutHelpModalElements = await page.$$( - '.edit-post-keyboard-shortcut-help-modal' - ); - expect( shortcutHelpModalElements ).toHaveLength( 1 ); - } ); - - it( 'closes the shortcut help modal when the shortcut key (access+h) is pressed again', async () => { - await pressKeyWithModifier( 'access', 'h' ); - const shortcutHelpModalElements = await page.$$( - '.edit-post-keyboard-shortcut-help-modal' - ); - expect( shortcutHelpModalElements ).toHaveLength( 0 ); - } ); -} ); diff --git a/test/e2e/specs/editor/various/shortcut-help.spec.js b/test/e2e/specs/editor/various/shortcut-help.spec.js new file mode 100644 index 00000000000000..1aaf5e93c975c5 --- /dev/null +++ b/test/e2e/specs/editor/various/shortcut-help.spec.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'keyboard shortcut help modal', () => { + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test( 'opens from the options menu, closes with its close button and returns focus', async ( { + page, + } ) => { + await page + .locator( 'role=region[name="Editor top bar"]' ) + .locator( '[aria-label="Options"]' ) + .click(); + const menuItem = page.locator( 'role=menuitem', { + hasText: /^Keyboard shortcuts/i, + } ); + const dialog = page.locator( 'role=dialog[name="Keyboard shortcuts"]' ); + + await menuItem.click(); + await expect( dialog ).toBeVisible(); + + await page.locator( 'role=button[name="Close"]' ).click(); + await expect( dialog ).toBeHidden(); + await expect( menuItem ).toBeFocused(); + } ); + + test( 'toggles open/closed using the keyboard shortcut (access+h)', async ( { + page, + pageUtils, + } ) => { + await pageUtils.pressKeys( 'access+h' ); + const dialog = page.locator( 'role=dialog[name="Keyboard shortcuts"]' ); + await expect( dialog ).toBeVisible(); + + await pageUtils.pressKeys( 'access+h' ); + await expect( dialog ).toBeHidden(); + } ); +} ); From 37dbd03cc1e3b7098aa4047e03994ba69478f7ad Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Wed, 30 Aug 2023 13:35:09 +0300 Subject: [PATCH 32/56] [Commands]: Fix `move to` command condition for registering (#54049) --- .../block-editor/src/components/use-block-commands/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/use-block-commands/index.js b/packages/block-editor/src/components/use-block-commands/index.js index 184c33714e7103..4c3dfc71ea4f27 100644 --- a/packages/block-editor/src/components/use-block-commands/index.js +++ b/packages/block-editor/src/components/use-block-commands/index.js @@ -126,6 +126,7 @@ const useActionsCommands = () => { getBlocksByClientId, canMoveBlocks, canRemoveBlocks, + getBlockCount, } = useSelect( blockEditorStore ); const { getDefaultBlockName, getGroupingBlockName } = useSelect( blocksStore ); @@ -189,7 +190,9 @@ const useActionsCommands = () => { ); } ); const canRemove = canRemoveBlocks( clientIds, rootClientId ); - const canMove = canMoveBlocks( clientIds, rootClientId ); + const canMove = + canMoveBlocks( clientIds, rootClientId ) && + getBlockCount( rootClientId ) !== 1; const commands = [ { From cd5d5fee5edca95cd029bb18601c49dec10b35a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Wed, 30 Aug 2023 13:13:54 +0200 Subject: [PATCH 33/56] Docs: Extend the information about using `render` with `block.json` (#53973) * Docs: Extend the information about using `render` with `block.json` * Refactor the example to use a block attribute * Reword the note for render for clarity --- docs/reference-guides/block-api/block-metadata.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 216509ab1df133..ba24ff0f584011 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -601,6 +601,16 @@ PHP file to use when rendering the block type on the server to show on the front - `$content` (`string`): The block default content. - `$block` (`WP_Block`): The block instance. +An example implementation of the `render.php` file defined with `render` could look like: + +```php +
    > + +
    +``` + +_Note: This file loads for every instance of the block type when rendering the page HTML on the server. Accounting for that is essential when declaring functions or classes in the file. The simplest way to avoid the risk of errors is to consume that shared logic from another file._ + ## Assets ### `WPDefinedPath` From 0ae22b5edd875442e7e92e984e591714402b8ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Walb=C3=B8=20Johnsg=C3=A5rd?= Date: Wed, 30 Aug 2023 13:37:50 +0200 Subject: [PATCH 34/56] Search block: Fix width input field (#53952) --- packages/block-library/src/search/edit.js | 10 ++++++++-- packages/block-library/src/search/utils.js | 1 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/search/edit.js b/packages/block-library/src/search/edit.js index 80238ab1741f7e..ff957b575c7a4f 100644 --- a/packages/block-library/src/search/edit.js +++ b/packages/block-library/src/search/edit.js @@ -52,7 +52,7 @@ import { PC_WIDTH_DEFAULT, PX_WIDTH_DEFAULT, MIN_WIDTH, - MIN_WIDTH_UNIT, + isPercentageUnit, } from './utils.js'; // Used to calculate border radius adjustment to avoid "fat" corners when @@ -405,7 +405,13 @@ export default function SearchEdit( { > { const filteredWidth = widthUnit === '%' && diff --git a/packages/block-library/src/search/utils.js b/packages/block-library/src/search/utils.js index b54048b609eb33..8438dd7148a013 100644 --- a/packages/block-library/src/search/utils.js +++ b/packages/block-library/src/search/utils.js @@ -4,7 +4,6 @@ export const PC_WIDTH_DEFAULT = 50; export const PX_WIDTH_DEFAULT = 350; export const MIN_WIDTH = 220; -export const MIN_WIDTH_UNIT = 'px'; /** * Returns a boolean whether passed unit is percentage From 67dc1bc2bd1d56f8d8e8fba5bd4b7a388dade920 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 30 Aug 2023 15:05:52 +0200 Subject: [PATCH 35/56] Popover: update `@floating-ui` to latest version, remove custom fix for iframe positioning and scaling (#46845) * Update `@floating-ui` to latest version * Remove custom iframe logic * Middleware don't need filtering * Add contextElement fields to virtual elements * Fix zoom-out mode: don't manually account for scale, update on scroll * Changelog update * Disable the autoUpdate.layoutShift option for smoother scrolling * Remove fake timers from DotTip unit tests. Fixes popover act warnings. * Remove unneeded update() call: used to be updateFrameOffset() --------- Co-authored-by: Jarda Snajdr --- package-lock.json | 44 ++-- .../src/components/block-popover/inbetween.js | 4 +- .../src/components/block-popover/index.js | 2 +- .../components/list-view/drop-indicator.js | 9 +- packages/components/CHANGELOG.md | 1 + packages/components/package.json | 2 +- packages/components/src/popover/index.tsx | 140 ++++-------- .../components/src/popover/limit-shift.ts | 205 ------------------ .../src/popover/overlay-middlewares.tsx | 4 +- packages/components/src/popover/utils.ts | 61 +----- .../dot-tip/test/__snapshots__/index.js.snap | 2 +- .../nux/src/components/dot-tip/test/index.js | 16 +- .../rich-text/src/component/use-anchor.js | 4 +- 13 files changed, 83 insertions(+), 411 deletions(-) delete mode 100644 packages/components/src/popover/limit-shift.ts diff --git a/package-lock.json b/package-lock.json index 059180e5c24bab..4e6c42786efce2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3813,18 +3813,6 @@ "@floating-ui/utils": "^0.1.1" } }, - "node_modules/@floating-ui/react-dom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.0.0.tgz", - "integrity": "sha512-uiOalFKPG937UCLm42RxjESTWUVpbbatvlphQAU6bsv+ence6IoVG8JOUZcy8eW81NkU+Idiwvx10WFLmR4MIg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "node_modules/@floating-ui/utils": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", @@ -54555,7 +54543,7 @@ "@emotion/serialize": "^1.0.2", "@emotion/styled": "^11.6.0", "@emotion/utils": "^1.0.0", - "@floating-ui/react-dom": "1.0.0", + "@floating-ui/react-dom": "^2.0.1", "@radix-ui/react-dropdown-menu": "2.0.4", "@use-gesture/react": "^10.2.24", "@wordpress/a11y": "file:../a11y", @@ -54605,6 +54593,18 @@ "react-dom": "^18.0.0" } }, + "packages/components/node_modules/@floating-ui/react-dom": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.1.tgz", + "integrity": "sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==", + "dependencies": { + "@floating-ui/dom": "^1.3.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "packages/components/node_modules/framer-motion": { "version": "10.13.0", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.13.0.tgz", @@ -58757,14 +58757,6 @@ "@floating-ui/utils": "^0.1.1" } }, - "@floating-ui/react-dom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.0.0.tgz", - "integrity": "sha512-uiOalFKPG937UCLm42RxjESTWUVpbbatvlphQAU6bsv+ence6IoVG8JOUZcy8eW81NkU+Idiwvx10WFLmR4MIg==", - "requires": { - "@floating-ui/dom": "^1.0.0" - } - }, "@floating-ui/utils": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", @@ -67277,7 +67269,7 @@ "@emotion/serialize": "^1.0.2", "@emotion/styled": "^11.6.0", "@emotion/utils": "^1.0.0", - "@floating-ui/react-dom": "1.0.0", + "@floating-ui/react-dom": "^2.0.1", "@radix-ui/react-dropdown-menu": "2.0.4", "@use-gesture/react": "^10.2.24", "@wordpress/a11y": "file:../a11y", @@ -67320,6 +67312,14 @@ "valtio": "1.7.0" }, "dependencies": { + "@floating-ui/react-dom": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.1.tgz", + "integrity": "sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==", + "requires": { + "@floating-ui/dom": "^1.3.0" + } + }, "framer-motion": { "version": "10.13.0", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.13.0.tgz", diff --git a/packages/block-editor/src/components/block-popover/inbetween.js b/packages/block-editor/src/components/block-popover/inbetween.js index cadd49632b2e83..a0175c4d4ae584 100644 --- a/packages/block-editor/src/components/block-popover/inbetween.js +++ b/packages/block-editor/src/components/block-popover/inbetween.js @@ -81,10 +81,10 @@ function BlockPopoverInbetween( { return undefined; } - const { ownerDocument } = previousElement || nextElement; + const contextElement = previousElement || nextElement; return { - ownerDocument, + contextElement, getBoundingClientRect() { const previousRect = previousElement ? previousElement.getBoundingClientRect() diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index 26042e8c6d6e9c..13e6ba4d9e7f81 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -142,7 +142,7 @@ function BlockPopover( return new window.DOMRect( left, top, width, height ); }, - ownerDocument: selectedElement.ownerDocument, + contextElement: selectedElement, }; }, [ bottomClientId, diff --git a/packages/block-editor/src/components/list-view/drop-indicator.js b/packages/block-editor/src/components/list-view/drop-indicator.js index 8178bc92453bc1..04ce87b4a0c8d4 100644 --- a/packages/block-editor/src/components/list-view/drop-indicator.js +++ b/packages/block-editor/src/components/list-view/drop-indicator.js @@ -159,10 +159,8 @@ export default function ListViewDropIndicator( { return undefined; } - const ownerDocument = targetElement.ownerDocument; - return { - ownerDocument, + contextElement: targetElement, getBoundingClientRect() { const rect = targetElement.getBoundingClientRect(); const indent = getDropIndicatorIndent( rect ); @@ -189,9 +187,10 @@ export default function ListViewDropIndicator( { 'horizontal' ); + const doc = targetElement.ownerDocument; const windowScroll = - scrollContainer === ownerDocument.body || - scrollContainer === ownerDocument.documentElement; + scrollContainer === doc.body || + scrollContainer === doc.documentElement; // If the scroll container is not the window, offset the left position, if need be. if ( scrollContainer && ! windowScroll ) { diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index eb52028535f893..7dce9d2a315f4e 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -17,6 +17,7 @@ - `Shortcut`: Add Storybook stories ([#53627](https://github.com/WordPress/gutenberg/pull/53627)). - `SlotFill`: Do not render children when using ``. ([#53272](https://github.com/WordPress/gutenberg/pull/53272)) +- Update `@floating-ui/react-dom` to the latest version ([#46845](https://github.com/WordPress/gutenberg/pull/46845)). ## 25.6.0 (2023-08-16) diff --git a/packages/components/package.json b/packages/components/package.json index a245281fc5ec99..2a4f7c380ee979 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -38,7 +38,7 @@ "@emotion/serialize": "^1.0.2", "@emotion/styled": "^11.6.0", "@emotion/utils": "^1.0.0", - "@floating-ui/react-dom": "1.0.0", + "@floating-ui/react-dom": "^2.0.1", "@radix-ui/react-dropdown-menu": "2.0.4", "@use-gesture/react": "^10.2.24", "@wordpress/a11y": "file:../a11y", diff --git a/packages/components/src/popover/index.tsx b/packages/components/src/popover/index.tsx index 21f81e0f09e807..69c107cffda8d6 100644 --- a/packages/components/src/popover/index.tsx +++ b/packages/components/src/popover/index.tsx @@ -3,11 +3,11 @@ */ import type { ForwardedRef, SyntheticEvent, RefCallback } from 'react'; import classnames from 'classnames'; -import type { Middleware, MiddlewareArguments } from '@floating-ui/react-dom'; import { useFloating, flip as flipMiddleware, shift as shiftMiddleware, + limitShift, autoUpdate, arrow, offset as offsetMiddleware, @@ -50,8 +50,6 @@ import ScrollLock from '../scroll-lock'; import { Slot, Fill, useSlot } from '../slot-fill'; import { computePopoverPosition, - getFrameOffset, - getFrameScale, positionToPlacement, placementToMotionAnimationProps, getReferenceOwnerDocument, @@ -64,7 +62,6 @@ import type { PopoverAnchorRefReference, PopoverAnchorRefTopBottom, } from './types'; -import { limitShift as customLimitShift } from './limit-shift'; import { overlayMiddlewares } from './overlay-middlewares'; /** @@ -262,69 +259,34 @@ const UnforwardedPopover = ( ? positionToPlacement( position ) : placementProp; - /** - * Offsets the position of the popover when the anchor is inside an iframe. - * - * Store the offset in a ref, due to constraints with floating-ui: - * https://floating-ui.com/docs/react-dom#variables-inside-middleware-functions. - */ - const frameOffsetRef = useRef( getFrameOffset( referenceOwnerDocument ) ); - const middleware = [ ...( placementProp === 'overlay' ? overlayMiddlewares() : [] ), - // Custom middleware which adjusts the popover's position by taking into - // account the offset of the anchor's iframe (if any) compared to the page. - { - name: 'frameOffset', - fn( { x, y }: MiddlewareArguments ) { - if ( ! frameOffsetRef.current ) { - return { - x, - y, - }; - } - - return { - x: x + frameOffsetRef.current.x, - y: y + frameOffsetRef.current.y, - data: { - // This will be used in the customLimitShift() function. - amount: frameOffsetRef.current, - }, - }; - }, - }, offsetMiddleware( offsetProp ), - computedFlipProp ? flipMiddleware() : undefined, - computedResizeProp - ? size( { - apply( sizeProps ) { - const { firstElementChild } = - refs.floating.current ?? {}; - - // Only HTMLElement instances have the `style` property. - if ( ! ( firstElementChild instanceof HTMLElement ) ) - return; - - // Reduce the height of the popover to the available space. - Object.assign( firstElementChild.style, { - maxHeight: `${ sizeProps.availableHeight }px`, - overflow: 'auto', - } ); - }, - } ) - : undefined, - shift - ? shiftMiddleware( { - crossAxis: true, - limiter: customLimitShift(), - padding: 1, // Necessary to avoid flickering at the edge of the viewport. - } ) - : undefined, + computedFlipProp && flipMiddleware(), + computedResizeProp && + size( { + apply( sizeProps ) { + const { firstElementChild } = refs.floating.current ?? {}; + + // Only HTMLElement instances have the `style` property. + if ( ! ( firstElementChild instanceof HTMLElement ) ) + return; + + // Reduce the height of the popover to the available space. + Object.assign( firstElementChild.style, { + maxHeight: `${ sizeProps.availableHeight }px`, + overflow: 'auto', + } ); + }, + } ), + shift && + shiftMiddleware( { + crossAxis: true, + limiter: limitShift(), + padding: 1, // Necessary to avoid flickering at the edge of the viewport. + } ), arrow( { element: arrowRef } ), - ].filter( - ( m: Middleware | undefined ): m is Middleware => m !== undefined - ); + ]; const slotName = useContext( slotNameContext ) || __unstableSlotName; const slot = useSlot( slotName ); @@ -353,10 +315,6 @@ const UnforwardedPopover = ( // Positioning coordinates x, y, - // Callback refs (not regular refs). This allows the position to be updated. - // when either elements change. - reference: referenceCallbackRef, - floating, // Object with "regular" refs to both "reference" and "floating" refs, // Type of CSS position property to use (absolute or fixed) @@ -372,6 +330,7 @@ const UnforwardedPopover = ( middleware, whileElementsMounted: ( referenceParam, floatingParam, updateParam ) => autoUpdate( referenceParam, floatingParam, updateParam, { + layoutShift: false, animationFrame: true, } ), } ); @@ -406,17 +365,16 @@ const UnforwardedPopover = ( fallbackReferenceElement, fallbackDocument: document, } ); - const scale = getFrameScale( resultingReferenceOwnerDoc ); + const resultingReferenceElement = getReferenceElement( { anchor, anchorRef, anchorRect, getAnchorRect, fallbackReferenceElement, - scale, } ); - referenceCallbackRef( resultingReferenceElement ); + refs.setReference( resultingReferenceElement ); setReferenceOwnerDocument( resultingReferenceOwnerDoc ); }, [ @@ -429,23 +387,17 @@ const UnforwardedPopover = ( anchorRect, getAnchorRect, fallbackReferenceElement, - referenceCallbackRef, + refs, ] ); // If the reference element is in a different ownerDocument (e.g. iFrame), // we need to manually update the floating's position as the reference's owner - // document scrolls. Also update the frame offset if the view resizes. + // document scrolls. useLayoutEffect( () => { if ( - // Reference and root documents are the same. - referenceOwnerDocument === document || - // Reference and floating are in the same document. - referenceOwnerDocument === refs.floating.current?.ownerDocument || - // The reference's document has no view (i.e. window) - // or frame element (ie. it's not an iframe). - ! referenceOwnerDocument?.defaultView?.frameElement + ! referenceOwnerDocument || + ! referenceOwnerDocument.defaultView ) { - frameOffsetRef.current = undefined; return; } @@ -456,23 +408,17 @@ const UnforwardedPopover = ( ? getScrollContainer( frameElement ) : null; - const updateFrameOffset = () => { - frameOffsetRef.current = getFrameOffset( referenceOwnerDocument ); - update(); - }; - defaultView.addEventListener( 'resize', updateFrameOffset ); - scrollContainer?.addEventListener( 'scroll', updateFrameOffset ); - - updateFrameOffset(); + defaultView.addEventListener( 'resize', update ); + scrollContainer?.addEventListener( 'scroll', update ); return () => { - defaultView.removeEventListener( 'resize', updateFrameOffset ); - scrollContainer?.removeEventListener( 'scroll', updateFrameOffset ); + defaultView.removeEventListener( 'resize', update ); + scrollContainer?.removeEventListener( 'scroll', update ); }; - }, [ referenceOwnerDocument, update, refs.floating ] ); + }, [ referenceOwnerDocument, update ] ); const mergedFloatingRef = useMergeRefs( [ - floating, + refs.setFloating, dialogRef, forwardedRef, ] ); @@ -543,18 +489,12 @@ const UnforwardedPopover = ( left: typeof arrowData?.x !== 'undefined' && Number.isFinite( arrowData.x ) - ? `${ - arrowData.x + - ( frameOffsetRef.current?.x ?? 0 ) - }px` + ? `${ arrowData.x }px` : '', top: typeof arrowData?.y !== 'undefined' && Number.isFinite( arrowData.y ) - ? `${ - arrowData.y + - ( frameOffsetRef.current?.y ?? 0 ) - }px` + ? `${ arrowData.y }px` : '', } } > diff --git a/packages/components/src/popover/limit-shift.ts b/packages/components/src/popover/limit-shift.ts deleted file mode 100644 index 45e65a0b619098..00000000000000 --- a/packages/components/src/popover/limit-shift.ts +++ /dev/null @@ -1,205 +0,0 @@ -/** - * External dependencies - */ -import type { - Axis, - Coords, - Placement, - Side, - MiddlewareArguments, -} from '@floating-ui/react-dom'; - -/** - * Parts of this source were derived and modified from `floating-ui`, - * released under the MIT license. - * - * https://github.com/floating-ui/floating-ui - * - * Copyright (c) 2021 Floating UI contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * Custom limiter function for the `shift` middleware. - * This function is mostly identical default `limitShift` from ``@floating-ui`; - * the only difference is that, when computing the min/max shift limits, it - * also takes into account the iframe offset that is added by the - * custom "frameOffset" middleware. - * - * All unexported types and functions are also from the `@floating-ui` library, - * and have been copied to this file for convenience. - */ - -type LimitShiftOffset = - | ( ( args: MiddlewareArguments ) => - | number - | { - /** - * Offset the limiting of the axis that runs along the alignment of the - * floating element. - */ - mainAxis?: number; - /** - * Offset the limiting of the axis that runs along the side of the - * floating element. - */ - crossAxis?: number; - } ) - | number - | { - /** - * Offset the limiting of the axis that runs along the alignment of the - * floating element. - */ - mainAxis?: number; - /** - * Offset the limiting of the axis that runs along the side of the - * floating element. - */ - crossAxis?: number; - }; - -type LimitShiftOptions = { - /** - * Offset when limiting starts. `0` will limit when the opposite edges of the - * reference and floating elements are aligned. - * - positive = start limiting earlier - * - negative = start limiting later - */ - offset: LimitShiftOffset; - /** - * Whether to limit the axis that runs along the alignment of the floating - * element. - */ - mainAxis: boolean; - /** - * Whether to limit the axis that runs along the side of the floating element. - */ - crossAxis: boolean; -}; - -function getSide( placement: Placement ): Side { - return placement.split( '-' )[ 0 ] as Side; -} - -function getMainAxisFromPlacement( placement: Placement ): Axis { - return [ 'top', 'bottom' ].includes( getSide( placement ) ) ? 'x' : 'y'; -} - -function getCrossAxis( axis: Axis ): Axis { - return axis === 'x' ? 'y' : 'x'; -} - -export const limitShift = ( - options: Partial< LimitShiftOptions > = {} -): { - options: Partial< LimitShiftOffset >; - fn: ( middlewareArguments: MiddlewareArguments ) => Coords; -} => ( { - options, - fn( middlewareArguments ) { - const { x, y, placement, rects, middlewareData } = middlewareArguments; - const { - offset = 0, - mainAxis: checkMainAxis = true, - crossAxis: checkCrossAxis = true, - } = options; - - const coords = { x, y }; - const mainAxis = getMainAxisFromPlacement( placement ); - const crossAxis = getCrossAxis( mainAxis ); - - let mainAxisCoord = coords[ mainAxis ]; - let crossAxisCoord = coords[ crossAxis ]; - - const rawOffset = - typeof offset === 'function' - ? offset( middlewareArguments ) - : offset; - const computedOffset = - typeof rawOffset === 'number' - ? { mainAxis: rawOffset, crossAxis: 0 } - : { mainAxis: 0, crossAxis: 0, ...rawOffset }; - - // At the moment of writing, this is the only difference - // with the `limitShift` function from `@floating-ui`. - // This offset needs to be added to all min/max limits - // in order to make the shift-limiting work as expected. - const additionalFrameOffset = { - x: 0, - y: 0, - ...middlewareData.frameOffset?.amount, - }; - - if ( checkMainAxis ) { - const len = mainAxis === 'y' ? 'height' : 'width'; - const limitMin = - rects.reference[ mainAxis ] - - rects.floating[ len ] + - computedOffset.mainAxis + - additionalFrameOffset[ mainAxis ]; - const limitMax = - rects.reference[ mainAxis ] + - rects.reference[ len ] - - computedOffset.mainAxis + - additionalFrameOffset[ mainAxis ]; - - if ( mainAxisCoord < limitMin ) { - mainAxisCoord = limitMin; - } else if ( mainAxisCoord > limitMax ) { - mainAxisCoord = limitMax; - } - } - - if ( checkCrossAxis ) { - const len = mainAxis === 'y' ? 'width' : 'height'; - const isOriginSide = [ 'top', 'left' ].includes( - getSide( placement ) - ); - const limitMin = - rects.reference[ crossAxis ] - - rects.floating[ len ] + - ( isOriginSide - ? middlewareData.offset?.[ crossAxis ] ?? 0 - : 0 ) + - ( isOriginSide ? 0 : computedOffset.crossAxis ) + - additionalFrameOffset[ crossAxis ]; - const limitMax = - rects.reference[ crossAxis ] + - rects.reference[ len ] + - ( isOriginSide - ? 0 - : middlewareData.offset?.[ crossAxis ] ?? 0 ) - - ( isOriginSide ? computedOffset.crossAxis : 0 ) + - additionalFrameOffset[ crossAxis ]; - - if ( crossAxisCoord < limitMin ) { - crossAxisCoord = limitMin; - } else if ( crossAxisCoord > limitMax ) { - crossAxisCoord = limitMax; - } - } - - return { - [ mainAxis ]: mainAxisCoord, - [ crossAxis ]: crossAxisCoord, - } as Coords; - }, -} ); diff --git a/packages/components/src/popover/overlay-middlewares.tsx b/packages/components/src/popover/overlay-middlewares.tsx index 83cc1cd0d21a97..fb64d739dce3b6 100644 --- a/packages/components/src/popover/overlay-middlewares.tsx +++ b/packages/components/src/popover/overlay-middlewares.tsx @@ -1,14 +1,14 @@ /** * External dependencies */ -import type { MiddlewareArguments } from '@floating-ui/react-dom'; +import type { MiddlewareState } from '@floating-ui/react-dom'; import { size } from '@floating-ui/react-dom'; export function overlayMiddlewares() { return [ { name: 'overlay', - fn( { rects }: MiddlewareArguments ) { + fn( { rects }: MiddlewareState ) { return rects.reference; }, }, diff --git a/packages/components/src/popover/utils.ts b/packages/components/src/popover/utils.ts index 2112b285969828..5833a65816c6d1 100644 --- a/packages/components/src/popover/utils.ts +++ b/packages/components/src/popover/utils.ts @@ -3,7 +3,7 @@ */ // eslint-disable-next-line no-restricted-imports import type { MotionProps } from 'framer-motion'; -import type { ReferenceType } from '@floating-ui/react-dom'; +import type { ReferenceType, VirtualElement } from '@floating-ui/react-dom'; /** * Internal dependencies @@ -139,42 +139,6 @@ export const placementToMotionAnimationProps = ( }; }; -/** - * Returns the offset of a document's frame element. - * - * @param document The iframe's owner document. - * - * @return The offset of the document's frame element, or undefined if the - * document has no frame element. - */ -export const getFrameOffset = ( - document?: Document -): { x: number; y: number } | undefined => { - const frameElement = document?.defaultView?.frameElement; - if ( ! frameElement ) { - return; - } - const iframeRect = frameElement.getBoundingClientRect(); - return { x: iframeRect.left, y: iframeRect.top }; -}; - -export const getFrameScale = ( - document?: Document -): { - x: number; - y: number; -} => { - const frameElement = document?.defaultView?.frameElement as HTMLElement; - if ( ! frameElement ) { - return { x: 1, y: 1 }; - } - const rect = frameElement.getBoundingClientRect(); - return { - x: rect.width / frameElement.offsetWidth, - y: rect.height / frameElement.offsetHeight, - }; -}; - export const getReferenceOwnerDocument = ( { anchor, anchorRef, @@ -197,7 +161,10 @@ export const getReferenceOwnerDocument = ( { // with the `getBoundingClientRect()` function (like real elements). // See https://floating-ui.com/docs/virtual-elements for more info. let resultingReferenceOwnerDoc; - if ( anchor ) { + if ( ( anchor as VirtualElement )?.contextElement ) { + resultingReferenceOwnerDoc = ( anchor as VirtualElement ).contextElement + ?.ownerDocument; + } else if ( anchor ) { resultingReferenceOwnerDoc = anchor.ownerDocument; } else if ( ( anchorRef as PopoverAnchorRefTopBottom | undefined )?.top ) { resultingReferenceOwnerDoc = ( anchorRef as PopoverAnchorRefTopBottom ) @@ -231,13 +198,11 @@ export const getReferenceElement = ( { anchorRect, getAnchorRect, fallbackReferenceElement, - scale, }: Pick< PopoverProps, 'anchorRef' | 'anchorRect' | 'getAnchorRect' | 'anchor' > & { fallbackReferenceElement: Element | null; - scale: { x: number; y: number }; } ): ReferenceType | null => { let referenceElement = null; @@ -299,22 +264,6 @@ export const getReferenceElement = ( { referenceElement = fallbackReferenceElement.parentElement; } - if ( referenceElement && ( scale.x !== 1 || scale.y !== 1 ) ) { - // If the popover is inside an iframe, the coordinates of the - // reference element need to be scaled to match the iframe's scale. - const rect = referenceElement.getBoundingClientRect(); - referenceElement = { - getBoundingClientRect() { - return new window.DOMRect( - rect.x * scale.x, - rect.y * scale.y, - rect.width * scale.x, - rect.height * scale.y - ); - }, - }; - } - // Convert any `undefined` value to `null`. return referenceElement ?? null; }; diff --git a/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap b/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap index 29a743a5316de3..bfdb68b78cf578 100644 --- a/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap +++ b/packages/nux/src/components/dot-tip/test/__snapshots__/index.js.snap @@ -5,7 +5,7 @@ exports[`DotTip should render correctly 1`] = ` aria-label="Editor tips" class="components-popover nux-dot-tip is-positioned" role="dialog" - style="position: absolute; top: 0px; left: 0px; opacity: 1; transform: none; transform-origin: 0% 50% 0;" + style="position: absolute; top: 0px; left: 0px; opacity: 0; transform: translateX(0px) translateY(0px) translateX(-2em) scale(0) translateZ(0); transform-origin: 0% 50% 0;" tabindex="-1" >
    { - beforeEach( () => { - jest.useFakeTimers(); - } ); - - afterEach( () => { - jest.useRealTimers(); - } ); - it( 'should not render anything if invisible', () => { render( @@ -43,9 +35,7 @@ describe( 'DotTip', () => { } ); it( 'should call onDismiss when the dismiss button is clicked', async () => { - const user = userEvent.setup( { - advanceTimers: jest.advanceTimersByTime, - } ); + const user = userEvent.setup(); const onDismiss = jest.fn(); render( @@ -64,9 +54,7 @@ describe( 'DotTip', () => { } ); it( 'should call onDisable when the X button is clicked', async () => { - const user = userEvent.setup( { - advanceTimers: jest.advanceTimersByTime, - } ); + const user = userEvent.setup(); const onDisable = jest.fn(); render( diff --git a/packages/rich-text/src/component/use-anchor.js b/packages/rich-text/src/component/use-anchor.js index aa803df7c76660..5cc62a2de4ffdd 100644 --- a/packages/rich-text/src/component/use-anchor.js +++ b/packages/rich-text/src/component/use-anchor.js @@ -51,7 +51,7 @@ function getFormatElement( range, editableContentElement, tagName, className ) { /** * @typedef {Object} VirtualAnchorElement * @property {() => DOMRect} getBoundingClientRect A function returning a DOMRect - * @property {Document} ownerDocument The element's ownerDocument + * @property {HTMLElement} contextElement The actual DOM element */ /** @@ -64,7 +64,7 @@ function getFormatElement( range, editableContentElement, tagName, className ) { */ function createVirtualAnchorElement( range, editableContentElement ) { return { - ownerDocument: range.startContainer.ownerDocument, + contextElement: editableContentElement, getBoundingClientRect() { return editableContentElement.contains( range.startContainer ) ? range.getBoundingClientRect() From bd630b72c3404431f7714478ea71827613c00c36 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Wed, 30 Aug 2023 15:13:08 +0200 Subject: [PATCH 36/56] Blocks: move bootstrapped block types to Redux state (#53807) * Blocks: move bootstrapped block types to Redux state * Fix the ADD_UNPROCESSED_BLOCK_TYPE reducer * Unit test for reapplyBlockFilters, fixing block unregistration * Fixup unprocessedBlockTypes reducer tests * Remove the apiVersion and ancestor polyfills * Improve action/selector documentation * Add -Type suffix to block registration actions * Stabilize reapplyBlockTypeFilters * Revert back to boostrapping metadata only when provided --- .../reference-guides/data/data-core-blocks.md | 6 +- packages/blocks/src/api/registration.js | 98 +-------- packages/blocks/src/api/test/registration.js | 118 +++------- packages/blocks/src/store/actions.js | 202 +++--------------- packages/blocks/src/store/index.js | 2 + packages/blocks/src/store/private-actions.js | 42 ++++ .../blocks/src/store/private-selectors.js | 24 +++ .../blocks/src/store/process-block-type.js | 159 ++++++++++++++ packages/blocks/src/store/reducer.js | 74 ++++++- packages/blocks/src/store/selectors.js | 11 - packages/blocks/src/store/test/reducer.js | 15 +- packages/customize-widgets/src/index.js | 2 +- packages/edit-post/src/index.js | 2 +- packages/edit-site/src/index.js | 2 +- packages/edit-widgets/src/index.js | 2 +- 15 files changed, 387 insertions(+), 372 deletions(-) create mode 100644 packages/blocks/src/store/private-actions.js create mode 100644 packages/blocks/src/store/process-block-type.js diff --git a/docs/reference-guides/data/data-core-blocks.md b/docs/reference-guides/data/data-core-blocks.md index ba047160f047de..084c9c1d7a5fbc 100644 --- a/docs/reference-guides/data/data-core-blocks.md +++ b/docs/reference-guides/data/data-core-blocks.md @@ -712,6 +712,10 @@ The actions in this package shouldn't be used directly. Instead, use the functio -Nothing to document. +### reapplyBlockTypeFilters + +Signals that all block types should be computed again. It uses stored unprocessed block types and all the most recent list of registered filters. + +It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 1. Filter A. 2. Block B. 3. Block C. 4. Filter D. 5. Filter E. 6. Block F. 7. Filter G. In this scenario some filters would not get applied for all blocks because they are registered too late. diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 702582ff6489e8..72c0a30db02059 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -1,10 +1,5 @@ /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ -/** - * External dependencies - */ -import { camelCase } from 'change-case'; - /** * WordPress dependencies */ @@ -15,8 +10,8 @@ import { _x } from '@wordpress/i18n'; * Internal dependencies */ import i18nBlockSchema from './i18n-block.json'; -import { BLOCK_ICON_DEFAULT } from './constants'; import { store as blocksStore } from '../store'; +import { unlock } from '../lock-unlock'; /** * An icon type definition. One of a Dashicon slug, an element, @@ -129,8 +124,6 @@ import { store as blocksStore } from '../store'; * then no preview is shown. */ -const serverSideBlockDefinitions = {}; - function isObject( object ) { return object !== null && typeof object === 'object'; } @@ -142,65 +135,9 @@ function isObject( object ) { */ // eslint-disable-next-line camelcase export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { - for ( const blockName of Object.keys( definitions ) ) { - // Don't overwrite if already set. It covers the case when metadata - // was initialized from the server. - if ( serverSideBlockDefinitions[ blockName ] ) { - // We still need to polyfill `apiVersion` for WordPress version - // lower than 5.7. If it isn't present in the definition shared - // from the server, we try to fallback to the definition passed. - // @see https://github.com/WordPress/gutenberg/pull/29279 - if ( - serverSideBlockDefinitions[ blockName ].apiVersion === - undefined && - definitions[ blockName ].apiVersion - ) { - serverSideBlockDefinitions[ blockName ].apiVersion = - definitions[ blockName ].apiVersion; - } - // The `ancestor` prop is not included in the definitions shared - // from the server yet, so it needs to be polyfilled as well. - // @see https://github.com/WordPress/gutenberg/pull/39894 - if ( - serverSideBlockDefinitions[ blockName ].ancestor === - undefined && - definitions[ blockName ].ancestor - ) { - serverSideBlockDefinitions[ blockName ].ancestor = - definitions[ blockName ].ancestor; - } - // The `selectors` prop is not yet included in the server provided - // definitions. Polyfill it as well. This can be removed when the - // minimum supported WordPress is >= 6.3. - if ( - serverSideBlockDefinitions[ blockName ].selectors === - undefined && - definitions[ blockName ].selectors - ) { - serverSideBlockDefinitions[ blockName ].selectors = - definitions[ blockName ].selectors; - } - - if ( - serverSideBlockDefinitions[ blockName ] - .__experimentalAutoInsert === undefined && - definitions[ blockName ].__experimentalAutoInsert - ) { - serverSideBlockDefinitions[ - blockName - ].__experimentalAutoInsert = - definitions[ blockName ].__experimentalAutoInsert; - } - continue; - } - - serverSideBlockDefinitions[ blockName ] = Object.fromEntries( - Object.entries( definitions[ blockName ] ) - .filter( - ( [ , value ] ) => value !== null && value !== undefined - ) - .map( ( [ key, value ] ) => [ camelCase( key ), value ] ) - ); + const { addBootstrappedBlockType } = unlock( dispatch( blocksStore ) ); + for ( const [ name, blockType ] of Object.entries( definitions ) ) { + addBootstrappedBlockType( name, blockType ); } } @@ -302,29 +239,16 @@ export function registerBlockType( blockNameOrMetadata, settings ) { return; } + const { addBootstrappedBlockType, addUnprocessedBlockType } = unlock( + dispatch( blocksStore ) + ); + if ( isObject( blockNameOrMetadata ) ) { - unstable__bootstrapServerSideBlockDefinitions( { - [ name ]: getBlockSettingsFromMetadata( blockNameOrMetadata ), - } ); + const metadata = getBlockSettingsFromMetadata( blockNameOrMetadata ); + addBootstrappedBlockType( name, metadata ); } - const blockType = { - name, - icon: BLOCK_ICON_DEFAULT, - keywords: [], - attributes: {}, - providesContext: {}, - usesContext: [], - selectors: {}, - supports: {}, - styles: [], - variations: [], - save: () => null, - ...serverSideBlockDefinitions?.[ name ], - ...settings, - }; - - dispatch( blocksStore ).__experimentalRegisterBlockType( blockType ); + addUnprocessedBlockType( name, settings ); return select( blocksStore ).getBlockType( name ); } diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index 42f4dcfbf0e48f..877c9fdc4a038a 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -5,7 +5,7 @@ */ import { addFilter, removeAllFilters, removeFilter } from '@wordpress/hooks'; import { logged } from '@wordpress/deprecated'; -import { select } from '@wordpress/data'; +import { select, dispatch } from '@wordpress/data'; /** * Internal dependencies @@ -33,6 +33,7 @@ import { import { BLOCK_ICON_DEFAULT, DEPRECATED_ENTRY_KEYS } from '../constants'; import { omit } from '../utils'; import { store as blocksStore } from '../../store'; +import { unlock } from '../../lock-unlock'; const noop = () => {}; @@ -48,19 +49,14 @@ describe( 'blocks', () => { title: 'block title', }; - beforeAll( () => { - // Initialize the block store. - require( '../../store' ); - } ); - afterEach( () => { - getBlockTypes().forEach( ( block ) => { - unregisterBlockType( block.name ); - } ); + const registeredNames = Object.keys( + unlock( select( blocksStore ) ).getUnprocessedBlockTypes() + ); + dispatch( blocksStore ).removeBlockTypes( registeredNames ); setFreeformContentHandlerName( undefined ); setUnregisteredTypeHandlerName( undefined ); setDefaultBlockName( undefined ); - unstable__bootstrapServerSideBlockDefinitions( {} ); // Reset deprecation logging to ensure we properly track warnings. for ( const key in logged ) { @@ -392,80 +388,6 @@ describe( 'blocks', () => { } ); } ); - // This test can be removed once the polyfill for apiVersion gets removed. - it( 'should apply apiVersion on the client when not set on the server', () => { - const blockName = 'core/test-block-back-compat'; - unstable__bootstrapServerSideBlockDefinitions( { - [ blockName ]: { - category: 'widgets', - }, - } ); - unstable__bootstrapServerSideBlockDefinitions( { - [ blockName ]: { - apiVersion: 3, - category: 'ignored', - }, - } ); - - const blockType = { - title: 'block title', - }; - registerBlockType( blockName, blockType ); - expect( getBlockType( blockName ) ).toEqual( { - apiVersion: 3, - name: blockName, - save: expect.any( Function ), - title: 'block title', - category: 'widgets', - icon: { src: BLOCK_ICON_DEFAULT }, - attributes: {}, - providesContext: {}, - usesContext: [], - keywords: [], - selectors: {}, - supports: {}, - styles: [], - variations: [], - } ); - } ); - - // This test can be removed once the polyfill for ancestor gets removed. - it( 'should apply ancestor on the client when not set on the server', () => { - const blockName = 'core/test-block-with-ancestor'; - unstable__bootstrapServerSideBlockDefinitions( { - [ blockName ]: { - category: 'widgets', - }, - } ); - unstable__bootstrapServerSideBlockDefinitions( { - [ blockName ]: { - ancestor: 'core/test-block-ancestor', - category: 'ignored', - }, - } ); - - const blockType = { - title: 'block title', - }; - registerBlockType( blockName, blockType ); - expect( getBlockType( blockName ) ).toEqual( { - ancestor: 'core/test-block-ancestor', - name: blockName, - save: expect.any( Function ), - title: 'block title', - category: 'widgets', - icon: { src: BLOCK_ICON_DEFAULT }, - attributes: {}, - providesContext: {}, - usesContext: [], - keywords: [], - selectors: {}, - supports: {}, - styles: [], - variations: [], - } ); - } ); - // This can be removed once polyfill adding selectors has been removed. it( 'should apply selectors on the client when not set on the server', () => { const blockName = 'core/test-block-with-selectors'; @@ -920,6 +842,34 @@ describe( 'blocks', () => { 'Declaring non-string block descriptions is deprecated since version 6.2.' ); } ); + + it( 're-applies block filters', () => { + // register block + registerBlockType( 'test/block', defaultBlockSettings ); + + // register a filter after registering a block + addFilter( + 'blocks.registerBlockType', + 'core/blocks/reapply', + ( settings ) => ( { + ...settings, + title: settings.title + ' filtered', + } ) + ); + + // check that block type has unfiltered values + expect( getBlockType( 'test/block' ).title ).toBe( + 'block title' + ); + + // reapply the block filters + dispatch( blocksStore ).reapplyBlockTypeFilters(); + + // check that block type has filtered values + expect( getBlockType( 'test/block' ).title ).toBe( + 'block title filtered' + ); + } ); } ); test( 'registers block from metadata', () => { diff --git a/packages/blocks/src/store/actions.js b/packages/blocks/src/store/actions.js index 2c02fb73b03527..d3bd71c067ebe3 100644 --- a/packages/blocks/src/store/actions.js +++ b/packages/blocks/src/store/actions.js @@ -1,154 +1,17 @@ -/** - * External dependencies - */ -import { isPlainObject } from 'is-plain-object'; - /** * WordPress dependencies */ import deprecated from '@wordpress/deprecated'; -import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies */ -import { isValidIcon, normalizeIconObject, omit } from '../api/utils'; -import { DEPRECATED_ENTRY_KEYS } from '../api/constants'; +import { processBlockType } from './process-block-type'; /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ -const { error, warn } = window.console; - -/** - * Mapping of legacy category slugs to their latest normal values, used to - * accommodate updates of the default set of block categories. - * - * @type {Record} - */ -const LEGACY_CATEGORY_MAPPING = { - common: 'text', - formatting: 'text', - layout: 'design', -}; - -/** - * Whether the argument is a function. - * - * @param {*} maybeFunc The argument to check. - * @return {boolean} True if the argument is a function, false otherwise. - */ -function isFunction( maybeFunc ) { - return typeof maybeFunc === 'function'; -} - -/** - * Takes the unprocessed block type data and applies all the existing filters for the registered block type. - * Next, it validates all the settings and performs additional processing to the block type definition. - * - * @param {WPBlockType} blockType Unprocessed block type settings. - * @param {Object} thunkArgs Argument object for the thunk middleware. - * @param {Function} thunkArgs.select Function to select from the store. - * - * @return {WPBlockType | undefined} The block, if it has been successfully registered; otherwise `undefined`. - */ -const processBlockType = ( blockType, { select } ) => { - const { name } = blockType; - - const settings = applyFilters( - 'blocks.registerBlockType', - { ...blockType }, - name, - null - ); - - if ( settings.description && typeof settings.description !== 'string' ) { - deprecated( 'Declaring non-string block descriptions', { - since: '6.2', - } ); - } - - if ( settings.deprecated ) { - settings.deprecated = settings.deprecated.map( ( deprecation ) => - Object.fromEntries( - Object.entries( - // Only keep valid deprecation keys. - applyFilters( - 'blocks.registerBlockType', - // Merge deprecation keys with pre-filter settings - // so that filters that depend on specific keys being - // present don't fail. - { - // Omit deprecation keys here so that deprecations - // can opt out of specific keys like "supports". - ...omit( blockType, DEPRECATED_ENTRY_KEYS ), - ...deprecation, - }, - name, - deprecation - ) - ).filter( ( [ key ] ) => DEPRECATED_ENTRY_KEYS.includes( key ) ) - ) - ); - } - - if ( ! isPlainObject( settings ) ) { - error( 'Block settings must be a valid object.' ); - return; - } - - if ( ! isFunction( settings.save ) ) { - error( 'The "save" property must be a valid function.' ); - return; - } - if ( 'edit' in settings && ! isFunction( settings.edit ) ) { - error( 'The "edit" property must be a valid function.' ); - return; - } - - // Canonicalize legacy categories to equivalent fallback. - if ( LEGACY_CATEGORY_MAPPING.hasOwnProperty( settings.category ) ) { - settings.category = LEGACY_CATEGORY_MAPPING[ settings.category ]; - } - - if ( - 'category' in settings && - ! select - .getCategories() - .some( ( { slug } ) => slug === settings.category ) - ) { - warn( - 'The block "' + - name + - '" is registered with an invalid category "' + - settings.category + - '".' - ); - delete settings.category; - } - - if ( ! ( 'title' in settings ) || settings.title === '' ) { - error( 'The block "' + name + '" must have a title.' ); - return; - } - if ( typeof settings.title !== 'string' ) { - error( 'Block titles must be strings.' ); - return; - } - - settings.icon = normalizeIconObject( settings.icon ); - if ( ! isValidIcon( settings.icon.src ) ) { - error( - 'The icon passed is invalid. ' + - 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional' - ); - return; - } - - return settings; -}; - /** * Returns an action object used in signalling that block types have been added. * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. @@ -167,26 +30,6 @@ export function addBlockTypes( blockTypes ) { }; } -/** - * Signals that the passed block type's settings should be stored in the state. - * - * @param {WPBlockType} blockType Unprocessed block type settings. - */ -export const __experimentalRegisterBlockType = - ( blockType ) => - ( { dispatch, select } ) => { - dispatch( { - type: 'ADD_UNPROCESSED_BLOCK_TYPE', - blockType, - } ); - - const processedBlockType = processBlockType( blockType, { select } ); - if ( ! processedBlockType ) { - return; - } - dispatch.addBlockTypes( processedBlockType ); - }; - /** * Signals that all block types should be computed again. * It uses stored unprocessed block types and all the most recent list of registered filters. @@ -201,25 +44,17 @@ export const __experimentalRegisterBlockType = * 7. Filter G. * In this scenario some filters would not get applied for all blocks because they are registered too late. */ -export const __experimentalReapplyBlockTypeFilters = - () => - ( { dispatch, select } ) => { - const unprocessedBlockTypes = - select.__experimentalGetUnprocessedBlockTypes(); - - const processedBlockTypes = Object.keys( unprocessedBlockTypes ).reduce( - ( accumulator, blockName ) => { - const result = processBlockType( - unprocessedBlockTypes[ blockName ], - { select } - ); - if ( result ) { - accumulator.push( result ); - } - return accumulator; - }, - [] - ); +export function reapplyBlockTypeFilters() { + return ( { dispatch, select } ) => { + const processedBlockTypes = []; + for ( const [ name, settings ] of Object.entries( + select.getUnprocessedBlockTypes() + ) ) { + const result = dispatch( processBlockType( name, settings ) ); + if ( result ) { + processedBlockTypes.push( result ); + } + } if ( ! processedBlockTypes.length ) { return; @@ -227,6 +62,19 @@ export const __experimentalReapplyBlockTypeFilters = dispatch.addBlockTypes( processedBlockTypes ); }; +} + +export function __experimentalReapplyBlockFilters() { + deprecated( + 'wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', + { + since: '6.4', + alternative: 'reapplyBlockFilters', + } + ); + + return reapplyBlockTypeFilters(); +} /** * Returns an action object used to remove a registered block type. diff --git a/packages/blocks/src/store/index.js b/packages/blocks/src/store/index.js index ce69fd83d4e6c0..ffda3ffe000261 100644 --- a/packages/blocks/src/store/index.js +++ b/packages/blocks/src/store/index.js @@ -10,6 +10,7 @@ import reducer from './reducer'; import * as selectors from './selectors'; import * as privateSelectors from './private-selectors'; import * as actions from './actions'; +import * as privateActions from './private-actions'; import { STORE_NAME } from './constants'; import { unlock } from '../lock-unlock'; @@ -28,3 +29,4 @@ export const store = createReduxStore( STORE_NAME, { register( store ); unlock( store ).registerPrivateSelectors( privateSelectors ); +unlock( store ).registerPrivateActions( privateActions ); diff --git a/packages/blocks/src/store/private-actions.js b/packages/blocks/src/store/private-actions.js new file mode 100644 index 00000000000000..bc06e231b17222 --- /dev/null +++ b/packages/blocks/src/store/private-actions.js @@ -0,0 +1,42 @@ +/** + * Internal dependencies + */ +import { processBlockType } from './process-block-type'; + +/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ + +/** + * Add bootstrapped block type metadata to the store. These metadata usually come from + * the `block.json` file and are either statically boostrapped from the server, or + * passed as the `metadata` parameter to the `registerBlockType` function. + * + * @param {string} name Block name. + * @param {WPBlockType} blockType Block type metadata. + */ +export function addBootstrappedBlockType( name, blockType ) { + return { + type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', + name, + blockType, + }; +} + +/** + * Add unprocessed block type settings to the store. These data are passed as the + * `settings` parameter to the client-side `registerBlockType` function. + * + * @param {string} name Block name. + * @param {WPBlockType} blockType Unprocessed block type settings. + */ +export function addUnprocessedBlockType( name, blockType ) { + return ( { dispatch } ) => { + dispatch( { type: 'ADD_UNPROCESSED_BLOCK_TYPE', name, blockType } ); + const processedBlockType = dispatch( + processBlockType( name, blockType ) + ); + if ( ! processedBlockType ) { + return; + } + dispatch.addBlockTypes( processedBlockType ); + }; +} diff --git a/packages/blocks/src/store/private-selectors.js b/packages/blocks/src/store/private-selectors.js index c9f5002b2219a3..7e4311658c8694 100644 --- a/packages/blocks/src/store/private-selectors.js +++ b/packages/blocks/src/store/private-selectors.js @@ -152,3 +152,27 @@ export const getSupportedStyles = createSelector( }, ( state, name ) => [ state.blockTypes[ name ] ] ); + +/** + * Returns the bootstrapped block type metadata for a give block name. + * + * @param {Object} state Data state. + * @param {string} name Block name. + * + * @return {Object} Bootstrapped block type metadata for a block. + */ +export function getBootstrappedBlockType( state, name ) { + return state.bootstrappedBlockTypes[ name ]; +} + +/** + * Returns all the unprocessed (before applying the `registerBlockType` filter) + * block type settings as passed during block registration. + * + * @param {Object} state Data state. + * + * @return {Array} Unprocessed block type settings for all blocks. + */ +export function getUnprocessedBlockTypes( state ) { + return state.unprocessedBlockTypes; +} diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js new file mode 100644 index 00000000000000..aab198af6c66fb --- /dev/null +++ b/packages/blocks/src/store/process-block-type.js @@ -0,0 +1,159 @@ +/** + * External dependencies + */ +import { isPlainObject } from 'is-plain-object'; + +/** + * WordPress dependencies + */ +import deprecated from '@wordpress/deprecated'; +import { applyFilters } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import { isValidIcon, normalizeIconObject, omit } from '../api/utils'; +import { BLOCK_ICON_DEFAULT, DEPRECATED_ENTRY_KEYS } from '../api/constants'; + +/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ + +const { error, warn } = window.console; + +/** + * Mapping of legacy category slugs to their latest normal values, used to + * accommodate updates of the default set of block categories. + * + * @type {Record} + */ +const LEGACY_CATEGORY_MAPPING = { + common: 'text', + formatting: 'text', + layout: 'design', +}; + +/** + * Takes the unprocessed block type settings, merges them with block type metadata + * and applies all the existing filters for the registered block type. + * Next, it validates all the settings and performs additional processing to the block type definition. + * + * @param {string} name Block name. + * @param {WPBlockType} blockSettings Unprocessed block type settings. + * + * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. + */ +export const processBlockType = + ( name, blockSettings ) => + ( { select } ) => { + const blockType = { + name, + icon: BLOCK_ICON_DEFAULT, + keywords: [], + attributes: {}, + providesContext: {}, + usesContext: [], + selectors: {}, + supports: {}, + styles: [], + variations: [], + save: () => null, + ...select.getBootstrappedBlockType( name ), + ...blockSettings, + }; + + const settings = applyFilters( + 'blocks.registerBlockType', + blockType, + name, + null + ); + + if ( + settings.description && + typeof settings.description !== 'string' + ) { + deprecated( 'Declaring non-string block descriptions', { + since: '6.2', + } ); + } + + if ( settings.deprecated ) { + settings.deprecated = settings.deprecated.map( ( deprecation ) => + Object.fromEntries( + Object.entries( + // Only keep valid deprecation keys. + applyFilters( + 'blocks.registerBlockType', + // Merge deprecation keys with pre-filter settings + // so that filters that depend on specific keys being + // present don't fail. + { + // Omit deprecation keys here so that deprecations + // can opt out of specific keys like "supports". + ...omit( blockType, DEPRECATED_ENTRY_KEYS ), + ...deprecation, + }, + blockType.name, + deprecation + ) + ).filter( ( [ key ] ) => + DEPRECATED_ENTRY_KEYS.includes( key ) + ) + ) + ); + } + + if ( ! isPlainObject( settings ) ) { + error( 'Block settings must be a valid object.' ); + return; + } + + if ( typeof settings.save !== 'function' ) { + error( 'The "save" property must be a valid function.' ); + return; + } + if ( 'edit' in settings && typeof settings.edit !== 'function' ) { + error( 'The "edit" property must be a valid function.' ); + return; + } + + // Canonicalize legacy categories to equivalent fallback. + if ( LEGACY_CATEGORY_MAPPING.hasOwnProperty( settings.category ) ) { + settings.category = LEGACY_CATEGORY_MAPPING[ settings.category ]; + } + + if ( + 'category' in settings && + ! select + .getCategories() + .some( ( { slug } ) => slug === settings.category ) + ) { + warn( + 'The block "' + + name + + '" is registered with an invalid category "' + + settings.category + + '".' + ); + delete settings.category; + } + + if ( ! ( 'title' in settings ) || settings.title === '' ) { + error( 'The block "' + name + '" must have a title.' ); + return; + } + if ( typeof settings.title !== 'string' ) { + error( 'Block titles must be strings.' ); + return; + } + + settings.icon = normalizeIconObject( settings.icon ); + if ( ! isValidIcon( settings.icon.src ) ) { + error( + 'The icon passed is invalid. ' + + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional' + ); + return; + } + + return settings; + }; diff --git a/packages/blocks/src/store/reducer.js b/packages/blocks/src/store/reducer.js index d8f76e00fc71d5..a8f114fea79c70 100644 --- a/packages/blocks/src/store/reducer.js +++ b/packages/blocks/src/store/reducer.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { camelCase } from 'change-case'; + /** * WordPress dependencies */ @@ -52,6 +57,72 @@ function getUniqueItemsByName( items ) { }, [] ); } +function bootstrappedBlockTypes( state = {}, action ) { + switch ( action.type ) { + case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': + const { name, blockType } = action; + const serverDefinition = state[ name ]; + let newDefinition; + // Don't overwrite if already set. It covers the case when metadata + // was initialized from the server. + if ( serverDefinition ) { + // The `selectors` prop is not yet included in the server provided + // definitions and needs to be polyfilled. This can be removed when the + // minimum supported WordPress is >= 6.3. + if ( + serverDefinition.selectors === undefined && + blockType.selectors + ) { + newDefinition = { + ...serverDefinition, + selectors: blockType.selectors, + }; + } + + // The `autoInsert` prop is not yet included in the server provided + // definitions and needs to be polyfilled. This can be removed when the + // minimum supported WordPress is >= 6.4. + if ( + serverDefinition.__experimentalAutoInsert === undefined && + blockType.__experimentalAutoInsert + ) { + newDefinition = { + ...serverDefinition, + ...newDefinition, + __experimentalAutoInsert: + blockType.__experimentalAutoInsert, + }; + } + } else { + newDefinition = Object.fromEntries( + Object.entries( blockType ) + .filter( + ( [ , value ] ) => + value !== null && value !== undefined + ) + .map( ( [ key, value ] ) => [ + camelCase( key ), + value, + ] ) + ); + newDefinition.name = name; + } + + if ( newDefinition ) { + return { + ...state, + [ name ]: newDefinition, + }; + } + + return state; + case 'REMOVE_BLOCK_TYPES': + return omit( state, action.names ); + } + + return state; +} + /** * Reducer managing the unprocessed block types in a form passed when registering the by block. * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters @@ -67,7 +138,7 @@ export function unprocessedBlockTypes( state = {}, action ) { case 'ADD_UNPROCESSED_BLOCK_TYPE': return { ...state, - [ action.blockType.name ]: action.blockType, + [ action.name ]: action.blockType, }; case 'REMOVE_BLOCK_TYPES': return omit( state, action.names ); @@ -300,6 +371,7 @@ export function collections( state = {}, action ) { } export default combineReducers( { + bootstrappedBlockTypes, unprocessedBlockTypes, blockTypes, blockStyles, diff --git a/packages/blocks/src/store/selectors.js b/packages/blocks/src/store/selectors.js index cf577c695c9c5a..b2b8ab8106f097 100644 --- a/packages/blocks/src/store/selectors.js +++ b/packages/blocks/src/store/selectors.js @@ -32,17 +32,6 @@ const getNormalizedBlockType = ( state, nameOrType ) => ? getBlockType( state, nameOrType ) : nameOrType; -/** - * Returns all the unprocessed block types as passed during the registration. - * - * @param {Object} state Data state. - * - * @return {Array} Unprocessed block types. - */ -export function __experimentalGetUnprocessedBlockTypes( state ) { - return state.unprocessedBlockTypes; -} - /** * Returns all the available block types. * diff --git a/packages/blocks/src/store/test/reducer.js b/packages/blocks/src/store/test/reducer.js index b4312d0fd7df22..5664f9d876cb6e 100644 --- a/packages/blocks/src/store/test/reducer.js +++ b/packages/blocks/src/store/test/reducer.js @@ -31,24 +31,25 @@ describe( 'unprocessedBlockTypes', () => { it( 'should add a new block type', () => { const original = deepFreeze( { - 'core/paragraph': { name: 'core/paragraph' }, + 'core/paragraph': { title: 'Paragraph' }, } ); const state = unprocessedBlockTypes( original, { type: 'ADD_UNPROCESSED_BLOCK_TYPE', - blockType: { name: 'core/code' }, + name: 'core/code', + blockType: { title: 'Code' }, } ); expect( state ).toEqual( { - 'core/paragraph': { name: 'core/paragraph' }, - 'core/code': { name: 'core/code' }, + 'core/paragraph': { title: 'Paragraph' }, + 'core/code': { title: 'Code' }, } ); } ); it( 'should remove unprocessed block types', () => { const original = deepFreeze( { - 'core/paragraph': { name: 'core/paragraph' }, - 'core/code': { name: 'core/code' }, + 'core/paragraph': { title: 'Paragraph' }, + 'core/code': { title: 'Code' }, } ); const state = blockTypes( original, { @@ -57,7 +58,7 @@ describe( 'unprocessedBlockTypes', () => { } ); expect( state ).toEqual( { - 'core/paragraph': { name: 'core/paragraph' }, + 'core/paragraph': { title: 'Paragraph' }, } ); } ); } ); diff --git a/packages/customize-widgets/src/index.js b/packages/customize-widgets/src/index.js index 10ca00ff783090..5b438cac86f49b 100644 --- a/packages/customize-widgets/src/index.js +++ b/packages/customize-widgets/src/index.js @@ -49,7 +49,7 @@ export function initialize( editorName, blockEditorSettings ) { welcomeGuide: true, } ); - dispatch( blocksStore ).__experimentalReapplyBlockTypeFilters(); + dispatch( blocksStore ).reapplyBlockTypeFilters(); const coreBlocks = __experimentalGetCoreBlocks().filter( ( block ) => { return ! ( DISABLED_BLOCKS.includes( block.name ) || diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index fc5ce8c948e2ab..9dec0c6cd5e357 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -62,7 +62,7 @@ export function initializeEditor( welcomeGuideTemplate: true, } ); - dispatch( blocksStore ).__experimentalReapplyBlockTypeFilters(); + dispatch( blocksStore ).reapplyBlockTypeFilters(); // Check if the block list view should be open by default. // If `distractionFree` mode is enabled, the block list view should not be open. diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js index ea2899a8abc105..18cb0d5e5db69b 100644 --- a/packages/edit-site/src/index.js +++ b/packages/edit-site/src/index.js @@ -43,7 +43,7 @@ export function initializeEditor( id, settings ) { fetchLinkSuggestions( search, searchOptions, settings ); settings.__experimentalFetchRichUrlData = fetchUrlData; - dispatch( blocksStore ).__experimentalReapplyBlockTypeFilters(); + dispatch( blocksStore ).reapplyBlockTypeFilters(); const coreBlocks = __experimentalGetCoreBlocks().filter( ( { name } ) => name !== 'core/freeform' ); diff --git a/packages/edit-widgets/src/index.js b/packages/edit-widgets/src/index.js index 56421ebe357bac..eb87d22fefef9e 100644 --- a/packages/edit-widgets/src/index.js +++ b/packages/edit-widgets/src/index.js @@ -70,7 +70,7 @@ export function initializeEditor( id, settings ) { themeStyles: true, } ); - dispatch( blocksStore ).__experimentalReapplyBlockTypeFilters(); + dispatch( blocksStore ).reapplyBlockTypeFilters(); registerCoreBlocks( coreBlocks ); registerLegacyWidgetBlock(); if ( process.env.IS_GUTENBERG_PLUGIN ) { From f706c86f201f325a4108d74fdf1e0315521db705 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Wed, 30 Aug 2023 16:35:04 +0300 Subject: [PATCH 37/56] Toggle Distraction free mode mode based on compatibility (#54030) * Toggle DFM mode based on compatibility * rename `dfm` to `distractionFreeMode` * add tests * rename to `isDistractionFree` --- .../data/data-core-edit-site.md | 4 + .../keyboard-shortcuts/edit-mode.js | 32 +------ .../index.js | 41 +-------- .../src/hooks/commands/use-common-commands.js | 22 ----- .../hooks/commands/use-edit-mode-commands.js | 28 +++--- packages/edit-site/src/store/actions.js | 77 ++++++++++++++-- packages/edit-site/src/store/test/actions.js | 88 +++++++++++++++++++ packages/edit-site/src/store/test/reducer.js | 31 +++++-- 8 files changed, 198 insertions(+), 125 deletions(-) diff --git a/docs/reference-guides/data/data-core-edit-site.md b/docs/reference-guides/data/data-core-edit-site.md index 83e9b09dfd7d89..0cac2268b2ab29 100644 --- a/docs/reference-guides/data/data-core-edit-site.md +++ b/docs/reference-guides/data/data-core-edit-site.md @@ -408,6 +408,10 @@ _Returns_ Undocumented declaration. +### toggleDistractionFree + +Action that toggles Distraction free mode. Distraction free mode expects there are no sidebars, as due to the z-index values set, you can't close sidebars. + ### toggleFeature Dispatches an action that toggles a feature flag. diff --git a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js b/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js index 49efa11368a7d2..1346041b6a94c1 100644 --- a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js +++ b/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js @@ -1,15 +1,12 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; import { useShortcut } from '@wordpress/keyboard-shortcuts'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as interfaceStore } from '@wordpress/interface'; import { createBlock } from '@wordpress/blocks'; -import { store as preferencesStore } from '@wordpress/preferences'; -import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies @@ -32,12 +29,8 @@ function KeyboardShortcutsEditMode() { [] ); const { redo, undo } = useDispatch( coreStore ); - const { - setIsListViewOpened, - switchEditorMode, - setIsInserterOpened, - closeGeneralSidebar, - } = useDispatch( editSiteStore ); + const { setIsListViewOpened, switchEditorMode, toggleDistractionFree } = + useDispatch( editSiteStore ); const { enableComplementaryArea, disableComplementaryArea } = useDispatch( interfaceStore ); @@ -45,17 +38,6 @@ function KeyboardShortcutsEditMode() { const { getBlockName, getSelectedBlockClientId, getBlockAttributes } = useSelect( blockEditorStore ); - const { get: getPreference } = useSelect( preferencesStore ); - const { set: setPreference, toggle } = useDispatch( preferencesStore ); - const { createInfoNotice } = useDispatch( noticesStore ); - - const toggleDistractionFree = () => { - setPreference( 'core/edit-site', 'fixedToolbar', false ); - setIsInserterOpened( false ); - setIsListViewOpened( false ); - closeGeneralSidebar(); - }; - const handleTextLevelShortcut = ( event, level ) => { event.preventDefault(); const destinationBlockName = @@ -134,16 +116,6 @@ function KeyboardShortcutsEditMode() { useShortcut( 'core/edit-site/toggle-distraction-free', () => { toggleDistractionFree(); - toggle( 'core/edit-site', 'distractionFree' ); - createInfoNotice( - getPreference( 'core/edit-site', 'distractionFree' ) - ? __( 'Distraction free mode turned on.' ) - : __( 'Distraction free mode turned off.' ), - { - id: 'core/edit-site/distraction-free-mode/notice', - type: 'snackbar', - } - ); } ); return null; diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index a156bd40c22115..5ad7691c5e5a2a 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -15,8 +15,6 @@ import { useViewportMatch } from '@wordpress/compose'; import { BlockEditorProvider } from '@wordpress/block-editor'; import { humanTimeDiff } from '@wordpress/date'; import { useCallback } from '@wordpress/element'; -import { store as noticesStore } from '@wordpress/notices'; -import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -35,24 +33,7 @@ const noop = () => {}; export function SidebarNavigationItemGlobalStyles( props ) { const { openGeneralSidebar } = useDispatch( editSiteStore ); const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - const { createNotice } = useDispatch( noticesStore ); - const { set: setPreference } = useDispatch( preferencesStore ); - const { get: getPreference } = useSelect( preferencesStore ); - const turnOffDistractionFreeMode = useCallback( () => { - const isDistractionFree = getPreference( - editSiteStore.name, - 'distractionFree' - ); - if ( ! isDistractionFree ) { - return; - } - setPreference( editSiteStore.name, 'distractionFree', false ); - createNotice( 'info', __( 'Distraction free mode turned off' ), { - isDismissible: true, - type: 'snackbar', - } ); - }, [ createNotice, setPreference, getPreference ] ); const hasGlobalStyleVariations = useSelect( ( select ) => !! select( @@ -73,7 +54,6 @@ export function SidebarNavigationItemGlobalStyles( props ) { { - turnOffDistractionFreeMode(); // Switch to edit mode. setCanvasMode( 'edit' ); // Open global styles sidebar. @@ -150,9 +130,6 @@ export default function SidebarNavigationScreenGlobalStyles() { const { setCanvasMode, setEditorCanvasContainerView } = unlock( useDispatch( editSiteStore ) ); - const { createNotice } = useDispatch( noticesStore ); - const { set: setPreference } = useDispatch( preferencesStore ); - const { get: getPreference } = useSelect( preferencesStore ); const { isViewMode, isStyleBookOpened, revisionsCount } = useSelect( ( select ) => { const { getCanvasMode, getEditorCanvasContainerView } = unlock( @@ -176,28 +153,12 @@ export default function SidebarNavigationScreenGlobalStyles() { [] ); - const turnOffDistractionFreeMode = useCallback( () => { - const isDistractionFree = getPreference( - editSiteStore.name, - 'distractionFree' - ); - if ( ! isDistractionFree ) { - return; - } - setPreference( editSiteStore.name, 'distractionFree', false ); - createNotice( 'info', __( 'Distraction free mode turned off' ), { - isDismissible: true, - type: 'snackbar', - } ); - }, [ createNotice, setPreference, getPreference ] ); - const openGlobalStyles = useCallback( async () => { - turnOffDistractionFreeMode(); return Promise.all( [ setCanvasMode( 'edit' ), openGeneralSidebar( 'edit-site/global-styles' ), ] ); - }, [ setCanvasMode, openGeneralSidebar, turnOffDistractionFreeMode ] ); + }, [ setCanvasMode, openGeneralSidebar ] ); const openStyleBook = useCallback( async () => { await openGlobalStyles(); diff --git a/packages/edit-site/src/hooks/commands/use-common-commands.js b/packages/edit-site/src/hooks/commands/use-common-commands.js index c1a023d0b1b200..16d07132ad7c74 100644 --- a/packages/edit-site/src/hooks/commands/use-common-commands.js +++ b/packages/edit-site/src/hooks/commands/use-common-commands.js @@ -10,7 +10,6 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { store as preferencesStore } from '@wordpress/preferences'; import { store as coreStore } from '@wordpress/core-data'; -import { store as noticesStore } from '@wordpress/notices'; import { useViewportMatch } from '@wordpress/compose'; /** @@ -31,16 +30,7 @@ function useGlobalStylesOpenStylesCommands() { const isMobileViewport = useViewportMatch( 'medium', '<' ); const isEditorPage = ! getIsListPage( params, isMobileViewport ); const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); - const { set } = useDispatch( preferencesStore ); - const { createInfoNotice } = useDispatch( noticesStore ); - const history = useHistory(); - const isDistractionFree = useSelect( ( select ) => { - return select( preferencesStore ).get( - editSiteStore.name, - 'distractionFree' - ); - }, [] ); const isBlockBasedTheme = useSelect( ( select ) => { return select( coreStore ).getCurrentTheme().is_block_theme; @@ -66,15 +56,6 @@ function useGlobalStylesOpenStylesCommands() { if ( isEditorPage && getCanvasMode() !== 'edit' ) { setCanvasMode( 'edit' ); } - if ( isDistractionFree ) { - set( editSiteStore.name, 'distractionFree', false ); - createInfoNotice( - __( 'Distraction free mode turned off.' ), - { - type: 'snackbar', - } - ); - } openGeneralSidebar( 'edit-site/global-styles' ); }, icon: styles, @@ -85,11 +66,8 @@ function useGlobalStylesOpenStylesCommands() { openGeneralSidebar, setCanvasMode, isEditorPage, - createInfoNotice, getCanvasMode, - isDistractionFree, isBlockBasedTheme, - set, ] ); return { diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index 6079c01773be78..76c7eea5137439 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -195,7 +195,7 @@ function useEditUICommands() { const { openGeneralSidebar, closeGeneralSidebar, - setIsInserterOpened, + toggleDistractionFree, setIsListViewOpened, switchEditorMode, } = useDispatch( editSiteStore ); @@ -205,6 +205,7 @@ function useEditUICommands() { activeSidebar, showBlockBreadcrumbs, isListViewOpen, + isDistractionFree, } = useSelect( ( select ) => { const { isListViewOpened, getEditorMode } = select( editSiteStore ); return { @@ -218,11 +219,14 @@ function useEditUICommands() { 'showBlockBreadcrumbs' ), isListViewOpen: isListViewOpened(), + isDistractionFree: select( preferencesStore ).get( + editSiteStore.name, + 'distractionFree' + ), }; }, [] ); const { openModal } = useDispatch( interfaceStore ); - const { get: getPreference } = useSelect( preferencesStore ); - const { set: setPreference, toggle } = useDispatch( preferencesStore ); + const { toggle } = useDispatch( preferencesStore ); const { createInfoNotice } = useDispatch( noticesStore ); if ( canvasMode !== 'edit' ) { @@ -272,20 +276,7 @@ function useEditUICommands() { name: 'core/toggle-distraction-free', label: __( 'Toggle distraction free' ), callback: ( { close } ) => { - setPreference( 'core/edit-site', 'fixedToolbar', false ); - setIsInserterOpened( false ); - setIsListViewOpened( false ); - closeGeneralSidebar(); - toggle( 'core/edit-site', 'distractionFree' ); - createInfoNotice( - getPreference( 'core/edit-site', 'distractionFree' ) - ? __( 'Distraction free on.' ) - : __( 'Distraction free off.' ), - { - id: 'core/edit-site/distraction-free-mode/notice', - type: 'snackbar', - } - ); + toggleDistractionFree(); close(); }, } ); @@ -295,6 +286,9 @@ function useEditUICommands() { label: __( 'Toggle top toolbar' ), callback: ( { close } ) => { toggle( 'core/edit-site', 'fixedToolbar' ); + if ( isDistractionFree ) { + toggleDistractionFree(); + } close(); }, } ); diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index ac07ac5beaa2af..0ad521a9c9a54e 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -373,12 +373,20 @@ export function updateSettings( settings ) { * @param {boolean} isOpen If true, opens the list view. If false, closes it. * It does not toggle the state, but sets it directly. */ -export function setIsListViewOpened( isOpen ) { - return { - type: 'SET_IS_LIST_VIEW_OPENED', - isOpen, +export const setIsListViewOpened = + ( isOpen ) => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ); + if ( isDistractionFree && isOpen ) { + dispatch.toggleDistractionFree(); + } + dispatch( { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen, + } ); }; -} /** * Sets whether the save view panel should be open. @@ -533,7 +541,13 @@ export const revertTemplate = */ export const openGeneralSidebar = ( name ) => - ( { registry } ) => { + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ); + if ( isDistractionFree ) { + dispatch.toggleDistractionFree(); + } registry .dispatch( interfaceStore ) .enableComplementaryArea( editSiteStoreName, name ); @@ -552,7 +566,7 @@ export const closeGeneralSidebar = export const switchEditorMode = ( mode ) => - ( { registry } ) => { + ( { dispatch, registry } ) => { registry .dispatch( 'core/preferences' ) .set( 'core/edit-site', 'editorMode', mode ); @@ -565,6 +579,12 @@ export const switchEditorMode = if ( mode === 'visual' ) { speak( __( 'Visual editor selected' ), 'assertive' ); } else if ( mode === 'text' ) { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ); + if ( isDistractionFree ) { + dispatch.toggleDistractionFree(); + } speak( __( 'Code editor selected' ), 'assertive' ); } }; @@ -587,3 +607,46 @@ export const setHasPageContentFocus = hasPageContentFocus, } ); }; + +/** + * Action that toggles Distraction free mode. + * Distraction free mode expects there are no sidebars, as due to the + * z-index values set, you can't close sidebars. + */ +export const toggleDistractionFree = + () => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ); + if ( ! isDistractionFree ) { + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( 'core/edit-site', 'fixedToolbar', false ); + dispatch.setIsInserterOpened( false ); + dispatch.setIsListViewOpened( false ); + dispatch.closeGeneralSidebar(); + } ); + } + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( + 'core/edit-site', + 'distractionFree', + ! isDistractionFree + ); + registry + .dispatch( noticesStore ) + .createInfoNotice( + isDistractionFree + ? __( 'Distraction free off.' ) + : __( 'Distraction free on.' ), + { + id: 'core/edit-site/distraction-free-mode/notice', + type: 'snackbar', + } + ); + } ); + }; diff --git a/packages/edit-site/src/store/test/actions.js b/packages/edit-site/src/store/test/actions.js index 8ce914b00b208e..345fcddbbba3b2 100644 --- a/packages/edit-site/src/store/test/actions.js +++ b/packages/edit-site/src/store/test/actions.js @@ -215,6 +215,94 @@ describe( 'actions', () => { false ); } ); + it( 'should turn off distraction free mode when opening the list view', () => { + const registry = createRegistryWithStores(); + registry + .dispatch( preferencesStore ) + .set( 'core/edit-site', 'distractionFree', true ); + registry.dispatch( editSiteStore ).setIsListViewOpened( true ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ) + ).toBe( false ); + } ); + } ); + + describe( 'openGeneralSidebar', () => { + it( 'should turn off distraction free mode when opening a general sidebar', () => { + const registry = createRegistryWithStores(); + registry + .dispatch( preferencesStore ) + .set( 'core/edit-site', 'distractionFree', true ); + + registry + .dispatch( editSiteStore ) + .openGeneralSidebar( 'edit-site/global-styles' ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ) + ).toBe( false ); + } ); + } ); + + describe( 'switchEditorMode', () => { + it( 'should turn off distraction free mode when switching to code editor', () => { + const registry = createRegistryWithStores(); + registry + .dispatch( preferencesStore ) + .set( 'core/edit-site', 'distractionFree', true ); + registry.dispatch( editSiteStore ).switchEditorMode( 'visual' ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ) + ).toBe( true ); + registry.dispatch( editSiteStore ).switchEditorMode( 'text' ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ) + ).toBe( false ); + } ); + } ); + + describe( 'toggleDistractionFree', () => { + it( 'should properly update settings to prevent layout corruption when enabling distraction free mode', () => { + const registry = createRegistryWithStores(); + // Enable everything that shouldn't be enabled in distraction free mode. + registry + .dispatch( preferencesStore ) + .set( 'core/edit-site', 'fixedToolbar', true ); + registry.dispatch( editSiteStore ).setIsListViewOpened( true ); + registry + .dispatch( editSiteStore ) + .openGeneralSidebar( 'edit-site/global-styles' ); + // Initial state is falsy. + registry.dispatch( editSiteStore ).toggleDistractionFree(); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'fixedToolbar' ) + ).toBe( false ); + expect( registry.select( editSiteStore ).isListViewOpened() ).toBe( + false + ); + expect( registry.select( editSiteStore ).isInserterOpened() ).toBe( + false + ); + expect( + registry + .select( interfaceStore ) + .getActiveComplementaryArea( editSiteStore.name ) + ).toBeNull(); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-site', 'distractionFree' ) + ).toBe( true ); + } ); } ); describe( 'setHasPageContentFocus', () => { diff --git a/packages/edit-site/src/store/test/reducer.js b/packages/edit-site/src/store/test/reducer.js index 9ab7f8e3964f8b..fc06faf925b386 100644 --- a/packages/edit-site/src/store/test/reducer.js +++ b/packages/edit-site/src/store/test/reducer.js @@ -14,7 +14,7 @@ import { hasPageContentFocus, } from '../reducer'; -import { setIsInserterOpened, setIsListViewOpened } from '../actions'; +import { setIsInserterOpened } from '../actions'; describe( 'state', () => { describe( 'settings()', () => { @@ -95,13 +95,19 @@ describe( 'state', () => { it( 'should close the inserter when opening the list view panel', () => { expect( - blockInserterPanel( true, setIsListViewOpened( true ) ) + blockInserterPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: true, + } ) ).toBe( false ); } ); it( 'should not change the state when closing the list view panel', () => { expect( - blockInserterPanel( true, setIsListViewOpened( false ) ) + blockInserterPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: false, + } ) ).toBe( true ); } ); } ); @@ -116,12 +122,19 @@ describe( 'state', () => { } ); it( 'should set the open state of the list view panel', () => { - expect( listViewPanel( false, setIsListViewOpened( true ) ) ).toBe( - true - ); - expect( listViewPanel( true, setIsListViewOpened( false ) ) ).toBe( - false - ); + // registry.dispatch( editSiteStore ).toggleFeature( 'name' ); + expect( + listViewPanel( false, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: true, + } ) + ).toBe( true ); + expect( + listViewPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: false, + } ) + ).toBe( false ); } ); it( 'should close the list view when opening the inserter panel', () => { From 69dabb1e5604e4598c5916b24fc2aa6a0c4099e2 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 30 Aug 2023 16:39:01 +0000 Subject: [PATCH 38/56] Bump plugin version to 16.6.0-rc.1 --- gutenberg.php | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index d42b0a09017c07..44146b0c57d305 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.1 * Requires PHP: 7.0 - * Version: 16.5.1 + * Version: 16.6.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 4e6c42786efce2..e70301a75ef61c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gutenberg", - "version": "16.5.1", + "version": "16.6.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gutenberg", - "version": "16.5.1", + "version": "16.6.0-rc.1", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { diff --git a/package.json b/package.json index a4131bca556d9e..d8640a128c10f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "16.5.1", + "version": "16.6.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From 2d4314d754dcec540ac05890cc0d2dbf89ab5d53 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 30 Aug 2023 16:49:26 +0000 Subject: [PATCH 39/56] Update Changelog for 16.6.0-rc.1 --- changelog.txt | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) diff --git a/changelog.txt b/changelog.txt index 40c6e315feac6f..0f4f5bcf9bbcf1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,255 @@ == Changelog == += 16.6.0-rc.1 = + +## Changelog + +### Features + +#### Interactivity API +- Add Slot and Fill directives. ([53958](https://github.com/WordPress/gutenberg/pull/53958)) +- Query block: Client-side pagination. ([53812](https://github.com/WordPress/gutenberg/pull/53812)) +- Update `data-wp-bind` directive logic. ([54003](https://github.com/WordPress/gutenberg/pull/54003)) + + +### Enhancements + +- Bundle ObserveTyping within the BlockList component. ([53875](https://github.com/WordPress/gutenberg/pull/53875)) +- Default appender: Hide the dashed indicator until ancestor is selected. ([53761](https://github.com/WordPress/gutenberg/pull/53761)) +- Register the block editor keyboard shortcuts automatically when using BlockEditorProvider. ([53910](https://github.com/WordPress/gutenberg/pull/53910)) +- [Commands]: Add toggle list view command in site editor. ([53983](https://github.com/WordPress/gutenberg/pull/53983)) + +#### Components +- Bundle SlotFillProvider within BlockEditorProvider. ([53940](https://github.com/WordPress/gutenberg/pull/53940)) +- Make the Popover.Slot optional. ([53889](https://github.com/WordPress/gutenberg/pull/53889)) +- Popover: Update `@floating-ui` to latest version, remove custom fix for iframe positioning and scaling. ([46845](https://github.com/WordPress/gutenberg/pull/46845)) +- `AlignmentMatrixControl`: Replace `act()` with `userEvent`. ([53703](https://github.com/WordPress/gutenberg/pull/53703)) +- `ProgressBar`: Add transition to determinate indicator. ([53877](https://github.com/WordPress/gutenberg/pull/53877)) + +#### Block Library +- Blocks: Move bootstrapped block types to Redux state. ([53807](https://github.com/WordPress/gutenberg/pull/53807)) +- Capture toolbars in navigation block. ([53697](https://github.com/WordPress/gutenberg/pull/53697)) +- Content Block: Change placeholder and end-to-end test to refer to Content block. ([53902](https://github.com/WordPress/gutenberg/pull/53902)) +- Make mid size parameter settable for Query Pagination block. ([51216](https://github.com/WordPress/gutenberg/pull/51216)) + +#### Block Editor +- Capture toolbars in quote block. ([53699](https://github.com/WordPress/gutenberg/pull/53699)) +- Improve writing flow for lists by capturing list item toolbars. ([53306](https://github.com/WordPress/gutenberg/pull/53306)) +- RichTextValue: Typescript Adjustment. ([54002](https://github.com/WordPress/gutenberg/pull/54002)) + +#### Typography +- Font Face: Prepare for merge into Core. ([53858](https://github.com/WordPress/gutenberg/pull/53858)) +- Renames "Fonts Library" to "Font Library". ([53780](https://github.com/WordPress/gutenberg/pull/53780)) + +#### Post Editor +- Edit Post: Use hooks instead of HoCs in `TaxonomyPanel`. ([53773](https://github.com/WordPress/gutenberg/pull/53773)) + +#### List View +- Add keyboard shortcut for duplicating blocks. ([53559](https://github.com/WordPress/gutenberg/pull/53559)) + +#### Patterns +- Add a custom taxonomy for user created patterns. ([53163](https://github.com/WordPress/gutenberg/pull/53163)) + + +### New APIs + +#### Interactivity API +- Router with region-based client-side navigation. ([53733](https://github.com/WordPress/gutenberg/pull/53733)) + + +### Bug Fixes + +- Add missing aria roles for block locking toolbar and menu buttons. ([53734](https://github.com/WordPress/gutenberg/pull/53734)) +- Block Editor: Fix cleanup in the 'useNavModeExit' hook. ([53795](https://github.com/WordPress/gutenberg/pull/53795)) +- Command Palette: Fix crash on block-related commands. ([53923](https://github.com/WordPress/gutenberg/pull/53923)) +- Date: Add relative time translations for moment.js. ([53931](https://github.com/WordPress/gutenberg/pull/53931)) +- Date: Update translation domains for strings to be translatable. ([53995](https://github.com/WordPress/gutenberg/pull/53995)) +- Iframe: Set character encoding to utf-8. ([53519](https://github.com/WordPress/gutenberg/pull/53519)) +- Replace horizontal ellipsis icon with vertical ellipsis icon. ([52731](https://github.com/WordPress/gutenberg/pull/52731)) +- Toggle Distraction free mode mode based on compatibility. ([54030](https://github.com/WordPress/gutenberg/pull/54030)) +- Warning: Introduce `SCRIPT_DEBUG` to make the package compatible with webpack 5. ([50122](https://github.com/WordPress/gutenberg/pull/50122)) +- [Commands]: Fix `move to` command condition for registering. ([54049](https://github.com/WordPress/gutenberg/pull/54049)) +- [Commands]: Fix block editor commands availability. ([53994](https://github.com/WordPress/gutenberg/pull/53994)) +- [Format library]: Fix `language` popover position. ([53841](https://github.com/WordPress/gutenberg/pull/53841)) + +#### Block Library +- Add init.js module for the Footnotes block. ([53763](https://github.com/WordPress/gutenberg/pull/53763)) +- Adding center align css for social icon issue. ([43120](https://github.com/WordPress/gutenberg/pull/43120)) +- Cover block: Fix exception when adding video background. ([53961](https://github.com/WordPress/gutenberg/pull/53961)) +- List View: Allow replacing template part when a block isn't selected. ([53757](https://github.com/WordPress/gutenberg/pull/53757)) +- Post Navigation Link: Remove unnecessary space between arrows and label. ([53572](https://github.com/WordPress/gutenberg/pull/53572)) +- Search block: Fix width input field. ([53952](https://github.com/WordPress/gutenberg/pull/53952)) +- Simplify check for no posts in query-no-results block. ([53772](https://github.com/WordPress/gutenberg/pull/53772)) +- Site Logo: Remove line-height for the anchor element. ([53909](https://github.com/WordPress/gutenberg/pull/53909)) + +#### Components +- Always render the fallback Popover anchor within the Popover's parent element. ([53982](https://github.com/WordPress/gutenberg/pull/53982)) +- Fix the cleanup method for SandBox. ([53796](https://github.com/WordPress/gutenberg/pull/53796)) +- PaletteEdit: Fix component height. ([54000](https://github.com/WordPress/gutenberg/pull/54000)) + +#### Post Editor +- Edit Post: Fix tab border conflicts in the Document Overview panel. ([53711](https://github.com/WordPress/gutenberg/pull/53711)) +- EditPostPreferencesModal: Fix intermittently failing tests. ([53814](https://github.com/WordPress/gutenberg/pull/53814)) +- getInsertionPoint: Fix type check for the state value. ([53793](https://github.com/WordPress/gutenberg/pull/53793)) + +#### npm Packages +- Workflow: Run Learn directly from GitHub action when publishing to npm targeting WP core. ([53762](https://github.com/WordPress/gutenberg/pull/53762)) +- Workflows: Fix issues with the npm publishing workflow when using locally. ([53565](https://github.com/WordPress/gutenberg/pull/53565)) + +#### Themes +- Command Palette: Proper handling of page/post links in all themes. ([53718](https://github.com/WordPress/gutenberg/pull/53718)) +- Fix query loop bugs by correctly relying on the main query and removing problematic workaround. ([49904](https://github.com/WordPress/gutenberg/pull/49904)) + +#### Block Editor +- Fix: Indicator style when block moving mode. ([53972](https://github.com/WordPress/gutenberg/pull/53972)) + +#### Icons +- Fix invalid namespaces. ([53955](https://github.com/WordPress/gutenberg/pull/53955)) + +#### Patterns +- Disable the preview option button when editing. ([53913](https://github.com/WordPress/gutenberg/pull/53913)) + +#### Global Styles +- Gallery: Re-enable block spacing at block level while still hiding in global styles. ([53900](https://github.com/WordPress/gutenberg/pull/53900)) + +#### Layout +- BlockList: Ensure element styles (and svg) are always appended at the end of the document. ([53859](https://github.com/WordPress/gutenberg/pull/53859)) + +#### Interactivity API +- Add "supports.interactivity" to Image block. ([53850](https://github.com/WordPress/gutenberg/pull/53850)) + +#### Style Variations +- Block Styles: Fix misplaced preview popover on RTL site. ([53726](https://github.com/WordPress/gutenberg/pull/53726)) + +#### List View +- Recalculate window list when expanded state changes (fix logic for long nested lists). ([53716](https://github.com/WordPress/gutenberg/pull/53716)) + +#### Widgets Editor +- Block Widget: Fix content cutoff in the keyboard shortcut modal. ([53638](https://github.com/WordPress/gutenberg/pull/53638)) + +#### Rich Text +- Fix cleanup in `useRemoveBrowserShortcuts`. ([52225](https://github.com/WordPress/gutenberg/pull/52225)) + + +### Accessibility + +- Edit site: Add missing label to post status password protected input field. ([52885](https://github.com/WordPress/gutenberg/pull/52885)) +- [a11y] Fix: Aria-haspop, aria-expanded attributes on the link format button. ([53691](https://github.com/WordPress/gutenberg/pull/53691)) + +#### Site Editor +- Add missing aria roles to the 'Create template part' menu item. ([53754](https://github.com/WordPress/gutenberg/pull/53754)) +- Unify the delete button style in the dropdown menu with red. ([52597](https://github.com/WordPress/gutenberg/pull/52597)) + +#### Block Library +- Add missing aria roles to the 'Replace template part' menu item. ([53755](https://github.com/WordPress/gutenberg/pull/53755)) + +#### Patterns +- Add missing aria roles to the 'Create pattern' menu item. ([53739](https://github.com/WordPress/gutenberg/pull/53739)) + +#### List View +- [a11y] Fix: Aria-haspop and aria-expanded attributes on list view button. ([53693](https://github.com/WordPress/gutenberg/pull/53693)) + +#### Block Editor +- [a11y] Fix: Aria-haspop and aria-expanded attributes on the inserter button. ([53692](https://github.com/WordPress/gutenberg/pull/53692)) + + +### Performance + +- Revert "Switch performance tests to Playwright (#52022)". ([53741](https://github.com/WordPress/gutenberg/pull/53741)) +- StartPageOptions: Load and parse patterns only after establishing the need for them. ([53673](https://github.com/WordPress/gutenberg/pull/53673)) +- Switch performance tests to Playwright: Take 2. ([53768](https://github.com/WordPress/gutenberg/pull/53768)) + + +### Experiments + +#### Block API +- Auto-inserting blocks: Add block inspector panel. ([52969](https://github.com/WordPress/gutenberg/pull/52969)) + + +### Documentation + +- Add juanmaguitar as codeowner of /packages/interactivity/docs. ([53845](https://github.com/WordPress/gutenberg/pull/53845)) +- Add new How-to Guide for enqueueing assets in the Editor. ([53828](https://github.com/WordPress/gutenberg/pull/53828)) +- Adds example for useBlockProps hook. ([53646](https://github.com/WordPress/gutenberg/pull/53646)) +- Adds explanatory text to view.js template. ([53870](https://github.com/WordPress/gutenberg/pull/53870)) +- Clarification for `parent` and `ancestor` hierarchical relationships. ([53855](https://github.com/WordPress/gutenberg/pull/53855)) +- Docs: Extend the information about using `render` with `block.json`. ([53973](https://github.com/WordPress/gutenberg/pull/53973)) +- Docs: Remove duplicate sections from FAQ page. ([53830](https://github.com/WordPress/gutenberg/pull/53830)) +- Document the naming convention for `block-library` PHP functions. ([53777](https://github.com/WordPress/gutenberg/pull/53777)) +- Fix 'lerna' links in the release documentation. ([53770](https://github.com/WordPress/gutenberg/pull/53770)) +- Fix typo in code sample for Interactivity API. ([53916](https://github.com/WordPress/gutenberg/pull/53916)) +- MenuItem: Add Storybook stories. ([53613](https://github.com/WordPress/gutenberg/pull/53613)) +- Shortcut: Add Storybook stories. ([53627](https://github.com/WordPress/gutenberg/pull/53627)) +- Storybook: Add back subcomponents to props table. ([53751](https://github.com/WordPress/gutenberg/pull/53751)) +- Storybook: Fix default source visibility. ([53749](https://github.com/WordPress/gutenberg/pull/53749)) +- Storybook: Show main story before description. ([53753](https://github.com/WordPress/gutenberg/pull/53753)) +- Update local instructions on the dev env documentation. ([53924](https://github.com/WordPress/gutenberg/pull/53924)) +- Update the Block Variations API doc. ([53817](https://github.com/WordPress/gutenberg/pull/53817)) +- Update to node 16 and npm 8 in the getting started with code contribution doc. ([53912](https://github.com/WordPress/gutenberg/pull/53912)) +- docs: Fix report-flaky-test link. ([53848](https://github.com/WordPress/gutenberg/pull/53848)) + + +### Code Quality + +- Components: Update Popover per reviews. ([53907](https://github.com/WordPress/gutenberg/pull/53907)) +- Edit Site: Rename `CanvasSpinner` to `CanvasLoader`. ([53728](https://github.com/WordPress/gutenberg/pull/53728)) +- Enforce valid function names in the packages/block-library/src/*/*.php files. ([53438](https://github.com/WordPress/gutenberg/pull/53438)) +- Fonts Library: Update properties name from snake case to camel case to match the rest of the properties. ([53746](https://github.com/WordPress/gutenberg/pull/53746)) + +#### Post Editor +- Editor: Fix the 'useSelect' warning in the 'useIsDirty' hook. ([53759](https://github.com/WordPress/gutenberg/pull/53759)) +- Fix browser console error when changing device preview mode. ([53969](https://github.com/WordPress/gutenberg/pull/53969)) +- Refactor latest content selectors in 'CopyContentMenuItem' components. ([53676](https://github.com/WordPress/gutenberg/pull/53676)) + +#### Components +- Remove unnecessary utils. ([53679](https://github.com/WordPress/gutenberg/pull/53679)) +- SlotFill: Refactor ``. ([53272](https://github.com/WordPress/gutenberg/pull/53272)) +- Storybook: Update TypeScript types. ([53748](https://github.com/WordPress/gutenberg/pull/53748)) + +#### List View +- Fix warning error when the gallery block has the same image URLs. ([53809](https://github.com/WordPress/gutenberg/pull/53809)) + +#### Typography +- Font Face API: Use `gutenberg_get_global_settings` instead of private API. ([53805](https://github.com/WordPress/gutenberg/pull/53805)) + + +### Tools + +- Try: Change PR label enforcer automation not to work on draft PRs by default. ([53417](https://github.com/WordPress/gutenberg/pull/53417)) + +#### Testing +- Attempt to fix intermittent end-to-end test failure. ([53905](https://github.com/WordPress/gutenberg/pull/53905)) +- Fonts Library: Test improvements. ([53702](https://github.com/WordPress/gutenberg/pull/53702)) +- Make fonts test files use Core approach. ([53856](https://github.com/WordPress/gutenberg/pull/53856)) +- Migrate shortcut help end-to-end tests to Playwright. ([53832](https://github.com/WordPress/gutenberg/pull/53832)) +- Relocates Font Face and Fonts Library PHP files into Core's fonts directory. ([53747](https://github.com/WordPress/gutenberg/pull/53747)) +- `ColorPalette`: Refine test query. ([53704](https://github.com/WordPress/gutenberg/pull/53704)) +- end-to-end Playwright Utils: Automatically detect canvas type. ([53744](https://github.com/WordPress/gutenberg/pull/53744)) +- test: Automate mobile editor tests. ([53991](https://github.com/WordPress/gutenberg/pull/53991)) + +#### Build Tooling +- Update Jest to latest version, and use optimized JSDOM. ([53736](https://github.com/WordPress/gutenberg/pull/53736)) + +#### Plugin +- Backport themes `is_block_theme` collection param from core. ([53846](https://github.com/WordPress/gutenberg/pull/53846)) + + +## First time contributors + +The following PRs were merged by first time contributors: + +- @JEverhart383: Fix typo in code sample for Interactivity API. ([53916](https://github.com/WordPress/gutenberg/pull/53916)) +- @krokodok: Make mid size parameter settable for Query Pagination block. ([51216](https://github.com/WordPress/gutenberg/pull/51216)) +- @mklute101: Update local instructions on the dev env documentation. ([53924](https://github.com/WordPress/gutenberg/pull/53924)) + + +## Contributors + +The following contributors merged PRs in this release: + +@afercia @andrewserong @anton-vlasenko @bangank36 @brookewp @ciampo @colorful-tones @DAreRodz @dcalhoun @derekblank @ellatrix @felixarntz @geriux @glendaviesnz @gziolo @hellofromtonya @jasmussen @jblz @JEverhart383 @jordesign @jorgefilipecosta @jsnajdr @juanmaguitar @krokodok @luisherranz @Mamaduka @margolisj @matiasbenedetto @mburridge @mirka @mklute101 @mokagio @ndiego @ntsekouras @oandregal @ocean90 @ockham @priethor @ramonjd @richtabor @SiobhyB @Smit2808 @stokesman @t-hamano @torounit @tyxla @walbo @WunderBart @youknowriad + + = 16.5.1 = From 22d24f352df72b7507939f3eb70d7b372547c5c3 Mon Sep 17 00:00:00 2001 From: Gerardo Pacheco Date: Wed, 30 Aug 2023 19:28:15 +0200 Subject: [PATCH 40/56] Mobile - Columns block - Fix transforming into a Group block crash (#54035) * Mobile - Column block - Fix issue when transforming a Columns block that's nested in a container block like Group. By avoid accessing the width value outside of the isSelected and adding a fallback value. * Mobile - Columns block - Add transform Columns block integration test * Mobile - Columns Block Tests - Update usage of the screen variable, now its imported from the helpers instead of the initializedEditor * Mobile - Update changelog --- .../block-library/src/column/edit.native.js | 8 +-- .../test/__snapshots__/edit.native.js.snap | 14 ++++ .../src/columns/test/edit.native.js | 64 ++++++++++++++----- packages/react-native-editor/CHANGELOG.md | 1 + test/native/__mocks__/styleMock.js | 4 ++ 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js index 46e5012f68a345..7e18e73a9b14ae 100644 --- a/packages/block-library/src/column/edit.native.js +++ b/packages/block-library/src/column/edit.native.js @@ -111,10 +111,10 @@ function ColumnEdit( { }; const renderAppender = useCallback( () => { - const { width: columnWidth } = contentStyle[ clientId ]; - const isFullWidth = columnWidth === screenWidth; - if ( isSelected ) { + const { width: columnWidth } = contentStyle[ clientId ] || {}; + const isFullWidth = columnWidth === screenWidth; + return ( " `; +exports[`Columns block transforms a nested Columns block into a Group block 1`] = ` +" +
    +
    +
    +
    +

    +
    +
    +
    +
    +" +`; + exports[`Columns block when using columns percentage mechanism sets custom values correctly 1`] = ` "
    diff --git a/packages/block-library/src/columns/test/edit.native.js b/packages/block-library/src/columns/test/edit.native.js index bb7bfbdafea4b0..20430704c8e1e2 100644 --- a/packages/block-library/src/columns/test/edit.native.js +++ b/packages/block-library/src/columns/test/edit.native.js @@ -4,14 +4,16 @@ import { act, addBlock, + dismissModal, fireEvent, + getBlock, getEditorHtml, initializeEditor, + openBlockActionsMenu, openBlockSettings, - within, - getBlock, - dismissModal, + screen, waitForModalVisible, + within, } from 'test/helpers'; /** @@ -43,7 +45,7 @@ afterAll( () => { describe( 'Columns block', () => { it( 'inserts block', async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Columns' ); @@ -55,7 +57,7 @@ describe( 'Columns block', () => { } ); it( 'adds a column block using the appender', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); @@ -73,7 +75,7 @@ describe( 'Columns block', () => { describe( 'when using the number of columns setting', () => { it( 'adds a column block when incrementing the value', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -95,7 +97,7 @@ describe( 'Columns block', () => { } ); it( 'adds at least 15 Column blocks without limitation', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -120,7 +122,7 @@ describe( 'Columns block', () => { } ); it( 'removes a column block when decrementing the value', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -142,7 +144,7 @@ describe( 'Columns block', () => { } ); it( 'reaches the minimum limit of number of column blocks', async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Columns' ); @@ -185,7 +187,7 @@ describe( 'Columns block', () => { } ); it( 'removes column with the remove button', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -210,7 +212,7 @@ describe( 'Columns block', () => { } ); it( 'removes the only one left Column with the remove button', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -247,7 +249,7 @@ describe( 'Columns block', () => { } ); it( 'changes vertical alignment on Columns', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -270,7 +272,7 @@ describe( 'Columns block', () => { } ); it( 'changes the vertical alignment on individual Column', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); @@ -308,7 +310,7 @@ describe( 'Columns block', () => { } ); it( 'sets current vertical alignment on new Columns', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText } = screen; @@ -337,7 +339,7 @@ describe( 'Columns block', () => { describe( 'when using columns percentage mechanism', () => { it( "updates the slider's input value", async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Columns' ); @@ -377,7 +379,7 @@ describe( 'Columns block', () => { } ); it( 'sets custom values correctly', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: TWO_COLUMNS_BLOCK_HTML, } ); const { getByLabelText, getByTestId } = screen; @@ -443,7 +445,7 @@ describe( 'Columns block', () => { test.each( testData )( 'sets the predefined percentages for %s', async ( layout ) => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Columns' ); @@ -463,4 +465,32 @@ describe( 'Columns block', () => { } ); } ); + + it( 'transforms a nested Columns block into a Group block', async () => { + await initializeEditor( { + initialHtml: ` +
    +
    +
    +

    +
    +
    +
    + `, + } ); + + // Get Columns block + const columnsBlock = await getBlock( screen, 'Columns' ); + fireEvent.press( columnsBlock ); + + // Open block actions menu + await openBlockActionsMenu( screen ); + + // Tap on the Transform block button + fireEvent.press( screen.getByLabelText( /Transform block…/ ) ); + + // Tap on the Group transform button + fireEvent.press( screen.getByLabelText( 'Group' ) ); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); } ); diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 7cb02a4848dd64..a9fa07190f2fcd 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -15,6 +15,7 @@ For each user feature we should also add a importance categorization label to i - [*] Improve horizontal rule styles to avoid invisible lines [#53883] - [*] Fix horizontal rule style extensions [#53917] - [*] Add block outline to all Social Link blocks when selected [#54011] +- [*] Columns block - Fix transforming into a Group block crash [#54035] ## 1.102.1 - [**] Fix Voice Over and assistive keyboards [#53895] diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js index e0c690b6282349..8b682ef005e496 100644 --- a/test/native/__mocks__/styleMock.js +++ b/test/native/__mocks__/styleMock.js @@ -204,4 +204,8 @@ module.exports = { }, picker: {}, pickerPointer: {}, + columnsContainer: { + marginLeft: 16, + minWidth: 32, + }, }; From 54103891010f05984e6751b4b1d33f048fd1900c Mon Sep 17 00:00:00 2001 From: merickarabulut <91661972+MericKarabulut@users.noreply.github.com> Date: Thu, 31 Aug 2023 01:39:28 +0300 Subject: [PATCH 41/56] Improving error messages and codes in jest-console, matcher.js (#53743) * code maintainability and error messages improved * code maintainability and error messages improved * Added changelog entry for recent changes. --- packages/jest-console/CHANGELOG.md | 4 ++ packages/jest-console/src/matchers.js | 84 +++++++++++++++------------ 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/packages/jest-console/CHANGELOG.md b/packages/jest-console/CHANGELOG.md index caa7f460f6f2b4..f5aa959e2542e7 100644 --- a/packages/jest-console/CHANGELOG.md +++ b/packages/jest-console/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- Improved error messages and codes printed on the console ([#53743](https://github.com/WordPress/gutenberg/pull/53743)). + ## 7.11.0 (2023-08-16) ## 7.10.0 (2023-08-10) diff --git a/packages/jest-console/src/matchers.js b/packages/jest-console/src/matchers.js index 078ef47fb1da55..9793164f532b32 100644 --- a/packages/jest-console/src/matchers.js +++ b/packages/jest-console/src/matchers.js @@ -8,58 +8,66 @@ import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; */ import supportedMatchers from './supported-matchers'; +const createErrorMessage = ( spyInfo ) => { + const { spy, pass, calls, matcherName, methodName, expected } = spyInfo; + const hint = pass ? `.not${ matcherName }` : matcherName; + const message = pass + ? `Expected mock function not to be called but it was called with:\n${ calls.map( + printReceived + ) }` + : `Expected mock function to be called${ + expected ? ` with:\n${ printExpected( expected ) }\n` : '.' + }\nbut it was called with:\n${ calls.map( printReceived ) }`; + + return () => + `${ matcherHint( hint, spy.getMockName() ) }` + + '\n\n' + + message + + '\n\n' + + `console.${ methodName }() should not be used unless explicitly expected\n` + + 'See https://www.npmjs.com/package/@wordpress/jest-console for details.'; +}; + +const createSpyInfo = ( spy, matcherName, methodName, expected ) => { + const calls = spy.mock.calls; + + const pass = expected + ? JSON.stringify( calls ).includes( JSON.stringify( expected ) ) + : calls.length > 0; + + const message = createErrorMessage( { + spy, + pass, + calls, + matcherName, + methodName, + expected, + } ); + + return { + pass, + message, + }; +}; + const createToHaveBeenCalledMatcher = ( matcherName, methodName ) => ( received ) => { const spy = received[ methodName ]; - const calls = spy.mock.calls; - const pass = calls.length > 0; - const message = pass - ? () => - matcherHint( `.not${ matcherName }`, spy.getMockName() ) + - '\n\n' + - 'Expected mock function not to be called but it was called with:\n' + - calls.map( printReceived ) - : () => - matcherHint( matcherName, spy.getMockName() ) + - '\n\n' + - 'Expected mock function to be called.'; + const spyInfo = createSpyInfo( spy, matcherName, methodName ); spy.assertionsNumber += 1; - return { - message, - pass, - }; + return spyInfo; }; const createToHaveBeenCalledWith = ( matcherName, methodName ) => function ( received, ...expected ) { const spy = received[ methodName ]; - const calls = spy.mock.calls; - const pass = calls.some( ( objects ) => - this.equals( objects, expected ) - ); - const message = pass - ? () => - matcherHint( `.not${ matcherName }`, spy.getMockName() ) + - '\n\n' + - 'Expected mock function not to be called with:\n' + - printExpected( expected ) - : () => - matcherHint( matcherName, spy.getMockName() ) + - '\n\n' + - 'Expected mock function to be called with:\n' + - printExpected( expected ) + - '\n' + - 'but it was called with:\n' + - calls.map( printReceived ); + const spyInfo = createSpyInfo( spy, matcherName, methodName, expected ); spy.assertionsNumber += 1; - return { - message, - pass, - }; + return spyInfo; }; expect.extend( From dcb4df603308c7737825fb3ba432a69feeca3011 Mon Sep 17 00:00:00 2001 From: annezazu Date: Wed, 30 Aug 2023 17:12:31 -0700 Subject: [PATCH 42/56] Update versions for 6.3.1 (#54069) --- docs/contributors/versions-in-wordpress.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/contributors/versions-in-wordpress.md b/docs/contributors/versions-in-wordpress.md index 6709d124b242b8..c4e25c3b2095eb 100644 --- a/docs/contributors/versions-in-wordpress.md +++ b/docs/contributors/versions-in-wordpress.md @@ -6,6 +6,7 @@ If anything looks incorrect here, please bring it up in #core-editor in [WordPre | Gutenberg Versions | WordPress Version | | ------------------ | ----------------- | +| 15.2-16.1 | 6.3.1 | | 15.2-16.1 | 6.3 | | 14.2-15.1 | 6.2 | | 13.1-14.1 | 6.1.1 | From d67a8d5852918a054bfa99de750bff91ca8f1e28 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 31 Aug 2023 05:30:58 +0100 Subject: [PATCH 43/56] Update the components changelog to mark the popover slot removal as a breaking change (#54022) --- packages/components/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 7dce9d2a315f4e..a12e300ad4724b 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,9 +2,12 @@ ## Unreleased +### Breaking changes + +- Make the `Popover.Slot` optional and render popovers at the bottom of the document's body by default. ([#53889](https://github.com/WordPress/gutenberg/pull/53889), [#53982](https://github.com/WordPress/gutenberg/pull/53982)). + ### Enhancements -- Make the `Popover.Slot` optional and render popovers at the bottom of the document's body by default. ([#53889](https://github.com/WordPress/gutenberg/pull/53889)). - `ProgressBar`: Add transition to determinate indicator ([#53877](https://github.com/WordPress/gutenberg/pull/53877)). - Prevent nested `SlotFillProvider` from rendering ([#53940](https://github.com/WordPress/gutenberg/pull/53940)). From 3db444b6cbe8e67ee00cc43aca43b83300fa83dd Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Thu, 31 Aug 2023 07:53:47 +0200 Subject: [PATCH 44/56] Post navigation link: Fix the writing mode setting on the front. (#54053) Add style attributes to the wrapper in the index.php file --- .../block-library/src/post-navigation-link/index.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/post-navigation-link/index.php b/packages/block-library/src/post-navigation-link/index.php index cb066ad69f2c5d..8b5d82e745aeed 100644 --- a/packages/block-library/src/post-navigation-link/index.php +++ b/packages/block-library/src/post-navigation-link/index.php @@ -28,7 +28,16 @@ function render_block_core_post_navigation_link( $attributes, $content ) { if ( isset( $attributes['textAlign'] ) ) { $classes .= " has-text-align-{$attributes['textAlign']}"; } - $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) ); + $styles = ''; + if ( isset( $attributes['style']['typography']['writingMode'] ) ) { + $styles = "writing-mode:{$attributes['style']['typography']['writingMode']};"; + } + $wrapper_attributes = get_block_wrapper_attributes( + array( + 'class' => $classes, + 'style' => $styles, + ) + ); // Set default values. $format = '%link'; $link = 'next' === $navigation_type ? _x( 'Next', 'label for next post link' ) : _x( 'Previous', 'label for previous post link' ); From a8dbc883c4d68b6d025b91f763596206182bae6f Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:43:41 +1000 Subject: [PATCH 45/56] Design Tools: Add block instance elements support for buttons and headings (#53667) --- docs/reference-guides/core-blocks.md | 2 +- lib/block-supports/colors.php | 6 +- lib/block-supports/elements.php | 176 ++++++++++++++---- packages/block-editor/src/hooks/style.js | 120 ++++++++---- packages/block-editor/src/hooks/utils.js | 4 + packages/block-library/src/group/block.json | 1 + .../style-engine/class-wp-style-engine.php | 6 + 7 files changed, 238 insertions(+), 77 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 0f25cead8b07a9..7f66c40bb00ba8 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -302,7 +302,7 @@ Gather blocks in a layout container. ([Source](https://github.com/WordPress/gute - **Name:** core/group - **Category:** design -- **Supports:** align (full, wide), anchor, ariaLabel, color (background, gradients, heading, link, text), dimensions (minHeight), layout (allowSizingOnChildren), position (sticky), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~ +- **Supports:** align (full, wide), anchor, ariaLabel, color (background, button, gradients, heading, link, text), dimensions (minHeight), layout (allowSizingOnChildren), position (sticky), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~ - **Attributes:** allowedBlocks, tagName, templateLock ## Heading diff --git a/lib/block-supports/colors.php b/lib/block-supports/colors.php index 7ec32bf14d7537..88e13abfc9cc9b 100644 --- a/lib/block-supports/colors.php +++ b/lib/block-supports/colors.php @@ -16,10 +16,14 @@ function gutenberg_register_colors_support( $block_type ) { $has_background_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'background' ), true ) ); $has_gradients_support = _wp_array_get( $color_support, array( 'gradients' ), false ); $has_link_colors_support = _wp_array_get( $color_support, array( 'link' ), false ); + $has_button_colors_support = _wp_array_get( $color_support, array( 'button' ), false ); + $has_heading_colors_support = _wp_array_get( $color_support, array( 'heading' ), false ); $has_color_support = $has_text_colors_support || $has_background_colors_support || $has_gradients_support || - $has_link_colors_support; + $has_link_colors_support || + $has_button_colors_support || + $has_heading_colors_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); diff --git a/lib/block-supports/elements.php b/lib/block-supports/elements.php index d4502aaa2e4785..4029c91aa40a35 100644 --- a/lib/block-supports/elements.php +++ b/lib/block-supports/elements.php @@ -23,34 +23,79 @@ function gutenberg_get_elements_class_name( $block ) { * @return string Filtered block content. */ function gutenberg_render_elements_support( $block_content, $block ) { - if ( ! $block_content ) { + if ( ! $block_content || empty( $block['attrs'] ) ) { return $block_content; } - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); - $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); + + $element_color_properties = array( + 'button' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ), + 'paths' => array( + 'style.elements.button.color.text', + 'style.elements.button.color.background', + 'style.elements.button.color.gradient', + ), + ), + 'link' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ), + 'paths' => array( + 'style.elements.link.color.text', + 'style.elements.link.:hover.color.text', + ), + ), + 'heading' => array( + 'skip' => wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ), + 'paths' => array( + 'style.elements.heading.color.text', + 'style.elements.heading.color.background', + 'style.elements.heading.color.gradient', + 'style.elements.h1.color.text', + 'style.elements.h1.color.background', + 'style.elements.h1.color.gradient', + 'style.elements.h2.color.text', + 'style.elements.h2.color.background', + 'style.elements.h2.color.gradient', + 'style.elements.h3.color.text', + 'style.elements.h3.color.background', + 'style.elements.h3.color.gradient', + 'style.elements.h4.color.text', + 'style.elements.h4.color.background', + 'style.elements.h4.color.gradient', + 'style.elements.h5.color.text', + 'style.elements.h5.color.background', + 'style.elements.h5.color.gradient', + 'style.elements.h6.color.text', + 'style.elements.h6.color.background', + 'style.elements.h6.color.gradient', + ), + ), + ); + + $skip_all_element_color_serialization = $element_color_properties['button']['skip'] && + $element_color_properties['link']['skip'] && + $element_color_properties['heading']['skip']; - if ( $skip_link_color_serialization ) { + if ( $skip_all_element_color_serialization ) { return $block_content; } - $link_color = null; - if ( ! empty( $block['attrs'] ) ) { - $link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', 'color', 'text' ), null ); - } + $element_colors_set = 0; + + foreach ( $element_color_properties as $element_config ) { + if ( $element_config['skip'] ) { + continue; + } - $hover_link_color = null; - if ( ! empty( $block['attrs'] ) ) { - $hover_link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', ':hover', 'color', 'text' ), null ); + foreach ( $element_config['paths'] as $path ) { + if ( null !== _wp_array_get( $block['attrs'], explode( '.', $path ), null ) ) { + $element_colors_set++; + } + } } - /* - * For now we only care about link colors. - * This code in the future when we have a public API - * should take advantage of WP_Theme_JSON_Gutenberg::compute_style_properties - * and work for any element and style. - */ - if ( null === $link_color && null === $hover_link_color ) { + if ( ! $element_colors_set ) { return $block_content; } @@ -80,33 +125,84 @@ function gutenberg_render_elements_support_styles( $pre_render, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $element_block_styles = isset( $block['attrs']['style']['elements'] ) ? $block['attrs']['style']['elements'] : null; - /* - * For now we only care about link color. - */ - $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); + if ( ! $element_block_styles ) { + return null; + } - if ( $skip_link_color_serialization ) { + $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); + $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); + $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); + $skips_all_element_color_serialization = $skip_link_color_serialization && + $skip_heading_color_serialization && + $skip_button_color_serialization; + + if ( $skips_all_element_color_serialization ) { return null; } - $class_name = gutenberg_get_elements_class_name( $block ); - $link_block_styles = isset( $element_block_styles['link'] ) ? $element_block_styles['link'] : null; - - gutenberg_style_engine_get_styles( - $link_block_styles, - array( - 'selector' => ".$class_name a", - 'context' => 'block-supports', - ) + + $class_name = gutenberg_get_elements_class_name( $block ); + + $element_types = array( + 'button' => array( + 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", + 'skip' => $skip_button_color_serialization, + ), + 'link' => array( + 'selector' => ".$class_name a", + 'hover_selector' => ".$class_name a:hover", + 'skip' => $skip_link_color_serialization, + ), + 'heading' => array( + 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", + 'skip' => $skip_heading_color_serialization, + 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), + ), ); - if ( isset( $link_block_styles[':hover'] ) ) { - gutenberg_style_engine_get_styles( - $link_block_styles[':hover'], - array( - 'selector' => ".$class_name a:hover", - 'context' => 'block-supports', - ) - ); + foreach ( $element_types as $element_type => $element_config ) { + if ( $element_config['skip'] ) { + continue; + } + + $element_style_object = _wp_array_get( $element_block_styles, array( $element_type ), null ); + + // Process primary element type styles. + if ( $element_style_object ) { + gutenberg_style_engine_get_styles( + $element_style_object, + array( + 'selector' => $element_config['selector'], + 'context' => 'block-supports', + ) + ); + + if ( isset( $element_style_object[':hover'] ) ) { + gutenberg_style_engine_get_styles( + $element_style_object[':hover'], + array( + 'selector' => $element_config['hover_selector'], + 'context' => 'block-supports', + ) + ); + } + } + + // Process related elements e.g. h1-h6 for headings. + if ( isset( $element_config['elements'] ) ) { + foreach ( $element_config['elements'] as $element ) { + $element_style_object = _wp_array_get( $element_block_styles, array( $element ), null ); + + if ( $element_style_object ) { + gutenberg_style_engine_get_styles( + $element_style_object, + array( + 'selector' => ".$class_name $element", + 'context' => 'block-supports', + ) + ); + } + } + } } return null; diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index b416c86405e512..e165a888822948 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -34,6 +34,7 @@ import { } from './dimensions'; import useDisplayBlockControls from '../components/use-display-block-controls'; import { shouldSkipSerialization } from './utils'; +import { scopeSelector } from '../components/global-styles/utils'; import { useBlockEditingMode } from '../components/block-editing-mode'; const styleSupportKeys = [ @@ -371,6 +372,18 @@ export const withBlockControls = createHigherOrderComponent( 'withToolbarControls' ); +// Defines which element types are supported, including their hover styles or +// any other elements that have been included under a single element type +// e.g. heading and h1-h6. +const elementTypes = [ + { elementType: 'button' }, + { elementType: 'link', pseudo: [ ':hover' ] }, + { + elementType: 'heading', + elements: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], + }, +]; + /** * Override the default block element to include elements styles. * @@ -383,47 +396,84 @@ const withElementsStyles = createHigherOrderComponent( BlockListBlock ) }`; - const skipLinkColorSerialization = shouldSkipSerialization( - props.name, - COLOR_SUPPORT_KEY, - 'link' - ); + // The .editor-styles-wrapper selector is required on elements styles. As it is + // added to all other editor styles, not providing it causes reset and global + // styles to override element styles because of higher specificity. + const baseElementSelector = `.editor-styles-wrapper .${ blockElementsContainerIdentifier }`; + const blockElementStyles = props.attributes.style?.elements; const styles = useMemo( () => { - // The .editor-styles-wrapper selector is required on elements styles. As it is - // added to all other editor styles, not providing it causes reset and global - // styles to override element styles because of higher specificity. - const elements = [ - { - styles: ! skipLinkColorSerialization - ? props.attributes.style?.elements?.link - : undefined, - selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS.link }`, - }, - { - styles: ! skipLinkColorSerialization - ? props.attributes.style?.elements?.link?.[ ':hover' ] - : undefined, - selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS.link }:hover`, - }, - ]; - const elementCssRules = []; - for ( const { styles: elementStyles, selector } of elements ) { + if ( ! blockElementStyles ) { + return; + } + + const elementCSSRules = []; + + elementTypes.forEach( ( { elementType, pseudo, elements } ) => { + const skipSerialization = shouldSkipSerialization( + props.name, + COLOR_SUPPORT_KEY, + elementType + ); + + if ( skipSerialization ) { + return; + } + + const elementStyles = blockElementStyles?.[ elementType ]; + + // Process primary element type styles. if ( elementStyles ) { - const cssRule = compileCSS( elementStyles, { - selector, + const selector = scopeSelector( + baseElementSelector, + ELEMENTS[ elementType ] + ); + + elementCSSRules.push( + compileCSS( elementStyles, { selector } ) + ); + + // Process any interactive states for the element type. + if ( pseudo ) { + pseudo.forEach( ( pseudoSelector ) => { + if ( elementStyles[ pseudoSelector ] ) { + elementCSSRules.push( + compileCSS( + elementStyles[ pseudoSelector ], + { + selector: scopeSelector( + baseElementSelector, + `${ ELEMENTS[ elementType ] }${ pseudoSelector }` + ), + } + ) + ); + } + } ); + } + } + + // Process related elements e.g. h1-h6 for headings + if ( elements ) { + elements.forEach( ( element ) => { + if ( blockElementStyles[ element ] ) { + elementCSSRules.push( + compileCSS( blockElementStyles[ element ], { + selector: scopeSelector( + baseElementSelector, + ELEMENTS[ element ] + ), + } ) + ); + } } ); - elementCssRules.push( cssRule ); } - } - return elementCssRules.length > 0 - ? elementCssRules.join( '' ) + } ); + + return elementCSSRules.length > 0 + ? elementCSSRules.join( '' ) : undefined; - }, [ - props.attributes.style?.elements, - blockElementsContainerIdentifier, - skipLinkColorSerialization, - ] ); + }, [ baseElementSelector, blockElementStyles, props.name ] ); const element = useContext( BlockList.__unstableElementContext ); diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 9c6bf957d61c51..f81fc118ea84bb 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -166,6 +166,8 @@ export function useBlockSettings( name, parentLayout ) { const isBackgroundEnabled = useSetting( 'color.background' ); const isLinkEnabled = useSetting( 'color.link' ); const isTextEnabled = useSetting( 'color.text' ); + const isHeadingEnabled = useSetting( 'color.heading' ); + const isButtonEnabled = useSetting( 'color.button' ); const rawSettings = useMemo( () => { return { @@ -193,6 +195,8 @@ export function useBlockSettings( name, parentLayout ) { customDuotone, background: isBackgroundEnabled, link: isLinkEnabled, + heading: isHeadingEnabled, + button: isButtonEnabled, text: isTextEnabled, }, typography: { diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index 4f8de8802ea70c..9c2d012620c3c1 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -31,6 +31,7 @@ "color": { "gradients": true, "heading": true, + "button": true, "link": true, "__experimentalDefaultControls": { "background": true, diff --git a/packages/style-engine/class-wp-style-engine.php b/packages/style-engine/class-wp-style-engine.php index 7304b57ec56123..283601e551c98f 100644 --- a/packages/style-engine/class-wp-style-engine.php +++ b/packages/style-engine/class-wp-style-engine.php @@ -60,6 +60,9 @@ final class WP_Style_Engine { 'default' => 'background-color', ), 'path' => array( 'color', 'background' ), + 'css_vars' => array( + 'color' => '--wp--preset--color--$slug', + ), 'classnames' => array( 'has-background' => true, 'has-$slug-background-color' => 'color', @@ -69,6 +72,9 @@ final class WP_Style_Engine { 'property_keys' => array( 'default' => 'background', ), + 'css_vars' => array( + 'gradient' => '--wp--preset--gradient--$slug', + ), 'path' => array( 'color', 'gradient' ), 'classnames' => array( 'has-background' => true, From e691d320e2a13ba4c514ca01d1a1400009d9ee2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Zi=C3=B3=C5=82kowski?= Date: Thu, 31 Aug 2023 11:09:01 +0200 Subject: [PATCH 46/56] Packages: Ensure that the release branch is fetched from origin during publishing Fixes the issue detected during the last attempt logged at https://github.com/WordPress/gutenberg/actions/runs/6027639373/job/16374862576. The exact message printed: "GitError: fatal: invalid reference: origin/release/16.6". --- bin/plugin/commands/packages.js | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/plugin/commands/packages.js b/bin/plugin/commands/packages.js index 87ecc6eb89cfca..4cf509764436c6 100644 --- a/bin/plugin/commands/packages.js +++ b/bin/plugin/commands/packages.js @@ -150,6 +150,7 @@ async function runNpmReleaseBranchSyncStep( pluginReleaseBranch, config ) { */ await repo .raw( 'rm', '-r', '.' ) + .fetch( 'origin', pluginReleaseBranch, [ '--depth=1' ] ) .raw( 'checkout', `origin/${ pluginReleaseBranch }`, '--', '.' ); const { commit: commitHash } = await repo.commit( From 5b42dda991a756b3a5f354ac58f200bc54759c75 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Thu, 31 Aug 2023 09:12:27 +0000 Subject: [PATCH 47/56] Update changelog files --- packages/a11y/CHANGELOG.md | 2 ++ packages/a11y/package.json | 2 +- packages/annotations/CHANGELOG.md | 2 ++ packages/annotations/package.json | 2 +- packages/api-fetch/CHANGELOG.md | 2 ++ packages/api-fetch/package.json | 2 +- packages/autop/CHANGELOG.md | 2 ++ packages/autop/package.json | 2 +- packages/babel-plugin-import-jsx-pragma/CHANGELOG.md | 2 ++ packages/babel-plugin-import-jsx-pragma/package.json | 2 +- packages/babel-plugin-makepot/CHANGELOG.md | 2 ++ packages/babel-plugin-makepot/package.json | 2 +- packages/babel-preset-default/CHANGELOG.md | 2 ++ packages/babel-preset-default/package.json | 2 +- packages/base-styles/CHANGELOG.md | 2 ++ packages/base-styles/package.json | 2 +- packages/blob/CHANGELOG.md | 2 ++ packages/blob/package.json | 2 +- packages/block-directory/CHANGELOG.md | 2 ++ packages/block-directory/package.json | 2 +- packages/block-editor/CHANGELOG.md | 2 ++ packages/block-editor/package.json | 2 +- packages/block-library/CHANGELOG.md | 2 ++ packages/block-library/package.json | 2 +- packages/block-serialization-default-parser/CHANGELOG.md | 2 ++ packages/block-serialization-default-parser/package.json | 2 +- packages/block-serialization-spec-parser/CHANGELOG.md | 2 ++ packages/block-serialization-spec-parser/package.json | 2 +- packages/blocks/CHANGELOG.md | 2 ++ packages/blocks/package.json | 2 +- packages/browserslist-config/CHANGELOG.md | 2 ++ packages/browserslist-config/package.json | 2 +- packages/commands/CHANGELOG.md | 2 ++ packages/commands/package.json | 2 +- packages/components/CHANGELOG.md | 2 ++ packages/components/package.json | 2 +- packages/compose/CHANGELOG.md | 2 ++ packages/compose/package.json | 2 +- packages/core-commands/CHANGELOG.md | 2 ++ packages/core-commands/package.json | 2 +- packages/core-data/CHANGELOG.md | 2 ++ packages/core-data/package.json | 2 +- packages/create-block-interactive-template/CHANGELOG.md | 2 ++ packages/create-block-interactive-template/package.json | 2 +- packages/create-block-tutorial-template/CHANGELOG.md | 2 ++ packages/create-block-tutorial-template/package.json | 2 +- packages/create-block/CHANGELOG.md | 2 ++ packages/create-block/package.json | 2 +- packages/customize-widgets/CHANGELOG.md | 2 ++ packages/customize-widgets/package.json | 2 +- packages/data-controls/CHANGELOG.md | 2 ++ packages/data-controls/package.json | 2 +- packages/data/CHANGELOG.md | 2 ++ packages/data/package.json | 2 +- packages/date/CHANGELOG.md | 2 ++ packages/date/package.json | 2 +- packages/dependency-extraction-webpack-plugin/CHANGELOG.md | 2 ++ packages/dependency-extraction-webpack-plugin/package.json | 2 +- packages/deprecated/CHANGELOG.md | 2 ++ packages/deprecated/package.json | 2 +- packages/docgen/CHANGELOG.md | 2 ++ packages/docgen/package.json | 2 +- packages/dom-ready/CHANGELOG.md | 2 ++ packages/dom-ready/package.json | 2 +- packages/dom/CHANGELOG.md | 2 ++ packages/dom/package.json | 2 +- packages/e2e-test-utils-playwright/CHANGELOG.md | 2 ++ packages/e2e-test-utils-playwright/package.json | 2 +- packages/e2e-test-utils/CHANGELOG.md | 2 ++ packages/e2e-test-utils/package.json | 2 +- packages/e2e-tests/CHANGELOG.md | 2 ++ packages/e2e-tests/package.json | 2 +- packages/edit-post/CHANGELOG.md | 2 ++ packages/edit-post/package.json | 2 +- packages/edit-site/CHANGELOG.md | 2 ++ packages/edit-site/package.json | 2 +- packages/edit-widgets/CHANGELOG.md | 2 ++ packages/edit-widgets/package.json | 2 +- packages/editor/CHANGELOG.md | 2 ++ packages/editor/package.json | 2 +- packages/element/CHANGELOG.md | 2 ++ packages/element/package.json | 2 +- packages/env/CHANGELOG.md | 2 ++ packages/env/package.json | 2 +- packages/escape-html/CHANGELOG.md | 2 ++ packages/escape-html/package.json | 2 +- packages/eslint-plugin/CHANGELOG.md | 2 ++ packages/eslint-plugin/package.json | 2 +- packages/format-library/CHANGELOG.md | 2 ++ packages/format-library/package.json | 2 +- packages/hooks/CHANGELOG.md | 2 ++ packages/hooks/package.json | 2 +- packages/html-entities/CHANGELOG.md | 2 ++ packages/html-entities/package.json | 2 +- packages/i18n/CHANGELOG.md | 2 ++ packages/i18n/package.json | 2 +- packages/icons/CHANGELOG.md | 2 ++ packages/icons/package.json | 2 +- packages/interactivity/CHANGELOG.md | 2 ++ packages/interactivity/package.json | 2 +- packages/interface/CHANGELOG.md | 2 ++ packages/interface/package.json | 2 +- packages/is-shallow-equal/CHANGELOG.md | 2 ++ packages/is-shallow-equal/package.json | 2 +- packages/jest-console/CHANGELOG.md | 6 ++++-- packages/jest-console/package.json | 2 +- packages/jest-preset-default/CHANGELOG.md | 2 ++ packages/jest-preset-default/package.json | 2 +- packages/jest-puppeteer-axe/CHANGELOG.md | 2 ++ packages/jest-puppeteer-axe/package.json | 2 +- packages/keyboard-shortcuts/CHANGELOG.md | 2 ++ packages/keyboard-shortcuts/package.json | 2 +- packages/keycodes/CHANGELOG.md | 2 ++ packages/keycodes/package.json | 2 +- packages/lazy-import/CHANGELOG.md | 2 ++ packages/lazy-import/package.json | 2 +- packages/list-reusable-blocks/CHANGELOG.md | 2 ++ packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/CHANGELOG.md | 2 ++ packages/media-utils/package.json | 2 +- packages/notices/CHANGELOG.md | 2 ++ packages/notices/package.json | 2 +- packages/npm-package-json-lint-config/CHANGELOG.md | 2 ++ packages/npm-package-json-lint-config/package.json | 2 +- packages/nux/CHANGELOG.md | 2 ++ packages/nux/package.json | 2 +- packages/patterns/CHANGELOG.md | 2 ++ packages/patterns/package.json | 2 +- packages/plugins/CHANGELOG.md | 2 ++ packages/plugins/package.json | 2 +- packages/postcss-plugins-preset/CHANGELOG.md | 2 ++ packages/postcss-plugins-preset/package.json | 2 +- packages/postcss-themes/CHANGELOG.md | 2 ++ packages/postcss-themes/package.json | 2 +- packages/preferences-persistence/CHANGELOG.md | 2 ++ packages/preferences-persistence/package.json | 2 +- packages/preferences/CHANGELOG.md | 2 ++ packages/preferences/package.json | 2 +- packages/prettier-config/CHANGELOG.md | 2 ++ packages/prettier-config/package.json | 2 +- packages/primitives/CHANGELOG.md | 2 ++ packages/primitives/package.json | 2 +- packages/priority-queue/CHANGELOG.md | 2 ++ packages/priority-queue/package.json | 2 +- packages/private-apis/CHANGELOG.md | 2 ++ packages/private-apis/package.json | 2 +- packages/project-management-automation/CHANGELOG.md | 2 ++ packages/project-management-automation/package.json | 2 +- packages/react-i18n/CHANGELOG.md | 2 ++ packages/react-i18n/package.json | 2 +- packages/readable-js-assets-webpack-plugin/CHANGELOG.md | 2 ++ packages/readable-js-assets-webpack-plugin/package.json | 2 +- packages/redux-routine/CHANGELOG.md | 2 ++ packages/redux-routine/package.json | 2 +- packages/reusable-blocks/CHANGELOG.md | 2 ++ packages/reusable-blocks/package.json | 2 +- packages/rich-text/CHANGELOG.md | 2 ++ packages/rich-text/package.json | 2 +- packages/router/CHANGELOG.md | 2 ++ packages/router/package.json | 2 +- packages/scripts/CHANGELOG.md | 2 ++ packages/scripts/package.json | 2 +- packages/server-side-render/CHANGELOG.md | 2 ++ packages/server-side-render/package.json | 2 +- packages/shortcode/CHANGELOG.md | 2 ++ packages/shortcode/package.json | 2 +- packages/style-engine/CHANGELOG.md | 2 ++ packages/style-engine/package.json | 2 +- packages/stylelint-config/CHANGELOG.md | 2 ++ packages/stylelint-config/package.json | 2 +- packages/sync/CHANGELOG.md | 2 ++ packages/sync/package.json | 2 +- packages/token-list/CHANGELOG.md | 2 ++ packages/token-list/package.json | 2 +- packages/url/CHANGELOG.md | 2 ++ packages/url/package.json | 2 +- packages/viewport/CHANGELOG.md | 2 ++ packages/viewport/package.json | 2 +- packages/warning/CHANGELOG.md | 2 ++ packages/warning/package.json | 2 +- packages/widgets/CHANGELOG.md | 2 ++ packages/widgets/package.json | 2 +- packages/wordcount/CHANGELOG.md | 2 ++ packages/wordcount/package.json | 2 +- 184 files changed, 278 insertions(+), 94 deletions(-) diff --git a/packages/a11y/CHANGELOG.md b/packages/a11y/CHANGELOG.md index dbfbf491522039..011948dfe9f34b 100644 --- a/packages/a11y/CHANGELOG.md +++ b/packages/a11y/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index d37f77eddb36aa..837633b0a97ea8 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/CHANGELOG.md b/packages/annotations/CHANGELOG.md index c57f7caff11a39..6bd4cdaa1ee8f7 100644 --- a/packages/annotations/CHANGELOG.md +++ b/packages/annotations/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.41.0 (2023-08-31) + ## 2.40.0 (2023-08-16) ## 2.39.0 (2023-08-10) diff --git a/packages/annotations/package.json b/packages/annotations/package.json index 2cadc82cb2f4e2..b3e444e85499fa 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "2.40.0", + "version": "2.41.0-prerelease", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index 6bcbbbc76bc02a..8deb000c264f8b 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.38.0 (2023-08-31) + ## 6.37.0 (2023-08-16) ## 6.36.0 (2023-08-10) diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index b4f51ad8930462..7d9425fe0a968a 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "6.37.0", + "version": "6.38.0-prerelease", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/CHANGELOG.md b/packages/autop/CHANGELOG.md index 4cd68bcfd4bb29..ebe2a449d26b80 100644 --- a/packages/autop/CHANGELOG.md +++ b/packages/autop/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/autop/package.json b/packages/autop/package.json index b60fcc15cec5d3..c9534a7ea36fce 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md index 5f1bfd8bfde9d0..003b6f4e215a52 100644 --- a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md +++ b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.24.0 (2023-08-31) + ## 4.23.0 (2023-08-16) ## 4.22.0 (2023-08-10) diff --git a/packages/babel-plugin-import-jsx-pragma/package.json b/packages/babel-plugin-import-jsx-pragma/package.json index 478bbc3856e242..dfb6a5ce615585 100644 --- a/packages/babel-plugin-import-jsx-pragma/package.json +++ b/packages/babel-plugin-import-jsx-pragma/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-import-jsx-pragma", - "version": "4.23.0", + "version": "4.24.0-prerelease", "description": "Babel transform plugin for automatically injecting an import to be used as the pragma for the React JSX Transform plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-makepot/CHANGELOG.md b/packages/babel-plugin-makepot/CHANGELOG.md index 5c2ce02f635793..b8f66bb633d2bc 100644 --- a/packages/babel-plugin-makepot/CHANGELOG.md +++ b/packages/babel-plugin-makepot/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.25.0 (2023-08-31) + ## 5.24.0 (2023-08-16) ## 5.23.0 (2023-08-10) diff --git a/packages/babel-plugin-makepot/package.json b/packages/babel-plugin-makepot/package.json index d3912b587721f5..5315010b8c4421 100644 --- a/packages/babel-plugin-makepot/package.json +++ b/packages/babel-plugin-makepot/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-makepot", - "version": "5.24.0", + "version": "5.25.0-prerelease", "description": "WordPress Babel internationalization (i18n) plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/CHANGELOG.md b/packages/babel-preset-default/CHANGELOG.md index f66a844f8f6413..dbf4cdc7eafa95 100644 --- a/packages/babel-preset-default/CHANGELOG.md +++ b/packages/babel-preset-default/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.25.0 (2023-08-31) + ## 7.24.0 (2023-08-16) ## 7.23.0 (2023-08-10) diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index ee62386610e720..949d0495a0fbce 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "7.24.0", + "version": "7.25.0-prerelease", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/CHANGELOG.md b/packages/base-styles/CHANGELOG.md index 59dba998089a83..525dd6f7713ca2 100644 --- a/packages/base-styles/CHANGELOG.md +++ b/packages/base-styles/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.32.0 (2023-08-31) + ## 4.31.0 (2023-08-16) ## 4.30.0 (2023-08-10) diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json index c1639194eb4e9d..6bfa5e33056353 100644 --- a/packages/base-styles/package.json +++ b/packages/base-styles/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/base-styles", - "version": "4.31.0", + "version": "4.32.0-prerelease", "description": "Base SCSS utilities and variables for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 1c73ea77fbd6d7..ea3944697d7f3f 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/blob/package.json b/packages/blob/package.json index b3a398881a5283..705fe60013633d 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/CHANGELOG.md b/packages/block-directory/CHANGELOG.md index ad6cba079850b1..800ee154682131 100644 --- a/packages/block-directory/CHANGELOG.md +++ b/packages/block-directory/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index b90a0a38e1c4e7..fc14b4ce524cf4 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index c74c20d6f21aed..63a6281f78b426 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 12.9.0 (2023-08-31) + ### Enhancements - Embed the `ObserveTyping` behavior within the `BlockList` component making to simplify instanciations of third-party block editors. diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 8e25e6f6496545..4b70c30e946eb2 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "12.8.0", + "version": "12.9.0-prerelease", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index a7fe0bd99bd4a0..e31c8ba509518f 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.18.0 (2023-08-31) + ## 8.17.0 (2023-08-16) ## 8.16.0 (2023-08-10) diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 5fe213651f54a8..c9031f8f2d6cf8 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "8.17.0", + "version": "8.18.0-prerelease", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-default-parser/CHANGELOG.md b/packages/block-serialization-default-parser/CHANGELOG.md index c99b60550849e4..3a235ffe77b2cf 100644 --- a/packages/block-serialization-default-parser/CHANGELOG.md +++ b/packages/block-serialization-default-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index 0cda27b554e2e9..4727c4249d1409 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/CHANGELOG.md b/packages/block-serialization-spec-parser/CHANGELOG.md index 799f24ec663660..c760b228dc9f53 100644 --- a/packages/block-serialization-spec-parser/CHANGELOG.md +++ b/packages/block-serialization-spec-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index 7e39e035848be6..ea3adfe911d528 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 34c7f2c7ceb508..d843396d51504c 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 12.18.0 (2023-08-31) + ## 12.17.0 (2023-08-16) ## 12.16.0 (2023-08-10) diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 1dee1f1d4ae004..470b71c92de9f1 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "12.17.0", + "version": "12.18.0-prerelease", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/browserslist-config/CHANGELOG.md b/packages/browserslist-config/CHANGELOG.md index cd3e675cb577dc..a78c54cf9a6626 100644 --- a/packages/browserslist-config/CHANGELOG.md +++ b/packages/browserslist-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.24.0 (2023-08-31) + ## 5.23.0 (2023-08-16) ## 5.22.0 (2023-08-10) diff --git a/packages/browserslist-config/package.json b/packages/browserslist-config/package.json index 9136613a01dc2b..0283bd39a1e608 100644 --- a/packages/browserslist-config/package.json +++ b/packages/browserslist-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/browserslist-config", - "version": "5.23.0", + "version": "5.24.0-prerelease", "description": "WordPress Browserslist shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/commands/CHANGELOG.md b/packages/commands/CHANGELOG.md index 7eaf493e7ce98e..e3af451de196a0 100644 --- a/packages/commands/CHANGELOG.md +++ b/packages/commands/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.12.0 (2023-08-31) + ## 0.11.0 (2023-08-16) ## 0.10.0 (2023-08-10) diff --git a/packages/commands/package.json b/packages/commands/package.json index ea89a529dc4c47..52812c3297e9f6 100644 --- a/packages/commands/package.json +++ b/packages/commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/commands", - "version": "0.11.0", + "version": "0.12.0-prerelease", "description": "Handles the commands menu.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index a12e300ad4724b..be5608c72fc06d 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -6,6 +6,8 @@ - Make the `Popover.Slot` optional and render popovers at the bottom of the document's body by default. ([#53889](https://github.com/WordPress/gutenberg/pull/53889), [#53982](https://github.com/WordPress/gutenberg/pull/53982)). +## 25.7.0 (2023-08-31) + ### Enhancements - `ProgressBar`: Add transition to determinate indicator ([#53877](https://github.com/WordPress/gutenberg/pull/53877)). diff --git a/packages/components/package.json b/packages/components/package.json index 2a4f7c380ee979..a06d94e70e8861 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "25.6.0", + "version": "25.7.0-prerelease", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index c8db63936b6561..ab2f98424481d5 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.18.0 (2023-08-31) + ## 6.17.0 (2023-08-16) ## 6.16.0 (2023-08-10) diff --git a/packages/compose/package.json b/packages/compose/package.json index 0ae05b14739397..e862e30ea1c179 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "6.17.0", + "version": "6.18.0-prerelease", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-commands/CHANGELOG.md b/packages/core-commands/CHANGELOG.md index 9a5cabcae8392c..abf22fac3e2cab 100644 --- a/packages/core-commands/CHANGELOG.md +++ b/packages/core-commands/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.10.0 (2023-08-31) + ## 0.9.0 (2023-08-16) ## 0.8.0 (2023-08-10) diff --git a/packages/core-commands/package.json b/packages/core-commands/package.json index a802e4d384c500..8d408785583d86 100644 --- a/packages/core-commands/package.json +++ b/packages/core-commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-commands", - "version": "0.9.0", + "version": "0.10.0-prerelease", "description": "WordPress core reusable commands.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/CHANGELOG.md b/packages/core-data/CHANGELOG.md index 830aed362938c7..6e47bd2b3dd756 100644 --- a/packages/core-data/CHANGELOG.md +++ b/packages/core-data/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.18.0 (2023-08-31) + ## 6.17.0 (2023-08-16) ## 6.16.0 (2023-08-10) diff --git a/packages/core-data/package.json b/packages/core-data/package.json index 8bb83bfdbbf247..d7501a4c25e232 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "6.17.0", + "version": "6.18.0-prerelease", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block-interactive-template/CHANGELOG.md b/packages/create-block-interactive-template/CHANGELOG.md index e5c32350167c92..c423f364d62a46 100644 --- a/packages/create-block-interactive-template/CHANGELOG.md +++ b/packages/create-block-interactive-template/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.4.0 (2023-08-31) + ## 1.3.0 (2023-08-16) ## 1.2.0 (2023-08-10) diff --git a/packages/create-block-interactive-template/package.json b/packages/create-block-interactive-template/package.json index 8022c86ecb8a1c..92ea21667d39bb 100644 --- a/packages/create-block-interactive-template/package.json +++ b/packages/create-block-interactive-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-interactive-template", - "version": "1.3.0", + "version": "1.4.0-prerelease", "description": "Template for @wordpress/create-block to create interactive blocks with the Interactivity API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block-tutorial-template/CHANGELOG.md b/packages/create-block-tutorial-template/CHANGELOG.md index 8fc38debebc194..77d47333db0590 100644 --- a/packages/create-block-tutorial-template/CHANGELOG.md +++ b/packages/create-block-tutorial-template/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.29.0 (2023-08-31) + ## 2.28.0 (2023-08-16) ## 2.27.0 (2023-08-10) diff --git a/packages/create-block-tutorial-template/package.json b/packages/create-block-tutorial-template/package.json index cb48abc1d4650a..1c26630d1555d0 100644 --- a/packages/create-block-tutorial-template/package.json +++ b/packages/create-block-tutorial-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-tutorial-template", - "version": "2.28.0", + "version": "2.29.0-prerelease", "description": "Template for @wordpress/create-block used in the official WordPress tutorial.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block/CHANGELOG.md b/packages/create-block/CHANGELOG.md index af94e7a1400d38..202d1f774ac2b1 100644 --- a/packages/create-block/CHANGELOG.md +++ b/packages/create-block/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.25.0 (2023-08-31) + ## 4.24.0 (2023-08-16) ## 4.23.0 (2023-08-10) diff --git a/packages/create-block/package.json b/packages/create-block/package.json index 4dc0c99fd51c95..c005d4c27440ca 100644 --- a/packages/create-block/package.json +++ b/packages/create-block/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block", - "version": "4.24.0", + "version": "4.25.0-prerelease", "description": "Generates PHP, JS and CSS code for registering a block for a WordPress plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/CHANGELOG.md b/packages/customize-widgets/CHANGELOG.md index cd20fea8312055..d9ce39cbb68461 100644 --- a/packages/customize-widgets/CHANGELOG.md +++ b/packages/customize-widgets/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 497879afbf94e9..42cd5d209b783e 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data-controls/CHANGELOG.md b/packages/data-controls/CHANGELOG.md index 5cefd056155b9e..f5ed8ea0e7da43 100644 --- a/packages/data-controls/CHANGELOG.md +++ b/packages/data-controls/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.10.0 (2023-08-31) + ## 3.9.0 (2023-08-16) ## 3.8.0 (2023-08-10) diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index 71601bb4e08487..4911949ac90d7d 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "3.9.0", + "version": "3.10.0-prerelease", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/CHANGELOG.md b/packages/data/CHANGELOG.md index ba2abd614681fc..4d970465b7b9d4 100644 --- a/packages/data/CHANGELOG.md +++ b/packages/data/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 9.11.0 (2023-08-31) + ## 9.10.0 (2023-08-16) ### Enhancements diff --git a/packages/data/package.json b/packages/data/package.json index f6050a3abee341..5917feb3143cf7 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "9.10.0", + "version": "9.11.0-prerelease", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/date/CHANGELOG.md b/packages/date/CHANGELOG.md index 1ef50cd50cdee2..b12bf6a06a09ea 100644 --- a/packages/date/CHANGELOG.md +++ b/packages/date/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/date/package.json b/packages/date/package.json index 64f21a4b286fab..a3e1e721857d4a 100644 --- a/packages/date/package.json +++ b/packages/date/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/date", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "Date module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md index b5d33757b0e297..cdc42b5696a3d0 100644 --- a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md +++ b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.24.0 (2023-08-31) + ## 4.23.0 (2023-08-16) ## 4.22.0 (2023-08-10) diff --git a/packages/dependency-extraction-webpack-plugin/package.json b/packages/dependency-extraction-webpack-plugin/package.json index 874c28165c56f3..51e911fc11090f 100644 --- a/packages/dependency-extraction-webpack-plugin/package.json +++ b/packages/dependency-extraction-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dependency-extraction-webpack-plugin", - "version": "4.23.0", + "version": "4.24.0-prerelease", "description": "Extract WordPress script dependencies from webpack bundles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/deprecated/CHANGELOG.md b/packages/deprecated/CHANGELOG.md index 00ec41b9cb5e74..7df9106e59418e 100644 --- a/packages/deprecated/CHANGELOG.md +++ b/packages/deprecated/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index f5401e350629f3..d14453ac5b4279 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/docgen/CHANGELOG.md b/packages/docgen/CHANGELOG.md index 43e411ec15cdee..7a1c50c38231ce 100644 --- a/packages/docgen/CHANGELOG.md +++ b/packages/docgen/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.50.0 (2023-08-31) + ## 1.49.0 (2023-08-16) ## 1.48.0 (2023-08-10) diff --git a/packages/docgen/package.json b/packages/docgen/package.json index c3333e5adad4f0..4bfba69df01d51 100644 --- a/packages/docgen/package.json +++ b/packages/docgen/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/docgen", - "version": "1.49.0", + "version": "1.50.0-prerelease", "description": "Autogenerate public API documentation from exports and JSDoc comments.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/CHANGELOG.md b/packages/dom-ready/CHANGELOG.md index 7adb8755b8cc12..5713c42d33ecc2 100644 --- a/packages/dom-ready/CHANGELOG.md +++ b/packages/dom-ready/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 0dd190caf2ad52..6220897a8cf5cf 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md index dc51858e17ab2c..33b7597519dff4 100644 --- a/packages/dom/CHANGELOG.md +++ b/packages/dom/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/dom/package.json b/packages/dom/package.json index a7fec1b3e8b156..428004ba396151 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils-playwright/CHANGELOG.md b/packages/e2e-test-utils-playwright/CHANGELOG.md index d889a1751a2a8f..e698734ec7d3fb 100644 --- a/packages/e2e-test-utils-playwright/CHANGELOG.md +++ b/packages/e2e-test-utils-playwright/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.9.0 (2023-08-31) + ## 0.8.0 (2023-08-16) ## 0.7.0 (2023-08-10) diff --git a/packages/e2e-test-utils-playwright/package.json b/packages/e2e-test-utils-playwright/package.json index 584e90df0342ef..82579c877a9d0b 100644 --- a/packages/e2e-test-utils-playwright/package.json +++ b/packages/e2e-test-utils-playwright/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils-playwright", - "version": "0.8.0", + "version": "0.9.0-prerelease", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index ab52a15b3f7aa8..f75ecf987eb7ad 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 10.12.0 (2023-08-31) + ## 10.11.0 (2023-08-16) ## 10.10.0 (2023-08-10) diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 135e25517b59f7..e8058cb780e2c5 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "10.11.0", + "version": "10.12.0-prerelease", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/CHANGELOG.md b/packages/e2e-tests/CHANGELOG.md index 4dc2746182f9f5..6d5daa89447198 100644 --- a/packages/e2e-tests/CHANGELOG.md +++ b/packages/e2e-tests/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.12.0 (2023-08-31) + ## 7.11.0 (2023-08-16) ## 7.10.0 (2023-08-10) diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index f9ad6efcf0e2c3..9fc4ccf4ba7699 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "7.11.0", + "version": "7.12.0-prerelease", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index dc5f6267945b72..c56c3b968764ad 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.18.0 (2023-08-31) + ## 7.17.0 (2023-08-16) ## 7.16.0 (2023-08-10) diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index d3ac35d5012d94..e7d2c22af2dc27 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "7.17.0", + "version": "7.18.0-prerelease", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/CHANGELOG.md b/packages/edit-site/CHANGELOG.md index 2a904820625175..452755b4557c75 100644 --- a/packages/edit-site/CHANGELOG.md +++ b/packages/edit-site/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.18.0 (2023-08-31) + ## 5.17.0 (2023-08-16) ## 5.16.0 (2023-08-10) diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index e0f9ac3dfcb5c3..ae0ca530a288b4 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "5.17.0", + "version": "5.18.0-prerelease", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/CHANGELOG.md b/packages/edit-widgets/CHANGELOG.md index 995ba74ef66eeb..13d457c8fa4573 100644 --- a/packages/edit-widgets/CHANGELOG.md +++ b/packages/edit-widgets/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.18.0 (2023-08-31) + ## 5.17.0 (2023-08-16) ## 5.16.0 (2023-08-10) diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 0e4fb70d95f2cd..61545a5f40ce38 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "5.17.0", + "version": "5.18.0-prerelease", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 2a7d933ad5c667..30c51d93f23b3b 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 13.18.0 (2023-08-31) + ## 13.17.0 (2023-08-16) ## 13.16.0 (2023-08-10) diff --git a/packages/editor/package.json b/packages/editor/package.json index ba7cba3fa03e5e..bb39cfdec2d086 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "13.17.0", + "version": "13.18.0-prerelease", "description": "Enhanced block editor for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/CHANGELOG.md b/packages/element/CHANGELOG.md index 6e1c9539740b5b..e49a949134f370 100644 --- a/packages/element/CHANGELOG.md +++ b/packages/element/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.18.0 (2023-08-31) + ## 5.17.0 (2023-08-16) ## 5.16.0 (2023-08-10) diff --git a/packages/element/package.json b/packages/element/package.json index 102874371d4cfe..89cf2c0d996c2c 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "5.17.0", + "version": "5.18.0-prerelease", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index c909b2654acaa0..52b7f97b82ac9e 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.7.0 (2023-08-31) + ## 8.6.0 (2023-08-16) ## 8.5.0 (2023-08-10) diff --git a/packages/env/package.json b/packages/env/package.json index ba83d8c5b6ef11..33a81f2568f45e 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "8.6.0", + "version": "8.7.0-prerelease", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/escape-html/CHANGELOG.md b/packages/escape-html/CHANGELOG.md index 86320c1dd505de..fdbdc1d6ec4e5d 100644 --- a/packages/escape-html/CHANGELOG.md +++ b/packages/escape-html/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.41.0 (2023-08-31) + ## 2.40.0 (2023-08-16) ## 2.39.0 (2023-08-10) diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index c20e43f8fb32e0..0baf569edb8963 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "2.40.0", + "version": "2.41.0-prerelease", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index dc1ca8f9b3da2e..d8d39769a279be 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 15.1.0 (2023-08-31) + ## 15.0.0 (2023-08-16) ### Breaking Changes diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 6abf721e120105..71abe7e887e0a7 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/eslint-plugin", - "version": "15.0.0", + "version": "15.1.0-prerelease", "description": "ESLint plugin for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/CHANGELOG.md b/packages/format-library/CHANGELOG.md index d2aa5c66405ff7..d46aa5959d1a6a 100644 --- a/packages/format-library/CHANGELOG.md +++ b/packages/format-library/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 793ca7cbd9599f..88c10386e5a488 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 49c9320fd63ad9..8ad1d109473e2d 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 35218c60f5ff8b..e404ee67738068 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "WordPress hooks library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/html-entities/CHANGELOG.md b/packages/html-entities/CHANGELOG.md index ca3b32d6dd6b04..878c95e28be922 100644 --- a/packages/html-entities/CHANGELOG.md +++ b/packages/html-entities/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/html-entities/package.json b/packages/html-entities/package.json index 2484954ca5210b..63aad915a10f55 100644 --- a/packages/html-entities/package.json +++ b/packages/html-entities/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/html-entities", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "HTML entity utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md index 43676a827be9a8..a38f7ecd49edc2 100644 --- a/packages/i18n/CHANGELOG.md +++ b/packages/i18n/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 1b25f9a9fe2deb..30236afa6f83be 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/i18n", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "WordPress internationalization (i18n) library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index 7ce0c1bbfa3ffb..3c1715455ad497 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 9.32.0 (2023-08-31) + ### Bug Fix - Fixed invalid XML namespace on `alignJustify`, `customLink`, `mapMarker`, `postContent` and `title` ([#53955](https://github.com/WordPress/gutenberg/pull/53955)). diff --git a/packages/icons/package.json b/packages/icons/package.json index 8aa25cba5cb221..7199d55bdcd8ae 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/icons", - "version": "9.31.0", + "version": "9.32.0-prerelease", "description": "WordPress Icons package, based on dashicon.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 6a4565f3ad1833..636f78d3357cfc 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.2.0 (2023-08-31) + ### Enhancements - Support keys using `data-wp-key`. ([#53844](https://github.com/WordPress/gutenberg/pull/53844)) diff --git a/packages/interactivity/package.json b/packages/interactivity/package.json index 4903126004fc74..68a159473ace21 100644 --- a/packages/interactivity/package.json +++ b/packages/interactivity/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interactivity", - "version": "2.1.0", + "version": "2.2.0-prerelease", "description": "Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interface/CHANGELOG.md b/packages/interface/CHANGELOG.md index d378dfa6c7ca81..1dc013ea4d497d 100644 --- a/packages/interface/CHANGELOG.md +++ b/packages/interface/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.18.0 (2023-08-31) + ## 5.17.0 (2023-08-16) ## 5.16.0 (2023-08-10) diff --git a/packages/interface/package.json b/packages/interface/package.json index 55de7645dff678..5f4591f77f075d 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interface", - "version": "5.17.0", + "version": "5.18.0-prerelease", "description": "Interface module for WordPress. The package contains shared functionality across the modern JavaScript-based WordPress screens.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/is-shallow-equal/CHANGELOG.md b/packages/is-shallow-equal/CHANGELOG.md index 057275132433e2..8ce603c82a3b5f 100644 --- a/packages/is-shallow-equal/CHANGELOG.md +++ b/packages/is-shallow-equal/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index 17c3f85398a02e..fdc8de459ef907 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-console/CHANGELOG.md b/packages/jest-console/CHANGELOG.md index f5aa959e2542e7..6a97368b82762f 100644 --- a/packages/jest-console/CHANGELOG.md +++ b/packages/jest-console/CHANGELOG.md @@ -4,7 +4,9 @@ ### Enhancement -- Improved error messages and codes printed on the console ([#53743](https://github.com/WordPress/gutenberg/pull/53743)). +- Improved error messages and codes printed on the console ([#53743](https://github.com/WordPress/gutenberg/pull/53743)). + +## 7.12.0 (2023-08-31) ## 7.11.0 (2023-08-16) @@ -32,7 +34,7 @@ ### Breaking Changes -- Started requiring Jest v29 instead of v27 as a peer dependency. See [breaking changes in Jest 28](https://jestjs.io/blog/2022/04/25/jest-28) and [in jest 29](https://jestjs.io/blog/2022/08/25/jest-29) ([#47388](https://github.com/WordPress/gutenberg/pull/47388)) +- Started requiring Jest v29 instead of v27 as a peer dependency. See [breaking changes in Jest 28](https://jestjs.io/blog/2022/04/25/jest-28) and [in jest 29](https://jestjs.io/blog/2022/08/25/jest-29) ([#47388](https://github.com/WordPress/gutenberg/pull/47388)) ## 6.11.0 (2023-03-01) diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index 9c5433c632173d..24c264f8123252 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-console", - "version": "7.11.0", + "version": "7.12.0-prerelease", "description": "Custom Jest matchers for the Console object.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-preset-default/CHANGELOG.md b/packages/jest-preset-default/CHANGELOG.md index 77f8976807d96a..e206afd899930f 100644 --- a/packages/jest-preset-default/CHANGELOG.md +++ b/packages/jest-preset-default/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 11.12.0 (2023-08-31) + ## 11.11.0 (2023-08-16) ## 11.10.0 (2023-08-10) diff --git a/packages/jest-preset-default/package.json b/packages/jest-preset-default/package.json index 61f5e3590ce85c..2c53457515d98b 100644 --- a/packages/jest-preset-default/package.json +++ b/packages/jest-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-preset-default", - "version": "11.11.0", + "version": "11.12.0-prerelease", "description": "Default Jest preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-puppeteer-axe/CHANGELOG.md b/packages/jest-puppeteer-axe/CHANGELOG.md index aa77aa43d54033..22ca105f55dd2a 100644 --- a/packages/jest-puppeteer-axe/CHANGELOG.md +++ b/packages/jest-puppeteer-axe/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.12.0 (2023-08-31) + ## 6.11.0 (2023-08-16) ## 6.10.0 (2023-08-10) diff --git a/packages/jest-puppeteer-axe/package.json b/packages/jest-puppeteer-axe/package.json index 0145bf3c1e3ab0..717d4279571f54 100644 --- a/packages/jest-puppeteer-axe/package.json +++ b/packages/jest-puppeteer-axe/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-puppeteer-axe", - "version": "6.11.0", + "version": "6.12.0-prerelease", "description": "Axe API integration with Jest and Puppeteer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keyboard-shortcuts/CHANGELOG.md b/packages/keyboard-shortcuts/CHANGELOG.md index ef50c5f3c1594f..858c80ffce79a7 100644 --- a/packages/keyboard-shortcuts/CHANGELOG.md +++ b/packages/keyboard-shortcuts/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/keyboard-shortcuts/package.json b/packages/keyboard-shortcuts/package.json index 1c87e9b72eac9d..3de49133c9e13c 100644 --- a/packages/keyboard-shortcuts/package.json +++ b/packages/keyboard-shortcuts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keyboard-shortcuts", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Handling keyboard shortcuts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keycodes/CHANGELOG.md b/packages/keycodes/CHANGELOG.md index 8b166452f814ab..7c8f372643b739 100644 --- a/packages/keycodes/CHANGELOG.md +++ b/packages/keycodes/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index e3923149b7b3bb..e2c206c33bfc29 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/lazy-import/CHANGELOG.md b/packages/lazy-import/CHANGELOG.md index 8960e4cf55f09c..65b4dca4ab1607 100644 --- a/packages/lazy-import/CHANGELOG.md +++ b/packages/lazy-import/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.28.0 (2023-08-31) + ## 1.27.0 (2023-08-16) ## 1.26.0 (2023-08-10) diff --git a/packages/lazy-import/package.json b/packages/lazy-import/package.json index 28e2366de98414..4725970c1fdac1 100644 --- a/packages/lazy-import/package.json +++ b/packages/lazy-import/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/lazy-import", - "version": "1.27.0", + "version": "1.28.0-prerelease", "description": "Lazily import a module, installing it automatically if missing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/CHANGELOG.md b/packages/list-reusable-blocks/CHANGELOG.md index 9db39b32d6b101..b1812c42dbc009 100644 --- a/packages/list-reusable-blocks/CHANGELOG.md +++ b/packages/list-reusable-blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index f55344e7838d15..532f929eecbbc1 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/CHANGELOG.md b/packages/media-utils/CHANGELOG.md index 6421e4238cdd92..435a971621d90e 100644 --- a/packages/media-utils/CHANGELOG.md +++ b/packages/media-utils/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.32.0 (2023-08-31) + ## 4.31.0 (2023-08-16) ## 4.30.0 (2023-08-10) diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index fcfbd1e9edff8a..0869be440f1b9a 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "4.31.0", + "version": "4.32.0-prerelease", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/CHANGELOG.md b/packages/notices/CHANGELOG.md index 51ac0b28d96445..a4b42df832dcbb 100644 --- a/packages/notices/CHANGELOG.md +++ b/packages/notices/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.9.0 (2023-08-31) + ## 4.8.0 (2023-08-16) ## 4.7.0 (2023-08-10) diff --git a/packages/notices/package.json b/packages/notices/package.json index 67a1dc161add61..f129e65344c991 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "4.8.0", + "version": "4.9.0-prerelease", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/npm-package-json-lint-config/CHANGELOG.md b/packages/npm-package-json-lint-config/CHANGELOG.md index cb8971f86de4f9..63e6266d9bbfb2 100644 --- a/packages/npm-package-json-lint-config/CHANGELOG.md +++ b/packages/npm-package-json-lint-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.26.0 (2023-08-31) + ## 4.25.0 (2023-08-16) ### Enhancement diff --git a/packages/npm-package-json-lint-config/package.json b/packages/npm-package-json-lint-config/package.json index 8a5e2993ee2bdf..7747193e297714 100644 --- a/packages/npm-package-json-lint-config/package.json +++ b/packages/npm-package-json-lint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/npm-package-json-lint-config", - "version": "4.25.0", + "version": "4.26.0-prerelease", "description": "WordPress npm-package-json-lint shareable configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/CHANGELOG.md b/packages/nux/CHANGELOG.md index 5fda6a3c01ac01..1514e24433eeff 100644 --- a/packages/nux/CHANGELOG.md +++ b/packages/nux/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.3.0 (2023-08-31) + ## 8.2.0 (2023-08-16) ## 8.1.0 (2023-08-10) diff --git a/packages/nux/package.json b/packages/nux/package.json index 64d56e80ac0ec8..d1bda5c1452cd6 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "8.2.0", + "version": "8.3.0-prerelease", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/patterns/CHANGELOG.md b/packages/patterns/CHANGELOG.md index 694450fd27090c..19a81007d00567 100644 --- a/packages/patterns/CHANGELOG.md +++ b/packages/patterns/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.2.0 (2023-08-31) + ## 1.1.0 (2023-08-16) Initial release. diff --git a/packages/patterns/package.json b/packages/patterns/package.json index 59a783cc436b59..52f61e45e8ef9b 100644 --- a/packages/patterns/package.json +++ b/packages/patterns/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/patterns", - "version": "1.1.0", + "version": "1.2.0-prerelease", "description": "Management of user pattern editing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/plugins/CHANGELOG.md b/packages/plugins/CHANGELOG.md index 2fe5c6cca77b88..8a1dc3dcd8c23e 100644 --- a/packages/plugins/CHANGELOG.md +++ b/packages/plugins/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.9.0 (2023-08-31) + ## 6.8.0 (2023-08-16) ## 6.7.0 (2023-08-10) diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 83a3cf295447a3..f3effbc5086793 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "6.8.0", + "version": "6.9.0-prerelease", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-plugins-preset/CHANGELOG.md b/packages/postcss-plugins-preset/CHANGELOG.md index b9e20bdb6fc0e2..a482f56dc53416 100644 --- a/packages/postcss-plugins-preset/CHANGELOG.md +++ b/packages/postcss-plugins-preset/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.25.0 (2023-08-31) + ## 4.24.0 (2023-08-16) ## 4.23.0 (2023-08-10) diff --git a/packages/postcss-plugins-preset/package.json b/packages/postcss-plugins-preset/package.json index 642fd74ff72e9f..14ed00e50cf6f6 100644 --- a/packages/postcss-plugins-preset/package.json +++ b/packages/postcss-plugins-preset/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-plugins-preset", - "version": "4.24.0", + "version": "4.25.0-prerelease", "description": "PostCSS sharable plugins preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-themes/CHANGELOG.md b/packages/postcss-themes/CHANGELOG.md index 4bde8d7a96fe24..eb571d1a74fa2d 100644 --- a/packages/postcss-themes/CHANGELOG.md +++ b/packages/postcss-themes/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.24.0 (2023-08-31) + ## 5.23.0 (2023-08-16) ## 5.22.0 (2023-08-10) diff --git a/packages/postcss-themes/package.json b/packages/postcss-themes/package.json index 278a50a6c14d22..bcdd0613e46391 100644 --- a/packages/postcss-themes/package.json +++ b/packages/postcss-themes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-themes", - "version": "5.23.0", + "version": "5.24.0-prerelease", "description": "PostCSS plugin to generate theme colors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences-persistence/CHANGELOG.md b/packages/preferences-persistence/CHANGELOG.md index 2ce6d991ba5ad2..5718f3d30dcf0e 100644 --- a/packages/preferences-persistence/CHANGELOG.md +++ b/packages/preferences-persistence/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.33.0 (2023-08-31) + ## 1.32.0 (2023-08-16) ## 1.31.0 (2023-08-10) diff --git a/packages/preferences-persistence/package.json b/packages/preferences-persistence/package.json index d43098c3908c4f..2c9ab6789998d0 100644 --- a/packages/preferences-persistence/package.json +++ b/packages/preferences-persistence/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences-persistence", - "version": "1.32.0", + "version": "1.33.0-prerelease", "description": "Persistence utilities for `wordpress/preferences`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences/CHANGELOG.md b/packages/preferences/CHANGELOG.md index cf151618f2e357..053ad37366324e 100644 --- a/packages/preferences/CHANGELOG.md +++ b/packages/preferences/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.18.0 (2023-08-31) + ## 3.17.0 (2023-08-16) ## 3.16.0 (2023-08-10) diff --git a/packages/preferences/package.json b/packages/preferences/package.json index a452fea6f113bd..e7bbeeb246b054 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences", - "version": "3.17.0", + "version": "3.18.0-prerelease", "description": "Utilities for managing WordPress preferences.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/prettier-config/CHANGELOG.md b/packages/prettier-config/CHANGELOG.md index 96744789fa9e56..ca25b1f957347e 100644 --- a/packages/prettier-config/CHANGELOG.md +++ b/packages/prettier-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.24.0 (2023-08-31) + ## 2.23.0 (2023-08-16) ## 2.22.0 (2023-08-10) diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json index 32d0d1347f62c6..56b7a522df2be8 100644 --- a/packages/prettier-config/package.json +++ b/packages/prettier-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/prettier-config", - "version": "2.23.0", + "version": "2.24.0-prerelease", "description": "WordPress Prettier shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/primitives/CHANGELOG.md b/packages/primitives/CHANGELOG.md index 9fa6f6f9dc02b2..6beb37c1b9dd8a 100644 --- a/packages/primitives/CHANGELOG.md +++ b/packages/primitives/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.39.0 (2023-08-31) + ## 3.38.0 (2023-08-16) ## 3.37.0 (2023-08-10) diff --git a/packages/primitives/package.json b/packages/primitives/package.json index 05167c44277594..c6c4f997df19d0 100644 --- a/packages/primitives/package.json +++ b/packages/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/primitives", - "version": "3.38.0", + "version": "3.39.0-prerelease", "description": "WordPress cross-platform primitives.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/priority-queue/CHANGELOG.md b/packages/priority-queue/CHANGELOG.md index 7b256496708d6a..40fc696323955c 100644 --- a/packages/priority-queue/CHANGELOG.md +++ b/packages/priority-queue/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.41.0 (2023-08-31) + ## 2.40.0 (2023-08-16) ## 2.39.0 (2023-08-10) diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index 94e68e7c7ce1b5..777a0ffe4e4014 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "2.40.0", + "version": "2.41.0-prerelease", "description": "Generic browser priority queue.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/private-apis/CHANGELOG.md b/packages/private-apis/CHANGELOG.md index 59966f0881d651..e21054feb4bdea 100644 --- a/packages/private-apis/CHANGELOG.md +++ b/packages/private-apis/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.23.0 (2023-08-31) + ## 0.22.0 (2023-08-16) ## 0.21.0 (2023-08-10) diff --git a/packages/private-apis/package.json b/packages/private-apis/package.json index 78afafd14a6192..2a4ea80bf268cc 100644 --- a/packages/private-apis/package.json +++ b/packages/private-apis/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/private-apis", - "version": "0.22.0", + "version": "0.23.0-prerelease", "description": "Internal experimental APIs for WordPress core.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/project-management-automation/CHANGELOG.md b/packages/project-management-automation/CHANGELOG.md index bdb4343242f423..bbee02666f64e2 100644 --- a/packages/project-management-automation/CHANGELOG.md +++ b/packages/project-management-automation/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.40.0 (2023-08-31) + ## 1.39.0 (2023-08-16) ## 1.38.0 (2023-08-10) diff --git a/packages/project-management-automation/package.json b/packages/project-management-automation/package.json index 0d426fab0dc28f..4848ed96f40e0d 100644 --- a/packages/project-management-automation/package.json +++ b/packages/project-management-automation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/project-management-automation", - "version": "1.39.0", + "version": "1.40.0-prerelease", "description": "GitHub Action that implements various automation to assist with managing the Gutenberg GitHub repository.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/react-i18n/CHANGELOG.md b/packages/react-i18n/CHANGELOG.md index 9da0ce01a7deac..f9a4be68245c3a 100644 --- a/packages/react-i18n/CHANGELOG.md +++ b/packages/react-i18n/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.39.0 (2023-08-31) + ## 3.38.0 (2023-08-16) ## 3.37.0 (2023-08-10) diff --git a/packages/react-i18n/package.json b/packages/react-i18n/package.json index 185d009525530f..d4269c65259da6 100644 --- a/packages/react-i18n/package.json +++ b/packages/react-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-i18n", - "version": "3.38.0", + "version": "3.39.0-prerelease", "description": "React bindings for @wordpress/i18n.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/readable-js-assets-webpack-plugin/CHANGELOG.md b/packages/readable-js-assets-webpack-plugin/CHANGELOG.md index d762a1ee4aff27..213e4269dfb09f 100644 --- a/packages/readable-js-assets-webpack-plugin/CHANGELOG.md +++ b/packages/readable-js-assets-webpack-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.24.0 (2023-08-31) + ## 2.23.0 (2023-08-16) ## 2.22.0 (2023-08-10) diff --git a/packages/readable-js-assets-webpack-plugin/package.json b/packages/readable-js-assets-webpack-plugin/package.json index 7099596310c4d8..3b85ff6731f022 100644 --- a/packages/readable-js-assets-webpack-plugin/package.json +++ b/packages/readable-js-assets-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/readable-js-assets-webpack-plugin", - "version": "2.23.0", + "version": "2.24.0-prerelease", "description": "Generate a readable JS file for each JS asset.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/redux-routine/CHANGELOG.md b/packages/redux-routine/CHANGELOG.md index 050b18e2d0fa4b..d48813aeaf577f 100644 --- a/packages/redux-routine/CHANGELOG.md +++ b/packages/redux-routine/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.41.0 (2023-08-31) + ## 4.40.0 (2023-08-16) ## 4.39.0 (2023-08-10) diff --git a/packages/redux-routine/package.json b/packages/redux-routine/package.json index 66e8d2406cbad7..d32bd95ee5ab28 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "4.40.0", + "version": "4.41.0-prerelease", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/CHANGELOG.md b/packages/reusable-blocks/CHANGELOG.md index 1960e2b9987c07..724be83d370e85 100644 --- a/packages/reusable-blocks/CHANGELOG.md +++ b/packages/reusable-blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index 3ef73b83a49f20..1bd14c5b30116a 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/CHANGELOG.md b/packages/rich-text/CHANGELOG.md index db497e6bc6f40c..15294e759c6eee 100644 --- a/packages/rich-text/CHANGELOG.md +++ b/packages/rich-text/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.18.0 (2023-08-31) + ## 6.17.0 (2023-08-16) ## 6.16.0 (2023-08-10) diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index 6a92d30e008b38..23affc1b33919d 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "6.17.0", + "version": "6.18.0-prerelease", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md index 228169a90570de..435d0af0463156 100644 --- a/packages/router/CHANGELOG.md +++ b/packages/router/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.10.0 (2023-08-31) + ## 0.9.0 (2023-08-16) ## 0.8.0 (2023-08-10) diff --git a/packages/router/package.json b/packages/router/package.json index 2906fef9cd8a94..9055184b97d322 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/router", - "version": "0.9.0", + "version": "0.10.0-prerelease", "description": "Router API for WordPress pages.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 48bd891edc2dd5..b7dce7e73cf585 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 26.12.0 (2023-08-31) + ## 26.11.0 (2023-08-16) ### Enhancement diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 3410c6e4d9e650..1a8688b28417eb 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "26.11.0", + "version": "26.12.0-prerelease", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/CHANGELOG.md b/packages/server-side-render/CHANGELOG.md index c6d734e9367601..bee32324689bbb 100644 --- a/packages/server-side-render/CHANGELOG.md +++ b/packages/server-side-render/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.18.0 (2023-08-31) + ## 4.17.0 (2023-08-16) ## 4.16.0 (2023-08-10) diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index a2d1f596cbb780..9da663ea3c1ff3 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "4.17.0", + "version": "4.18.0-prerelease", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/shortcode/CHANGELOG.md b/packages/shortcode/CHANGELOG.md index 75fda3827e6e0c..44164e747e75b1 100644 --- a/packages/shortcode/CHANGELOG.md +++ b/packages/shortcode/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/shortcode/package.json b/packages/shortcode/package.json index 940eba49cd28ab..f2caf9c90f3f1d 100644 --- a/packages/shortcode/package.json +++ b/packages/shortcode/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/shortcode", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "Shortcode module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/style-engine/CHANGELOG.md b/packages/style-engine/CHANGELOG.md index fbf1aa1eb6ba95..48030434c19496 100644 --- a/packages/style-engine/CHANGELOG.md +++ b/packages/style-engine/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.24.0 (2023-08-31) + ## 1.23.0 (2023-08-16) ## 1.22.0 (2023-08-10) diff --git a/packages/style-engine/package.json b/packages/style-engine/package.json index 30b1c2a1c8036c..e0489f43380a00 100644 --- a/packages/style-engine/package.json +++ b/packages/style-engine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/style-engine", - "version": "1.23.0", + "version": "1.24.0-prerelease", "description": "A suite of parsers and compilers for WordPress styles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/stylelint-config/CHANGELOG.md b/packages/stylelint-config/CHANGELOG.md index 697007028d26d9..2c15a878361212 100644 --- a/packages/stylelint-config/CHANGELOG.md +++ b/packages/stylelint-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 21.24.0 (2023-08-31) + ## 21.23.0 (2023-08-16) ## 21.22.0 (2023-08-10) diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json index 9255a5eae9f5ef..586ecb152c40ee 100644 --- a/packages/stylelint-config/package.json +++ b/packages/stylelint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/stylelint-config", - "version": "21.23.0", + "version": "21.24.0-prerelease", "description": "stylelint config for WordPress development.", "author": "The WordPress Contributors", "license": "MIT", diff --git a/packages/sync/CHANGELOG.md b/packages/sync/CHANGELOG.md index 4cae82da1cac88..cca705e0ec86d4 100644 --- a/packages/sync/CHANGELOG.md +++ b/packages/sync/CHANGELOG.md @@ -2,4 +2,6 @@ ## Unreleased +## 0.3.0 (2023-08-31) + ## 0.2.0 (2023-08-16) diff --git a/packages/sync/package.json b/packages/sync/package.json index 04e7355f14ead5..8469d6703fe1f2 100644 --- a/packages/sync/package.json +++ b/packages/sync/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/sync", - "version": "0.2.0", + "version": "0.3.0-prerelease", "description": "Sync Data.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/token-list/CHANGELOG.md b/packages/token-list/CHANGELOG.md index 741560797cac38..a3709066a1e240 100644 --- a/packages/token-list/CHANGELOG.md +++ b/packages/token-list/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.41.0 (2023-08-31) + ## 2.40.0 (2023-08-16) ## 2.39.0 (2023-08-10) diff --git a/packages/token-list/package.json b/packages/token-list/package.json index 978a3810233149..36b2d9a76612a7 100644 --- a/packages/token-list/package.json +++ b/packages/token-list/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/token-list", - "version": "2.40.0", + "version": "2.41.0-prerelease", "description": "Constructable, plain JavaScript DOMTokenList implementation, supporting non-browser runtimes.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index e51bf2521f7d22..cfeede0f278533 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.42.0 (2023-08-31) + ## 3.41.0 (2023-08-16) ## 3.40.0 (2023-08-10) diff --git a/packages/url/package.json b/packages/url/package.json index e0aee8699528d3..8e56d357a34d6d 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "3.41.0", + "version": "3.42.0-prerelease", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/viewport/CHANGELOG.md b/packages/viewport/CHANGELOG.md index eb1fb65de3bb4e..812b195c768f56 100644 --- a/packages/viewport/CHANGELOG.md +++ b/packages/viewport/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.18.0 (2023-08-31) + ## 5.17.0 (2023-08-16) ## 5.16.0 (2023-08-10) diff --git a/packages/viewport/package.json b/packages/viewport/package.json index 981e39c3527ff0..ba1b78792b3918 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "5.17.0", + "version": "5.18.0-prerelease", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/warning/CHANGELOG.md b/packages/warning/CHANGELOG.md index 93d9395d68c251..6a7154ccdbdc3c 100644 --- a/packages/warning/CHANGELOG.md +++ b/packages/warning/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.41.0 (2023-08-31) + ## 2.40.0 (2023-08-16) ## 2.39.0 (2023-08-10) diff --git a/packages/warning/package.json b/packages/warning/package.json index 09a83537ec8c6d..58c50aed2da90a 100644 --- a/packages/warning/package.json +++ b/packages/warning/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/warning", - "version": "2.40.0", + "version": "2.41.0-prerelease", "description": "Warning utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/CHANGELOG.md b/packages/widgets/CHANGELOG.md index 856dc7555bad04..9307d83e42d221 100644 --- a/packages/widgets/CHANGELOG.md +++ b/packages/widgets/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.18.0 (2023-08-31) + ## 3.17.0 (2023-08-16) ## 3.16.0 (2023-08-10) diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 4650479b71b478..f63cb4cd38dd32 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "3.17.0", + "version": "3.18.0-prerelease", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/CHANGELOG.md b/packages/wordcount/CHANGELOG.md index d0b54b70a81d47..24fec1ce33086a 100644 --- a/packages/wordcount/CHANGELOG.md +++ b/packages/wordcount/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.41.0 (2023-08-31) + ## 3.40.0 (2023-08-16) ## 3.39.0 (2023-08-10) diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index f0f5cf017f7e1b..2579bdf7f63ac1 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "3.40.0", + "version": "3.41.0-prerelease", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From cc85f9b0055ab5d746d555d13de5d8ae627cad13 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Thu, 31 Aug 2023 09:14:51 +0000 Subject: [PATCH 48/56] chore(release): publish - @wordpress/a11y@3.41.0 - @wordpress/annotations@2.41.0 - @wordpress/api-fetch@6.38.0 - @wordpress/autop@3.41.0 - @wordpress/babel-plugin-import-jsx-pragma@4.24.0 - @wordpress/babel-plugin-makepot@5.25.0 - @wordpress/babel-preset-default@7.25.0 - @wordpress/base-styles@4.32.0 - @wordpress/blob@3.41.0 - @wordpress/block-directory@4.18.0 - @wordpress/block-editor@12.9.0 - @wordpress/block-library@8.18.0 - @wordpress/block-serialization-default-parser@4.41.0 - @wordpress/block-serialization-spec-parser@4.41.0 - @wordpress/blocks@12.18.0 - @wordpress/browserslist-config@5.24.0 - @wordpress/commands@0.12.0 - @wordpress/components@25.7.0 - @wordpress/compose@6.18.0 - @wordpress/core-commands@0.10.0 - @wordpress/core-data@6.18.0 - @wordpress/create-block@4.25.0 - @wordpress/create-block-interactive-template@1.4.0 - @wordpress/create-block-tutorial-template@2.29.0 - @wordpress/customize-widgets@4.18.0 - @wordpress/data@9.11.0 - @wordpress/data-controls@3.10.0 - @wordpress/date@4.41.0 - @wordpress/dependency-extraction-webpack-plugin@4.24.0 - @wordpress/deprecated@3.41.0 - @wordpress/docgen@1.50.0 - @wordpress/dom@3.41.0 - @wordpress/dom-ready@3.41.0 - @wordpress/e2e-test-utils@10.12.0 - @wordpress/e2e-test-utils-playwright@0.9.0 - @wordpress/e2e-tests@7.12.0 - @wordpress/edit-post@7.18.0 - @wordpress/edit-site@5.18.0 - @wordpress/edit-widgets@5.18.0 - @wordpress/editor@13.18.0 - @wordpress/element@5.18.0 - @wordpress/env@8.7.0 - @wordpress/escape-html@2.41.0 - @wordpress/eslint-plugin@15.1.0 - @wordpress/format-library@4.18.0 - @wordpress/hooks@3.41.0 - @wordpress/html-entities@3.41.0 - @wordpress/i18n@4.41.0 - @wordpress/icons@9.32.0 - @wordpress/interactivity@2.2.0 - @wordpress/interface@5.18.0 - @wordpress/is-shallow-equal@4.41.0 - @wordpress/jest-console@7.12.0 - @wordpress/jest-preset-default@11.12.0 - @wordpress/jest-puppeteer-axe@6.12.0 - @wordpress/keyboard-shortcuts@4.18.0 - @wordpress/keycodes@3.41.0 - @wordpress/lazy-import@1.28.0 - @wordpress/list-reusable-blocks@4.18.0 - @wordpress/media-utils@4.32.0 - @wordpress/notices@4.9.0 - @wordpress/npm-package-json-lint-config@4.26.0 - @wordpress/nux@8.3.0 - @wordpress/patterns@1.2.0 - @wordpress/plugins@6.9.0 - @wordpress/postcss-plugins-preset@4.25.0 - @wordpress/postcss-themes@5.24.0 - @wordpress/preferences@3.18.0 - @wordpress/preferences-persistence@1.33.0 - @wordpress/prettier-config@2.24.0 - @wordpress/primitives@3.39.0 - @wordpress/priority-queue@2.41.0 - @wordpress/private-apis@0.23.0 - @wordpress/project-management-automation@1.40.0 - @wordpress/react-i18n@3.39.0 - @wordpress/readable-js-assets-webpack-plugin@2.24.0 - @wordpress/redux-routine@4.41.0 - @wordpress/reusable-blocks@4.18.0 - @wordpress/rich-text@6.18.0 - @wordpress/router@0.10.0 - @wordpress/scripts@26.12.0 - @wordpress/server-side-render@4.18.0 - @wordpress/shortcode@3.41.0 - @wordpress/style-engine@1.24.0 - @wordpress/stylelint-config@21.24.0 - @wordpress/sync@0.3.0 - @wordpress/token-list@2.41.0 - @wordpress/url@3.42.0 - @wordpress/viewport@5.18.0 - @wordpress/warning@2.41.0 - @wordpress/widgets@3.18.0 - @wordpress/wordcount@3.41.0 --- package-lock.json | 182 +++++++++--------- packages/a11y/package.json | 2 +- packages/annotations/package.json | 2 +- packages/api-fetch/package.json | 2 +- packages/autop/package.json | 2 +- .../package.json | 2 +- packages/babel-plugin-makepot/package.json | 2 +- packages/babel-preset-default/package.json | 2 +- packages/base-styles/package.json | 2 +- packages/blob/package.json | 2 +- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- packages/blocks/package.json | 2 +- packages/browserslist-config/package.json | 2 +- packages/commands/package.json | 2 +- packages/components/package.json | 2 +- packages/compose/package.json | 2 +- packages/core-commands/package.json | 2 +- packages/core-data/package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- packages/create-block/package.json | 2 +- packages/customize-widgets/package.json | 2 +- packages/data-controls/package.json | 2 +- packages/data/package.json | 2 +- packages/date/package.json | 2 +- .../package.json | 2 +- packages/deprecated/package.json | 2 +- packages/docgen/package.json | 2 +- packages/dom-ready/package.json | 2 +- packages/dom/package.json | 2 +- .../e2e-test-utils-playwright/package.json | 2 +- packages/e2e-test-utils/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-site/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/element/package.json | 2 +- packages/env/package.json | 2 +- packages/escape-html/package.json | 2 +- packages/eslint-plugin/package.json | 2 +- packages/format-library/package.json | 2 +- packages/hooks/package.json | 2 +- packages/html-entities/package.json | 2 +- packages/i18n/package.json | 2 +- packages/icons/package.json | 2 +- packages/interactivity/package.json | 2 +- packages/interface/package.json | 2 +- packages/is-shallow-equal/package.json | 2 +- packages/jest-console/package.json | 2 +- packages/jest-preset-default/package.json | 2 +- packages/jest-puppeteer-axe/package.json | 2 +- packages/keyboard-shortcuts/package.json | 2 +- packages/keycodes/package.json | 2 +- packages/lazy-import/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/package.json | 2 +- packages/notices/package.json | 2 +- .../npm-package-json-lint-config/package.json | 2 +- packages/nux/package.json | 2 +- packages/patterns/package.json | 2 +- packages/plugins/package.json | 2 +- packages/postcss-plugins-preset/package.json | 2 +- packages/postcss-themes/package.json | 2 +- packages/preferences-persistence/package.json | 2 +- packages/preferences/package.json | 2 +- packages/prettier-config/package.json | 2 +- packages/primitives/package.json | 2 +- packages/priority-queue/package.json | 2 +- packages/private-apis/package.json | 2 +- .../package.json | 2 +- packages/react-i18n/package.json | 2 +- .../package.json | 2 +- packages/redux-routine/package.json | 2 +- packages/reusable-blocks/package.json | 2 +- packages/rich-text/package.json | 2 +- packages/router/package.json | 2 +- packages/scripts/package.json | 2 +- packages/server-side-render/package.json | 2 +- packages/shortcode/package.json | 2 +- packages/style-engine/package.json | 2 +- packages/stylelint-config/package.json | 2 +- packages/sync/package.json | 2 +- packages/token-list/package.json | 2 +- packages/url/package.json | 2 +- packages/viewport/package.json | 2 +- packages/warning/package.json | 2 +- packages/widgets/package.json | 2 +- packages/wordcount/package.json | 2 +- 93 files changed, 183 insertions(+), 183 deletions(-) diff --git a/package-lock.json b/package-lock.json index e70301a75ef61c..cabb3c8c18155b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54159,7 +54159,7 @@ }, "packages/a11y": { "name": "@wordpress/a11y", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54172,7 +54172,7 @@ }, "packages/annotations": { "name": "@wordpress/annotations", - "version": "2.40.0", + "version": "2.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54192,7 +54192,7 @@ }, "packages/api-fetch": { "name": "@wordpress/api-fetch", - "version": "6.37.0", + "version": "6.38.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54205,7 +54205,7 @@ }, "packages/autop": { "name": "@wordpress/autop", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54216,7 +54216,7 @@ }, "packages/babel-plugin-import-jsx-pragma": { "name": "@wordpress/babel-plugin-import-jsx-pragma", - "version": "4.23.0", + "version": "4.24.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -54228,7 +54228,7 @@ }, "packages/babel-plugin-makepot": { "name": "@wordpress/babel-plugin-makepot", - "version": "5.24.0", + "version": "5.25.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54245,7 +54245,7 @@ }, "packages/babel-preset-default": { "name": "@wordpress/babel-preset-default", - "version": "7.24.0", + "version": "7.25.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54268,13 +54268,13 @@ }, "packages/base-styles": { "name": "@wordpress/base-styles", - "version": "4.31.0", + "version": "4.32.0", "dev": true, "license": "GPL-2.0-or-later" }, "packages/blob": { "name": "@wordpress/blob", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54285,7 +54285,7 @@ }, "packages/block-directory": { "name": "@wordpress/block-directory", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54319,7 +54319,7 @@ }, "packages/block-editor": { "name": "@wordpress/block-editor", - "version": "12.8.0", + "version": "12.9.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54380,7 +54380,7 @@ }, "packages/block-library": { "name": "@wordpress/block-library", - "version": "8.17.0", + "version": "8.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54435,7 +54435,7 @@ }, "packages/block-serialization-default-parser": { "name": "@wordpress/block-serialization-default-parser", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54446,7 +54446,7 @@ }, "packages/block-serialization-spec-parser": { "name": "@wordpress/block-serialization-spec-parser", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "pegjs": "^0.10.0", @@ -54458,7 +54458,7 @@ }, "packages/blocks": { "name": "@wordpress/blocks", - "version": "12.17.0", + "version": "12.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54498,7 +54498,7 @@ }, "packages/browserslist-config": { "name": "@wordpress/browserslist-config", - "version": "5.23.0", + "version": "5.24.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -54507,7 +54507,7 @@ }, "packages/commands": { "name": "@wordpress/commands", - "version": "0.11.0", + "version": "0.12.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54532,7 +54532,7 @@ }, "packages/components": { "name": "@wordpress/components", - "version": "25.6.0", + "version": "25.7.0", "license": "GPL-2.0-or-later", "dependencies": { "@ariakit/react": "^0.2.12", @@ -54623,7 +54623,7 @@ }, "packages/compose": { "name": "@wordpress/compose", - "version": "6.17.0", + "version": "6.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54648,7 +54648,7 @@ }, "packages/core-commands": { "name": "@wordpress/core-commands", - "version": "0.9.0", + "version": "0.10.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54673,7 +54673,7 @@ }, "packages/core-data": { "name": "@wordpress/core-data", - "version": "6.17.0", + "version": "6.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54707,7 +54707,7 @@ }, "packages/create-block": { "name": "@wordpress/create-block", - "version": "4.24.0", + "version": "4.25.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54735,13 +54735,13 @@ }, "packages/create-block-tutorial-template": { "name": "@wordpress/create-block-tutorial-template", - "version": "2.28.0", + "version": "2.29.0", "dev": true, "license": "GPL-2.0-or-later" }, "packages/customize-widgets": { "name": "@wordpress/customize-widgets", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54778,7 +54778,7 @@ }, "packages/data": { "name": "@wordpress/data", - "version": "9.10.0", + "version": "9.11.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54806,7 +54806,7 @@ }, "packages/data-controls": { "name": "@wordpress/data-controls", - "version": "3.9.0", + "version": "3.10.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54823,7 +54823,7 @@ }, "packages/date": { "name": "@wordpress/date", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54837,7 +54837,7 @@ }, "packages/dependency-extraction-webpack-plugin": { "name": "@wordpress/dependency-extraction-webpack-plugin", - "version": "4.23.0", + "version": "4.24.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54853,7 +54853,7 @@ }, "packages/deprecated": { "name": "@wordpress/deprecated", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54865,7 +54865,7 @@ }, "packages/docgen": { "name": "@wordpress/docgen", - "version": "1.49.0", + "version": "1.50.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54883,7 +54883,7 @@ }, "packages/dom": { "name": "@wordpress/dom", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54895,7 +54895,7 @@ }, "packages/dom-ready": { "name": "@wordpress/dom-ready", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54906,7 +54906,7 @@ }, "packages/e2e-test-utils": { "name": "@wordpress/e2e-test-utils", - "version": "10.11.0", + "version": "10.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54928,7 +54928,7 @@ }, "packages/e2e-test-utils-playwright": { "name": "@wordpress/e2e-test-utils-playwright", - "version": "0.8.0", + "version": "0.9.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54948,7 +54948,7 @@ }, "packages/e2e-tests": { "name": "@wordpress/e2e-tests", - "version": "7.11.0", + "version": "7.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54977,7 +54977,7 @@ }, "packages/edit-post": { "name": "@wordpress/edit-post", - "version": "7.17.0", + "version": "7.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55025,7 +55025,7 @@ }, "packages/edit-site": { "name": "@wordpress/edit-site", - "version": "5.17.0", + "version": "5.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55089,7 +55089,7 @@ }, "packages/edit-widgets": { "name": "@wordpress/edit-widgets", - "version": "5.17.0", + "version": "5.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55131,7 +55131,7 @@ }, "packages/editor": { "name": "@wordpress/editor", - "version": "13.17.0", + "version": "13.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55181,7 +55181,7 @@ }, "packages/element": { "name": "@wordpress/element", - "version": "5.17.0", + "version": "5.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55199,7 +55199,7 @@ }, "packages/env": { "name": "@wordpress/env", - "version": "8.6.0", + "version": "8.7.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55312,7 +55312,7 @@ }, "packages/escape-html": { "name": "@wordpress/escape-html", - "version": "2.40.0", + "version": "2.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55323,7 +55323,7 @@ }, "packages/eslint-plugin": { "name": "@wordpress/eslint-plugin", - "version": "15.0.0", + "version": "15.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55365,7 +55365,7 @@ }, "packages/format-library": { "name": "@wordpress/format-library", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55391,7 +55391,7 @@ }, "packages/hooks": { "name": "@wordpress/hooks", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55402,7 +55402,7 @@ }, "packages/html-entities": { "name": "@wordpress/html-entities", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55413,7 +55413,7 @@ }, "packages/i18n": { "name": "@wordpress/i18n", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55432,7 +55432,7 @@ }, "packages/icons": { "name": "@wordpress/icons", - "version": "9.31.0", + "version": "9.32.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55445,7 +55445,7 @@ }, "packages/interactivity": { "name": "@wordpress/interactivity", - "version": "2.1.0", + "version": "2.2.0", "license": "GPL-2.0-or-later", "dependencies": { "@preact/signals": "^1.1.3", @@ -55458,7 +55458,7 @@ }, "packages/interface": { "name": "@wordpress/interface", - "version": "5.17.0", + "version": "5.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55485,7 +55485,7 @@ }, "packages/is-shallow-equal": { "name": "@wordpress/is-shallow-equal", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55496,7 +55496,7 @@ }, "packages/jest-console": { "name": "@wordpress/jest-console", - "version": "7.11.0", + "version": "7.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55512,7 +55512,7 @@ }, "packages/jest-preset-default": { "name": "@wordpress/jest-preset-default", - "version": "11.11.0", + "version": "11.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55529,7 +55529,7 @@ }, "packages/jest-puppeteer-axe": { "name": "@wordpress/jest-puppeteer-axe", - "version": "6.11.0", + "version": "6.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55551,7 +55551,7 @@ }, "packages/keyboard-shortcuts": { "name": "@wordpress/keyboard-shortcuts", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55569,7 +55569,7 @@ }, "packages/keycodes": { "name": "@wordpress/keycodes", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55582,7 +55582,7 @@ }, "packages/lazy-import": { "name": "@wordpress/lazy-import", - "version": "1.27.0", + "version": "1.28.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55596,7 +55596,7 @@ }, "packages/list-reusable-blocks": { "name": "@wordpress/list-reusable-blocks", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55617,7 +55617,7 @@ }, "packages/media-utils": { "name": "@wordpress/media-utils", - "version": "4.31.0", + "version": "4.32.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55632,7 +55632,7 @@ }, "packages/notices": { "name": "@wordpress/notices", - "version": "4.8.0", + "version": "4.9.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55648,7 +55648,7 @@ }, "packages/npm-package-json-lint-config": { "name": "@wordpress/npm-package-json-lint-config", - "version": "4.25.0", + "version": "4.26.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55660,7 +55660,7 @@ }, "packages/nux": { "name": "@wordpress/nux", - "version": "8.2.0", + "version": "8.3.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55683,7 +55683,7 @@ }, "packages/patterns": { "name": "@wordpress/patterns", - "version": "1.1.0", + "version": "1.2.0", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/block-editor": "file:../block-editor", @@ -55710,7 +55710,7 @@ }, "packages/plugins": { "name": "@wordpress/plugins", - "version": "6.8.0", + "version": "6.9.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55732,7 +55732,7 @@ }, "packages/postcss-plugins-preset": { "name": "@wordpress/postcss-plugins-preset", - "version": "4.24.0", + "version": "4.25.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55748,7 +55748,7 @@ }, "packages/postcss-themes": { "name": "@wordpress/postcss-themes", - "version": "5.23.0", + "version": "5.24.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55760,7 +55760,7 @@ }, "packages/preferences": { "name": "@wordpress/preferences", - "version": "3.17.0", + "version": "3.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55782,7 +55782,7 @@ }, "packages/preferences-persistence": { "name": "@wordpress/preferences-persistence", - "version": "1.32.0", + "version": "1.33.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55794,7 +55794,7 @@ }, "packages/prettier-config": { "name": "@wordpress/prettier-config", - "version": "2.23.0", + "version": "2.24.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55806,7 +55806,7 @@ }, "packages/primitives": { "name": "@wordpress/primitives", - "version": "3.38.0", + "version": "3.39.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55819,7 +55819,7 @@ }, "packages/priority-queue": { "name": "@wordpress/priority-queue", - "version": "2.40.0", + "version": "2.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55831,7 +55831,7 @@ }, "packages/private-apis": { "name": "@wordpress/private-apis", - "version": "0.22.0", + "version": "0.23.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55842,7 +55842,7 @@ }, "packages/project-management-automation": { "name": "@wordpress/project-management-automation", - "version": "1.39.0", + "version": "1.40.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55855,7 +55855,7 @@ }, "packages/react-i18n": { "name": "@wordpress/react-i18n", - "version": "3.38.0", + "version": "3.39.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55949,7 +55949,7 @@ }, "packages/readable-js-assets-webpack-plugin": { "name": "@wordpress/readable-js-assets-webpack-plugin", - "version": "2.23.0", + "version": "2.24.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55961,7 +55961,7 @@ }, "packages/redux-routine": { "name": "@wordpress/redux-routine", - "version": "4.40.0", + "version": "4.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56005,7 +56005,7 @@ }, "packages/reusable-blocks": { "name": "@wordpress/reusable-blocks", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56031,7 +56031,7 @@ }, "packages/rich-text": { "name": "@wordpress/rich-text", - "version": "6.17.0", + "version": "6.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56055,7 +56055,7 @@ }, "packages/router": { "name": "@wordpress/router", - "version": "0.9.0", + "version": "0.10.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56073,7 +56073,7 @@ }, "packages/scripts": { "name": "@wordpress/scripts", - "version": "26.11.0", + "version": "26.12.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -56148,7 +56148,7 @@ }, "packages/server-side-render": { "name": "@wordpress/server-side-render", - "version": "4.17.0", + "version": "4.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56173,7 +56173,7 @@ }, "packages/shortcode": { "name": "@wordpress/shortcode", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56185,7 +56185,7 @@ }, "packages/style-engine": { "name": "@wordpress/style-engine", - "version": "1.23.0", + "version": "1.24.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56197,7 +56197,7 @@ }, "packages/stylelint-config": { "name": "@wordpress/stylelint-config", - "version": "21.23.0", + "version": "21.24.0", "dev": true, "license": "MIT", "dependencies": { @@ -56213,7 +56213,7 @@ }, "packages/sync": { "name": "@wordpress/sync", - "version": "0.2.0", + "version": "0.3.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56227,7 +56227,7 @@ }, "packages/token-list": { "name": "@wordpress/token-list", - "version": "2.40.0", + "version": "2.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -56238,7 +56238,7 @@ }, "packages/url": { "name": "@wordpress/url", - "version": "3.41.0", + "version": "3.42.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56250,7 +56250,7 @@ }, "packages/viewport": { "name": "@wordpress/viewport", - "version": "5.17.0", + "version": "5.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56267,7 +56267,7 @@ }, "packages/warning": { "name": "@wordpress/warning", - "version": "2.40.0", + "version": "2.41.0", "license": "GPL-2.0-or-later", "engines": { "node": ">=12" @@ -56275,7 +56275,7 @@ }, "packages/widgets": { "name": "@wordpress/widgets", - "version": "3.17.0", + "version": "3.18.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -56299,7 +56299,7 @@ }, "packages/wordcount": { "name": "@wordpress/wordcount", - "version": "3.40.0", + "version": "3.41.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 837633b0a97ea8..6f2e9ca3d8e75b 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/package.json b/packages/annotations/package.json index b3e444e85499fa..faf9e4acf78e0f 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "2.41.0-prerelease", + "version": "2.41.0", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index 7d9425fe0a968a..12396223a7ec30 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "6.38.0-prerelease", + "version": "6.38.0", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/package.json b/packages/autop/package.json index c9534a7ea36fce..501b163c4341df 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-import-jsx-pragma/package.json b/packages/babel-plugin-import-jsx-pragma/package.json index dfb6a5ce615585..4a7e892fe52f07 100644 --- a/packages/babel-plugin-import-jsx-pragma/package.json +++ b/packages/babel-plugin-import-jsx-pragma/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-import-jsx-pragma", - "version": "4.24.0-prerelease", + "version": "4.24.0", "description": "Babel transform plugin for automatically injecting an import to be used as the pragma for the React JSX Transform plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-makepot/package.json b/packages/babel-plugin-makepot/package.json index 5315010b8c4421..aae54179b186ec 100644 --- a/packages/babel-plugin-makepot/package.json +++ b/packages/babel-plugin-makepot/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-makepot", - "version": "5.25.0-prerelease", + "version": "5.25.0", "description": "WordPress Babel internationalization (i18n) plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index 949d0495a0fbce..748c219e2a7e1d 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "7.25.0-prerelease", + "version": "7.25.0", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json index 6bfa5e33056353..1ff2b3a34e825e 100644 --- a/packages/base-styles/package.json +++ b/packages/base-styles/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/base-styles", - "version": "4.32.0-prerelease", + "version": "4.32.0", "description": "Base SCSS utilities and variables for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/package.json b/packages/blob/package.json index 705fe60013633d..7a317ee29affab 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index fc14b4ce524cf4..d8bf8bc0f3acb5 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 4b70c30e946eb2..50b58568b861db 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "12.9.0-prerelease", + "version": "12.9.0", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index c9031f8f2d6cf8..443c48f8bf4ef8 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "8.18.0-prerelease", + "version": "8.18.0", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index 4727c4249d1409..61741c4ca04120 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index ea3adfe911d528..ccdeee4fff5c30 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 470b71c92de9f1..71b560154223e0 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "12.18.0-prerelease", + "version": "12.18.0", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/browserslist-config/package.json b/packages/browserslist-config/package.json index 0283bd39a1e608..4490a5a949526d 100644 --- a/packages/browserslist-config/package.json +++ b/packages/browserslist-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/browserslist-config", - "version": "5.24.0-prerelease", + "version": "5.24.0", "description": "WordPress Browserslist shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/commands/package.json b/packages/commands/package.json index 52812c3297e9f6..5c33f43deb2e9b 100644 --- a/packages/commands/package.json +++ b/packages/commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/commands", - "version": "0.12.0-prerelease", + "version": "0.12.0", "description": "Handles the commands menu.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/package.json b/packages/components/package.json index a06d94e70e8861..cc4db850438b83 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "25.7.0-prerelease", + "version": "25.7.0", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/compose/package.json b/packages/compose/package.json index e862e30ea1c179..e8d98651f768be 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "6.18.0-prerelease", + "version": "6.18.0", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-commands/package.json b/packages/core-commands/package.json index 8d408785583d86..58698d98ce87a0 100644 --- a/packages/core-commands/package.json +++ b/packages/core-commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-commands", - "version": "0.10.0-prerelease", + "version": "0.10.0", "description": "WordPress core reusable commands.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/package.json b/packages/core-data/package.json index d7501a4c25e232..80bc41ff0a5afe 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "6.18.0-prerelease", + "version": "6.18.0", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block-interactive-template/package.json b/packages/create-block-interactive-template/package.json index 92ea21667d39bb..f91db15ecbf95e 100644 --- a/packages/create-block-interactive-template/package.json +++ b/packages/create-block-interactive-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-interactive-template", - "version": "1.4.0-prerelease", + "version": "1.4.0", "description": "Template for @wordpress/create-block to create interactive blocks with the Interactivity API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block-tutorial-template/package.json b/packages/create-block-tutorial-template/package.json index 1c26630d1555d0..a92a21fbc66cce 100644 --- a/packages/create-block-tutorial-template/package.json +++ b/packages/create-block-tutorial-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-tutorial-template", - "version": "2.29.0-prerelease", + "version": "2.29.0", "description": "Template for @wordpress/create-block used in the official WordPress tutorial.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block/package.json b/packages/create-block/package.json index c005d4c27440ca..0c5cf181700e01 100644 --- a/packages/create-block/package.json +++ b/packages/create-block/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block", - "version": "4.25.0-prerelease", + "version": "4.25.0", "description": "Generates PHP, JS and CSS code for registering a block for a WordPress plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 42cd5d209b783e..ae71dcb1d80693 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index 4911949ac90d7d..591c5113c56b1f 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "3.10.0-prerelease", + "version": "3.10.0", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/package.json b/packages/data/package.json index 5917feb3143cf7..b5c7737c2ba767 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "9.11.0-prerelease", + "version": "9.11.0", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/date/package.json b/packages/date/package.json index a3e1e721857d4a..d3f812ea68d360 100644 --- a/packages/date/package.json +++ b/packages/date/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/date", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "Date module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dependency-extraction-webpack-plugin/package.json b/packages/dependency-extraction-webpack-plugin/package.json index 51e911fc11090f..abf0c8182b9e8e 100644 --- a/packages/dependency-extraction-webpack-plugin/package.json +++ b/packages/dependency-extraction-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dependency-extraction-webpack-plugin", - "version": "4.24.0-prerelease", + "version": "4.24.0", "description": "Extract WordPress script dependencies from webpack bundles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index d14453ac5b4279..89568c0a58dfb1 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/docgen/package.json b/packages/docgen/package.json index 4bfba69df01d51..786e4e30102ad4 100644 --- a/packages/docgen/package.json +++ b/packages/docgen/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/docgen", - "version": "1.50.0-prerelease", + "version": "1.50.0", "description": "Autogenerate public API documentation from exports and JSDoc comments.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 6220897a8cf5cf..d8ebbd484eca32 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/package.json b/packages/dom/package.json index 428004ba396151..c50aae35a53ffd 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils-playwright/package.json b/packages/e2e-test-utils-playwright/package.json index 82579c877a9d0b..cb2789369d979f 100644 --- a/packages/e2e-test-utils-playwright/package.json +++ b/packages/e2e-test-utils-playwright/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils-playwright", - "version": "0.9.0-prerelease", + "version": "0.9.0", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index e8058cb780e2c5..bdb31b9ef62b03 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "10.12.0-prerelease", + "version": "10.12.0", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 9fc4ccf4ba7699..d3efad955d360d 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "7.12.0-prerelease", + "version": "7.12.0", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index e7d2c22af2dc27..3f1625891960a5 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "7.18.0-prerelease", + "version": "7.18.0", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index ae0ca530a288b4..a74742def329cf 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "5.18.0-prerelease", + "version": "5.18.0", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 61545a5f40ce38..d05022730beae1 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "5.18.0-prerelease", + "version": "5.18.0", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index bb39cfdec2d086..e0ab76755e5472 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "13.18.0-prerelease", + "version": "13.18.0", "description": "Enhanced block editor for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/package.json b/packages/element/package.json index 89cf2c0d996c2c..0b999f7c539ae3 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "5.18.0-prerelease", + "version": "5.18.0", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/env/package.json b/packages/env/package.json index 33a81f2568f45e..573f2534870362 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "8.7.0-prerelease", + "version": "8.7.0", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index 0baf569edb8963..0be67719079515 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "2.41.0-prerelease", + "version": "2.41.0", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 71abe7e887e0a7..9fada24d1782d2 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/eslint-plugin", - "version": "15.1.0-prerelease", + "version": "15.1.0", "description": "ESLint plugin for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 88c10386e5a488..31b89eedf797c5 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index e404ee67738068..800c89ea490d8d 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "WordPress hooks library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/html-entities/package.json b/packages/html-entities/package.json index 63aad915a10f55..bed86a9fe4004c 100644 --- a/packages/html-entities/package.json +++ b/packages/html-entities/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/html-entities", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "HTML entity utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 30236afa6f83be..9a980843c907a9 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/i18n", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "WordPress internationalization (i18n) library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/icons/package.json b/packages/icons/package.json index 7199d55bdcd8ae..375b3c327f4c4a 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/icons", - "version": "9.32.0-prerelease", + "version": "9.32.0", "description": "WordPress Icons package, based on dashicon.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interactivity/package.json b/packages/interactivity/package.json index 68a159473ace21..96254c822d511f 100644 --- a/packages/interactivity/package.json +++ b/packages/interactivity/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interactivity", - "version": "2.2.0-prerelease", + "version": "2.2.0", "description": "Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interface/package.json b/packages/interface/package.json index 5f4591f77f075d..ec5f49f64c8b17 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interface", - "version": "5.18.0-prerelease", + "version": "5.18.0", "description": "Interface module for WordPress. The package contains shared functionality across the modern JavaScript-based WordPress screens.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index fdc8de459ef907..69a750e180e8f5 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index 24c264f8123252..668b7e3f25e4e5 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-console", - "version": "7.12.0-prerelease", + "version": "7.12.0", "description": "Custom Jest matchers for the Console object.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-preset-default/package.json b/packages/jest-preset-default/package.json index 2c53457515d98b..7fc4186291ca60 100644 --- a/packages/jest-preset-default/package.json +++ b/packages/jest-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-preset-default", - "version": "11.12.0-prerelease", + "version": "11.12.0", "description": "Default Jest preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-puppeteer-axe/package.json b/packages/jest-puppeteer-axe/package.json index 717d4279571f54..93aad7655dc6af 100644 --- a/packages/jest-puppeteer-axe/package.json +++ b/packages/jest-puppeteer-axe/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-puppeteer-axe", - "version": "6.12.0-prerelease", + "version": "6.12.0", "description": "Axe API integration with Jest and Puppeteer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keyboard-shortcuts/package.json b/packages/keyboard-shortcuts/package.json index 3de49133c9e13c..9e973e51a67eef 100644 --- a/packages/keyboard-shortcuts/package.json +++ b/packages/keyboard-shortcuts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keyboard-shortcuts", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Handling keyboard shortcuts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index e2c206c33bfc29..e5eade2431bbb8 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/lazy-import/package.json b/packages/lazy-import/package.json index 4725970c1fdac1..4137ddcc4d44ae 100644 --- a/packages/lazy-import/package.json +++ b/packages/lazy-import/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/lazy-import", - "version": "1.28.0-prerelease", + "version": "1.28.0", "description": "Lazily import a module, installing it automatically if missing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index 532f929eecbbc1..5de3a23f416ae3 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index 0869be440f1b9a..930b1e108364de 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "4.32.0-prerelease", + "version": "4.32.0", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/package.json b/packages/notices/package.json index f129e65344c991..cca709be07c557 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "4.9.0-prerelease", + "version": "4.9.0", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/npm-package-json-lint-config/package.json b/packages/npm-package-json-lint-config/package.json index 7747193e297714..db060226e11313 100644 --- a/packages/npm-package-json-lint-config/package.json +++ b/packages/npm-package-json-lint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/npm-package-json-lint-config", - "version": "4.26.0-prerelease", + "version": "4.26.0", "description": "WordPress npm-package-json-lint shareable configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/package.json b/packages/nux/package.json index d1bda5c1452cd6..7af3c790d5254d 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "8.3.0-prerelease", + "version": "8.3.0", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/patterns/package.json b/packages/patterns/package.json index 52f61e45e8ef9b..ea796ce9ec8675 100644 --- a/packages/patterns/package.json +++ b/packages/patterns/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/patterns", - "version": "1.2.0-prerelease", + "version": "1.2.0", "description": "Management of user pattern editing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/plugins/package.json b/packages/plugins/package.json index f3effbc5086793..7e6f6994aadbd0 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "6.9.0-prerelease", + "version": "6.9.0", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-plugins-preset/package.json b/packages/postcss-plugins-preset/package.json index 14ed00e50cf6f6..7063303be190c8 100644 --- a/packages/postcss-plugins-preset/package.json +++ b/packages/postcss-plugins-preset/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-plugins-preset", - "version": "4.25.0-prerelease", + "version": "4.25.0", "description": "PostCSS sharable plugins preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-themes/package.json b/packages/postcss-themes/package.json index bcdd0613e46391..96293c2548c5ce 100644 --- a/packages/postcss-themes/package.json +++ b/packages/postcss-themes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-themes", - "version": "5.24.0-prerelease", + "version": "5.24.0", "description": "PostCSS plugin to generate theme colors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences-persistence/package.json b/packages/preferences-persistence/package.json index 2c9ab6789998d0..34a1ca20385157 100644 --- a/packages/preferences-persistence/package.json +++ b/packages/preferences-persistence/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences-persistence", - "version": "1.33.0-prerelease", + "version": "1.33.0", "description": "Persistence utilities for `wordpress/preferences`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences/package.json b/packages/preferences/package.json index e7bbeeb246b054..78dc5e93db525e 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences", - "version": "3.18.0-prerelease", + "version": "3.18.0", "description": "Utilities for managing WordPress preferences.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json index 56b7a522df2be8..6775d9360138a9 100644 --- a/packages/prettier-config/package.json +++ b/packages/prettier-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/prettier-config", - "version": "2.24.0-prerelease", + "version": "2.24.0", "description": "WordPress Prettier shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/primitives/package.json b/packages/primitives/package.json index c6c4f997df19d0..673051f2d4a16e 100644 --- a/packages/primitives/package.json +++ b/packages/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/primitives", - "version": "3.39.0-prerelease", + "version": "3.39.0", "description": "WordPress cross-platform primitives.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index 777a0ffe4e4014..2c0b141e13106d 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "2.41.0-prerelease", + "version": "2.41.0", "description": "Generic browser priority queue.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/private-apis/package.json b/packages/private-apis/package.json index 2a4ea80bf268cc..1e227c47ef9407 100644 --- a/packages/private-apis/package.json +++ b/packages/private-apis/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/private-apis", - "version": "0.23.0-prerelease", + "version": "0.23.0", "description": "Internal experimental APIs for WordPress core.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/project-management-automation/package.json b/packages/project-management-automation/package.json index 4848ed96f40e0d..a74a7ecaa1fccf 100644 --- a/packages/project-management-automation/package.json +++ b/packages/project-management-automation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/project-management-automation", - "version": "1.40.0-prerelease", + "version": "1.40.0", "description": "GitHub Action that implements various automation to assist with managing the Gutenberg GitHub repository.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/react-i18n/package.json b/packages/react-i18n/package.json index d4269c65259da6..6bab711027e36e 100644 --- a/packages/react-i18n/package.json +++ b/packages/react-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-i18n", - "version": "3.39.0-prerelease", + "version": "3.39.0", "description": "React bindings for @wordpress/i18n.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/readable-js-assets-webpack-plugin/package.json b/packages/readable-js-assets-webpack-plugin/package.json index 3b85ff6731f022..51a92af7e282bf 100644 --- a/packages/readable-js-assets-webpack-plugin/package.json +++ b/packages/readable-js-assets-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/readable-js-assets-webpack-plugin", - "version": "2.24.0-prerelease", + "version": "2.24.0", "description": "Generate a readable JS file for each JS asset.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/redux-routine/package.json b/packages/redux-routine/package.json index d32bd95ee5ab28..024ed111cba641 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "4.41.0-prerelease", + "version": "4.41.0", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index 1bd14c5b30116a..94addf36b7ccc0 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index 23affc1b33919d..806fe721e16afe 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "6.18.0-prerelease", + "version": "6.18.0", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/router/package.json b/packages/router/package.json index 9055184b97d322..ce23d3cdd35b24 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/router", - "version": "0.10.0-prerelease", + "version": "0.10.0", "description": "Router API for WordPress pages.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 1a8688b28417eb..faad42de3585a8 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "26.12.0-prerelease", + "version": "26.12.0", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index 9da663ea3c1ff3..bff3db88d43937 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "4.18.0-prerelease", + "version": "4.18.0", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/shortcode/package.json b/packages/shortcode/package.json index f2caf9c90f3f1d..5eb37c6c2bdfb9 100644 --- a/packages/shortcode/package.json +++ b/packages/shortcode/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/shortcode", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "Shortcode module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/style-engine/package.json b/packages/style-engine/package.json index e0489f43380a00..be455df5a0159e 100644 --- a/packages/style-engine/package.json +++ b/packages/style-engine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/style-engine", - "version": "1.24.0-prerelease", + "version": "1.24.0", "description": "A suite of parsers and compilers for WordPress styles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json index 586ecb152c40ee..a07d01f8f27370 100644 --- a/packages/stylelint-config/package.json +++ b/packages/stylelint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/stylelint-config", - "version": "21.24.0-prerelease", + "version": "21.24.0", "description": "stylelint config for WordPress development.", "author": "The WordPress Contributors", "license": "MIT", diff --git a/packages/sync/package.json b/packages/sync/package.json index 8469d6703fe1f2..7631a826ec5543 100644 --- a/packages/sync/package.json +++ b/packages/sync/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/sync", - "version": "0.3.0-prerelease", + "version": "0.3.0", "description": "Sync Data.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/token-list/package.json b/packages/token-list/package.json index 36b2d9a76612a7..a14987b5b182ca 100644 --- a/packages/token-list/package.json +++ b/packages/token-list/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/token-list", - "version": "2.41.0-prerelease", + "version": "2.41.0", "description": "Constructable, plain JavaScript DOMTokenList implementation, supporting non-browser runtimes.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/package.json b/packages/url/package.json index 8e56d357a34d6d..c7b6e2f572a778 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "3.42.0-prerelease", + "version": "3.42.0", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/viewport/package.json b/packages/viewport/package.json index ba1b78792b3918..2148327bb87baa 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "5.18.0-prerelease", + "version": "5.18.0", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/warning/package.json b/packages/warning/package.json index 58c50aed2da90a..3f85c55d131a77 100644 --- a/packages/warning/package.json +++ b/packages/warning/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/warning", - "version": "2.41.0-prerelease", + "version": "2.41.0", "description": "Warning utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index f63cb4cd38dd32..5192ab611e663b 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "3.18.0-prerelease", + "version": "3.18.0", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index 2579bdf7f63ac1..9be22933f2e439 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "3.41.0-prerelease", + "version": "3.41.0", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From ad410d8fc6fb901eb1d930a782c7852ddd159226 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Thu, 31 Aug 2023 13:17:16 +0300 Subject: [PATCH 49/56] [Post editor]: Toggle Distraction free mode mode based on compatibility (#54073) --- .../data/data-core-edit-post.md | 4 + .../components/keyboard-shortcuts/index.js | 33 +------- .../src/hooks/commands/use-common-commands.js | 11 ++- packages/edit-post/src/store/actions.js | 81 +++++++++++++++++-- packages/edit-post/src/store/test/actions.js | 75 +++++++++++++++++ packages/edit-post/src/store/test/reducer.js | 30 ++++--- packages/edit-site/src/store/test/actions.js | 1 - packages/edit-site/src/store/test/reducer.js | 1 - 8 files changed, 187 insertions(+), 49 deletions(-) diff --git a/docs/reference-guides/data/data-core-edit-post.md b/docs/reference-guides/data/data-core-edit-post.md index b579e7e658007a..7d6a1deed455b5 100644 --- a/docs/reference-guides/data/data-core-edit-post.md +++ b/docs/reference-guides/data/data-core-edit-post.md @@ -490,6 +490,10 @@ _Parameters_ - _mode_ `string`: The editor mode. +### toggleDistractionFree + +Action that toggles Distraction free mode. Distraction free mode expects there are no sidebars, as due to the z-index values set, you can't close sidebars. + ### toggleEditorPanelEnabled Returns an action object used to enable or disable a panel in the editor. diff --git a/packages/edit-post/src/components/keyboard-shortcuts/index.js b/packages/edit-post/src/components/keyboard-shortcuts/index.js index 1760edd8d3fc0c..31db06794e027d 100644 --- a/packages/edit-post/src/components/keyboard-shortcuts/index.js +++ b/packages/edit-post/src/components/keyboard-shortcuts/index.js @@ -10,8 +10,6 @@ import { import { __ } from '@wordpress/i18n'; import { store as editorStore } from '@wordpress/editor'; import { store as blockEditorStore } from '@wordpress/block-editor'; -import { store as noticesStore } from '@wordpress/notices'; -import { store as preferencesStore } from '@wordpress/preferences'; import { createBlock } from '@wordpress/blocks'; /** @@ -21,39 +19,24 @@ import { store as editPostStore } from '../../store'; function KeyboardShortcuts() { const { getBlockSelectionStart } = useSelect( blockEditorStore ); - const { - getEditorMode, - isEditorSidebarOpened, - isListViewOpened, - isFeatureActive, - } = useSelect( editPostStore ); + const { getEditorMode, isEditorSidebarOpened, isListViewOpened } = + useSelect( editPostStore ); const isModeToggleDisabled = useSelect( ( select ) => { const { richEditingEnabled, codeEditingEnabled } = select( editorStore ).getEditorSettings(); return ! richEditingEnabled || ! codeEditingEnabled; }, [] ); - const { createInfoNotice } = useDispatch( noticesStore ); - const { switchEditorMode, openGeneralSidebar, closeGeneralSidebar, toggleFeature, setIsListViewOpened, - setIsInserterOpened, + toggleDistractionFree, } = useDispatch( editPostStore ); const { registerShortcut } = useDispatch( keyboardShortcutsStore ); - const { set: setPreference } = useDispatch( preferencesStore ); - - const toggleDistractionFree = () => { - setPreference( 'core/edit-post', 'fixedToolbar', false ); - setIsInserterOpened( false ); - setIsListViewOpened( false ); - closeGeneralSidebar(); - }; - const { replaceBlocks } = useDispatch( blockEditorStore ); const { getBlockName, getSelectedBlockClientId, getBlockAttributes } = useSelect( blockEditorStore ); @@ -224,16 +207,6 @@ function KeyboardShortcuts() { useShortcut( 'core/edit-post/toggle-distraction-free', () => { toggleDistractionFree(); - toggleFeature( 'distractionFree' ); - createInfoNotice( - isFeatureActive( 'distractionFree' ) - ? __( 'Distraction free on.' ) - : __( 'Distraction free off.' ), - { - id: 'core/edit-post/distraction-free-mode/notice', - type: 'snackbar', - } - ); } ); useShortcut( 'core/edit-post/toggle-sidebar', ( event ) => { diff --git a/packages/edit-post/src/hooks/commands/use-common-commands.js b/packages/edit-post/src/hooks/commands/use-common-commands.js index dfb7c82a1029ca..e9534b190416a3 100644 --- a/packages/edit-post/src/hooks/commands/use-common-commands.js +++ b/packages/edit-post/src/hooks/commands/use-common-commands.js @@ -33,6 +33,7 @@ export default function useCommonCommands() { closeGeneralSidebar, switchEditorMode, setIsListViewOpened, + toggleDistractionFree, } = useDispatch( editPostStore ); const { openModal } = useDispatch( interfaceStore ); const { @@ -41,6 +42,7 @@ export default function useCommonCommands() { isListViewOpen, isPublishSidebarEnabled, showBlockBreadcrumbs, + isDistractionFree, } = useSelect( ( select ) => { const { getEditorMode, isListViewOpened, isFeatureActive } = select( editPostStore ); @@ -53,6 +55,10 @@ export default function useCommonCommands() { isPublishSidebarEnabled: select( editorStore ).isPublishSidebarEnabled(), showBlockBreadcrumbs: isFeatureActive( 'showBlockBreadcrumbs' ), + isDistractionFree: select( preferencesStore ).get( + editPostStore.name, + 'distractionFree' + ), }; }, [] ); const { toggle } = useDispatch( preferencesStore ); @@ -92,7 +98,7 @@ export default function useCommonCommands() { name: 'core/toggle-distraction-free', label: __( 'Toggle distraction free' ), callback: ( { close } ) => { - toggle( 'core/edit-post', 'distractionFree' ); + toggleDistractionFree(); close(); }, } ); @@ -131,6 +137,9 @@ export default function useCommonCommands() { label: __( 'Toggle top toolbar' ), callback: ( { close } ) => { toggle( 'core/edit-post', 'fixedToolbar' ); + if ( isDistractionFree ) { + toggleDistractionFree(); + } close(); }, } ); diff --git a/packages/edit-post/src/store/actions.js b/packages/edit-post/src/store/actions.js index 0ee1efb62b02ea..f7a5e211fd769c 100644 --- a/packages/edit-post/src/store/actions.js +++ b/packages/edit-post/src/store/actions.js @@ -26,10 +26,17 @@ import { store as editPostStore } from '.'; */ export const openGeneralSidebar = ( name ) => - ( { registry } ) => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ); + if ( isDistractionFree ) { + dispatch.toggleDistractionFree(); + } registry .dispatch( interfaceStore ) .enableComplementaryArea( editPostStore.name, name ); + }; /** * Returns an action object signalling that the user closed the sidebar. @@ -210,7 +217,7 @@ export const toggleFeature = */ export const switchEditorMode = ( mode ) => - ( { registry } ) => { + ( { dispatch, registry } ) => { registry .dispatch( preferencesStore ) .set( 'core/edit-post', 'editorMode', mode ); @@ -220,6 +227,15 @@ export const switchEditorMode = registry.dispatch( blockEditorStore ).clearSelectedBlock(); } + if ( + mode === 'text' && + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ) + ) { + dispatch.toggleDistractionFree(); + } + const message = mode === 'visual' ? __( 'Visual editor selected' ) @@ -479,12 +495,20 @@ export function setIsInserterOpened( value ) { * @param {boolean} isOpen A boolean representing whether the list view should be opened or closed. * @return {Object} Action object. */ -export function setIsListViewOpened( isOpen ) { - return { - type: 'SET_IS_LIST_VIEW_OPENED', - isOpen, +export const setIsListViewOpened = + ( isOpen ) => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ); + if ( isDistractionFree && isOpen ) { + dispatch.toggleDistractionFree(); + } + dispatch( { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen, + } ); }; -} /** * Returns an action object used to switch to template editing. @@ -590,3 +614,46 @@ export const initializeMetaBoxes = type: 'META_BOXES_INITIALIZED', } ); }; + +/** + * Action that toggles Distraction free mode. + * Distraction free mode expects there are no sidebars, as due to the + * z-index values set, you can't close sidebars. + */ +export const toggleDistractionFree = + () => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ); + if ( ! isDistractionFree ) { + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( 'core/edit-post', 'fixedToolbar', false ); + dispatch.setIsInserterOpened( false ); + dispatch.setIsListViewOpened( false ); + dispatch.closeGeneralSidebar(); + } ); + } + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( + 'core/edit-post', + 'distractionFree', + ! isDistractionFree + ); + registry + .dispatch( noticesStore ) + .createInfoNotice( + isDistractionFree + ? __( 'Distraction free off.' ) + : __( 'Distraction free on.' ), + { + id: 'core/edit-post/distraction-free-mode/notice', + type: 'snackbar', + } + ); + } ); + }; diff --git a/packages/edit-post/src/store/test/actions.js b/packages/edit-post/src/store/test/actions.js index 97494e03afca6b..cfd3eecb39e5b8 100644 --- a/packages/edit-post/src/store/test/actions.js +++ b/packages/edit-post/src/store/test/actions.js @@ -53,6 +53,20 @@ describe( 'actions', () => { ).toBeNull(); } ); + it( 'openGeneralSidebar - should turn off distraction free mode when opening a general sidebar', () => { + registry + .dispatch( preferencesStore ) + .set( 'core/edit-post', 'distractionFree', true ); + registry + .dispatch( editPostStore ) + .openGeneralSidebar( 'edit-post/block' ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ) + ).toBe( false ); + } ); + it( 'toggleFeature', () => { registry.dispatch( editPostStore ).toggleFeature( 'welcomeGuide' ); expect( @@ -102,6 +116,17 @@ describe( 'actions', () => { 'text' ); } ); + it( 'should turn off distraction free mode when switching to code editor', () => { + registry + .dispatch( preferencesStore ) + .set( 'core/edit-post', 'distractionFree', true ); + registry.dispatch( editPostStore ).switchEditorMode( 'text' ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ) + ).toBe( false ); + } ); } ); it( 'togglePinnedPluginItem', () => { @@ -333,4 +358,54 @@ describe( 'actions', () => { } ); } ); } ); + + describe( 'toggleDistractionFree', () => { + it( 'should properly update settings to prevent layout corruption when enabling distraction free mode', () => { + // Enable everything that shouldn't be enabled in distraction free mode. + registry + .dispatch( preferencesStore ) + .set( 'core/edit-post', 'fixedToolbar', true ); + registry.dispatch( editPostStore ).setIsListViewOpened( true ); + registry + .dispatch( editPostStore ) + .openGeneralSidebar( 'edit-post/block' ); + // Initial state is falsy. + registry.dispatch( editPostStore ).toggleDistractionFree(); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'fixedToolbar' ) + ).toBe( false ); + expect( registry.select( editPostStore ).isListViewOpened() ).toBe( + false + ); + expect( registry.select( editPostStore ).isInserterOpened() ).toBe( + false + ); + expect( + registry + .select( interfaceStore ) + .getActiveComplementaryArea( editPostStore.name ) + ).toBeNull(); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ) + ).toBe( true ); + } ); + } ); + + describe( 'setIsListViewOpened', () => { + it( 'should turn off distraction free mode when opening the list view', () => { + registry + .dispatch( preferencesStore ) + .set( 'core/edit-post', 'distractionFree', true ); + registry.dispatch( editPostStore ).setIsListViewOpened( true ); + expect( + registry + .select( preferencesStore ) + .get( 'core/edit-post', 'distractionFree' ) + ).toBe( false ); + } ); + } ); } ); diff --git a/packages/edit-post/src/store/test/reducer.js b/packages/edit-post/src/store/test/reducer.js index a083de9c672868..2e8d923d022f36 100644 --- a/packages/edit-post/src/store/test/reducer.js +++ b/packages/edit-post/src/store/test/reducer.js @@ -14,7 +14,7 @@ import { listViewPanel, } from '../reducer'; -import { setIsInserterOpened, setIsListViewOpened } from '../actions'; +import { setIsInserterOpened } from '../actions'; describe( 'state', () => { describe( 'isSavingMetaBoxes', () => { @@ -135,13 +135,19 @@ describe( 'state', () => { it( 'should close the inserter when opening the list view panel', () => { expect( - blockInserterPanel( true, setIsListViewOpened( true ) ) + blockInserterPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: true, + } ) ).toBe( false ); } ); it( 'should not change the state when closing the list view panel', () => { expect( - blockInserterPanel( true, setIsListViewOpened( false ) ) + blockInserterPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: false, + } ) ).toBe( true ); } ); } ); @@ -156,12 +162,18 @@ describe( 'state', () => { } ); it( 'should set the open state of the list view panel', () => { - expect( listViewPanel( false, setIsListViewOpened( true ) ) ).toBe( - true - ); - expect( listViewPanel( true, setIsListViewOpened( false ) ) ).toBe( - false - ); + expect( + listViewPanel( false, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: true, + } ) + ).toBe( true ); + expect( + listViewPanel( true, { + type: 'SET_IS_LIST_VIEW_OPENED', + isOpen: false, + } ) + ).toBe( false ); } ); it( 'should close the list view when opening the inserter panel', () => { diff --git a/packages/edit-site/src/store/test/actions.js b/packages/edit-site/src/store/test/actions.js index 345fcddbbba3b2..5fbbf62f369e87 100644 --- a/packages/edit-site/src/store/test/actions.js +++ b/packages/edit-site/src/store/test/actions.js @@ -235,7 +235,6 @@ describe( 'actions', () => { registry .dispatch( preferencesStore ) .set( 'core/edit-site', 'distractionFree', true ); - registry .dispatch( editSiteStore ) .openGeneralSidebar( 'edit-site/global-styles' ); diff --git a/packages/edit-site/src/store/test/reducer.js b/packages/edit-site/src/store/test/reducer.js index fc06faf925b386..d3816f6ac0ac2a 100644 --- a/packages/edit-site/src/store/test/reducer.js +++ b/packages/edit-site/src/store/test/reducer.js @@ -122,7 +122,6 @@ describe( 'state', () => { } ); it( 'should set the open state of the list view panel', () => { - // registry.dispatch( editSiteStore ).toggleFeature( 'name' ); expect( listViewPanel( false, { type: 'SET_IS_LIST_VIEW_OPENED', From 0d7548f8f4ffa6ccba241d154377dacd4a45e837 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 31 Aug 2023 20:17:47 +1000 Subject: [PATCH 50/56] Update editor pckg config to address "multiple Podfile" warn (#54077) --- packages/react-native-editor/.gitignore | 1 - packages/react-native-editor/ios/.bundle/config | 2 +- packages/react-native-editor/react-native.config.js | 5 +++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-native-editor/.gitignore b/packages/react-native-editor/.gitignore index a57f050efe86ca..f9d5282d7c2a4d 100644 --- a/packages/react-native-editor/.gitignore +++ b/packages/react-native-editor/.gitignore @@ -120,5 +120,4 @@ bin/wp-cli.phar # Ruby / CocoaPods ios/Pods -ios/vendor /vendor/bundle/ diff --git a/packages/react-native-editor/ios/.bundle/config b/packages/react-native-editor/ios/.bundle/config index 2369228816d467..3e22e4d08d33ad 100644 --- a/packages/react-native-editor/ios/.bundle/config +++ b/packages/react-native-editor/ios/.bundle/config @@ -1,2 +1,2 @@ --- -BUNDLE_PATH: "vendor/bundle" +BUNDLE_PATH: "../vendor/bundle" diff --git a/packages/react-native-editor/react-native.config.js b/packages/react-native-editor/react-native.config.js index 1dfc03662f7b5b..eafa0b41ca9558 100644 --- a/packages/react-native-editor/react-native.config.js +++ b/packages/react-native-editor/react-native.config.js @@ -12,4 +12,9 @@ module.exports = { root: path.resolve( __dirname, '../react-native-aztec' ), }, }, + project: { + ios: { + sourceDir: './ios/', + }, + }, }; From 9ce50480a72e62668c861a0715f5e7df84ecfe31 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 31 Aug 2023 15:53:28 +0400 Subject: [PATCH 51/56] Post Terms: Fix the 'useSelect' warning in the 'usePostTerms' hook (#54068) --- packages/block-library/src/post-terms/use-post-terms.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/post-terms/use-post-terms.js b/packages/block-library/src/post-terms/use-post-terms.js index 2d0aca51db1620..ed22df9a9728b0 100644 --- a/packages/block-library/src/post-terms/use-post-terms.js +++ b/packages/block-library/src/post-terms/use-post-terms.js @@ -4,6 +4,8 @@ import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; +const EMPTY_ARRAY = []; + export default function usePostTerms( { postId, term } ) { const { slug } = term; @@ -12,8 +14,8 @@ export default function usePostTerms( { postId, term } ) { const visible = term?.visibility?.publicly_queryable; if ( ! visible ) { return { - postTerms: [], - _isLoading: false, + postTerms: EMPTY_ARRAY, + isLoading: false, hasPostTerms: false, }; } From ea3c23d58f4caf036dd73f89cbf262a7323ac3db Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Thu, 31 Aug 2023 12:03:05 +0000 Subject: [PATCH 52/56] E2E: Do not run page actions in beforeEach hook when using fixme (#54065) This fixes the flaky tests from inserting-blocks.spec.js --- .../e2e-test-utils-playwright/src/test.ts | 12 +++-- test/e2e/playwright.config.ts | 2 +- .../editor/various/inserting-blocks.spec.js | 52 +++++++++++++------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/packages/e2e-test-utils-playwright/src/test.ts b/packages/e2e-test-utils-playwright/src/test.ts index eec8e4e279c0ff..d65174f44695e5 100644 --- a/packages/e2e-test-utils-playwright/src/test.ts +++ b/packages/e2e-test-utils-playwright/src/test.ts @@ -120,9 +120,15 @@ const test = base.extend< await use( page ); // Clear local storage after each test. - await page.evaluate( () => { - window.localStorage.clear(); - } ); + // This needs to be wrapped with a try/catch because it can fail when + // the test is skipped (e.g. via fixme). + try { + await page.evaluate( () => { + window.localStorage.clear(); + } ); + } catch ( error ) { + // noop. + } await page.close(); }, diff --git a/test/e2e/playwright.config.ts b/test/e2e/playwright.config.ts index 2e117b9745840d..e1724a61d61263 100644 --- a/test/e2e/playwright.config.ts +++ b/test/e2e/playwright.config.ts @@ -17,7 +17,7 @@ const config = defineConfig( { forbidOnly: !! process.env.CI, workers: 1, retries: process.env.CI ? 2 : 0, - timeout: parseInt( process.env.TIMEOUT || '', 10 ) || 200_000, // Defaults to 200 seconds. + timeout: parseInt( process.env.TIMEOUT || '', 10 ) || 100_000, // Defaults to 100 seconds. // Don't report slow test "files", as we will be running our tests in serial. reportSlowTests: null, testDir: fileURLToPath( new URL( './specs', 'file:' + __filename ).href ), diff --git a/test/e2e/specs/editor/various/inserting-blocks.spec.js b/test/e2e/specs/editor/various/inserting-blocks.spec.js index 39c159b00b75c0..822257e67deff7 100644 --- a/test/e2e/specs/editor/various/inserting-blocks.spec.js +++ b/test/e2e/specs/editor/various/inserting-blocks.spec.js @@ -15,23 +15,12 @@ test.use( { } ); test.describe( 'Inserting blocks (@firefox, @webkit)', () => { - test.beforeEach( async ( { admin, page } ) => { - await admin.createNewPost(); - // To do: some drag an drop tests are failing, so run them without - // iframe for now. - await page.evaluate( () => { - window.wp.blocks.registerBlockType( 'test/v2', { - apiVersion: '2', - title: 'test', - } ); - } ); - } ); - test.afterAll( async ( { requestUtils } ) => { await requestUtils.deleteAllPosts(); } ); test( 'inserts blocks by dragging and dropping from the global inserter', async ( { + admin, page, editor, insertingBlocksUtils, @@ -41,6 +30,9 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { 'The clientX value is always 0 in firefox, see https://github.com/microsoft/playwright/issues/17761 for more info.' ); + await admin.createNewPost(); + await insertingBlocksUtils.runWithoutIframe(); + // We need a dummy block in place to display the drop indicator due to a bug. // @see https://github.com/WordPress/gutenberg/issues/44064 await editor.insertBlock( { @@ -111,10 +103,14 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { } ); test( 'cancels dragging blocks from the global inserter by pressing Escape', async ( { + admin, page, editor, insertingBlocksUtils, } ) => { + await admin.createNewPost(); + await insertingBlocksUtils.runWithoutIframe(); + // We need a dummy block in place to display the drop indicator due to a bug. // @see https://github.com/WordPress/gutenberg/issues/44064 await editor.insertBlock( { @@ -168,6 +164,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { } ); test( 'inserts patterns by dragging and dropping from the global inserter', async ( { + admin, page, editor, insertingBlocksUtils, @@ -177,6 +174,9 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { 'The clientX value is always 0 in firefox, see https://github.com/microsoft/playwright/issues/17761 for more info.' ); + await admin.createNewPost(); + await insertingBlocksUtils.runWithoutIframe(); + // We need a dummy block in place to display the drop indicator due to a bug. // @see https://github.com/WordPress/gutenberg/issues/44064 await editor.insertBlock( { @@ -239,10 +239,14 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { } ); test( 'cancels dragging patterns from the global inserter by pressing Escape', async ( { + admin, page, editor, insertingBlocksUtils, } ) => { + await admin.createNewPost(); + await insertingBlocksUtils.runWithoutIframe(); + // We need a dummy block in place to display the drop indicator due to a bug. // @see https://github.com/WordPress/gutenberg/issues/44064 await editor.insertBlock( { @@ -300,9 +304,14 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { // A test for https://github.com/WordPress/gutenberg/issues/43090. test( 'should close the inserter when clicking on the toggle button', async ( { + admin, page, editor, + insertingBlocksUtils, } ) => { + await admin.createNewPost(); + await insertingBlocksUtils.runWithoutIframe(); + const inserterButton = page.getByRole( 'button', { name: 'Toggle block inserter', } ); @@ -341,13 +350,14 @@ test.describe( 'insert media from inserter', () => { requestUtils.deleteAllPosts(), ] ); } ); - test.beforeEach( async ( { admin } ) => { - await admin.createNewPost(); - } ); + test( 'insert media from the global inserter', async ( { + admin, page, editor, } ) => { + await admin.createNewPost(); + await page.click( 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' ); @@ -380,4 +390,16 @@ class InsertingBlocksUtils { 'data-testid=block-draggable-chip >> visible=true' ); } + + async runWithoutIframe() { + /** + * @todo Some drag an drop tests are failing, so run them without iframe for now. + */ + return await this.page.evaluate( () => { + window.wp.blocks.registerBlockType( 'test/v2', { + apiVersion: '2', + title: 'test', + } ); + } ); + } } From 6d77fd28f50adb39040d27cb797b9fc3a1393ef7 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 31 Aug 2023 13:18:35 +0100 Subject: [PATCH 53/56] Adds 'nofollow' setting to inline links (rich text only) (#53945) * Add ability for inline link format to parse and handle rel no follow * Add no follow to Link Control * Add support for optional help text on setting controls * Only apply new setting to inline links for now * Expose default link settings for use by component consumers * Extend default settings in inline link implementation * Use nofollow lowercase * Make help text the title * Adds test coverage * Use help text to reduce size of label * Correct text to qualify statement Search engines are not compelled to obey this rule * Remove help text --- .../src/components/link-control/index.js | 1 + .../src/components/link-control/settings.js | 1 + .../src/components/link-control/style.scss | 10 +-- packages/format-library/src/link/index.js | 1 + packages/format-library/src/link/inline.js | 15 +++- packages/format-library/src/link/utils.js | 20 ++++- test/e2e/specs/editor/blocks/links.spec.js | 82 +++++++++++++++++++ 7 files changed, 121 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index ac1ec660934a3a..4e0a1f2291b02c 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -475,5 +475,6 @@ function LinkControl( { } LinkControl.ViewerFill = ViewerFill; +LinkControl.DEFAULT_LINK_SETTINGS = DEFAULT_LINK_SETTINGS; export default LinkControl; diff --git a/packages/block-editor/src/components/link-control/settings.js b/packages/block-editor/src/components/link-control/settings.js index 1d70cc97dff417..e63ef926358fe9 100644 --- a/packages/block-editor/src/components/link-control/settings.js +++ b/packages/block-editor/src/components/link-control/settings.js @@ -26,6 +26,7 @@ const LinkControlSettings = ( { value, onChange = noop, settings } ) => { label={ setting.title } onChange={ handleSettingChange( setting ) } checked={ value ? !! value[ setting.id ] : false } + help={ setting?.help } /> ) ); diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss index 0ca13fa9167773..2b37d7fccdfe4b 100644 --- a/packages/block-editor/src/components/link-control/style.scss +++ b/packages/block-editor/src/components/link-control/style.scss @@ -401,19 +401,19 @@ $preview-image-height: 140px; } .block-editor-link-control__setting { - margin-bottom: $grid-unit-20; + margin-bottom: 0; flex: 1; padding: $grid-unit-10 0 $grid-unit-10 $grid-unit-30; + .components-base-control__field { + display: flex; // don't allow label to wrap under checkbox. + } + // Cancel left margin inherited from WP Admin Forms CSS. input { margin-left: 0; } - &.block-editor-link-control__setting:last-child { - margin-bottom: 0; - } - .is-preview & { padding: 20px $grid-unit-10 $grid-unit-10 0; } diff --git a/packages/format-library/src/link/index.js b/packages/format-library/src/link/index.js index 03e25a37b9b8e9..50019be4cc958e 100644 --- a/packages/format-library/src/link/index.js +++ b/packages/format-library/src/link/index.js @@ -131,6 +131,7 @@ export const link = { type: 'data-type', id: 'data-id', target: 'target', + rel: 'rel', }, __unstablePasteRule( value, { html, plainText } ) { if ( isCollapsed( value ) ) { diff --git a/packages/format-library/src/link/inline.js b/packages/format-library/src/link/inline.js index 29636a8d8b94be..62dc4ee3229421 100644 --- a/packages/format-library/src/link/inline.js +++ b/packages/format-library/src/link/inline.js @@ -31,6 +31,17 @@ import { createLinkFormat, isValidHref, getFormatBoundary } from './utils'; import { link as settings } from './index'; import useLinkInstanceKey from './use-link-instance-key'; +const LINK_SETTINGS = [ + ...LinkControl.DEFAULT_LINK_SETTINGS, + { + id: 'nofollow', + title: createInterpolateElement( + __( 'Mark as nofollow' ), + { code: } + ), + }, +]; + function InlineLinkUI( { isActive, activeAttributes, @@ -60,6 +71,7 @@ function InlineLinkUI( { type: activeAttributes.type, id: activeAttributes.id, opensInNewTab: activeAttributes.target === '_blank', + nofollow: activeAttributes.rel?.includes( 'nofollow' ), title: richTextText, }; @@ -77,7 +89,6 @@ function InlineLinkUI( { const didToggleSetting = linkValue.opensInNewTab !== nextValue.opensInNewTab && nextValue.url === undefined; - // Merge the next value with the current link value. nextValue = { ...linkValue, @@ -93,6 +104,7 @@ function InlineLinkUI( { ? String( nextValue.id ) : undefined, opensInNewWindow: nextValue.opensInNewTab, + nofollow: nextValue.nofollow, } ); const newText = nextValue.title || newUrl; @@ -247,6 +259,7 @@ function InlineLinkUI( { withCreateSuggestion={ userCanCreatePages } createSuggestionButtonText={ createButtonText } hasTextControl + settings={ LINK_SETTINGS } /> ); diff --git a/packages/format-library/src/link/utils.js b/packages/format-library/src/link/utils.js index 4c7a582a2e8f21..12fc56f2420313 100644 --- a/packages/format-library/src/link/utils.js +++ b/packages/format-library/src/link/utils.js @@ -85,10 +85,16 @@ export function isValidHref( href ) { * @param {string} options.type The type of the link. * @param {string} options.id The ID of the link. * @param {boolean} options.opensInNewWindow Whether this link will open in a new window. - * + * @param {boolean} options.nofollow Whether this link is marked as no follow relationship. * @return {Object} The final format object. */ -export function createLinkFormat( { url, type, id, opensInNewWindow } ) { +export function createLinkFormat( { + url, + type, + id, + opensInNewWindow, + nofollow, +} ) { const format = { type: 'core/link', attributes: { @@ -101,7 +107,15 @@ export function createLinkFormat( { url, type, id, opensInNewWindow } ) { if ( opensInNewWindow ) { format.attributes.target = '_blank'; - format.attributes.rel = 'noreferrer noopener'; + format.attributes.rel = format.attributes.rel + ? format.attributes.rel + ' noreferrer noopener' + : 'noreferrer noopener'; + } + + if ( nofollow ) { + format.attributes.rel = format.attributes.rel + ? format.attributes.rel + ' nofollow' + : 'nofollow'; } return format; diff --git a/test/e2e/specs/editor/blocks/links.spec.js b/test/e2e/specs/editor/blocks/links.spec.js index b84f954566fd55..83efef0bce2f02 100644 --- a/test/e2e/specs/editor/blocks/links.spec.js +++ b/test/e2e/specs/editor/blocks/links.spec.js @@ -233,4 +233,86 @@ test.describe( 'Links', () => { // This verifies that the editor preference was persisted. await expect( page.getByLabel( 'Open in new tab' ) ).not.toBeVisible(); } ); + + test( 'can toggle link settings and save', async ( { + page, + editor, + pageUtils, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: + 'Gutenberg', + }, + } ); + + // Move caret into the link. + await pageUtils.pressKeys( 'ArrowRight' ); + + // Switch Link UI to "edit" mode. + await page.getByRole( 'button', { name: 'Edit' } ).click(); + + // Open Advanced Settings + await page + .getByRole( 'region', { + name: 'Editor content', + } ) + .getByRole( 'button', { + name: 'Advanced', + } ) + .click(); + + // expect settings for `Open in new tab` and `No follow` + await expect( page.getByLabel( 'Open in new tab' ) ).not.toBeChecked(); + await expect( page.getByLabel( 'nofollow' ) ).not.toBeChecked(); + + // Toggle both of the settings + await page.getByLabel( 'Open in new tab' ).click(); + await page.getByLabel( 'nofollow' ).click(); + + // Save the link + await page + .locator( '.block-editor-link-control' ) + .getByRole( 'button', { name: 'Save' } ) + .click(); + + // Expect correct attributes to be set on the underlying link. + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/paragraph', + attributes: { + content: `Gutenberg`, + }, + }, + ] ); + + // Move caret back into the link. + await page.keyboard.press( 'ArrowRight' ); + await page.keyboard.press( 'ArrowRight' ); + + // Edit the link + await page.getByRole( 'button', { name: 'Edit' } ).click(); + + // Toggle both the settings to be off. + // Note: no need to toggle settings again because the open setting should be persisted. + await page.getByLabel( 'Open in new tab' ).click(); + await page.getByLabel( 'nofollow' ).click(); + + // Save the link + await page + .locator( '.block-editor-link-control' ) + .getByRole( 'button', { name: 'Save' } ) + .click(); + + // Expect correct attributes to be set on the underlying link. + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/paragraph', + attributes: { + content: `Gutenberg`, + }, + }, + ] ); + } ); } ); From 4df5573ea926474d1c50d83cff54d362e7036aec Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 31 Aug 2023 19:53:31 +0400 Subject: [PATCH 54/56] useMediaQuery: Avoid crashing on Safari < 14 (#54023) * useMediaQuery: Avoid crashing on Safari < 14 * Add comment --- packages/compose/src/hooks/use-media-query/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/compose/src/hooks/use-media-query/index.js b/packages/compose/src/hooks/use-media-query/index.js index bd8a0e724a40b7..59e6e5d99a4af3 100644 --- a/packages/compose/src/hooks/use-media-query/index.js +++ b/packages/compose/src/hooks/use-media-query/index.js @@ -38,9 +38,10 @@ export default function useMediaQuery( query ) { return () => {}; } - mediaQueryList.addEventListener( 'change', onStoreChange ); + // Avoid a fatal error when browsers don't support `addEventListener` on MediaQueryList. + mediaQueryList.addEventListener?.( 'change', onStoreChange ); return () => { - mediaQueryList.removeEventListener( + mediaQueryList.removeEventListener?.( 'change', onStoreChange ); From 3c27042b0ec65125ef0bfc0dc36d2386d9545c10 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 31 Aug 2023 17:20:47 +0100 Subject: [PATCH 55/56] Prevent the list view shortcut from typing unexpected characters (#54078) --- packages/edit-post/src/components/keyboard-shortcuts/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/edit-post/src/components/keyboard-shortcuts/index.js b/packages/edit-post/src/components/keyboard-shortcuts/index.js index 31db06794e027d..18f6acc9de89f6 100644 --- a/packages/edit-post/src/components/keyboard-shortcuts/index.js +++ b/packages/edit-post/src/components/keyboard-shortcuts/index.js @@ -225,8 +225,9 @@ function KeyboardShortcuts() { } ); // Only opens the list view. Other functionality for this shortcut happens in the rendered sidebar. - useShortcut( 'core/edit-post/toggle-list-view', () => { + useShortcut( 'core/edit-post/toggle-list-view', ( event ) => { if ( ! isListViewOpened() ) { + event.preventDefault(); setIsListViewOpened( true ); } } ); From 0ecfa2b74b819e0873e838cacc199526143b6429 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 31 Aug 2023 23:59:48 +0400 Subject: [PATCH 56/56] Footnotes: Add missing placeholder instructions text (#54056) --- packages/block-library/src/footnotes/edit.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/footnotes/edit.js b/packages/block-library/src/footnotes/edit.js index b8b92170fe217f..d8777b77f09e27 100644 --- a/packages/block-library/src/footnotes/edit.js +++ b/packages/block-library/src/footnotes/edit.js @@ -23,7 +23,9 @@ export default function FootnotesEdit( { context: { postType, postId } } ) { } label={ __( 'Footnotes' ) } - // To do: add instructions. We can't add new string in RC. + instructions={ __( + 'Footnotes are not supported here. Add this block to post or page content.' + ) } />
    );