diff --git a/backport-changelog/6.7/7258.md b/backport-changelog/6.7/7258.md new file mode 100644 index 00000000000000..6714b13b70b8d2 --- /dev/null +++ b/backport-changelog/6.7/7258.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7258 + +* https://github.com/WordPress/gutenberg/pull/64570 \ No newline at end of file diff --git a/lib/compat/wordpress-6.7/block-bindings.php b/lib/compat/wordpress-6.7/block-bindings.php index 398b53b340673b..9e82c1843f35a0 100644 --- a/lib/compat/wordpress-6.7/block-bindings.php +++ b/lib/compat/wordpress-6.7/block-bindings.php @@ -38,3 +38,18 @@ function gutenberg_add_server_block_bindings_sources_to_editor_settings( $editor } add_filter( 'block_editor_settings_all', 'gutenberg_add_server_block_bindings_sources_to_editor_settings', 10 ); + +/** + * Initialize `canUpdateBlockBindings` editor setting if it doesn't exist. By default, it is `true` only for admin users. + * + * @param array $settings The block editor settings from the `block_editor_settings_all` filter. + * @return array The editor settings including `canUpdateBlockBindings`. + */ +function gutenberg_add_can_update_block_bindings_editor_setting( $editor_settings ) { + if ( empty( $editor_settings['canUpdateBlockBindings'] ) ) { + $editor_settings['canUpdateBlockBindings'] = current_user_can( 'manage_options' ); + } + return $editor_settings; +} + +add_filter( 'block_editor_settings_all', 'gutenberg_add_can_update_block_bindings_editor_setting', 10 ); diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index c6bd99a18bf4c7..cb9fddbb056a12 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -34,9 +34,6 @@ function gutenberg_enable_experiments() { if ( $gutenberg_experiments && array_key_exists( 'gutenberg-quick-edit-dataviews', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalQuickEditDataViews = true', 'before' ); } - if ( $gutenberg_experiments && array_key_exists( 'gutenberg-block-bindings-ui', $gutenberg_experiments ) ) { - wp_add_inline_script( 'wp-block-editor', 'window.__experimentalBlockBindingsUI = true', 'before' ); - } if ( $gutenberg_experiments && array_key_exists( 'gutenberg-media-processing', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalMediaProcessing = true', 'before' ); } diff --git a/lib/experiments-page.php b/lib/experiments-page.php index f76dcdca7d18cb..cccbab263c44fd 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -175,18 +175,6 @@ function gutenberg_initialize_experiments_settings() { ) ); - add_settings_field( - 'gutenberg-block-bindings-ui', - __( 'UI to create block bindings', 'gutenberg' ), - 'gutenberg_display_experiment_field', - 'gutenberg-experiments', - 'gutenberg_experiments_section', - array( - 'label' => __( 'Add UI to create and update block bindings in block inspector controls.', 'gutenberg' ), - 'id' => 'gutenberg-block-bindings-ui', - ) - ); - add_settings_field( 'gutenberg-media-processing', __( 'Client-side media processing', 'gutenberg' ), diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 9daf29f8043bba..9c610e9e8c2d46 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -307,6 +307,7 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => { /> +
diff --git a/packages/block-editor/src/components/inspector-controls-tabs/settings-tab.js b/packages/block-editor/src/components/inspector-controls-tabs/settings-tab.js index ec34035b754a91..ea2f45114bf9cf 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/settings-tab.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/settings-tab.js @@ -9,6 +9,7 @@ const SettingsTab = ( { showAdvancedControls = false } ) => ( <> + { showAdvancedControls && (
diff --git a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js index ff68be82a829f1..6a80d47f024816 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js @@ -32,6 +32,7 @@ function getShowTabs( blockName, tabSettings = {} ) { export default function useInspectorControlsTabs( blockName ) { const tabs = []; const { + bindings: bindingsGroup, border: borderGroup, color: colorGroup, default: defaultGroup, @@ -64,8 +65,10 @@ export default function useInspectorControlsTabs( blockName ) { // (i.e. both list view and styles), check only the default and position // InspectorControls slots. If we have multiple tabs, we'll need to check // the advanced controls slot as well to ensure they are rendered. - const advancedFills = - useSlotFills( InspectorAdvancedControls.slotName ) || []; + const advancedFills = [ + ...( useSlotFills( InspectorAdvancedControls.slotName ) || [] ), + ...( useSlotFills( bindingsGroup.Slot.__unstableName ) || [] ), + ]; const settingsFills = [ ...( useSlotFills( defaultGroup.Slot.__unstableName ) || [] ), diff --git a/packages/block-editor/src/components/inspector-controls/groups.js b/packages/block-editor/src/components/inspector-controls/groups.js index 9ca1a72b9918a6..34ec49a5e1cb41 100644 --- a/packages/block-editor/src/components/inspector-controls/groups.js +++ b/packages/block-editor/src/components/inspector-controls/groups.js @@ -5,6 +5,7 @@ import { createSlotFill } from '@wordpress/components'; const InspectorControlsDefault = createSlotFill( 'InspectorControls' ); const InspectorControlsAdvanced = createSlotFill( 'InspectorAdvancedControls' ); +const InspectorControlsBindings = createSlotFill( 'InspectorControlsBindings' ); const InspectorControlsBackground = createSlotFill( 'InspectorControlsBackground' ); @@ -26,6 +27,7 @@ const groups = { default: InspectorControlsDefault, advanced: InspectorControlsAdvanced, background: InspectorControlsBackground, + bindings: InspectorControlsBindings, border: InspectorControlsBorder, color: InspectorControlsColor, dimensions: InspectorControlsDimensions, diff --git a/packages/block-editor/src/hooks/block-bindings.js b/packages/block-editor/src/hooks/block-bindings.js index 961a34f6f858fc..d015eca5af9926 100644 --- a/packages/block-editor/src/hooks/block-bindings.js +++ b/packages/block-editor/src/hooks/block-bindings.js @@ -13,7 +13,7 @@ import { __experimentalVStack as VStack, privateApis as componentsPrivateApis, } from '@wordpress/components'; -import { useRegistry } from '@wordpress/data'; +import { useRegistry, useSelect } from '@wordpress/data'; import { useContext, Fragment } from '@wordpress/element'; import { useViewportMatch } from '@wordpress/compose'; @@ -28,6 +28,7 @@ import { unlock } from '../lock-unlock'; import InspectorControls from '../components/inspector-controls'; import BlockContext from '../components/block-context'; import { useBlockBindingsUtils } from '../utils/block-bindings'; +import { store as blockEditorStore } from '../store'; const { DropdownMenuV2 } = unlock( componentsPrivateApis ); @@ -201,6 +202,13 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => { } } ); + const { canUpdateBlockBindings } = useSelect( ( select ) => { + return { + canUpdateBlockBindings: + select( blockEditorStore ).getSettings().canUpdateBlockBindings, + }; + }, [] ); + if ( ! bindableAttributes || bindableAttributes.length === 0 ) { return null; } @@ -236,17 +244,16 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => { } } ); - // Lock the UI when the experiment is not enabled or there are no fields to connect to. + // Lock the UI when the user can't update bindings or there are no fields to connect to. const readOnly = - ! window.__experimentalBlockBindingsUI || - ! Object.keys( fieldsList ).length; + ! canUpdateBlockBindings || ! Object.keys( fieldsList ).length; if ( readOnly && Object.keys( filteredBindings ).length === 0 ) { return null; } return ( - + { @@ -268,9 +275,13 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => { /> ) } - - { __( 'Attributes connected to various sources.' ) } - + + + { __( + 'Attributes connected to custom fields or other dynamic data.' + ) } + + ); diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index 6aa2763cf9db06..48290caefc158e 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -47,6 +47,7 @@ const BLOCK_EDITOR_SETTINGS = [ 'allowedMimeTypes', 'bodyPlaceholder', 'canLockBlocks', + 'canUpdateBlockBindings', 'capabilities', 'clearBlockSelection', 'codeEditingEnabled', diff --git a/test/e2e/specs/editor/various/block-bindings.spec.js b/test/e2e/specs/editor/various/block-bindings.spec.js index d0e1f079ce8439..5feda2bdc3334a 100644 --- a/test/e2e/specs/editor/various/block-bindings.spec.js +++ b/test/e2e/specs/editor/various/block-bindings.spec.js @@ -1394,20 +1394,10 @@ test.describe( 'Block bindings', () => { editor, page, } ) => { - // Activate the block bindings UI experiment. - await page.evaluate( () => { - window.__experimentalBlockBindingsUI = true; - } ); - await editor.insertBlock( { name: 'core/paragraph', } ); - await page - .getByRole( 'tabpanel', { - name: 'Settings', - } ) - .getByLabel( 'Attributes options' ) - .click(); + await page.getByLabel( 'Attributes options' ).click(); const contentAttribute = page.getByRole( 'menuitemcheckbox', { name: 'Show content', } ); @@ -1417,11 +1407,6 @@ test.describe( 'Block bindings', () => { editor, page, } ) => { - // Activate the block bindings UI experiment. - await page.evaluate( () => { - window.__experimentalBlockBindingsUI = true; - } ); - await editor.insertBlock( { name: 'core/paragraph', attributes: { @@ -1436,12 +1421,7 @@ test.describe( 'Block bindings', () => { }, }, } ); - await page - .getByRole( 'tabpanel', { - name: 'Settings', - } ) - .getByRole( 'button', { name: 'content' } ) - .click(); + await page.getByRole( 'button', { name: 'content' } ).click(); await page .getByRole( 'menuitemradio' ) @@ -1539,20 +1519,10 @@ test.describe( 'Block bindings', () => { editor, page, } ) => { - // Activate the block bindings UI experiment. - await page.evaluate( () => { - window.__experimentalBlockBindingsUI = true; - } ); - await editor.insertBlock( { name: 'core/heading', } ); - await page - .getByRole( 'tabpanel', { - name: 'Settings', - } ) - .getByLabel( 'Attributes options' ) - .click(); + await page.getByLabel( 'Attributes options' ).click(); const contentAttribute = page.getByRole( 'menuitemcheckbox', { name: 'Show content', } ); @@ -1739,11 +1709,6 @@ test.describe( 'Block bindings', () => { editor, page, } ) => { - // Activate the block bindings UI experiment. - await page.evaluate( () => { - window.__experimentalBlockBindingsUI = true; - } ); - await editor.insertBlock( { name: 'core/buttons', innerBlocks: [ @@ -2074,11 +2039,6 @@ test.describe( 'Block bindings', () => { editor, page, } ) => { - // Activate the block bindings UI experiment. - await page.evaluate( () => { - window.__experimentalBlockBindingsUI = true; - } ); - await editor.insertBlock( { name: 'core/image', } ); @@ -2367,11 +2327,9 @@ test.describe( 'Block bindings', () => { }, } ); - const bindingsPanel = page - .getByRole( 'tabpanel', { - name: 'Settings', - } ) - .locator( '.block-editor-bindings__panel' ); + const bindingsPanel = page.locator( + '.block-editor-bindings__panel' + ); await expect( bindingsPanel ).toContainText( 'Server Source' ); } ); } );