From 5a1031bd2f54cb38749abaae53e9c8942454907a Mon Sep 17 00:00:00 2001 From: Rich Tabor Date: Mon, 10 Jun 2024 09:25:43 -0400 Subject: [PATCH 01/13] Color Variations: Use Grid rather than VStack (#62445) Co-authored-by: richtabor Co-authored-by: jasmussen Co-authored-by: bgardner --- .../global-styles/variations/variations-color.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/edit-site/src/components/global-styles/variations/variations-color.js b/packages/edit-site/src/components/global-styles/variations/variations-color.js index 2b3758e92a512..88361afcc58f8 100644 --- a/packages/edit-site/src/components/global-styles/variations/variations-color.js +++ b/packages/edit-site/src/components/global-styles/variations/variations-color.js @@ -1,7 +1,10 @@ /** * WordPress dependencies */ -import { __experimentalVStack as VStack } from '@wordpress/components'; +import { + __experimentalVStack as VStack, + __experimentalGrid as Grid, +} from '@wordpress/components'; /** * Internal dependencies @@ -22,13 +25,13 @@ export default function ColorVariations( { title, gap = 2 } ) { return ( { title && { title } } - + { colorVariations.map( ( variation, index ) => ( { () => } ) ) } - + ); } From bd6e764e1ba988d35ab17b5cfcb678715051fdd0 Mon Sep 17 00:00:00 2001 From: Amit Raj <77401999+amitraj2203@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:08:06 +0530 Subject: [PATCH 02/13] LinkControl: refined the display of the link preview title and url when both are same (#61819) * Add removeProtocol function to URL package * Fix redundant link preview display when link text includes protocol in LinkControl. * Changed regex for stripDomainPrefixes to handle all protocols * Add unit tests for stripDomainPrefixes function * Refactor URL filtering logic * Change variable name * Moved filterTitleForDisplay outside of component * Adds test cases for the updated regex * Fix typos and remove redundant tests for filterURLForDisplay * Fix isUrlRedundant check in LinkPreview component * Add test case for empty or falsy URL in filterURLForDisplay function Co-authored-by: amitraj2203 Co-authored-by: afercia Co-authored-by: tyxla --- .../components/link-control/link-preview.js | 19 ++++++++++++++++++- packages/url/src/filter-url-for-display.js | 8 +++++++- packages/url/src/test/index.js | 12 ++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/link-control/link-preview.js b/packages/block-editor/src/components/link-control/link-preview.js index fb4b3658e2a4f..d06c9971c680b 100644 --- a/packages/block-editor/src/components/link-control/link-preview.js +++ b/packages/block-editor/src/components/link-control/link-preview.js @@ -27,6 +27,20 @@ import { ViewerSlot } from './viewer-slot'; import useRichUrlData from './use-rich-url-data'; +/** + * Filters the title for display. Removes the protocol and www prefix. + * + * @param {string} title The title to be filtered. + * + * @return {string} The filtered title. + */ +function filterTitleForDisplay( title ) { + // Derived from `filterURLForDisplay` in `@wordpress/url`. + return title + .replace( /^[a-z\-.\+]+[0-9]*:(\/\/)?/i, '' ) + .replace( /^www\./i, '' ); +} + export default function LinkPreview( { value, onEditClick, @@ -59,6 +73,9 @@ export default function LinkPreview( { ! isEmptyURL && stripHTML( richData?.title || value?.title || displayURL ); + const isUrlRedundant = + ! value?.url || filterTitleForDisplay( displayTitle ) === displayURL; + let icon; if ( richData?.icon ) { @@ -112,7 +129,7 @@ export default function LinkPreview( { { displayTitle } - { value?.url && displayTitle !== displayURL && ( + { ! isUrlRedundant && ( { displayURL } diff --git a/packages/url/src/filter-url-for-display.js b/packages/url/src/filter-url-for-display.js index eede264e8e801..436070b667a3e 100644 --- a/packages/url/src/filter-url-for-display.js +++ b/packages/url/src/filter-url-for-display.js @@ -13,8 +13,14 @@ * @return {string} Displayed URL. */ export function filterURLForDisplay( url, maxLength = null ) { + if ( ! url ) { + return ''; + } + // Remove protocol and www prefixes. - let filteredURL = url.replace( /^(?:https?:)\/\/(?:www\.)?/, '' ); + let filteredURL = url + .replace( /^[a-z\-.\+]+[0-9]*:(\/\/)?/i, '' ) + .replace( /^www\./i, '' ); // Ends with / and only has that single slash, strip it. if ( filteredURL.match( /^[^\/]+\/$/ ) ) { diff --git a/packages/url/src/test/index.js b/packages/url/src/test/index.js index 0051b9b89fc73..bd48105baed96 100644 --- a/packages/url/src/test/index.js +++ b/packages/url/src/test/index.js @@ -992,11 +992,23 @@ describe( 'safeDecodeURI', () => { } ); describe( 'filterURLForDisplay', () => { + it( 'should return an empty string if the url is empty or falsy', () => { + let url = filterURLForDisplay( '' ); + expect( url ).toBe( '' ); + url = filterURLForDisplay( null ); + expect( url ).toBe( '' ); + } ); it( 'should remove protocol', () => { let url = filterURLForDisplay( 'http://wordpress.org' ); expect( url ).toBe( 'wordpress.org' ); url = filterURLForDisplay( 'https://wordpress.org' ); expect( url ).toBe( 'wordpress.org' ); + url = filterURLForDisplay( 'file:///folder/file.txt' ); + expect( url ).toBe( '/folder/file.txt' ); + url = filterURLForDisplay( 'tel:0123456789' ); + expect( url ).toBe( '0123456789' ); + url = filterURLForDisplay( 'blob:data' ); + expect( url ).toBe( 'data' ); } ); it( 'should remove www subdomain', () => { const url = filterURLForDisplay( 'http://www.wordpress.org' ); From 3b10cb61156579fad71d4895cc13efae3f598551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20K=C3=A4gy?= Date: Mon, 10 Jun 2024 18:53:25 +0200 Subject: [PATCH 03/13] Fix: Add `network-active` to valid options in `PluginStatus` Type definition (#62450) Co-authored-by: fabiankaegy Co-authored-by: Mamaduka --- packages/core-data/src/entity-types/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-data/src/entity-types/plugin.ts b/packages/core-data/src/entity-types/plugin.ts index 61954ec853531..4ebea97c27996 100644 --- a/packages/core-data/src/entity-types/plugin.ts +++ b/packages/core-data/src/entity-types/plugin.ts @@ -73,7 +73,7 @@ declare module './base-entity-records' { } } -export type PluginStatus = 'active' | 'inactive'; +export type PluginStatus = 'active' | 'inactive' | 'network-active'; export type Plugin< C extends Context = 'edit' > = OmitNevers< _BaseEntityRecords.Plugin< C > >; From f64a0afdd9adf85eba648b6a542a86bcb8b2d6c6 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Mon, 10 Jun 2024 21:35:26 +0300 Subject: [PATCH 04/13] List: fix pasting (#62428) --- .../writing-flow/use-clipboard-handler.js | 36 +++++++++++++++---- ...e-should-paste-list-in-list-1-chromium.txt | 9 +++++ ...ld-paste-paragraphs-in-list-1-chromium.txt | 9 +++++ .../editor/various/copy-cut-paste.spec.js | 26 ++++++++++++++ 4 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-list-in-list-1-chromium.txt create mode 100644 test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-paragraphs-in-list-1-chromium.txt diff --git a/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js b/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js index 56583447d3f0e..bed07b183cc0c 100644 --- a/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js +++ b/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js @@ -6,6 +6,7 @@ import { findTransform, getBlockTransforms, hasBlockSupport, + switchToBlockType, } from '@wordpress/blocks'; import { documentHasSelection, @@ -208,15 +209,36 @@ export default function useClipboardHandler() { firstSelectedClientId ); - if ( - ! blocks.every( ( block ) => - canInsertBlockType( block.name, rootClientId ) - ) - ) { - return; + const newBlocks = []; + + for ( const block of blocks ) { + if ( canInsertBlockType( block.name, rootClientId ) ) { + newBlocks.push( block ); + } else { + // If a block cannot be inserted in a root block, try + // converting it to that root block type and insert the + // inner blocks. + // Example: paragraphs cannot be inserted into a list, + // so convert the paragraphs to a list for list items. + const rootBlockName = getBlockName( rootClientId ); + const switchedBlocks = + block.name !== rootBlockName + ? switchToBlockType( block, rootBlockName ) + : [ block ]; + + if ( ! switchedBlocks ) { + return; + } + + for ( const switchedBlock of switchedBlocks ) { + for ( const innerBlock of switchedBlock.innerBlocks ) { + newBlocks.push( innerBlock ); + } + } + } } - __unstableSplitSelection( blocks ); + __unstableSplitSelection( newBlocks ); event.preventDefault(); } } diff --git a/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-list-in-list-1-chromium.txt b/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-list-in-list-1-chromium.txt new file mode 100644 index 0000000000000..7f74d7fd8b3d0 --- /dev/null +++ b/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-list-in-list-1-chromium.txt @@ -0,0 +1,9 @@ + +
    +
  • x
  • + + + +
  • y‸
  • +
+ \ No newline at end of file diff --git a/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-paragraphs-in-list-1-chromium.txt b/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-paragraphs-in-list-1-chromium.txt new file mode 100644 index 0000000000000..7f74d7fd8b3d0 --- /dev/null +++ b/test/e2e/specs/editor/various/__snapshots__/Copy-cut-paste-should-paste-paragraphs-in-list-1-chromium.txt @@ -0,0 +1,9 @@ + +
    +
  • x
  • + + + +
  • y‸
  • +
+ \ No newline at end of file diff --git a/test/e2e/specs/editor/various/copy-cut-paste.spec.js b/test/e2e/specs/editor/various/copy-cut-paste.spec.js index 48392170e66dd..4951f99fb6b5b 100644 --- a/test/e2e/specs/editor/various/copy-cut-paste.spec.js +++ b/test/e2e/specs/editor/various/copy-cut-paste.spec.js @@ -494,6 +494,32 @@ test.describe( 'Copy/cut/paste', () => { expect( await editor.getEditedPostContent() ).toMatchSnapshot(); } ); + test( 'should paste list in list', async ( { + page, + pageUtils, + editor, + } ) => { + pageUtils.setClipboardData( { html: '
  • x
  • y
' } ); + await editor.insertBlock( { name: 'core/list' } ); + await pageUtils.pressKeys( 'primary+v' ); + // Ensure the selection is correct. + await page.keyboard.type( '‸' ); + expect( await editor.getEditedPostContent() ).toMatchSnapshot(); + } ); + + test( 'should paste paragraphs in list', async ( { + page, + pageUtils, + editor, + } ) => { + pageUtils.setClipboardData( { html: '

x

y

' } ); + await editor.insertBlock( { name: 'core/list' } ); + await pageUtils.pressKeys( 'primary+v' ); + // Ensure the selection is correct. + await page.keyboard.type( '‸' ); + expect( await editor.getEditedPostContent() ).toMatchSnapshot(); + } ); + test( 'should link selection', async ( { pageUtils, editor } ) => { await editor.insertBlock( { name: 'core/paragraph', From c7bb2b7f720ec34140ebf94bde83902fdc92c9aa Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:25:50 +0900 Subject: [PATCH 05/13] DataViews: Fix unnecessary horizontal scrollbar in list layout (#62448) Co-authored-by: t-hamano Co-authored-by: stokesman --- packages/dataviews/src/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dataviews/src/style.scss b/packages/dataviews/src/style.scss index 0390a360f66d2..5844e0c913336 100644 --- a/packages/dataviews/src/style.scss +++ b/packages/dataviews/src/style.scss @@ -436,6 +436,7 @@ .components-button { opacity: 0; position: fixed; + right: 0; } } From e78cb552a5c53b3b124d41d9fdcc6eea44711df6 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 11 Jun 2024 13:28:25 +1000 Subject: [PATCH 06/13] List view: show context menu for content-only blocks in posts (#62354) * Ensure the Edit template context menu is shown in the post editor/site editor pages by checking only for a templateId. Previously it was only shown for pages and there was no check if the user can edit template. Show a not-very-pretty dialogue box where a user cannot edit a template. * Check for an entity before showing the canUser message. * Rename variable Move canUser fallback component beneath existing entity check block * Use existing component but disable the edit button and update the copy * Check for content blocks * Use `getContentLockingParent` Co-authored-by: ramonjd Co-authored-by: talldan Co-authored-by: kevin940726 Co-authored-by: andrewserong Co-authored-by: ellatrix --- .../content-only-settings-menu.js | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 4683dd38593a5..8527dfff4f752 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -19,7 +19,7 @@ import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; function ContentOnlySettingsMenuItems( { clientId, onClose } ) { - const { entity, onNavigateToEntityRecord } = useSelect( + const { entity, onNavigateToEntityRecord, canEditTemplates } = useSelect( ( select ) => { const { getBlockEditingMode, @@ -46,11 +46,12 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { getBlockAttributes( patternParent ).ref ); } else { - const { getCurrentPostType, getCurrentTemplateId } = - select( editorStore ); - const currentPostType = getCurrentPostType(); + const { getCurrentTemplateId } = select( editorStore ); const templateId = getCurrentTemplateId(); - if ( currentPostType === 'page' && templateId ) { + const { getContentLockingParent } = unlock( + select( blockEditorStore ) + ); + if ( ! getContentLockingParent( clientId ) && templateId ) { record = select( coreStore ).getEntityRecord( 'postType', 'wp_template', @@ -58,7 +59,12 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { ); } } + const _canEditTemplates = select( coreStore ).canUser( + 'create', + 'templates' + ); return { + canEditTemplates: _canEditTemplates, entity: record, onNavigateToEntityRecord: getSettings().onNavigateToEntityRecord, @@ -77,6 +83,19 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { } const isPattern = entity.type === 'wp_block'; + let helpText = isPattern + ? __( + 'Edit the pattern to move, delete, or make further changes to this block.' + ) + : __( + 'Edit the template to move, delete, or make further changes to this block.' + ); + + if ( ! canEditTemplates ) { + helpText = __( + 'Only users with permissions to edit the template can move or delete this block' + ); + } return ( <> @@ -88,6 +107,7 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { postType: entity.type, } ); } } + disabled={ ! canEditTemplates } > { isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) } @@ -97,13 +117,7 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { as="p" className="editor-content-only-settings-menu__description" > - { isPattern - ? __( - 'Edit the pattern to move, delete, or make further changes to this block.' - ) - : __( - 'Edit the template to move, delete, or make further changes to this block.' - ) } + { helpText } ); From b7368c01d087578fe104d00765da2c4f2c123057 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 11 Jun 2024 07:28:56 +0400 Subject: [PATCH 07/13] Fix flaky Site Editor command center e2e test (#62454) Co-authored-by: Mamaduka --- test/e2e/specs/site-editor/command-center.spec.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/e2e/specs/site-editor/command-center.spec.js b/test/e2e/specs/site-editor/command-center.spec.js index 6608f37f1701b..fce951ca767be 100644 --- a/test/e2e/specs/site-editor/command-center.spec.js +++ b/test/e2e/specs/site-editor/command-center.spec.js @@ -43,9 +43,11 @@ test.describe( 'Site editor command palette', () => { .click(); await page.keyboard.type( 'index' ); await page.getByRole( 'option', { name: 'index' } ).click(); - await expect( page.getByRole( 'heading', { level: 1 } ) ).toHaveText( - 'Index' - ); + await expect( + page + .getByRole( 'region', { name: 'Editor top bar' } ) + .getByRole( 'heading', { level: 1 } ) + ).toHaveText( 'Index' ); } ); test( 'Open the command palette and navigate to Customize CSS', async ( { From d2d7bf683bab94563a591e4e6abc3afe143ffcf1 Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Tue, 11 Jun 2024 06:08:20 +0200 Subject: [PATCH 08/13] Page creation and duplication: Decode HTML entities in success notices (#62313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Decode the page title when creating a new page from the Site Editor > Pages * Decode the page title when a page is duplicated from the Data Views * Decode the page title when you duplicate an item in the Edit Site > Editor component * Decode the page title when a page or post is duplicated from the block editor * Add ´@wordpress/html-entities´ to the edit post package. Co-authored-by: carolinan Co-authored-by: Mamaduka Co-authored-by: ellatrix --- package-lock.json | 2 ++ packages/edit-post/CHANGELOG.md | 4 ++++ packages/edit-post/package.json | 1 + packages/edit-post/src/components/layout/index.js | 3 ++- packages/edit-site/src/components/add-new-page/index.js | 3 ++- packages/edit-site/src/components/editor/index.js | 3 ++- packages/editor/src/components/post-actions/actions.js | 2 +- 7 files changed, 14 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e20ec0fa393d..4f2901c8fe8bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54118,6 +54118,7 @@ "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", + "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", @@ -69267,6 +69268,7 @@ "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", + "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index 3934ab8cda884..5065e4b903040 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fixes + +- Add ´@wordpress/html-entities´ package to the list of dependencies in package.json. ([#62313](https://github.com/WordPress/gutenberg/pull/62313)) + ## 8.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index b3327218dfc87..e293e459b6ac0 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -44,6 +44,7 @@ "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", + "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index e20732cb646bc..cfaaf810b4191 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -34,6 +34,7 @@ import { import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands'; import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library'; import { addQueryArgs } from '@wordpress/url'; +import { decodeEntities } from '@wordpress/html-entities'; import { store as coreStore } from '@wordpress/core-data'; import { SlotFillProvider } from '@wordpress/components'; @@ -288,7 +289,7 @@ function Layout( { sprintf( // translators: %s: Title of the created post e.g: "Post 1". __( '"%s" successfully created.' ), - title + decodeEntities( title ) ), { type: 'snackbar', diff --git a/packages/edit-site/src/components/add-new-page/index.js b/packages/edit-site/src/components/add-new-page/index.js index 56544c83f491b..a1b19298a1243 100644 --- a/packages/edit-site/src/components/add-new-page/index.js +++ b/packages/edit-site/src/components/add-new-page/index.js @@ -13,6 +13,7 @@ import { useDispatch } from '@wordpress/data'; import { useState } from '@wordpress/element'; import { store as coreStore } from '@wordpress/core-data'; import { store as noticesStore } from '@wordpress/notices'; +import { decodeEntities } from '@wordpress/html-entities'; export default function AddNewPageModal( { onSave, onClose } ) { const [ isCreatingPage, setIsCreatingPage ] = useState( false ); @@ -47,7 +48,7 @@ export default function AddNewPageModal( { onSave, onClose } ) { sprintf( // translators: %s: Title of the created template e.g: "Category". __( '"%s" successfully created.' ), - newPage.title?.rendered || title + decodeEntities( newPage.title?.rendered || title ) ), { type: 'snackbar', diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 50fb05d8d841f..96bf2fad4d6b6 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -21,6 +21,7 @@ import { useCallback, useMemo } from '@wordpress/element'; import { store as noticesStore } from '@wordpress/notices'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { store as preferencesStore } from '@wordpress/preferences'; +import { decodeEntities } from '@wordpress/html-entities'; /** * Internal dependencies @@ -146,7 +147,7 @@ export default function EditSiteEditor( { isLoading } ) { sprintf( // translators: %s: Title of the created post e.g: "Post 1". __( '"%s" successfully created.' ), - _title + decodeEntities( _title ) ), { type: 'snackbar', diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 69337e181f5e5..f376d0e8f969e 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -783,7 +783,7 @@ const duplicatePostAction = { sprintf( // translators: %s: Title of the created template e.g: "Category". __( '"%s" successfully created.' ), - newItem.title?.rendered || title + decodeEntities( newItem.title?.rendered || title ) ), { id: 'duplicate-post-action', From faf5cbaf651315f4a17076b26a6f3b034bd304a2 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:11:23 +1000 Subject: [PATCH 09/13] Section Styles: Register block style variations on `init` (#62461) Co-authored-by: aaronrobertshaw Co-authored-by: oandregal Co-authored-by: annezazu --- backport-changelog/6.6/6756.md | 3 + lib/block-supports/block-style-variations.php | 126 ++++++++++++++---- .../block-style-variations-test.php | 5 + 3 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 backport-changelog/6.6/6756.md diff --git a/backport-changelog/6.6/6756.md b/backport-changelog/6.6/6756.md new file mode 100644 index 0000000000000..e60e128bf45cb --- /dev/null +++ b/backport-changelog/6.6/6756.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6756 + +* https://github.com/WordPress/gutenberg/pull/62461 diff --git a/lib/block-supports/block-style-variations.php b/lib/block-supports/block-style-variations.php index e09bd4ce90bf0..bdda388bdcf61 100644 --- a/lib/block-supports/block-style-variations.php +++ b/lib/block-supports/block-style-variations.php @@ -209,9 +209,6 @@ function gutenberg_render_block_style_variation_class_name( $block_content, $blo /** * Collects block style variation data for merging with theme.json data. - * As each block style variation is processed it is registered if it hasn't - * been already. This registration is required for later sanitization of - * theme.json data. * * @since 6.6.0 * @@ -219,14 +216,13 @@ function gutenberg_render_block_style_variation_class_name( $block_content, $blo * * @return array Block variations data to be merged under `styles.blocks`. */ -function gutenberg_resolve_and_register_block_style_variations( $variations ) { +function gutenberg_resolve_block_style_variations( $variations ) { $variations_data = array(); if ( empty( $variations ) ) { return $variations_data; } - $registry = WP_Block_Styles_Registry::get_instance(); $have_named_variations = ! wp_is_numeric_array( $variations ); foreach ( $variations as $key => $variation ) { @@ -248,23 +244,9 @@ function gutenberg_resolve_and_register_block_style_variations( $variations ) { * Block style variations read in via standalone theme.json partials * need to have their name set to the kebab case version of their title. */ - $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] ); - $variation_label = $variation['title'] ?? $variation_name; + $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] ); foreach ( $supported_blocks as $block_type ) { - $registered_styles = $registry->get_registered_styles_for_block( $block_type ); - - // Register block style variation if it hasn't already been registered. - if ( ! array_key_exists( $variation_name, $registered_styles ) ) { - gutenberg_register_block_style( - $block_type, - array( - 'name' => $variation_name, - 'label' => $variation_label, - ) - ); - } - // Add block style variation data under current block type. $path = array( $block_type, 'variations', $variation_name ); _wp_array_set( $variations_data, $path, $variation_data ); @@ -320,7 +302,7 @@ function gutenberg_merge_block_style_variations_data( $variations_data, $theme_j function gutenberg_resolve_block_style_variations_from_theme_style_variation( $theme_json ) { $theme_json_data = $theme_json->get_data(); $shared_variations = $theme_json_data['styles']['blocks']['variations'] ?? array(); - $variations_data = gutenberg_resolve_and_register_block_style_variations( $shared_variations ); + $variations_data = gutenberg_resolve_block_style_variations( $shared_variations ); return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json, 'user' ); } @@ -337,7 +319,7 @@ function gutenberg_resolve_block_style_variations_from_theme_style_variation( $t */ function gutenberg_resolve_block_style_variations_from_theme_json_partials( $theme_json ) { $block_style_variations = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' ); - $variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations ); + $variations_data = gutenberg_resolve_block_style_variations( $block_style_variations ); return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json ); } @@ -355,7 +337,7 @@ function gutenberg_resolve_block_style_variations_from_theme_json_partials( $the function gutenberg_resolve_block_style_variations_from_primary_theme_json( $theme_json ) { $theme_json_data = $theme_json->get_data(); $block_style_variations = $theme_json_data['styles']['blocks']['variations'] ?? array(); - $variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations ); + $variations_data = gutenberg_resolve_block_style_variations( $block_style_variations ); return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json ); } @@ -411,3 +393,101 @@ function gutenberg_enqueue_block_style_variation_styles() { add_filter( 'wp_theme_json_data_theme', 'gutenberg_resolve_block_style_variations_from_styles_registry', 10, 1 ); add_filter( 'wp_theme_json_data_user', 'gutenberg_resolve_block_style_variations_from_theme_style_variation', 10, 1 ); + + +/** + * Registers any block style variations contained within the provided + * theme.json data. + * + * @access private + * + * @param array $variations Shared block style variations. + */ +function gutenberg_register_block_style_variations_from_theme_json_data( $variations ) { + if ( empty( $variations ) ) { + return; + } + + $registry = WP_Block_Styles_Registry::get_instance(); + $have_named_variations = ! wp_is_numeric_array( $variations ); + + foreach ( $variations as $key => $variation ) { + $supported_blocks = $variation['blockTypes'] ?? array(); + + /* + * Standalone theme.json partial files for block style variations + * will have their styles under a top-level property by the same name. + * Variations defined within an existing theme.json or theme style + * variation will themselves already be the required styles data. + */ + $variation_data = $variation['styles'] ?? $variation; + + if ( empty( $variation_data ) ) { + continue; + } + + /* + * Block style variations read in via standalone theme.json partials + * need to have their name set to the kebab case version of their title. + */ + $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] ); + $variation_label = $variation['title'] ?? $variation_name; + + foreach ( $supported_blocks as $block_type ) { + $registered_styles = $registry->get_registered_styles_for_block( $block_type ); + + // Register block style variation if it hasn't already been registered. + if ( ! array_key_exists( $variation_name, $registered_styles ) ) { + register_block_style( + $block_type, + array( + 'name' => $variation_name, + 'label' => $variation_label, + ) + ); + } + } + } +} + +/** + * Register shared block style variations defined by the theme. + * + * These can come in three forms: + * - the theme's theme.json + * - the theme's partials (standalone files in `/styles` that only define block style variations) + * - the user's theme.json (for example, theme style variations the user selected) + * + * @access private + */ +function gutenberg_register_block_style_variations_from_theme() { + // Partials from `/styles`. + $variations_partials = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' ); + gutenberg_register_block_style_variations_from_theme_json_data( $variations_partials ); + + /* + * Pull the data from the specific origin instead of the merged data. + * This is because, for 6.6, we only support registering block style variations + * for the 'theme' and 'custom' origins but not for 'default' (core theme.json) + * or 'custom' (theme.json in a block). + * + * When/If we add support for every origin, we should switch to using the public API + * instead, e.g.: wp_get_global_styles( array( 'blocks', 'variations' ) ). + */ + + // theme.json of the theme. + $theme_json_theme = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data(); + $variations_theme = $theme_json_theme->get_data()['styles']['blocks']['variations'] ?? array(); + gutenberg_register_block_style_variations_from_theme_json_data( $variations_theme ); + + // User data linked for this theme. + $theme_json_user = WP_Theme_JSON_Resolver_Gutenberg::get_user_data(); + $variations_user = $theme_json_user->get_data()['styles']['blocks']['variations'] ?? array(); + gutenberg_register_block_style_variations_from_theme_json_data( $variations_user ); +} + +// Remove core init action registering variations. +if ( function_exists( 'wp_register_block_style_variations_from_theme' ) ) { + remove_action( 'init', 'wp_register_block_style_variations_from_theme' ); +} +add_action( 'init', 'gutenberg_register_block_style_variations_from_theme' ); diff --git a/phpunit/block-supports/block-style-variations-test.php b/phpunit/block-supports/block-style-variations-test.php index b84267446330c..870a76a4fb4a4 100644 --- a/phpunit/block-supports/block-style-variations-test.php +++ b/phpunit/block-supports/block-style-variations-test.php @@ -63,6 +63,11 @@ public function filter_set_theme_root() { public function test_add_registered_block_styles_to_theme_data() { switch_theme( 'block-theme' ); + // Trigger block style registration that occurs on `init` action. + // do_action( 'init' ) could be used here however this direct call + // means only the updates being tested are performed. + gutenberg_register_block_style_variations_from_theme(); + $variation_styles_data = array( 'color' => array( 'background' => 'darkslateblue', From fd587da210b234364590db764219b2149c1d0789 Mon Sep 17 00:00:00 2001 From: Narendra Sishodiya <32844880+narenin@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:58:42 +0530 Subject: [PATCH 10/13] Fixed : Disambiguate "Cover" translatable string in the context of background-panel.js (#62440) * Fixed : Disambiguate 'Cover' translatable string in the context of background-panel.js * Added context for Contain and Tile * Implemented the suggestions Co-authored-by: narenin Co-authored-by: ramonjd Co-authored-by: audrasjb --- .../global-styles/background-panel.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/background-panel.js b/packages/block-editor/src/components/global-styles/background-panel.js index 7f3c3ed27e667..307c742befafd 100644 --- a/packages/block-editor/src/components/global-styles/background-panel.js +++ b/packages/block-editor/src/components/global-styles/background-panel.js @@ -23,7 +23,7 @@ import { __experimentalHStack as HStack, __experimentalTruncate as Truncate, } from '@wordpress/components'; -import { __, sprintf } from '@wordpress/i18n'; +import { __, _x, sprintf } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import { getFilename } from '@wordpress/url'; import { useCallback, Platform, useRef } from '@wordpress/element'; @@ -544,17 +544,26 @@ function BackgroundSizeToolsPanelItem( { From 48d936421e09122cb1aa1e94f38f726665ffdbf8 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:58:55 +1000 Subject: [PATCH 11/13] Block Styles: Remove core block style variations filters and action (#62090) Co-authored-by: aaronrobertshaw Co-authored-by: oandregal --- lib/block-supports/block-style-variations.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/block-supports/block-style-variations.php b/lib/block-supports/block-style-variations.php index bdda388bdcf61..f2bc6af92e9de 100644 --- a/lib/block-supports/block-style-variations.php +++ b/lib/block-supports/block-style-variations.php @@ -383,6 +383,31 @@ function gutenberg_enqueue_block_style_variation_styles() { // Register the block support. WP_Block_Supports::get_instance()->register( 'block-style-variation', array() ); +// Remove core filters and action. +if ( function_exists( 'wp_render_block_style_variation_support_styles' ) ) { + remove_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles' ); +} +if ( function_exists( 'wp_render_block_style_variation_class_name' ) ) { + remove_filter( 'render_block', 'wp_render_block_style_variation_class_name' ); +} +if ( function_exists( 'wp_enqueue_block_style_variation_styles' ) ) { + remove_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles' ); +} + +if ( function_exists( 'wp_resolve_block_style_variations_from_primary_theme_json' ) ) { + remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_primary_theme_json' ); +} +if ( function_exists( 'wp_resolve_block_style_variations_from_theme_json_partials' ) ) { + remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_theme_json_partials' ); +} +if ( function_exists( 'wp_resolve_block_style_variations_from_styles_registry' ) ) { + remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_styles_registry' ); +} +if ( function_exists( 'wp_resolve_block_style_variations_from_theme_style_variation' ) ) { + remove_filter( 'wp_theme_json_data_user', 'wp_resolve_block_style_variations_from_theme_style_variation' ); +} + +// Add Gutenberg filters and action. add_filter( 'render_block_data', 'gutenberg_render_block_style_variation_support_styles', 10, 2 ); add_filter( 'render_block', 'gutenberg_render_block_style_variation_class_name', 10, 2 ); add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_block_style_variation_styles', 1 ); From 3a20fb048ffa8500d3359c9e0a8d99fd2a514a72 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 11 Jun 2024 09:05:07 +0200 Subject: [PATCH 12/13] Site Editor: Remove editor specific classes from shell wrapper. (#62389) Co-authored-by: youknowriad Co-authored-by: jasmussen Co-authored-by: ntsekouras --- .../block-library/src/navigation/editor.scss | 12 ---- .../edit-site/src/components/layout/index.js | 55 ++++++------------- .../editor/src/components/post-title/index.js | 7 +-- .../components/post-title/post-title-raw.js | 7 +-- 4 files changed, 22 insertions(+), 59 deletions(-) diff --git a/packages/block-library/src/navigation/editor.scss b/packages/block-library/src/navigation/editor.scss index 9f22262c53bd9..c62cbe9614c91 100644 --- a/packages/block-library/src/navigation/editor.scss +++ b/packages/block-library/src/navigation/editor.scss @@ -457,12 +457,6 @@ $color-control-label-height: 20px; } } -.has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open { - @include break-medium() { - top: $admin-bar-height + $header-height + $block-toolbar-height + $border-width; - } -} - .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open, .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open { top: $admin-bar-height + $header-height + $block-toolbar-height + $border-width; @@ -479,12 +473,6 @@ $color-control-label-height: 20px; } } - .has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open { - @include break-medium() { - top: $header-height + $block-toolbar-height + $border-width; - } - } - .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open, .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open { top: $header-height + $block-toolbar-height + $border-width; diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index 58de32d4b4687..45a2b79adca65 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -25,7 +25,6 @@ import { CommandMenu, privateApis as commandsPrivateApis, } from '@wordpress/commands'; -import { store as preferencesStore } from '@wordpress/preferences'; import { privateApis as blockEditorPrivateApis, store as blockEditorStore, @@ -74,38 +73,24 @@ export default function Layout() { const isMobileViewport = useViewportMatch( 'medium', '<' ); const toggleRef = useRef(); - const { - isDistractionFree, - hasFixedToolbar, - hasBlockSelected, - canvasMode, - previousShortcut, - nextShortcut, - } = useSelect( ( select ) => { - const { getAllShortcutKeyCombinations } = select( - keyboardShortcutsStore - ); - const { getCanvasMode } = unlock( select( editSiteStore ) ); - return { - canvasMode: getCanvasMode(), - previousShortcut: getAllShortcutKeyCombinations( - 'core/editor/previous-region' - ), - nextShortcut: getAllShortcutKeyCombinations( - 'core/editor/next-region' - ), - hasFixedToolbar: select( preferencesStore ).get( - 'core', - 'fixedToolbar' - ), - isDistractionFree: select( preferencesStore ).get( - 'core', - 'distractionFree' - ), - hasBlockSelected: - select( blockEditorStore ).getBlockSelectionStart(), - }; - }, [] ); + const { hasBlockSelected, canvasMode, previousShortcut, nextShortcut } = + useSelect( ( select ) => { + const { getAllShortcutKeyCombinations } = select( + keyboardShortcutsStore + ); + const { getCanvasMode } = unlock( select( editSiteStore ) ); + return { + canvasMode: getCanvasMode(), + previousShortcut: getAllShortcutKeyCombinations( + 'core/editor/previous-region' + ), + nextShortcut: getAllShortcutKeyCombinations( + 'core/editor/next-region' + ), + hasBlockSelected: + select( blockEditorStore ).getBlockSelectionStart(), + }; + }, [] ); const navigateRegionsProps = useNavigateRegions( { previous: previousShortcut, next: nextShortcut, @@ -163,11 +148,7 @@ export default function Layout() { 'edit-site-layout', navigateRegionsProps.className, { - 'is-distraction-free': - isDistractionFree && canvasMode === 'edit', 'is-full-canvas': canvasMode === 'edit', - 'has-fixed-toolbar': hasFixedToolbar, - 'is-block-toolbar-visible': hasBlockSelected, } ) } > diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index 57ab39f006161..08bd07f4b72db 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -30,14 +30,12 @@ import usePostTitle from './use-post-title'; import PostTypeSupportCheck from '../post-type-support-check'; function PostTitle( _, forwardedRef ) { - const { placeholder, hasFixedToolbar } = useSelect( ( select ) => { + const { placeholder } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); - const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } = - getSettings(); + const { titlePlaceholder } = getSettings(); return { placeholder: titlePlaceholder, - hasFixedToolbar: _hasFixedToolbar, }; }, [] ); @@ -186,7 +184,6 @@ function PostTitle( _, forwardedRef ) { // This same block is used in both the visual and the code editor. const className = clsx( DEFAULT_CLASSNAMES, { 'is-selected': isSelected, - 'has-fixed-toolbar': hasFixedToolbar, } ); return ( diff --git a/packages/editor/src/components/post-title/post-title-raw.js b/packages/editor/src/components/post-title/post-title-raw.js index a4c9713a09492..66c944b45871a 100644 --- a/packages/editor/src/components/post-title/post-title-raw.js +++ b/packages/editor/src/components/post-title/post-title-raw.js @@ -29,14 +29,12 @@ import usePostTitle from './use-post-title'; * @return {Component} The rendered component. */ function PostTitleRaw( _, forwardedRef ) { - const { placeholder, hasFixedToolbar } = useSelect( ( select ) => { + const { placeholder } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); - const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } = - getSettings(); + const { titlePlaceholder } = getSettings(); return { placeholder: titlePlaceholder, - hasFixedToolbar: _hasFixedToolbar, }; }, [] ); @@ -61,7 +59,6 @@ function PostTitleRaw( _, forwardedRef ) { // This same block is used in both the visual and the code editor. const className = clsx( DEFAULT_CLASSNAMES, { 'is-selected': isSelected, - 'has-fixed-toolbar': hasFixedToolbar, 'is-raw-text': true, } ); From edd5fa4c0d8107d151f8e890eaaeb8293983bd6d Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 11 Jun 2024 18:20:45 +1000 Subject: [PATCH 13/13] Block style variation: rename hook (#62464) Co-authored-by: ramonjd Co-authored-by: aaronrobertshaw --- packages/block-editor/src/hooks/block-style-variation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/hooks/block-style-variation.js b/packages/block-editor/src/hooks/block-style-variation.js index ee02b97d21670..311997d46f0ad 100644 --- a/packages/block-editor/src/hooks/block-style-variation.js +++ b/packages/block-editor/src/hooks/block-style-variation.js @@ -43,7 +43,7 @@ function getVariationNameFromClass( className, registeredStyles = [] ) { return null; } -function useBlockSyleVariation( name, variation, clientId ) { +function useBlockStyleVariation( name, variation, clientId ) { // Prefer global styles data in GlobalStylesContext, which are available // if in the site editor. Otherwise fall back to whatever is in the // editor settings and available in the post editor. @@ -96,7 +96,7 @@ function useBlockProps( { name, className, clientId } ) { const variation = getVariationNameFromClass( className, registeredStyles ); const variationClass = `is-style-${ variation }-${ clientId }`; - const { settings, styles } = useBlockSyleVariation( + const { settings, styles } = useBlockStyleVariation( name, variation, clientId