diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml
index e6404c34208595..9c2de4d3355edd 100644
--- a/.github/workflows/rnmobile-android-runner.yml
+++ b/.github/workflows/rnmobile-android-runner.yml
@@ -15,6 +15,9 @@ concurrency:
jobs:
test:
runs-on: macos-latest
+ # The false value below disables the test while we investigate a
+ # foundational error causing failures
+ if: ${{ false }}
strategy:
matrix:
native-test-name: [gutenberg-editor-initial-html]
diff --git a/lib/block-patterns.php b/lib/block-patterns.php
index ff58b6df019a23..56fd179750e960 100644
--- a/lib/block-patterns.php
+++ b/lib/block-patterns.php
@@ -91,8 +91,8 @@ function register_gutenberg_patterns() {
'content' => '
-
-
+
+
@@ -136,8 +136,8 @@ function register_gutenberg_patterns() {
'title' => __( 'Offset', 'gutenberg' ),
'blockTypes' => array( 'core/query' ),
'categories' => array( 'query' ),
- 'content' => '
-
+ 'content' => '
+
@@ -162,7 +162,7 @@ function register_gutenberg_patterns() {
-
+
',
)
);
diff --git a/lib/blocks.php b/lib/blocks.php
index e6e2968a23fd4d..14dc99b9393dbc 100644
--- a/lib/blocks.php
+++ b/lib/blocks.php
@@ -133,7 +133,7 @@ function gutenberg_reregister_core_block_types() {
$registry->unregister( $metadata['name'] );
}
- gutenberg_register_core_block_styles( $folder_name );
+ gutenberg_register_core_block_assets( $folder_name );
register_block_type_from_metadata( $block_json_file );
}
@@ -147,7 +147,7 @@ function gutenberg_reregister_core_block_types() {
if ( $registry->is_registered( $block_name ) ) {
$registry->unregister( $block_name );
}
- gutenberg_register_core_block_styles( $block_name );
+ gutenberg_register_core_block_assets( $block_name );
}
require_once $blocks_dir . $file;
@@ -164,13 +164,39 @@ function gutenberg_reregister_core_block_types() {
*
* @return void
*/
-function gutenberg_register_core_block_styles( $block_name ) {
+function gutenberg_register_core_block_assets( $block_name ) {
+ $block_name = str_replace( 'core/', '', $block_name );
+
+ // When in production, use the plugin's version as the default asset version;
+ // else (for development or test) default to use the current time.
+ $default_version = defined( 'GUTENBERG_VERSION' ) && ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? GUTENBERG_VERSION : time();
+ $script_suffix = '.js';
+
+ $view_script_path = "build/block-library/blocks/$block_name/view$script_suffix";
+ if ( file_exists( gutenberg_dir_path() . $view_script_path ) ) {
+ $view_script_handle = "wp-block-{$block_name}-view";
+ wp_deregister_script( $view_script_handle );
+
+ // Replace suffix and extension with `.asset.php` to find the generated dependencies file.
+ $view_asset_file = substr( $view_script_path, 0, -( strlen( $script_suffix ) ) ) . '.asset.php';
+ $view_asset = file_exists( gutenberg_dir_path() . $view_asset_file )
+ ? require( gutenberg_dir_path() . $view_asset_file )
+ : null;
+ $view_script_dependencies = isset( $view_asset['dependencies'] ) ? $view_asset['dependencies'] : array();
+ $view_script_version = isset( $view_asset['version'] ) ? $view_asset['version'] : $default_version;
+
+ wp_register_script(
+ $view_script_handle,
+ gutenberg_url( $view_script_path ),
+ $view_script_dependencies,
+ $view_script_version
+ );
+ }
+
if ( ! gutenberg_should_load_separate_block_assets() ) {
return;
}
- $block_name = str_replace( 'core/', '', $block_name );
-
$style_path = "build/block-library/blocks/$block_name/style.css";
$editor_style_path = "build/block-library/blocks/$block_name/style-editor.css";
@@ -180,7 +206,7 @@ function gutenberg_register_core_block_styles( $block_name ) {
"wp-block-{$block_name}",
gutenberg_url( $style_path ),
array(),
- filemtime( gutenberg_dir_path() . $style_path )
+ $default_version
);
wp_style_add_data( "wp-block-{$block_name}", 'rtl', 'replace' );
@@ -196,7 +222,7 @@ function gutenberg_register_core_block_styles( $block_name ) {
"wp-block-{$block_name}-editor",
gutenberg_url( $editor_style_path ),
array(),
- filemtime( gutenberg_dir_path() . $editor_style_path )
+ $default_version
);
wp_style_add_data( "wp-block-{$block_name}-editor", 'rtl', 'replace' );
} else {
diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php
index 679e404258e1a9..c7a38362c964f9 100644
--- a/lib/class-wp-theme-json-gutenberg.php
+++ b/lib/class-wp-theme-json-gutenberg.php
@@ -1159,7 +1159,6 @@ public function merge( $incoming ) {
// For leaf values that are arrays it will use the numeric indexes for replacement.
// In those cases, we want to replace the existing with the incoming value, if it exists.
$to_replace = array();
- $to_replace[] = array( 'custom' );
$to_replace[] = array( 'spacing', 'units' );
$to_replace[] = array( 'color', 'duotone' );
foreach ( self::VALID_ORIGINS as $origin ) {
diff --git a/lib/global-styles.php b/lib/global-styles.php
index 31b3316360ed5a..85839483187d9f 100644
--- a/lib/global-styles.php
+++ b/lib/global-styles.php
@@ -184,12 +184,7 @@ function_exists( 'gutenberg_is_edit_site_page' ) &&
unset( $settings['__experimentalFeatures']['typography']['customLineHeight'] );
}
if ( isset( $settings['__experimentalFeatures']['spacing']['units'] ) ) {
- if ( ! is_array( $settings['__experimentalFeatures']['spacing']['units'] ) ) {
- $settings['enableCustomUnits'] = false;
- } else {
- $settings['enableCustomUnits'] = count( $settings['__experimentalFeatures']['spacing']['units'] ) > 0;
- }
- unset( $settings['__experimentalFeatures']['spacing']['units'] );
+ $settings['enableCustomUnits'] = $settings['__experimentalFeatures']['spacing']['units'];
}
if ( isset( $settings['__experimentalFeatures']['spacing']['customPadding'] ) ) {
$settings['enableCustomSpacing'] = $settings['__experimentalFeatures']['spacing']['customPadding'];
diff --git a/packages/block-editor/src/components/button-block-appender/style.scss b/packages/block-editor/src/components/button-block-appender/style.scss
index 80cccd7b9c9f38..4e68411ce9dc84 100644
--- a/packages/block-editor/src/components/button-block-appender/style.scss
+++ b/packages/block-editor/src/components/button-block-appender/style.scss
@@ -40,6 +40,7 @@
background-color: $gray-900;
color: $white;
border-radius: $radius-block-ui;
+ flex: 1 0 auto;
}
}
}
diff --git a/packages/block-editor/src/components/editor-styles/index.js b/packages/block-editor/src/components/editor-styles/index.js
index 413be503890296..4b0286d8eba71a 100644
--- a/packages/block-editor/src/components/editor-styles/index.js
+++ b/packages/block-editor/src/components/editor-styles/index.js
@@ -35,7 +35,7 @@ function useDarkThemeBodyClassName( styles ) {
// DOM, so calculate the background color by creating a fake
// wrapper.
const tempCanvas = ownerDocument.createElement( 'div' );
- tempCanvas.classList.add( EDITOR_STYLES_SELECTOR );
+ tempCanvas.classList.add( 'editor-styles-wrapper' );
body.appendChild( tempCanvas );
backgroundColor = defaultView
diff --git a/packages/block-editor/src/components/rich-text/utils.js b/packages/block-editor/src/components/rich-text/utils.js
index 16bcb2dd23a2c1..f1385eda82e26f 100644
--- a/packages/block-editor/src/components/rich-text/utils.js
+++ b/packages/block-editor/src/components/rich-text/utils.js
@@ -5,7 +5,7 @@ import { regexp } from '@wordpress/shortcode';
import deprecated from '@wordpress/deprecated';
export function addActiveFormats( value, activeFormats ) {
- if ( activeFormats.length ) {
+ if ( activeFormats?.length ) {
let index = value.formats.length;
while ( index-- ) {
diff --git a/packages/block-library/README.md b/packages/block-library/README.md
index 7b500f4a3b9831..84f86a88a5b749 100644
--- a/packages/block-library/README.md
+++ b/packages/block-library/README.md
@@ -14,20 +14,20 @@ _This package assumes that your code will run in an **ES2015+** environment. If
## Building JavaScript for the browser
-If a `frontend.js` file is present in the block's directory, this file will be built along other assets, making it available to load from the browser.
+If a `view.js` file is present in the block's directory, this file will be built along other assets, making it available to load from the browser.
This enables us to, for instance, load this file when the block is present on the page in two ways:
1. Using the block's `render_callback`:
```php
-function render_my_block() {
- $script_path = __DIR__ . '/block-name/frontend.js';
+function render_block_my_block() {
+ $script_path = __DIR__ . '/my-block/view.js';
if ( file_exists( $script_path ) ) {
wp_enqueue_script(
- 'my_block_frontend_script',
- plugins_url( 'frontend.js', $script_path ),
+ 'wp-block-my-block-view',
+ plugins_url( 'view.js', $script_path ),
array(),
false,
true
@@ -36,10 +36,10 @@ function render_my_block() {
}
function register_block_my_block() {
- register_block_type_from_metadata(
- __DIR__ . '/block-name',
+ register_block_type(
+ __DIR__ . '/my-block',
array(
- 'render_callback' => 'render_my_block',
+ 'render_callback' => 'render_block_my_block',
)
);
}
@@ -51,13 +51,13 @@ add_action( 'init', 'register_block_my_block' );
2. Using the `render_block` filter:
```php
-function render_my_block() {
- $script_path = __DIR__ . '/block-name/frontend.js';
+function render_block_my_block() {
+ $script_path = __DIR__ . '/my-block/view.js';
if ( file_exists( $script_path ) ) {
wp_enqueue_script(
- 'my_block_frontend_script',
- plugins_url( 'frontend.js', $script_path ),
+ 'wp-block-my-block-view',
+ plugins_url( 'view.js', $script_path ),
array(),
false,
true
@@ -65,7 +65,7 @@ function render_my_block() {
}
}
-apply_filter( 'render_block', 'render_my_block' );
+apply_filter( 'render_block', 'render_block_my_block' );
```
## API
diff --git a/packages/block-library/src/file/index.php b/packages/block-library/src/file/index.php
index 212bd31228f206..8209061dbb319e 100644
--- a/packages/block-library/src/file/index.php
+++ b/packages/block-library/src/file/index.php
@@ -6,7 +6,7 @@
*/
/**
- * When the `core/file` block is rendering, check if we need to enqueue the `'wp-block-library-file` script.
+ * When the `core/file` block is rendering, check if we need to enqueue the `'wp-block-file-view` script.
*
* @param array $attributes The block attributes.
* @param array $content The block content.
@@ -14,11 +14,9 @@
* @return string Returns the block content.
*/
function render_block_core_file( $attributes, $content ) {
- if ( ! empty( $attributes['displayPreview'] ) ) {
- // Check if it's already enqueued, so we don't add the inline script multiple times.
- if ( ! wp_script_is( 'wp-block-library-file' ) ) {
- wp_enqueue_script( 'wp-block-library-file', plugins_url( 'file/frontend.js', __FILE__ ) );
- }
+ $should_load_view_script = ! empty( $attributes['displayPreview'] ) && ! wp_script_is( 'wp-block-file-view' );
+ if ( $should_load_view_script ) {
+ wp_enqueue_script( 'wp-block-file-view' );
}
return $content;
diff --git a/packages/block-library/src/file/frontend.js b/packages/block-library/src/file/view.js
similarity index 100%
rename from packages/block-library/src/file/frontend.js
rename to packages/block-library/src/file/view.js
diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js
index 56561ae4d4fa13..bc6ac27412bf6d 100644
--- a/packages/block-library/src/image/edit.js
+++ b/packages/block-library/src/image/edit.js
@@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
-import { get, omit, pick } from 'lodash';
+import { get, has, omit, pick } from 'lodash';
/**
* WordPress dependencies
@@ -71,6 +71,22 @@ const isTemporaryImage = ( id, url ) => ! id && isBlobURL( url );
*/
export const isExternalImage = ( id, url ) => url && ! id && ! isBlobURL( url );
+/**
+ * Checks if WP generated default image size. Size generation is skipped
+ * when the image is smaller than the said size.
+ *
+ * @param {Object} image
+ * @param {string} defaultSize
+ *
+ * @return {boolean} Whether or not it has default image size.
+ */
+function hasDefaultSize( image, defaultSize ) {
+ return (
+ has( image, [ 'sizes', defaultSize, 'url' ] ) ||
+ has( image, [ 'media_details', 'sizes', defaultSize, 'source_url' ] )
+ );
+}
+
export function ImageEdit( {
attributes,
setAttributes,
@@ -148,7 +164,11 @@ export function ImageEdit( {
additionalAttributes = {
width: undefined,
height: undefined,
- sizeSlug: imageDefaultSize,
+ // Fallback to size "full" if there's no default image size.
+ // It means the image is smaller, and the block will use a full-size URL.
+ sizeSlug: hasDefaultSize( media, imageDefaultSize )
+ ? imageDefaultSize
+ : 'full',
};
} else {
// Keep the same url when selecting the same file, so "Image Size"
diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json
index 28ea05470ae708..9b8fe735885c8b 100644
--- a/packages/block-library/src/navigation/block.json
+++ b/packages/block-library/src/navigation/block.json
@@ -4,11 +4,7 @@
"title": "Navigation",
"category": "theme",
"description": "A collection of blocks that allow visitors to get around your site.",
- "keywords": [
- "menu",
- "navigation",
- "links"
- ],
+ "keywords": [ "menu", "navigation", "links" ],
"textdomain": "default",
"attributes": {
"orientation": {
@@ -56,10 +52,7 @@
"orientation": "orientation"
},
"supports": {
- "align": [
- "wide",
- "full"
- ],
+ "align": [ "wide", "full" ],
"anchor": true,
"html": false,
"inserter": true,
diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php
index 0dff15eeaa1978..565585aaa49eb9 100644
--- a/packages/block-library/src/navigation/index.php
+++ b/packages/block-library/src/navigation/index.php
@@ -120,16 +120,10 @@ function render_block_core_navigation( $attributes, $content, $block ) {
}
unset( $attributes['rgbTextColor'], $attributes['rgbBackgroundColor'] );
- $should_load_frontend_script = $attributes['isResponsive'] && ! wp_script_is( 'core_block_navigation_load_frontend_scripts' );
-
- if ( $should_load_frontend_script ) {
- wp_enqueue_script(
- 'core_block_navigation_load_frontend_scripts',
- plugins_url( 'frontend.js', __DIR__ . '/navigation/frontend.js' ),
- array(),
- false,
- true
- );
+
+ $should_load_view_script = ! empty( $attributes['isResponsive'] ) && ! wp_script_is( 'wp-block-navigation-view' );
+ if ( $should_load_view_script ) {
+ wp_enqueue_script( 'wp-block-navigation-view' );
}
if ( empty( $block->inner_blocks ) ) {
diff --git a/packages/block-library/src/navigation/frontend.js b/packages/block-library/src/navigation/view.js
similarity index 100%
rename from packages/block-library/src/navigation/frontend.js
rename to packages/block-library/src/navigation/view.js
diff --git a/packages/block-library/src/table-of-contents/edit.js b/packages/block-library/src/table-of-contents/edit.js
index 095a35800da8b9..d95e4bc0629d22 100644
--- a/packages/block-library/src/table-of-contents/edit.js
+++ b/packages/block-library/src/table-of-contents/edit.js
@@ -22,7 +22,6 @@ import {
ToolbarGroup,
} from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
-import { store as editorStore } from '@wordpress/editor';
import { renderToString, useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
@@ -61,7 +60,10 @@ export default function TableOfContentsEdit( {
listBlockExists: !! select( blocksStore ).getBlockType(
'core/list'
),
- postContent: select( editorStore ).getEditedPostContent(),
+ // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
+ // Blocks can be loaded into a *non-post* block editor.
+ // eslint-disable-next-line @wordpress/data-no-store-string-literals
+ postContent: select( 'core/editor' ).getEditedPostContent(),
} ),
[]
);
diff --git a/packages/block-library/src/template-part/edit/advanced-controls.js b/packages/block-library/src/template-part/edit/advanced-controls.js
index 8ac4807da1a4f9..9086b307b1a839 100644
--- a/packages/block-library/src/template-part/edit/advanced-controls.js
+++ b/packages/block-library/src/template-part/edit/advanced-controls.js
@@ -6,7 +6,6 @@ import { SelectControl, TextControl } from '@wordpress/components';
import { sprintf, __ } from '@wordpress/i18n';
import { InspectorAdvancedControls } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
-import { store as editorStore } from '@wordpress/editor';
export function TemplatePartAdvancedControls( {
tagName,
@@ -30,8 +29,11 @@ export function TemplatePartAdvancedControls( {
);
const { areaOptions } = useSelect( ( select ) => {
+ // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
+ // Blocks can be loaded into a *non-post* block editor.
+ // eslint-disable-next-line @wordpress/data-no-store-string-literals
const definedAreas = select(
- editorStore
+ 'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
return {
areaOptions: definedAreas.map( ( { label, area: _area } ) => ( {
diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js
index a4b6a62767cff2..e8ed05baa9b1f4 100644
--- a/packages/block-library/src/template-part/edit/index.js
+++ b/packages/block-library/src/template-part/edit/index.js
@@ -17,7 +17,6 @@ import {
} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
/**
* Internal dependencies
@@ -89,7 +88,10 @@ export default function TemplatePartEdit( {
)
: false;
- const defaultWrapperElement = select( editorStore )
+ // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
+ // Blocks can be loaded into a *non-post* block editor.
+ // eslint-disable-next-line @wordpress/data-no-store-string-literals
+ const defaultWrapperElement = select( 'core/editor' )
.__experimentalGetDefaultTemplatePartAreas()
.find( ( { area: value } ) => value === _area )?.area_tag;
diff --git a/packages/block-library/src/template-part/edit/placeholder/index.js b/packages/block-library/src/template-part/edit/placeholder/index.js
index db5da513802590..93a7baddb487fd 100644
--- a/packages/block-library/src/template-part/edit/placeholder/index.js
+++ b/packages/block-library/src/template-part/edit/placeholder/index.js
@@ -12,7 +12,6 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { Placeholder, Dropdown, Button } from '@wordpress/components';
import { serialize } from '@wordpress/blocks';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
/**
* Internal dependencies
@@ -36,8 +35,11 @@ export default function TemplatePartPlaceholder( {
const { areaIcon, areaLabel } = useSelect(
( select ) => {
+ // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
+ // Blocks can be loaded into a *non-post* block editor.
+ // eslint-disable-next-line @wordpress/data-no-store-string-literals
const definedAreas = select(
- editorStore
+ 'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
const selectedArea = find( definedAreas, { area } );
diff --git a/packages/block-library/src/template-part/edit/selection/template-part-previews.js b/packages/block-library/src/template-part/edit/selection/template-part-previews.js
index 8c0da142d339fb..83d6f94341930f 100644
--- a/packages/block-library/src/template-part/edit/selection/template-part-previews.js
+++ b/packages/block-library/src/template-part/edit/selection/template-part-previews.js
@@ -21,7 +21,7 @@ import {
import { useAsyncList } from '@wordpress/compose';
import { store as noticesStore } from '@wordpress/notices';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
+
/**
* Internal dependencies
*/
@@ -307,8 +307,11 @@ export default function TemplatePartPreviews( {
) !== templatePartId
);
+ // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
+ // Blocks can be loaded into a *non-post* block editor.
+ // eslint-disable-next-line @wordpress/data-no-store-string-literals
const definedAreas = select(
- editorStore
+ 'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
const _labelsByArea = {};
definedAreas.forEach( ( item ) => {
diff --git a/packages/customize-widgets/src/controls/style.scss b/packages/customize-widgets/src/controls/style.scss
index 6911971a69126b..40b20b03bdad3c 100644
--- a/packages/customize-widgets/src/controls/style.scss
+++ b/packages/customize-widgets/src/controls/style.scss
@@ -14,13 +14,13 @@
// Override the inline styles added via JS that make the section title
// sticky feature work. The customize widget block-editor disables this
// sticky title.
- padding-top: 10px !important;
+ padding-top: 12px !important;
.customize-section-title {
// Disable the sticky title. `!important` as this overrides inline
// styles added via JavaScript.
position: static !important;
- top: 0 !important;
+ margin-top: -12px !important;
width: unset !important;
}
}
diff --git a/packages/customize-widgets/src/index.js b/packages/customize-widgets/src/index.js
index 475629450f8609..bf3b8eef0c8622 100644
--- a/packages/customize-widgets/src/index.js
+++ b/packages/customize-widgets/src/index.js
@@ -22,6 +22,9 @@ import './filters';
const { wp } = window;
+const DISABLED_BLOCKS = [ 'core/more', 'core/block', 'core/freeform' ];
+const ENABLE_EXPERIMENTAL_FSE_BLOCKS = false;
+
/**
* Initializes the widgets block editor in the customizer.
*
@@ -29,13 +32,20 @@ const { wp } = window;
* @param {Object} blockEditorSettings Block editor settings.
*/
export function initialize( editorName, blockEditorSettings ) {
- const coreBlocks = __experimentalGetCoreBlocks().filter(
- ( block ) => ! [ 'core/more', 'core/freeform' ].includes( block.name )
- );
+ const coreBlocks = __experimentalGetCoreBlocks().filter( ( block ) => {
+ return ! (
+ DISABLED_BLOCKS.includes( block.name ) ||
+ block.name.startsWith( 'core/post' ) ||
+ block.name.startsWith( 'core/query' ) ||
+ block.name.startsWith( 'core/site' )
+ );
+ } );
registerCoreBlocks( coreBlocks );
registerLegacyWidgetBlock();
if ( process.env.GUTENBERG_PHASE === 2 ) {
- __experimentalRegisterExperimentalCoreBlocks();
+ __experimentalRegisterExperimentalCoreBlocks( {
+ enableFSEBlocks: ENABLE_EXPERIMENTAL_FSE_BLOCKS,
+ } );
}
registerLegacyWidgetVariations( blockEditorSettings );
diff --git a/packages/e2e-tests/plugins/block-templates.php b/packages/e2e-tests/plugins/block-templates.php
new file mode 100644
index 00000000000000..e8321a1d745421
--- /dev/null
+++ b/packages/e2e-tests/plugins/block-templates.php
@@ -0,0 +1,17 @@
+ {
await waitForImage( filename );
const regex = new RegExp(
- `\\s*
\\s*`
+ `\\s*
\\s*`
);
expect( await getEditedPostContent() ).toMatch( regex );
} );
@@ -80,7 +80,7 @@ describe( 'Image', () => {
await waitForImage( filename1 );
const regex1 = new RegExp(
- `\\s*
\\s*`
+ `\\s*
\\s*`
);
expect( await getEditedPostContent() ).toMatch( regex1 );
@@ -88,7 +88,7 @@ describe( 'Image', () => {
await page.click( '[aria-label="Image size presets"] button' );
const regex2 = new RegExp(
- `\\s*
<\\/figure>\\s*`
+ `\\s*
<\\/figure>\\s*`
);
expect( await getEditedPostContent() ).toMatch( regex2 );
@@ -100,7 +100,7 @@ describe( 'Image', () => {
await waitForImage( filename2 );
const regex3 = new RegExp(
- `\\s*
\\s*`
+ `\\s*
\\s*`
);
expect( await getEditedPostContent() ).toMatch( regex3 );
@@ -322,7 +322,7 @@ describe( 'Image', () => {
);
const regexBefore = new RegExp(
- `\\s*
<\\/figure>\\s*`
+ `\\s*
<\\/figure>\\s*`
);
// Check if dimensions are changed.
diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap
deleted file mode 100644
index 29a3d82f5f0685..00000000000000
--- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap
+++ /dev/null
@@ -1,3 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`WP Editor Meta Boxes Should save the changes 1`] = `"Typing in a metabox"`;
diff --git a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js
index 761830e8481c76..3045575ff15f5d 100644
--- a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js
+++ b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js
@@ -39,6 +39,8 @@ describe( 'WP Editor Meta Boxes', () => {
( textarea ) => textarea.value
);
- expect( content ).toMatchSnapshot();
+ expect( content ).toMatchInlineSnapshot(
+ `"Typing in a metabox
"`
+ );
} );
} );
diff --git a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js
index c29e1f5dadb786..cc970c75eee154 100644
--- a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js
+++ b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js
@@ -558,9 +558,7 @@ describe( 'Navigation', () => {
const isScriptLoaded = await previewPage.evaluate(
() =>
null !==
- document.querySelector(
- 'script[src*="navigation/frontend.js"]'
- )
+ document.querySelector( 'script[src*="navigation/view.js"]' )
);
expect( isScriptLoaded ).toBe( false );
@@ -582,7 +580,7 @@ describe( 'Navigation', () => {
() =>
Array.from(
document.querySelectorAll(
- 'script[src*="navigation/frontend.js"]'
+ 'script[src*="navigation/view.js"]'
)
).length
);
@@ -613,9 +611,7 @@ describe( 'Navigation', () => {
let isScriptLoaded = await previewPage.evaluate(
() =>
null !==
- document.querySelector(
- 'script[src*="navigation/frontend.js"]'
- )
+ document.querySelector( 'script[src*="navigation/view.js"]' )
);
expect( isScriptLoaded ).toBe( false );
@@ -631,9 +627,7 @@ describe( 'Navigation', () => {
isScriptLoaded = await previewPage.evaluate(
() =>
null !==
- document.querySelector(
- 'script[src*="navigation/frontend.js"]'
- )
+ document.querySelector( 'script[src*="navigation/view.js"]' )
);
expect( isScriptLoaded ).toBe( true );
diff --git a/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js b/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js
index a1c01f4c7d9f65..5e8d80b1f45c51 100644
--- a/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js
+++ b/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js
@@ -9,13 +9,22 @@ import {
trashAllPosts,
openPreviewPage,
openDocumentSettingsSidebar,
+ activatePlugin,
+ deactivatePlugin,
} from '@wordpress/e2e-test-utils';
const openSidebarPanelWithTitle = async ( title ) => {
const panel = await page.waitForXPath(
`//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ title }")]`
);
- await panel.click();
+
+ const expanded = await page.evaluate(
+ ( element ) => element.getAttribute( 'aria-expanded' ),
+ panel
+ );
+ if ( expanded === 'false' ) {
+ await panel.click();
+ }
};
const disableTemplateWelcomeGuide = async () => {
@@ -82,12 +91,14 @@ const createNewTemplate = async ( templateName ) => {
describe( 'Post Editor Template mode', () => {
beforeAll( async () => {
+ await activatePlugin( 'gutenberg-test-block-templates' );
await trashAllPosts( 'wp_template' );
await trashAllPosts( 'wp_template_part' );
} );
afterAll( async () => {
await activateTheme( 'twentytwentyone' );
+ await deactivatePlugin( 'gutenberg-test-block-templates' );
} );
it( 'Allow to switch to template mode, edit the template and check the result', async () => {
diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss
index ef28ff4124f032..e996ab588d1639 100644
--- a/packages/edit-post/src/components/layout/style.scss
+++ b/packages/edit-post/src/components/layout/style.scss
@@ -85,7 +85,3 @@
bottom: 0;
}
}
-
-.edit-post-layout .interface-interface-skeleton__content {
- background-color: $gray-800;
-}
diff --git a/packages/edit-post/src/components/sidebar/template/index.js b/packages/edit-post/src/components/sidebar/template/index.js
index 205812819d6bc0..3308b3838366a1 100644
--- a/packages/edit-post/src/components/sidebar/template/index.js
+++ b/packages/edit-post/src/components/sidebar/template/index.js
@@ -1,12 +1,13 @@
/**
* External dependencies
*/
-import { partial, isEmpty, map } from 'lodash';
+import { partial, isEmpty, map, fromPairs } from 'lodash';
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
+import { useMemo } from '@wordpress/element';
import { PanelBody, SelectControl } from '@wordpress/components';
import { store as editorStore } from '@wordpress/editor';
import { useSelect, useDispatch } from '@wordpress/data';
@@ -29,6 +30,7 @@ export function TemplatePanel() {
isOpened,
selectedTemplate,
availableTemplates,
+ fetchedTemplates,
isViewable,
template,
supportsTemplateMode,
@@ -43,24 +45,43 @@ export function TemplatePanel() {
getEditorSettings,
getCurrentPostType,
} = select( editorStore );
- const { getPostType } = select( coreStore );
+ const { getPostType, getEntityRecords } = select( coreStore );
const _isViewable =
getPostType( getCurrentPostType() )?.viewable ?? false;
const _supportsTemplateMode =
select( editorStore ).getEditorSettings().supportsTemplateMode &&
_isViewable;
+ const wpTemplates = getEntityRecords( 'postType', 'wp_template', {
+ per_page: -1,
+ } );
+
+ const newAvailableTemplates = fromPairs(
+ ( wpTemplates || [] ).map( ( { slug, title } ) => [
+ slug,
+ title.rendered,
+ ] )
+ );
+
return {
isEnabled: isEditorPanelEnabled( PANEL_NAME ),
isOpened: isEditorPanelOpened( PANEL_NAME ),
selectedTemplate: getEditedPostAttribute( 'template' ),
availableTemplates: getEditorSettings().availableTemplates,
+ fetchedTemplates: newAvailableTemplates,
template: _supportsTemplateMode && getEditedPostTemplate(),
isViewable: _isViewable,
supportsTemplateMode: _supportsTemplateMode,
};
}, [] );
+ const templates = useMemo( () => {
+ return {
+ ...availableTemplates,
+ ...fetchedTemplates,
+ };
+ }, [ availableTemplates, fetchedTemplates ] );
+
const { toggleEditorPanelOpened } = useDispatch( editPostStore );
const { editPost } = useDispatch( editorStore );
@@ -92,19 +113,20 @@ export function TemplatePanel() {
{
editPost( {
template: templateSlug || '',
} );
} }
- options={ map(
- availableTemplates,
- ( templateName, templateSlug ) => ( {
- value: templateSlug,
- label: templateName,
- } )
- ) }
+ options={ map( templates, ( templateName, templateSlug ) => ( {
+ value: templateSlug,
+ label: templateName,
+ } ) ) }
/>
diff --git a/packages/edit-post/src/components/visual-editor/style.scss b/packages/edit-post/src/components/visual-editor/style.scss
index 0d0e982642979f..38f8b91e4846c0 100644
--- a/packages/edit-post/src/components/visual-editor/style.scss
+++ b/packages/edit-post/src/components/visual-editor/style.scss
@@ -3,6 +3,11 @@
display: flex;
flex-flow: column;
+ // Gray preview overlay (desktop/tablet/mobile) is intentionally not set on an element with scrolling content like
+ // interface-interface-skeleton__content. This causes graphical glitches (flashes of the background color)
+ // when scrolling in Safari due to incorrect ordering of large compositing layers (GPU acceleration).
+ background-color: $gray-800;
+
// The button element easily inherits styles that are meant for the editor style.
// These rules enhance the specificity to reduce that inheritance.
// This is duplicated in edit-site.
diff --git a/packages/edit-widgets/src/blocks/widget-area/editor.scss b/packages/edit-widgets/src/blocks/widget-area/editor.scss
index 2f36e3b4a763af..e1c1fcbc69bc02 100644
--- a/packages/edit-widgets/src/blocks/widget-area/editor.scss
+++ b/packages/edit-widgets/src/blocks/widget-area/editor.scss
@@ -21,6 +21,10 @@
.block-list-appender.wp-block {
width: initial;
}
+ // Override theme custom widths for blocks.
+ .editor-styles-wrapper .wp-block.wp-block.wp-block.wp-block.wp-block {
+ max-width: 100%;
+ }
}
// Add some spacing above the inner blocks so that the block toolbar doesn't
diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss b/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss
index 66389620423a66..97a084b220393d 100644
--- a/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss
+++ b/packages/edit-widgets/src/components/widget-areas-block-editor-content/style.scss
@@ -1,10 +1,27 @@
.edit-widgets-block-editor {
position: relative;
- background: $gray-100;
// This is the default font that is going to be used in the content of the areas (blocks).
font-family: $default-font;
+ // Block list needs to stretch to full screen height so blocks can
+ // be deselected when clicking outside widget areas.
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ > div:last-of-type,
+ .block-editor-writing-flow,
+ .block-editor-writing-flow > div {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ }
+
+ .edit-widgets-main-block-list {
+ height: 100%;
+ }
+
// The button element easily inherits styles that are meant for the editor style.
// These rules enhance the specificity to reduce that inheritance.
// This is copied from edit-post/src/components/style.scss but without the padding.
diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
index 63244ffaf9be3a..c94754ba5bf431 100644
--- a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
+++ b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
@@ -24,6 +24,7 @@ import { useEntityBlockEditor } from '@wordpress/core-data';
import { buildWidgetAreasPostId, KIND, POST_TYPE } from '../../store/utils';
import useLastSelectedWidgetArea from '../../hooks/use-last-selected-widget-area';
import { store as editWidgetsStore } from '../../store';
+import { ALLOW_REUSABLE_BLOCKS } from '../../constants';
export default function WidgetAreasBlockEditorProvider( {
blockEditorSettings,
@@ -43,10 +44,9 @@ export default function WidgetAreasBlockEditorProvider( {
),
widgetAreas: select( editWidgetsStore ).getWidgetAreas(),
widgets: select( editWidgetsStore ).getWidgets(),
- reusableBlocks: select( 'core' ).getEntityRecords(
- 'postType',
- 'wp_block'
- ),
+ reusableBlocks: ALLOW_REUSABLE_BLOCKS
+ ? select( 'core' ).getEntityRecords( 'postType', 'wp_block' )
+ : [],
isFixedToolbarActive: select(
editWidgetsStore
).__unstableIsFeatureActive( 'fixedToolbar' ),
diff --git a/packages/edit-widgets/src/constants.js b/packages/edit-widgets/src/constants.js
new file mode 100644
index 00000000000000..c2ab518c5c9c4a
--- /dev/null
+++ b/packages/edit-widgets/src/constants.js
@@ -0,0 +1,2 @@
+export const ALLOW_REUSABLE_BLOCKS = false;
+export const ENABLE_EXPERIMENTAL_FSE_BLOCKS = false;
diff --git a/packages/edit-widgets/src/index.js b/packages/edit-widgets/src/index.js
index f2e98fc62b5a2c..7ed910113e7e8f 100644
--- a/packages/edit-widgets/src/index.js
+++ b/packages/edit-widgets/src/index.js
@@ -24,6 +24,16 @@ import './store';
import './filters';
import * as widgetArea from './blocks/widget-area';
import Layout from './components/layout';
+import {
+ ALLOW_REUSABLE_BLOCKS,
+ ENABLE_EXPERIMENTAL_FSE_BLOCKS,
+} from './constants';
+
+const disabledBlocks = [
+ 'core/more',
+ 'core/freeform',
+ ...( ! ALLOW_REUSABLE_BLOCKS && [ 'core/block' ] ),
+];
/**
* Initializes the block editor in the widgets screen.
@@ -32,18 +42,27 @@ import Layout from './components/layout';
* @param {Object} settings Block editor settings.
*/
export function initialize( id, settings ) {
- const coreBlocks = __experimentalGetCoreBlocks().filter(
- ( block ) => ! [ 'core/more', 'core/freeform' ].includes( block.name )
- );
+ const coreBlocks = __experimentalGetCoreBlocks().filter( ( block ) => {
+ return ! (
+ disabledBlocks.includes( block.name ) ||
+ block.name.startsWith( 'core/post' ) ||
+ block.name.startsWith( 'core/query' ) ||
+ block.name.startsWith( 'core/site' )
+ );
+ } );
+
registerCoreBlocks( coreBlocks );
registerLegacyWidgetBlock();
if ( process.env.GUTENBERG_PHASE === 2 ) {
- __experimentalRegisterExperimentalCoreBlocks();
+ __experimentalRegisterExperimentalCoreBlocks( {
+ enableFSEBlocks: ENABLE_EXPERIMENTAL_FSE_BLOCKS,
+ } );
}
registerLegacyWidgetVariations( settings );
registerBlock( widgetArea );
settings.__experimentalFetchLinkSuggestions = ( search, searchOptions ) =>
fetchLinkSuggestions( search, searchOptions, settings );
+
render(
,
document.getElementById( id )
diff --git a/packages/edit-widgets/src/style.scss b/packages/edit-widgets/src/style.scss
index 8cb54eb3aca8e2..c6a07b9b0356be 100644
--- a/packages/edit-widgets/src/style.scss
+++ b/packages/edit-widgets/src/style.scss
@@ -59,4 +59,10 @@ body.widgets-php {
display: none;
}
+// Don't display admin notices on the Widgets screen.
+// Needs !important because plugins may add inline styles to notices.
+.widgets-php .notice {
+ display: none !important;
+}
+
@include wordpress-admin-schemes();
diff --git a/packages/widgets/src/blocks/legacy-widget/editor.scss b/packages/widgets/src/blocks/legacy-widget/editor.scss
index bd4f505e8b6d91..8ad7a3faa5c330 100644
--- a/packages/widgets/src/blocks/legacy-widget/editor.scss
+++ b/packages/widgets/src/blocks/legacy-widget/editor.scss
@@ -12,7 +12,7 @@
margin: 0 0 $grid-unit-15 0;
}
- .widget-inside {
+ .widget-inside.widget-inside {
border: none;
box-shadow: none;
display: block;
@@ -25,6 +25,34 @@
label + .widefat {
margin-top: $grid-unit-15;
}
+
+ // Override theme style bleed.
+ label,
+ input,
+ a {
+ color: $black;
+ }
+ select {
+ font-family: system-ui;
+ -webkit-appearance: revert;
+ color: revert;
+ border: revert;
+ border-radius: revert;
+ background: revert;
+ box-shadow: revert;
+ text-shadow: revert;
+ outline: revert;
+ cursor: revert;
+ transform: revert;
+ font-size: revert;
+ line-height: revert;
+ padding: revert;
+ margin: revert;
+ min-height: revert;
+ max-width: revert;
+ vertical-align: revert;
+ font-weight: revert;
+ }
}
// Reset z-index set on https://github.com/WordPress/wordpress-develop/commit/f26d4d37351a55fd1fc5dad0f5fef8f0f964908c.
@@ -33,6 +61,12 @@
}
}
+// Make sure edit form text and no preview warning are always visible.
+.wp-block-legacy-widget__edit-form.wp-block-legacy-widget__edit-form,
+.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview {
+ color: $black;
+}
+
.wp-block-legacy-widget__edit-preview,
.wp-block-legacy-widget__edit-no-preview {
cursor: pointer;
diff --git a/phpunit/class-block-editor-test.php b/phpunit/class-block-editor-test.php
index 3f19167b2bc54e..905aff7993adfe 100644
--- a/phpunit/class-block-editor-test.php
+++ b/phpunit/class-block-editor-test.php
@@ -163,7 +163,7 @@ function test_get_default_block_editor_settings() {
$settings = gutenberg_get_default_block_editor_settings();
$this->assertCount( 17, $settings );
- $this->assertTrue( $settings['__unstableEnableFullSiteEditingBlocks'] );
+ $this->assertFalse( $settings['__unstableEnableFullSiteEditingBlocks'] );
$this->assertFalse( $settings['alignWide'] );
$this->assertInternalType( 'array', $settings['allowedMimeTypes'] );
$this->assertTrue( $settings['allowedBlockTypes'] );
diff --git a/webpack.config.js b/webpack.config.js
index acb2e7a1f405c6..24c0963ff1f635 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -67,34 +67,37 @@ const stylesTransform = ( content ) => {
/*
* Matches a block's name in paths in the form
- * build-module//frontend.js
+ * build-module//view.js
*/
-const blockNameRegex = new RegExp( /(?<=build-module\/).*(?=(\/frontend))/g );
+const blockNameRegex = new RegExp( /(?<=build-module\/).*(?=(\/view))/g );
const createEntrypoints = () => {
/*
- * Returns an array of paths to frontend.js files within the block-directory package.
+ * Returns an array of paths to view.js files within the `@wordpress/block-library` package.
* These paths can be matched by the regex `blockNameRegex` in order to extract
* the block's name.
*
* Returns an empty array if no files were found.
*/
- const scriptPaths = fastGlob.sync(
- './packages/block-library/build-module/**/frontend.js'
+ const blockViewScriptPaths = fastGlob.sync(
+ './packages/block-library/build-module/**/view.js'
);
/*
* Go through the paths found above, in order to define webpack entry points for
- * each block's frontend.js file.
+ * each block's view.js file.
*/
- const scriptEntries = scriptPaths.reduce( ( entries, scriptPath ) => {
- const [ blockName ] = scriptPath.match( blockNameRegex );
+ const blockViewScriptEntries = blockViewScriptPaths.reduce(
+ ( entries, scriptPath ) => {
+ const [ blockName ] = scriptPath.match( blockNameRegex );
- return {
- ...entries,
- [ blockName ]: scriptPath,
- };
- }, {} );
+ return {
+ ...entries,
+ [ 'blocks/' + blockName ]: scriptPath,
+ };
+ },
+ {}
+ );
const packageEntries = gutenbergPackages.reduce( ( memo, packageName ) => {
return {
@@ -103,7 +106,7 @@ const createEntrypoints = () => {
};
}, {} );
- return { ...packageEntries, ...scriptEntries };
+ return { ...packageEntries, ...blockViewScriptEntries };
};
module.exports = {
@@ -138,14 +141,17 @@ module.exports = {
filename: ( data ) => {
const { chunk } = data;
const { entryModule } = chunk;
- const { rawRequest } = entryModule;
+ const { rawRequest, rootModule } = entryModule;
+
+ // When processing ESM files, the requested path
+ // is defined in `entryModule.rootModule.rawRequest`, instead of
+ // being present in `entryModule.rawRequest`.
+ // In the context of frontend view files, they would be processed
+ // as ESM if they use `import` or `export` within it.
+ const request = rootModule?.rawRequest || rawRequest;
- /*
- * If the file being built is a Core Block's frontend file,
- * we build it in the block's directory.
- */
- if ( rawRequest && rawRequest.includes( '/frontend.js' ) ) {
- return `./build/block-library/blocks/[name]/frontend.js`;
+ if ( request.includes( '/view.js' ) ) {
+ return `./build/block-library/[name]/view.js`;
}
return './build/[name]/index.js';