diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss
index 2528139e8f30f1..418990bfaf6710 100644
--- a/packages/block-editor/src/components/inserter/style.scss
+++ b/packages/block-editor/src/components/inserter/style.scss
@@ -480,6 +480,7 @@ $block-inserter-tabs-height: 44px;
display: grid;
grid-gap: $grid-unit-40;
grid-template-columns: repeat(1, 1fr);
+ margin-bottom: $grid-unit-20;
@include break-xlarge() {
grid-template-columns: repeat(2, 1fr);
diff --git a/packages/block-library/src/navigation/style.scss b/packages/block-library/src/navigation/style.scss
index 180b40b43daca1..eb8ef7683e1988 100644
--- a/packages/block-library/src/navigation/style.scss
+++ b/packages/block-library/src/navigation/style.scss
@@ -506,10 +506,10 @@ button.wp-block-navigation-item__content {
@include reduce-motion("animation");
// Try to inherit any root paddings set, so the X can align to a top-right aligned menu.
- padding-top: var(--wp--style--root--padding-top, 2rem);
- padding-right: var(--wp--style--root--padding-right, 2rem);
- padding-bottom: var(--wp--style--root--padding-bottom, 2rem);
- padding-left: var(--wp--style--root--padding-left, 2rem);
+ padding-top: clamp(1rem, var(--wp--style--root--padding-top), 20rem);
+ padding-right: clamp(1rem, var(--wp--style--root--padding-right), 20rem);
+ padding-bottom: clamp(1rem, var(--wp--style--root--padding-bottom), 20rem);
+ padding-left: clamp(1rem, var(--wp--style--root--padding-left), 20em);
// Allow modal to scroll.
overflow: auto;
diff --git a/packages/block-library/src/social-link/icons/index.js b/packages/block-library/src/social-link/icons/index.js
index 62c32d2d5f35c7..85de13090ad5dc 100644
--- a/packages/block-library/src/social-link/icons/index.js
+++ b/packages/block-library/src/social-link/icons/index.js
@@ -40,5 +40,6 @@ export * from './vimeo';
export * from './vk';
export * from './whatsapp';
export * from './wordpress';
+export * from './x';
export * from './yelp';
export * from './youtube';
diff --git a/packages/block-library/src/social-link/icons/x.js b/packages/block-library/src/social-link/icons/x.js
new file mode 100644
index 00000000000000..cd70775ad7cb89
--- /dev/null
+++ b/packages/block-library/src/social-link/icons/x.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { Path, SVG } from '@wordpress/primitives';
+
+export const XIcon = () => (
+
+);
diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php
index 1ce60ff49fb41e..cda8e125097a50 100644
--- a/packages/block-library/src/social-link/index.php
+++ b/packages/block-library/src/social-link/index.php
@@ -238,6 +238,10 @@ function block_core_social_link_services( $service = '', $field = '' ) {
'name' => 'Reddit',
'icon' => '
',
),
+ 'share' => array(
+ 'name' => 'Share Icon',
+ 'icon' => '
',
+ ),
'skype' => array(
'name' => 'Skype',
'icon' => '
',
@@ -294,6 +298,10 @@ function block_core_social_link_services( $service = '', $field = '' ) {
'name' => 'WhatsApp',
'icon' => '
',
),
+ 'x' => array(
+ 'name' => 'X',
+ 'icon' => '
',
+ ),
'yelp' => array(
'name' => 'Yelp',
'icon' => '
',
@@ -302,10 +310,6 @@ function block_core_social_link_services( $service = '', $field = '' ) {
'name' => 'YouTube',
'icon' => '
',
),
- 'share' => array(
- 'name' => 'Share Icon',
- 'icon' => '
',
- ),
);
if ( ! empty( $service )
diff --git a/packages/block-library/src/social-link/socials-with-bg.scss b/packages/block-library/src/social-link/socials-with-bg.scss
index 042db464f6ee26..3ee9b4b5148a8a 100644
--- a/packages/block-library/src/social-link/socials-with-bg.scss
+++ b/packages/block-library/src/social-link/socials-with-bg.scss
@@ -199,6 +199,11 @@
color: #fff;
}
+.wp-social-link-x {
+ background-color: #000;
+ color: #fff;
+}
+
.wp-social-link-yelp {
background-color: #d32422;
color: #fff;
diff --git a/packages/block-library/src/social-link/socials-without-bg.scss b/packages/block-library/src/social-link/socials-without-bg.scss
index ea8fca5d7ab835..aa84b5ab1433c0 100644
--- a/packages/block-library/src/social-link/socials-without-bg.scss
+++ b/packages/block-library/src/social-link/socials-without-bg.scss
@@ -155,6 +155,10 @@
color: #3499cd;
}
+.wp-social-link-x {
+ color: #000;
+}
+
.wp-social-link-yelp {
color: #d32422;
}
diff --git a/packages/block-library/src/social-link/variations.js b/packages/block-library/src/social-link/variations.js
index 47307ca65c0882..5b03b85ae4e60e 100644
--- a/packages/block-library/src/social-link/variations.js
+++ b/packages/block-library/src/social-link/variations.js
@@ -44,6 +44,7 @@ import {
VkIcon,
WhatsAppIcon,
WordPressIcon,
+ XIcon,
YelpIcon,
YouTubeIcon,
} from './icons';
@@ -304,6 +305,13 @@ const variations = [
title: 'WhatsApp',
icon: WhatsAppIcon,
},
+ {
+ name: 'x',
+ attributes: { service: 'x' },
+ keywords: [ 'twitter' ],
+ title: 'X',
+ icon: XIcon,
+ },
{
name: 'yelp',
attributes: { service: 'yelp' },
diff --git a/packages/core-data/src/queried-data/selectors.js b/packages/core-data/src/queried-data/selectors.js
index a3e6f322274ced..562aab7ce6b79b 100644
--- a/packages/core-data/src/queried-data/selectors.js
+++ b/packages/core-data/src/queried-data/selectors.js
@@ -68,7 +68,7 @@ function getQueriedItemsUncached( state, query ) {
const field = fields[ f ].split( '.' );
let value = item;
field.forEach( ( fieldName ) => {
- value = value[ fieldName ];
+ value = value?.[ fieldName ];
} );
setNestedValue( filteredItem, field, value );
diff --git a/packages/core-data/src/selectors.ts b/packages/core-data/src/selectors.ts
index 7d6cbeb4daeee9..34445f73d2e60a 100644
--- a/packages/core-data/src/selectors.ts
+++ b/packages/core-data/src/selectors.ts
@@ -344,7 +344,7 @@ export const getEntityRecord = createSelector(
const field = fields[ f ].split( '.' );
let value = item;
field.forEach( ( fieldName ) => {
- value = value[ fieldName ];
+ value = value?.[ fieldName ];
} );
setNestedValue( filteredItem, field, value );
}
diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js
index 161d0af4ea5bca..5ae7a81fa144e9 100644
--- a/packages/core-data/src/test/selectors.js
+++ b/packages/core-data/src/test/selectors.js
@@ -135,6 +135,43 @@ describe.each( [
} )
).toEqual( { content: 'chicken' } );
} );
+
+ it( 'should work well for nested fields properties', () => {
+ const state = deepFreeze( {
+ entities: {
+ records: {
+ root: {
+ postType: {
+ queriedData: {
+ items: {
+ default: {
+ post: {
+ foo: undefined,
+ },
+ },
+ },
+ itemIsComplete: {
+ default: {
+ post: true,
+ },
+ },
+ queries: {},
+ },
+ },
+ },
+ },
+ },
+ } );
+ expect(
+ getEntityRecord( state, 'root', 'postType', 'post', {
+ _fields: [ 'foo.bar' ],
+ } )
+ ).toEqual( {
+ foo: {
+ bar: undefined,
+ },
+ } );
+ } );
} );
describe( 'hasEntityRecords', () => {
diff --git a/packages/e2e-test-utils/src/create-reusable-block.js b/packages/e2e-test-utils/src/create-reusable-block.js
index ed756353310dd9..0b2e327a5c05c2 100644
--- a/packages/e2e-test-utils/src/create-reusable-block.js
+++ b/packages/e2e-test-utils/src/create-reusable-block.js
@@ -34,7 +34,7 @@ export const createReusableBlock = async ( content, title ) => {
// Wait for creation to finish
await page.waitForXPath(
- '//*[contains(@class, "components-snackbar")]/*[contains(text(),"Pattern created:")]'
+ '//*[contains(@class, "components-snackbar")]/*[contains(text(),"pattern created:")]'
);
// Check that we have a reusable block on the page
diff --git a/packages/e2e-tests/specs/editor/various/datepicker.test.js b/packages/e2e-tests/specs/editor/various/datepicker.test.js
index b0fc3bf898d4a4..057418d3eacc38 100644
--- a/packages/e2e-tests/specs/editor/various/datepicker.test.js
+++ b/packages/e2e-tests/specs/editor/various/datepicker.test.js
@@ -61,7 +61,9 @@ async function getPublishingDate() {
);
}
-describe.each( [ [ 'UTC-10' ], [ 'UTC' ], [ 'UTC+10' ] ] )(
+// @todo: Change `UTC+1` back to `UTC` once the core regressions is resolved.
+// See: https://github.com/WordPress/gutenberg/pull/54806#issuecomment-1734840171.
+describe.each( [ [ 'UTC-10' ], [ 'UTC+1' ], [ 'UTC+10' ] ] )(
`Datepicker %s`,
( timezone ) => {
let oldTimezone;
diff --git a/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js b/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js
index 72f11f2c95e7a4..e0b3df5ef70a82 100644
--- a/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js
+++ b/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js
@@ -209,7 +209,7 @@ describe( 'Pattern blocks', () => {
// Wait for creation to finish.
await page.waitForXPath(
- '//*[contains(@class, "components-snackbar")]/*[contains(text(),"Pattern created:")]'
+ '//*[contains(@class, "components-snackbar")]/*[contains(text(),"pattern created:")]'
);
await clearAllBlocks();
diff --git a/packages/e2e-tests/specs/editor/various/scheduling.test.js b/packages/e2e-tests/specs/editor/various/scheduling.test.js
index 61c3541c1f47e5..87cc6e52a048c7 100644
--- a/packages/e2e-tests/specs/editor/various/scheduling.test.js
+++ b/packages/e2e-tests/specs/editor/various/scheduling.test.js
@@ -23,7 +23,9 @@ describe( 'Scheduling', () => {
} );
};
- describe.each( [ [ 'UTC-10' ], [ 'UTC' ], [ 'UTC+10' ] ] )(
+ // @todo: Change `UTC+1` back to `UTC` once the core regressions is resolved.
+ // See: https://github.com/WordPress/gutenberg/pull/54806#issuecomment-1734840171.
+ describe.each( [ [ 'UTC-10' ], [ 'UTC+1' ], [ 'UTC+10' ] ] )(
`Timezone %s`,
( timezone ) => {
let oldTimezone;
diff --git a/packages/edit-site/src/components/global-styles/font-families.js b/packages/edit-site/src/components/global-styles/font-families.js
index 06bf5953283323..15225c757fae5a 100644
--- a/packages/edit-site/src/components/global-styles/font-families.js
+++ b/packages/edit-site/src/components/global-styles/font-families.js
@@ -64,8 +64,12 @@ function FontFamilies() {
);
}
-export default ( { ...props } ) => (
+const FontFamiliesComponent = ( { ...props } ) => (
);
+
+export default process.env.IS_GUTENBERG_PLUGIN
+ ? FontFamiliesComponent
+ : undefined;
diff --git a/packages/edit-site/src/components/global-styles/screen-typography.js b/packages/edit-site/src/components/global-styles/screen-typography.js
index 2a895b68fa717f..7a812d44c0048d 100644
--- a/packages/edit-site/src/components/global-styles/screen-typography.js
+++ b/packages/edit-site/src/components/global-styles/screen-typography.js
@@ -22,9 +22,10 @@ function ScreenTypography() {
/>
- { ! window.__experimentalDisableFontLibrary && (
-
- ) }
+ { FontFamilies &&
+ ! window.__experimentalDisableFontLibrary && (
+
+ ) }
diff --git a/packages/list-reusable-blocks/src/components/import-form/index.js b/packages/list-reusable-blocks/src/components/import-form/index.js
index 9ba1589e52f39b..1f5e62f9115b36 100644
--- a/packages/list-reusable-blocks/src/components/import-form/index.js
+++ b/packages/list-reusable-blocks/src/components/import-form/index.js
@@ -49,8 +49,8 @@ function ImportForm( { instanceId, onUpload } ) {
case 'Invalid JSON file':
uiMessage = __( 'Invalid JSON file' );
break;
- case 'Invalid Pattern JSON file':
- uiMessage = __( 'Invalid Pattern JSON file' );
+ case 'Invalid pattern JSON file':
+ uiMessage = __( 'Invalid pattern JSON file' );
break;
default:
uiMessage = __( 'Unknown error' );
diff --git a/packages/list-reusable-blocks/src/utils/import.js b/packages/list-reusable-blocks/src/utils/import.js
index 465fb080ce8dfe..432948ce6d6dbc 100644
--- a/packages/list-reusable-blocks/src/utils/import.js
+++ b/packages/list-reusable-blocks/src/utils/import.js
@@ -31,7 +31,7 @@ async function importReusableBlock( file ) {
( parsedContent.syncStatus &&
typeof parsedContent.syncStatus !== 'string' )
) {
- throw new Error( 'Invalid Pattern JSON file' );
+ throw new Error( 'Invalid pattern JSON file' );
}
const postType = await apiFetch( { path: `/wp/v2/types/wp_block` } );
const reusableBlock = await apiFetch( {
diff --git a/packages/patterns/src/components/pattern-convert-button.js b/packages/patterns/src/components/pattern-convert-button.js
index 84340091338714..002dbbd8c0181d 100644
--- a/packages/patterns/src/components/pattern-convert-button.js
+++ b/packages/patterns/src/components/pattern-convert-button.js
@@ -21,6 +21,7 @@ import { store as noticesStore } from '@wordpress/notices';
import { store as patternsStore } from '../store';
import CreatePatternModal from './create-pattern-modal';
import { unlock } from '../lock-unlock';
+import { PATTERN_SYNC_TYPES } from '../constants';
/**
* Menu control to convert block(s) to a pattern block.
@@ -96,23 +97,25 @@ export default function PatternConvertButton( { clientIds, rootClientId } ) {
}
const handleSuccess = ( { pattern } ) => {
- const newBlock = createBlock( 'core/block', {
- ref: pattern.id,
- } );
+ if ( pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced ) {
+ const newBlock = createBlock( 'core/block', {
+ ref: pattern.id,
+ } );
- replaceBlocks( clientIds, newBlock );
- setEditingPattern( newBlock.clientId, true );
+ replaceBlocks( clientIds, newBlock );
+ setEditingPattern( newBlock.clientId, true );
+ }
createSuccessNotice(
- pattern.wp_pattern_sync_status === 'unsynced'
+ pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced
? sprintf(
// translators: %s: the name the user has given to the pattern.
- __( 'Unsynced Pattern created: %s' ),
+ __( 'Unsynced pattern created: %s' ),
pattern.title.raw
)
: sprintf(
// translators: %s: the name the user has given to the pattern.
- __( 'Synced Pattern created: %s' ),
+ __( 'Synced pattern created: %s' ),
pattern.title.raw
),
{
diff --git a/packages/patterns/src/store/actions.js b/packages/patterns/src/store/actions.js
index 2861e4ce2dac06..dfa0326a709416 100644
--- a/packages/patterns/src/store/actions.js
+++ b/packages/patterns/src/store/actions.js
@@ -69,7 +69,7 @@ export const createPatternFromFile =
( parsedContent.syncStatus &&
typeof parsedContent.syncStatus !== 'string' )
) {
- throw new Error( 'Invalid Pattern JSON file' );
+ throw new Error( 'Invalid pattern JSON file' );
}
const pattern = await dispatch.createPattern(
diff --git a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js
index de29a930e89f18..347638baeaf059 100644
--- a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js
+++ b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js
@@ -115,12 +115,12 @@ export default function ReusableBlockConvertButton( {
! syncType
? sprintf(
// translators: %s: the name the user has given to the pattern.
- __( 'Synced Pattern created: %s' ),
+ __( 'Synced pattern created: %s' ),
reusableBlockTitle
)
: sprintf(
// translators: %s: the name the user has given to the pattern.
- __( 'Unsynced Pattern created: %s' ),
+ __( 'Unsynced pattern created: %s' ),
reusableBlockTitle
),
{
diff --git a/packages/reusable-blocks/src/store/actions.js b/packages/reusable-blocks/src/store/actions.js
index 292a3082146aaa..85fe31138652a4 100644
--- a/packages/reusable-blocks/src/store/actions.js
+++ b/packages/reusable-blocks/src/store/actions.js
@@ -57,7 +57,7 @@ export const __experimentalConvertBlocksToReusable =
: undefined;
const reusableBlock = {
- title: title || __( 'Untitled Pattern block' ),
+ title: title || __( 'Untitled pattern block' ),
content: serialize(
registry
.select( blockEditorStore )
diff --git a/phpunit/class-gutenberg-rest-global-styles-revisions-controller-test.php b/phpunit/class-gutenberg-rest-global-styles-revisions-controller-test.php
index 77f95b2385a4ae..1b8e672fa78199 100644
--- a/phpunit/class-gutenberg-rest-global-styles-revisions-controller-test.php
+++ b/phpunit/class-gutenberg-rest-global-styles-revisions-controller-test.php
@@ -130,7 +130,7 @@ public static function wpSetupBeforeClass( $factory ) {
),
);
- wp_update_post( $new_styles_post, true, false );
+ wp_update_post( $new_styles_post, true, true );
$new_styles_post = array(
'ID' => self::$global_styles_id,
@@ -160,7 +160,7 @@ public static function wpSetupBeforeClass( $factory ) {
),
);
- wp_update_post( $new_styles_post, true, false );
+ wp_update_post( $new_styles_post, true, true );
$new_styles_post = array(
'ID' => self::$global_styles_id,
@@ -190,7 +190,7 @@ public static function wpSetupBeforeClass( $factory ) {
),
);
- wp_update_post( $new_styles_post, true, false );
+ wp_update_post( $new_styles_post, true, true );
wp_set_current_user( 0 );
}
diff --git a/phpunit/experimental/block-editor-settings-mobile-test.php b/phpunit/experimental/block-editor-settings-mobile-test.php
index 224fb4bfcb188b..907b750d8c8638 100644
--- a/phpunit/experimental/block-editor-settings-mobile-test.php
+++ b/phpunit/experimental/block-editor-settings-mobile-test.php
@@ -24,6 +24,7 @@ class Gutenberg_REST_Block_Editor_Settings_Controller_Test extends WP_Test_REST_
public function set_up() {
parent::set_up();
switch_theme( 'block-theme' );
+ remove_action( 'wp_print_styles', 'print_emoji_styles' );
}
/**
diff --git a/phpunit/tests/fonts/font-library/wpRestFontLibraryController/base.php b/phpunit/tests/fonts/font-library/wpRestFontLibraryController/base.php
index f1e712bab85b40..5caa40b2892932 100644
--- a/phpunit/tests/fonts/font-library/wpRestFontLibraryController/base.php
+++ b/phpunit/tests/fonts/font-library/wpRestFontLibraryController/base.php
@@ -7,9 +7,19 @@
*/
abstract class WP_REST_Font_Library_Controller_UnitTestCase extends WP_UnitTestCase {
+ /**
+ * Fonts directory.
+ *
+ * @var string
+ */
+ protected static $fonts_dir;
+
+
public function set_up() {
parent::set_up();
+ static::$fonts_dir = WP_Font_Library::get_fonts_dir();
+
// Create a user with administrator role.
$admin_id = $this->factory->user->create(
array(
@@ -30,5 +40,10 @@ public function tear_down() {
$property = $reflection->getProperty( 'collections' );
$property->setAccessible( true );
$property->setValue( array() );
+
+ // Clean up the /fonts directory.
+ foreach ( $this->files_in_dir( static::$fonts_dir ) as $file ) {
+ @unlink( $file );
+ }
}
}
diff --git a/test/e2e/specs/editor/blocks/navigation-colors.spec.js b/test/e2e/specs/editor/blocks/navigation-colors.spec.js
index 1fd8bd39f520a0..42ecb29aa6650f 100644
--- a/test/e2e/specs/editor/blocks/navigation-colors.spec.js
+++ b/test/e2e/specs/editor/blocks/navigation-colors.spec.js
@@ -413,6 +413,10 @@ class ColorControl {
.getByRole( 'button', { name: 'Open menu' } )
.click();
+ // Move the mouse to avoid accidentally triggering hover
+ // state on the links once the overlay opens.
+ await this.page.mouse.move( 1000, 1000 );
+
const overlay = this.editor.canvas
.locator( '.wp-block-navigation__responsive-container' )
.filter( { hasText: 'Submenu Link' } );
diff --git a/test/integration/fixtures/blocks/core__social-link-x.html b/test/integration/fixtures/blocks/core__social-link-x.html
new file mode 100644
index 00000000000000..a587f2d0962f6a
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__social-link-x.html
@@ -0,0 +1 @@
+
diff --git a/test/integration/fixtures/blocks/core__social-link-x.json b/test/integration/fixtures/blocks/core__social-link-x.json
new file mode 100644
index 00000000000000..d0cf492d2aa03e
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__social-link-x.json
@@ -0,0 +1,11 @@
+[
+ {
+ "name": "core/social-link",
+ "isValid": true,
+ "attributes": {
+ "url": "https://example.com/",
+ "service": "x"
+ },
+ "innerBlocks": []
+ }
+]
diff --git a/test/integration/fixtures/blocks/core__social-link-x.parsed.json b/test/integration/fixtures/blocks/core__social-link-x.parsed.json
new file mode 100644
index 00000000000000..2119720f5db0f5
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__social-link-x.parsed.json
@@ -0,0 +1,11 @@
+[
+ {
+ "blockName": "core/social-link-x",
+ "attrs": {
+ "url": "https://example.com/"
+ },
+ "innerBlocks": [],
+ "innerHTML": "",
+ "innerContent": []
+ }
+]
diff --git a/test/integration/fixtures/blocks/core__social-link-x.serialized.html b/test/integration/fixtures/blocks/core__social-link-x.serialized.html
new file mode 100644
index 00000000000000..be00807af4c9ea
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__social-link-x.serialized.html
@@ -0,0 +1 @@
+
diff --git a/test/performance/specs/post-editor.spec.js b/test/performance/specs/post-editor.spec.js
index 7b02ddd7f846b9..aa789f646516c3 100644
--- a/test/performance/specs/post-editor.spec.js
+++ b/test/performance/specs/post-editor.spec.js
@@ -179,7 +179,9 @@ test.describe( 'Post Editor Performance', () => {
// Select the block where we type in
await editor.canvas
- .getByRole( 'document', { name: 'Paragraph block' } )
+ .getByRole( 'document', {
+ name: /Paragraph block|Block: Paragraph/,
+ } )
.first()
.click();