From 8a0eedeb85ba019f7179070f63447bb120e60308 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Tue, 28 Feb 2023 16:34:01 +0000 Subject: [PATCH 01/24] Navigation: Don't create duplicate navigation menus (#48599) --- .../block-library/src/navigation/edit/unsaved-inner-blocks.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-library/src/navigation/edit/unsaved-inner-blocks.js b/packages/block-library/src/navigation/edit/unsaved-inner-blocks.js index bb23db9c3bc8d9..f83f29621579b1 100644 --- a/packages/block-library/src/navigation/edit/unsaved-inner-blocks.js +++ b/packages/block-library/src/navigation/edit/unsaved-inner-blocks.js @@ -146,7 +146,6 @@ export default function UnsavedInnerBlocks( { createNavigationMenu( null, blocks ); }, [ - blocks, createNavigationMenu, isDisabled, isSaving, From 35859ff0b24922f9d6115b381a3cc1001dd094eb Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:57:43 +0200 Subject: [PATCH 02/24] Autocomplete: avoid calling setState on input (#48565) --- packages/components/src/autocomplete/index.js | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/packages/components/src/autocomplete/index.js b/packages/components/src/autocomplete/index.js index be96839a2dd571..5903e2cf53f1fe 100644 --- a/packages/components/src/autocomplete/index.js +++ b/packages/components/src/autocomplete/index.js @@ -418,53 +418,47 @@ function useAutocomplete( { }; } +function useLastDifferentValue( value ) { + const history = useRef( new Set() ); + + history.current.add( value ); + + // Keep the history size to 2. + if ( history.current.size > 2 ) { + history.current.delete( Array.from( history.current )[ 0 ] ); + } + + return Array.from( history.current )[ 0 ]; +} + export function useAutocompleteProps( options ) { - const [ isVisible, setIsVisible ] = useState( false ); const ref = useRef(); - const recordAfterInput = useRef(); const onKeyDownRef = useRef(); + const { record } = options; + const previousRecord = useLastDifferentValue( record ); const { popover, listBoxId, activeId, onKeyDown } = useAutocomplete( { ...options, contentRef: ref, } ); onKeyDownRef.current = onKeyDown; - useEffect( () => { - if ( isVisible ) { - if ( ! recordAfterInput.current ) { - recordAfterInput.current = options.record; - } else if ( - recordAfterInput.current.start !== options.record.start || - recordAfterInput.current.end !== options.record.end - ) { - setIsVisible( false ); - recordAfterInput.current = null; - } - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ options.record ] ); - const mergedRefs = useMergeRefs( [ ref, useRefEffect( ( element ) => { function _onKeyDown( event ) { onKeyDownRef.current( event ); } - function _onInput() { - // Only show auto complete UI if the user is inputting text. - setIsVisible( true ); - recordAfterInput.current = null; - } element.addEventListener( 'keydown', _onKeyDown ); - element.addEventListener( 'input', _onInput ); return () => { element.removeEventListener( 'keydown', _onKeyDown ); - element.removeEventListener( 'input', _onInput ); }; }, [] ), ] ); - if ( ! isVisible ) { + // We only want to show the popover if the user has typed something. + const didUserInput = record.text !== previousRecord?.text; + + if ( ! didUserInput ) { return { ref: mergedRefs }; } From 641e4c0b1d26fd02d519497d26de6271dade500b Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Tue, 28 Feb 2023 22:06:43 +0000 Subject: [PATCH 03/24] Duotone: Use CSS variables instead of slugs in block attributes (#48426) Co-authored-by: Dave Smith Co-authored-by: Alex Lende --- lib/block-supports/duotone.php | 13 ++++++++----- packages/block-editor/src/hooks/duotone.js | 4 ++-- packages/block-editor/src/hooks/test/duotone.js | 9 ++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/block-supports/duotone.php b/lib/block-supports/duotone.php index e0dea9e97cc2bb..d973deb8416848 100644 --- a/lib/block-supports/duotone.php +++ b/lib/block-supports/duotone.php @@ -311,6 +311,9 @@ function gutenberg_get_duotone_filter_id( $preset ) { * @return string Duotone CSS filter property url value. */ function gutenberg_get_duotone_filter_property( $preset ) { + if ( isset( $preset['colors'] ) && 'unset' === $preset['colors'] ) { + return 'none'; + } $filter_id = gutenberg_get_duotone_filter_id( $preset ); return "url('#" . $filter_id . "')"; } @@ -449,16 +452,16 @@ function gutenberg_render_duotone_support( $block_content, $block ) { $duotone_attr = $block['attrs']['style']['color']['duotone']; $is_duotone_colors_array = is_array( $duotone_attr ); - $is_duotone_unset = 'unset' === $duotone_attr; - $is_duotone_preset = ! $is_duotone_colors_array && ! $is_duotone_unset; + $is_duotone_preset = ! $is_duotone_colors_array && strpos( $duotone_attr, 'var:preset|duotone|' ) === 0; if ( $is_duotone_preset ) { + $slug = str_replace( 'var:preset|duotone|', '', $duotone_attr ); $filter_preset = array( - 'slug' => $duotone_attr, + 'slug' => $slug, ); // Utilise existing CSS custom property. - $filter_property = "var(--wp--preset--duotone--$duotone_attr)"; + $filter_property = "var(--wp--preset--duotone--$slug)"; } else { // Handle when Duotone is either: // - "unset" @@ -472,7 +475,7 @@ function gutenberg_render_duotone_support( $block_content, $block ) { ); // Build a customised CSS filter property for unique slug. - $filter_property = $is_duotone_unset ? 'none' : gutenberg_get_duotone_filter_property( $filter_preset ); + $filter_property = gutenberg_get_duotone_filter_property( $filter_preset ); } // - Applied as a class attribute to the block wrapper. diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js index a2adb62f26b5c0..b56d9f64b4e832 100644 --- a/packages/block-editor/src/hooks/duotone.js +++ b/packages/block-editor/src/hooks/duotone.js @@ -80,7 +80,7 @@ export function getColorsFromDuotonePreset( duotone, duotonePalette ) { return; } const preset = duotonePalette?.find( ( { slug } ) => { - return slug === duotone; + return duotone === `var:preset|duotone|${ slug }`; } ); return preset ? preset.colors : undefined; @@ -97,7 +97,7 @@ export function getDuotonePresetFromColors( colors, duotonePalette ) { ); } ); - return preset ? preset.slug : undefined; + return preset ? `var:preset|duotone|${ preset.slug }` : undefined; } function DuotonePanel( { attributes, setAttributes } ) { diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index b97c967d212f07..8bee8f6c11dcfb 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -37,14 +37,17 @@ describe( 'Duotone utilities', () => { it( 'should return undefined if a non-existent preset is provided', () => { expect( - getColorsFromDuotonePreset( 'does-not-exist', duotonePalette ) + getColorsFromDuotonePreset( + `var:preset|duotone|does-not-exist`, + duotonePalette + ) ).toBeUndefined(); } ); it( 'should return the colors from the preset if found', () => { expect( getColorsFromDuotonePreset( - duotonePalette[ 2 ].slug, + `var:preset|duotone|${ duotonePalette[ 2 ].slug }`, duotonePalette ) ).toEqual( duotonePalette[ 2 ].colors ); @@ -93,7 +96,7 @@ describe( 'Duotone utilities', () => { duotonePalette[ 2 ].colors, duotonePalette ) - ).toEqual( duotonePalette[ 2 ].slug ); + ).toEqual( `var:preset|duotone|${ duotonePalette[ 2 ].slug }` ); } ); } ); } ); From 26555e5a230cfe2827304c6b94675de5696177e8 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Tue, 28 Feb 2023 22:25:17 +0000 Subject: [PATCH 04/24] Bump plugin version to 15.2.3 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index a0a30fbe079d69..f2ff542e9895d3 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.0 * Requires PHP: 5.6 - * Version: 15.2.2 + * Version: 15.2.3 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 5f8c1da350247d..d19e5fb97f5a66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "15.2.2", + "version": "15.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0bcf8ca16be47e..21c06ee4008167 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "15.2.2", + "version": "15.2.3", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From 82cb2fe263118c607c3bb184e292cedf2da30293 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Tue, 28 Feb 2023 22:37:53 +0000 Subject: [PATCH 05/24] Update Changelog for 15.2.3 --- changelog.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/changelog.txt b/changelog.txt index 4a23e8b0345a21..1d40cafd8a0abd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,20 @@ == Changelog == += 15.2.3 = + +## Changelog + +### Bug Fixes + +- useAsyncList: flush state updates when processing queue (https://github.com/WordPress/gutenberg/pull/48238). + +## Contributors + +The following contributors merged PRs in this release: + +@jsnajdr + + = 15.2.2 = From fa78dbd55b348f88461860877e42021ee16261d4 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 1 Mar 2023 10:27:18 +1000 Subject: [PATCH 06/24] Global Styles: Fix typo in valid settings for fluid typography (#48605) --- packages/block-editor/src/components/global-styles/hooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/global-styles/hooks.js b/packages/block-editor/src/components/global-styles/hooks.js index 33557025b84922..f483a9208e6e11 100644 --- a/packages/block-editor/src/components/global-styles/hooks.js +++ b/packages/block-editor/src/components/global-styles/hooks.js @@ -55,7 +55,7 @@ const VALID_SETTINGS = [ 'spacing.margin', 'spacing.padding', 'spacing.units', - 'typography.fuild', + 'typography.fluid', 'typography.customFontSize', 'typography.dropCap', 'typography.fontFamilies', From 245617ae547bff9e5202d01d76554ab22b089fb8 Mon Sep 17 00:00:00 2001 From: brookewp <35543432+brookewp@users.noreply.github.com> Date: Tue, 28 Feb 2023 17:40:13 -0800 Subject: [PATCH 07/24] ToggleControl: remove margin overrides and add opt-in prop (#47866) * ToggleControl: remove margin overrides and add opt-in prop * Replace span with help prop * Remove CSS for removed class --- .../src/components/block-lock/modal.js | 1 + .../src/components/block-lock/style.scss | 9 --------- .../src/components/date-format-picker/index.js | 14 ++++++-------- .../src/components/date-format-picker/style.scss | 5 ----- .../src/components/link-control/settings.js | 1 + .../components/responsive-block-control/index.js | 1 + .../src/components/url-popover/stories/index.js | 1 + packages/block-editor/src/hooks/layout.js | 1 + packages/block-editor/src/layouts/flex.js | 1 + packages/block-library/src/archives/edit.js | 3 +++ packages/block-library/src/audio/edit.js | 2 ++ packages/block-library/src/avatar/edit.js | 1 + packages/block-library/src/categories/edit.js | 5 +++++ packages/block-library/src/columns/edit.js | 1 + .../block-library/src/comment-author-name/edit.js | 2 ++ packages/block-library/src/comment-date/edit.js | 1 + .../block-library/src/comment-edit-link/edit.js | 1 + packages/block-library/src/comments-title/edit.js | 2 ++ .../src/cover/edit/inspector-controls.js | 2 ++ packages/block-library/src/embed/embed-controls.js | 1 + packages/block-library/src/file/inspector.js | 3 +++ packages/block-library/src/gallery/edit.js | 2 ++ packages/block-library/src/gallery/v1/edit.js | 1 + packages/block-library/src/latest-comments/edit.js | 3 +++ packages/block-library/src/latest-posts/edit.js | 4 ++++ .../src/list/ordered-list-settings.js | 1 + packages/block-library/src/loginout/edit.js | 2 ++ packages/block-library/src/media-text/edit.js | 2 ++ packages/block-library/src/more/edit.js | 1 + .../block-library/src/navigation/edit/index.js | 2 ++ .../src/navigation/edit/overlay-menu-preview.js | 1 + packages/block-library/src/paragraph/edit.js | 1 + .../block-library/src/post-author-name/edit.js | 2 ++ packages/block-library/src/post-author/edit.js | 4 ++++ packages/block-library/src/post-date/edit.js | 2 ++ packages/block-library/src/post-excerpt/edit.js | 1 + .../block-library/src/post-featured-image/edit.js | 2 ++ .../block-library/src/post-navigation-link/edit.js | 2 ++ packages/block-library/src/post-title/edit.js | 2 ++ packages/block-library/src/query-title/edit.js | 2 ++ .../src/query/edit/inspector-controls/index.js | 1 + packages/block-library/src/read-more/edit.js | 1 + packages/block-library/src/rss/edit.js | 3 +++ packages/block-library/src/site-logo/edit.js | 3 +++ .../block-library/src/site-title/edit/index.js | 2 ++ packages/block-library/src/social-links/edit.js | 2 ++ .../block-library/src/table-of-contents/edit.js | 1 + packages/block-library/src/table/edit.js | 3 +++ packages/block-library/src/tag-cloud/edit.js | 1 + .../src/video/edit-common-settings.js | 5 +++++ 50 files changed, 95 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/components/block-lock/modal.js b/packages/block-editor/src/components/block-lock/modal.js index 580498bc38e382..cfafa6c031bbd1 100644 --- a/packages/block-editor/src/components/block-lock/modal.js +++ b/packages/block-editor/src/components/block-lock/modal.js @@ -187,6 +187,7 @@ export default function BlockLockModal( { clientId, onClose } ) { { hasTemplateLock && ( { __( 'Date format' ) } - { __( 'Default format' ) } - - { dateI18n( defaultFormat, EXAMPLE_DATE ) } - - - } + __nextHasNoMarginBottom + label={ __( 'Default format' ) } + help={ `${ __( 'Example:' ) } ${ dateI18n( + defaultFormat, + EXAMPLE_DATE + ) }` } checked={ ! format } onChange={ ( checked ) => onChange( checked ? null : defaultFormat ) diff --git a/packages/block-editor/src/components/date-format-picker/style.scss b/packages/block-editor/src/components/date-format-picker/style.scss index f8d82c591cc0ae..d1ad52408d3502 100644 --- a/packages/block-editor/src/components/date-format-picker/style.scss +++ b/packages/block-editor/src/components/date-format-picker/style.scss @@ -2,11 +2,6 @@ margin-bottom: $grid-unit-20; } -.block-editor-date-format-picker__default-format-toggle-control__hint { - color: $gray-700; - display: block; -} - .block-editor-date-format-picker__custom-format-select-control__custom-option { border-top: 1px solid $gray-300; diff --git a/packages/block-editor/src/components/link-control/settings.js b/packages/block-editor/src/components/link-control/settings.js index beddc00d5cd50f..4e71bccaf3286d 100644 --- a/packages/block-editor/src/components/link-control/settings.js +++ b/packages/block-editor/src/components/link-control/settings.js @@ -20,6 +20,7 @@ const LinkControlSettings = ( { value, onChange = noop, settings } ) => { const theSettings = settings.map( ( setting ) => ( { onClose={ close } renderSettings={ () => ( diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 836a9cd5a57c6e..aa2d278aee5826 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -211,6 +211,7 @@ function LayoutPanel( { { showInheritToggle && ( <> { onChange( { diff --git a/packages/block-library/src/archives/edit.js b/packages/block-library/src/archives/edit.js index 9f1f681e95a09b..4eed206314e427 100644 --- a/packages/block-library/src/archives/edit.js +++ b/packages/block-library/src/archives/edit.js @@ -19,6 +19,7 @@ export default function ArchivesEdit( { attributes, setAttributes } ) { @@ -29,6 +30,7 @@ export default function ArchivesEdit( { attributes, setAttributes } ) { /> { displayAsDropdown && ( @@ -39,6 +41,7 @@ export default function ArchivesEdit( { attributes, setAttributes } ) { /> ) } diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index a11ab6fdc9442a..57bcb089c664fb 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -207,12 +207,14 @@ function AudioEdit( { setAttributes( { isLink: ! attributes.isLink } ) diff --git a/packages/block-library/src/categories/edit.js b/packages/block-library/src/categories/edit.js index ef47a5c91d8ff8..15a526f249cf22 100644 --- a/packages/block-library/src/categories/edit.js +++ b/packages/block-library/src/categories/edit.js @@ -143,27 +143,32 @@ export default function CategoriesEdit( { { ! showOnlyTopLevel && ( ) } diff --git a/packages/block-library/src/comment-author-name/edit.js b/packages/block-library/src/comment-author-name/edit.js index e71d26ccee361d..82e0c6b100ce77 100644 --- a/packages/block-library/src/comment-author-name/edit.js +++ b/packages/block-library/src/comment-author-name/edit.js @@ -72,12 +72,14 @@ export default function Edit( { setAttributes( { isLink: ! isLink } ) } checked={ isLink } /> { isLink && ( setAttributes( { diff --git a/packages/block-library/src/comment-date/edit.js b/packages/block-library/src/comment-date/edit.js index 4127f169c2db45..7139abece96397 100644 --- a/packages/block-library/src/comment-date/edit.js +++ b/packages/block-library/src/comment-date/edit.js @@ -48,6 +48,7 @@ export default function Edit( { } /> setAttributes( { isLink: ! isLink } ) } checked={ isLink } diff --git a/packages/block-library/src/comment-edit-link/edit.js b/packages/block-library/src/comment-edit-link/edit.js index 3f45948bc5c060..c2360063e33ad9 100644 --- a/packages/block-library/src/comment-edit-link/edit.js +++ b/packages/block-library/src/comment-edit-link/edit.js @@ -39,6 +39,7 @@ export default function Edit( { setAttributes( { diff --git a/packages/block-library/src/comments-title/edit.js b/packages/block-library/src/comments-title/edit.js index 7f4660d5735b27..72e16c88346831 100644 --- a/packages/block-library/src/comments-title/edit.js +++ b/packages/block-library/src/comments-title/edit.js @@ -110,6 +110,7 @@ export default function Edit( { @@ -117,6 +118,7 @@ export default function Edit( { } /> diff --git a/packages/block-library/src/cover/edit/inspector-controls.js b/packages/block-library/src/cover/edit/inspector-controls.js index b07f257ebf903d..fcacf44e1c6851 100644 --- a/packages/block-library/src/cover/edit/inspector-controls.js +++ b/packages/block-library/src/cover/edit/inspector-controls.js @@ -171,12 +171,14 @@ export default function CoverInspectorControls( { { isImageBackground && ( <> ) } { hasLinkTo && ( ) } @@ -48,6 +49,7 @@ export default function LatestComments( { attributes, setAttributes } ) { } /> @@ -55,6 +57,7 @@ export default function LatestComments( { attributes, setAttributes } ) { } /> diff --git a/packages/block-library/src/latest-posts/edit.js b/packages/block-library/src/latest-posts/edit.js index cc8a044b0a1eab..bbb03035723d77 100644 --- a/packages/block-library/src/latest-posts/edit.js +++ b/packages/block-library/src/latest-posts/edit.js @@ -247,6 +247,7 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { @@ -254,6 +255,7 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { } /> @@ -264,6 +266,7 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { @@ -315,6 +318,7 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { /> diff --git a/packages/block-library/src/list/ordered-list-settings.js b/packages/block-library/src/list/ordered-list-settings.js index cbcd954a4682ff..7fd51a5c7e576e 100644 --- a/packages/block-library/src/list/ordered-list-settings.js +++ b/packages/block-library/src/list/ordered-list-settings.js @@ -25,6 +25,7 @@ const OrderedListSettings = ( { setAttributes, reversed, start } ) => ( step="1" /> { diff --git a/packages/block-library/src/loginout/edit.js b/packages/block-library/src/loginout/edit.js index 64292a167e6a90..b6c2e9cf013041 100644 --- a/packages/block-library/src/loginout/edit.js +++ b/packages/block-library/src/loginout/edit.js @@ -13,6 +13,7 @@ export default function LoginOutEdit( { attributes, setAttributes } ) { @@ -22,6 +23,7 @@ export default function LoginOutEdit( { attributes, setAttributes } ) { } /> diff --git a/packages/block-library/src/media-text/edit.js b/packages/block-library/src/media-text/edit.js index 7e09bfa3193ccc..a2eecf255cad7a 100644 --- a/packages/block-library/src/media-text/edit.js +++ b/packages/block-library/src/media-text/edit.js @@ -243,6 +243,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes, clientId } ) { const mediaTextGeneralSettings = ( @@ -253,6 +254,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes, clientId } ) { /> { mediaType === 'image' && ( diff --git a/packages/block-library/src/more/edit.js b/packages/block-library/src/more/edit.js index f0ed625e458d70..7757af5e96ba1c 100644 --- a/packages/block-library/src/more/edit.js +++ b/packages/block-library/src/more/edit.js @@ -43,6 +43,7 @@ export default function MoreEdit( {

{ __( 'Submenus' ) }

{ setAttributes( { @@ -655,6 +656,7 @@ function Navigation( { /> { setAttributes( { diff --git a/packages/block-library/src/navigation/edit/overlay-menu-preview.js b/packages/block-library/src/navigation/edit/overlay-menu-preview.js index aa0abd11ad2757..adb1377a604ede 100644 --- a/packages/block-library/src/navigation/edit/overlay-menu-preview.js +++ b/packages/block-library/src/navigation/edit/overlay-menu-preview.js @@ -17,6 +17,7 @@ export default function OverlayMenuPreview( { setAttributes, hasIcon, icon } ) { return ( <> diff --git a/packages/block-library/src/post-author-name/edit.js b/packages/block-library/src/post-author-name/edit.js index 8eda3bf92d193c..14437972062315 100644 --- a/packages/block-library/src/post-author-name/edit.js +++ b/packages/block-library/src/post-author-name/edit.js @@ -71,12 +71,14 @@ function PostAuthorNameEdit( { setAttributes( { isLink: ! isLink } ) } checked={ isLink } /> { isLink && ( setAttributes( { diff --git a/packages/block-library/src/post-author/edit.js b/packages/block-library/src/post-author/edit.js index 9573eedde66cfe..a9b7106f49d388 100644 --- a/packages/block-library/src/post-author/edit.js +++ b/packages/block-library/src/post-author/edit.js @@ -120,6 +120,7 @@ function PostAuthorEdit( { /> ) ) } @@ -140,6 +141,7 @@ function PostAuthorEdit( { /> ) } @@ -147,12 +149,14 @@ function PostAuthorEdit( { } /> setAttributes( { isLink: ! isLink } ) } /> { isLink && ( setAttributes( { diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index 810eea2ebc9051..6ce9144023e6e7 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -150,6 +150,7 @@ export default function PostDateEdit( { } /> setAttributes( { diff --git a/packages/block-library/src/post-excerpt/edit.js b/packages/block-library/src/post-excerpt/edit.js index abe03705db6805..378aa34cd00baa 100644 --- a/packages/block-library/src/post-excerpt/edit.js +++ b/packages/block-library/src/post-excerpt/edit.js @@ -194,6 +194,7 @@ export default function PostExcerptEditor( { diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js index f378a14f5c9d1b..950dbd57667b3d 100644 --- a/packages/block-library/src/post-featured-image/edit.js +++ b/packages/block-library/src/post-featured-image/edit.js @@ -141,6 +141,7 @@ export default function PostFeaturedImageEdit( { setAttributes( { diff --git a/packages/block-library/src/post-navigation-link/edit.js b/packages/block-library/src/post-navigation-link/edit.js index 0bdb864768b432..f899788428bcdb 100644 --- a/packages/block-library/src/post-navigation-link/edit.js +++ b/packages/block-library/src/post-navigation-link/edit.js @@ -52,6 +52,7 @@ export default function PostNavigationLinkEdit( { { showTitle && ( setAttributes( { isLink: ! isLink } ) } checked={ isLink } @@ -125,6 +126,7 @@ export default function PostTitleEdit( { { isLink && ( <> setAttributes( { diff --git a/packages/block-library/src/query-title/edit.js b/packages/block-library/src/query-title/edit.js index 7c9689f3367408..da321bead7c0b8 100644 --- a/packages/block-library/src/query-title/edit.js +++ b/packages/block-library/src/query-title/edit.js @@ -49,6 +49,7 @@ export default function QueryTitleEdit( { setAttributes( { showPrefix: ! showPrefix } ) @@ -72,6 +73,7 @@ export default function QueryTitleEdit( { setAttributes( { diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js index 9d99e5ad793011..95ccb43e58452a 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -132,6 +132,7 @@ export default function QueryInspectorControls( { { showInheritControl && ( setAttributes( { diff --git a/packages/block-library/src/rss/edit.js b/packages/block-library/src/rss/edit.js index 0cf252e038b6f9..2fd94cdd2a021a 100644 --- a/packages/block-library/src/rss/edit.js +++ b/packages/block-library/src/rss/edit.js @@ -126,16 +126,19 @@ export default function RSSEdit( { attributes, setAttributes } ) { required /> setAttributes( { isLink: ! isLink } ) } checked={ isLink } @@ -307,6 +308,7 @@ const SiteLogo = ( { { isLink && ( <> setAttributes( { @@ -320,6 +322,7 @@ const SiteLogo = ( { { canUserEdit && ( <> { setAttributes( { shouldSyncIcon: value } ); diff --git a/packages/block-library/src/site-title/edit/index.js b/packages/block-library/src/site-title/edit/index.js index 5980dff6d88193..067f4fc7392036 100644 --- a/packages/block-library/src/site-title/edit/index.js +++ b/packages/block-library/src/site-title/edit/index.js @@ -111,12 +111,14 @@ export default function SiteTitleEdit( { setAttributes( { isLink: ! isLink } ) } checked={ isLink } /> { isLink && ( setAttributes( { diff --git a/packages/block-library/src/social-links/edit.js b/packages/block-library/src/social-links/edit.js index 383ae7b6f1355f..084ab1df9ac380 100644 --- a/packages/block-library/src/social-links/edit.js +++ b/packages/block-library/src/social-links/edit.js @@ -197,6 +197,7 @@ export function SocialLinksEdit( props ) { @@ -204,6 +205,7 @@ export function SocialLinksEdit( props ) { } /> diff --git a/packages/block-library/src/table-of-contents/edit.js b/packages/block-library/src/table-of-contents/edit.js index 38e93e06d7830b..7f3bb6529bf323 100644 --- a/packages/block-library/src/table-of-contents/edit.js +++ b/packages/block-library/src/table-of-contents/edit.js @@ -251,6 +251,7 @@ export default function TableOfContentsEdit( { diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index 904cc3028fc715..4f186f77a72918 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -478,6 +478,7 @@ function TableEdit( { className="blocks-table-settings" > diff --git a/packages/block-library/src/video/edit-common-settings.js b/packages/block-library/src/video/edit-common-settings.js index 5c8f5e2ab531f0..f0cdf210fe0d5f 100644 --- a/packages/block-library/src/video/edit-common-settings.js +++ b/packages/block-library/src/video/edit-common-settings.js @@ -48,27 +48,32 @@ const VideoSettings = ( { setAttributes, attributes } ) => { return ( <> Date: Tue, 28 Feb 2023 17:41:58 -0800 Subject: [PATCH 08/24] MediaReplaceFlow: fix styling for LinkControl (#47949) * MediaReplaceFlow: fix styling for LinkControl * Adjust width of popover * Fix missing focus outline --- .../src/components/media-replace-flow/style.scss | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/media-replace-flow/style.scss b/packages/block-editor/src/components/media-replace-flow/style.scss index 707fd9393ee6c6..81484cbf806623 100644 --- a/packages/block-editor/src/components/media-replace-flow/style.scss +++ b/packages/block-editor/src/components/media-replace-flow/style.scss @@ -23,24 +23,22 @@ } .block-editor-link-control { - width: 220px; // Hardcoded width avoids resizing of control when switching between preview/edit. + width: 300px; // Hardcoded width avoids resizing of control when switching between preview/edit. .block-editor-url-input { padding: 0; // Cancel unnecessary default 1px padding in this case. margin: 0; // Reset default LinkControl margins. } - .components-base-control .components-base-control__field { - margin-bottom: 0; - } - - .block-editor-link-control__search-item-title { - max-width: 180px; + .block-editor-link-control__search-item-title, + .block-editor-link-control__search-item-info { + max-width: 200px; white-space: nowrap; } - .block-editor-link-control__search-item-info { - white-space: nowrap; + .block-editor-link-control__tools { + justify-content: flex-end; + padding: $grid-unit-20 var(--wp-admin-border-width-focus) var(--wp-admin-border-width-focus); } .block-editor-link-control__search-item.is-current { From 58809f8f85865e875592b88d3c345ddc188eea80 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 1 Mar 2023 16:52:39 +1100 Subject: [PATCH 09/24] Only add layout classes to inner wrapper if block is a container. (#48611) --- lib/block-supports/layout.php | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 1c8de2e2c34121..cb9f1573e4e056 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -301,23 +301,6 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support return ''; } -/** - * Gets classname from last tag in a string of HTML. - * - * @param string $html markup to be processed. - * @return string String of inner wrapper classnames. - */ -function gutenberg_get_classnames_from_last_tag( $html ) { - $tags = new WP_HTML_Tag_Processor( $html ); - $last_classnames = ''; - - while ( $tags->next_tag() ) { - $last_classnames = $tags->get_attribute( 'class' ); - } - - return (string) $last_classnames; -} - /** * Renders the layout config to the block wrapper. * @@ -502,7 +485,17 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { * The first chunk of innerContent contains the block markup up until the inner blocks start. * We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk. */ - $inner_content_classnames = isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ? gutenberg_get_classnames_from_last_tag( $block['innerContent'][0] ) : ''; + $inner_content_classnames = ''; + + if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) && count( $block['innerContent'] ) > 1 ) { + $tags = new WP_HTML_Tag_Processor( $block['innerContent'][0] ); + $last_classnames = ''; + while ( $tags->next_tag() ) { + $last_classnames = $tags->get_attribute( 'class' ); + } + + $inner_content_classnames = (string) $last_classnames; + } $content = $content_with_outer_classnames ? new WP_HTML_Tag_Processor( $content_with_outer_classnames ) : new WP_HTML_Tag_Processor( $block_content ); From 65794bf0cff0cfadc65e4258fd79f30092c241d7 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Wed, 1 Mar 2023 10:30:51 +0200 Subject: [PATCH 10/24] Focus 1st parent block on block remove, if no previous block is available (#48204) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change default selection on remove blocks action to include selecting first available parent if there is no previous block * revert renaming the selectPreviousBlock API and add a param to also select the parent when needed * Fix removeBlock call in list item block * updates remove block test to account for new selectPreviousBlock param * Try to fix editing-widgets e2e test * focus back on widget body * Addressed feedback for documentation being more explanative Co-authored-by: Dave Smith <444434+getdave@users.noreply.github.com> Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com> * remove superfluous fix attewmpt * adds a test for parent selection by default --------- Co-authored-by: Ella van Durpe Co-authored-by: Tetsuaki Hamano Co-authored-by: Dave Smith <444434+getdave@users.noreply.github.com> Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com> --- .../data/data-core-block-editor.md | 4 +- .../block-settings-dropdown.js | 5 +- packages/block-editor/src/store/actions.js | 16 +++++-- .../block-editor/src/store/test/actions.js | 6 ++- .../list-item/hooks/use-outdent-list-item.js | 3 +- .../specs/widgets/editing-widgets.test.js | 5 ++ .../editor/various/block-deletion.spec.js | 47 +++++++++++++++++++ 7 files changed, 77 insertions(+), 9 deletions(-) diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index cfb95389ba0391..c76c4e7fbccf30 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -1496,11 +1496,13 @@ _Parameters_ ### selectPreviousBlock Yields action objects used in signalling that the block preceding the given -clientId should be selected. +clientId (or optionally, its first parent from bottom to top) +should be selected. _Parameters_ - _clientId_ `string`: Block client ID. +- _orFirstParent_ `boolean`: If true, select the first parent if there is no previous block. ### setBlockMovingClientId diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js index 18cf04d7f1ee02..b912bb44af5522 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js @@ -147,7 +147,9 @@ export function BlockSettingsDropdown( { __experimentalSelectBlock ? () => { const blockToSelect = - previousBlockClientId || nextBlockClientId; + previousBlockClientId || + nextBlockClientId || + firstParentClientId; if ( blockToSelect && @@ -166,6 +168,7 @@ export function BlockSettingsDropdown( { __experimentalSelectBlock, previousBlockClientId, nextBlockClientId, + firstParentClientId, selectedBlockClientIds, ] ); diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 98bdf1bffc78c0..b3f437fc94accf 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -232,17 +232,24 @@ export function selectBlock( clientId, initialPosition = 0 ) { /** * Yields action objects used in signalling that the block preceding the given - * clientId should be selected. + * clientId (or optionally, its first parent from bottom to top) + * should be selected. * - * @param {string} clientId Block client ID. + * @param {string} clientId Block client ID. + * @param {boolean} orFirstParent If true, select the first parent if there is no previous block. */ export const selectPreviousBlock = - ( clientId ) => + ( clientId, orFirstParent = false ) => ( { select, dispatch } ) => { const previousBlockClientId = select.getPreviousBlockClientId( clientId ); if ( previousBlockClientId ) { dispatch.selectBlock( previousBlockClientId, -1 ); + } else if ( orFirstParent ) { + const firstParentClientId = select.getBlockRootClientId( clientId ); + if ( firstParentClientId ) { + dispatch.selectBlock( firstParentClientId, -1 ); + } } }; @@ -1197,7 +1204,8 @@ export const removeBlocks = } if ( selectPrevious ) { - dispatch.selectPreviousBlock( clientIds[ 0 ] ); + const shouldSelectParent = true; + dispatch.selectPreviousBlock( clientIds[ 0 ], shouldSelectParent ); } dispatch( { type: 'REMOVE_BLOCKS', clientIds } ); diff --git a/packages/block-editor/src/store/test/actions.js b/packages/block-editor/src/store/test/actions.js index 45e432ad8bf3f8..65a1eca96d5fe3 100644 --- a/packages/block-editor/src/store/test/actions.js +++ b/packages/block-editor/src/store/test/actions.js @@ -625,7 +625,8 @@ describe( 'actions', () => { removeBlocks( clientIds )( { select, dispatch } ); expect( dispatch.selectPreviousBlock ).toHaveBeenCalledWith( - clientId + clientId, + true ); expect( dispatch ).toHaveBeenCalledWith( { @@ -734,7 +735,8 @@ describe( 'actions', () => { removeBlock( clientId )( { select, dispatch } ); expect( dispatch.selectPreviousBlock ).toHaveBeenCalledWith( - clientId + clientId, + true ); expect( dispatch ).toHaveBeenCalledWith( { diff --git a/packages/block-library/src/list-item/hooks/use-outdent-list-item.js b/packages/block-library/src/list-item/hooks/use-outdent-list-item.js index 870aeb5088f805..3f566dac30ab5a 100644 --- a/packages/block-library/src/list-item/hooks/use-outdent-list-item.js +++ b/packages/block-library/src/list-item/hooks/use-outdent-list-item.js @@ -112,7 +112,8 @@ export default function useOutdentListItem( clientId ) { getBlockIndex( parentListItemId ) + 1 ); if ( ! getBlockOrder( parentListId ).length ) { - removeBlock( parentListId ); + const shouldSelectParent = false; + removeBlock( parentListId, shouldSelectParent ); } } ); }, [] ), diff --git a/packages/e2e-tests/specs/widgets/editing-widgets.test.js b/packages/e2e-tests/specs/widgets/editing-widgets.test.js index bfd7b6b6a6c862..2f4211499985e7 100644 --- a/packages/e2e-tests/specs/widgets/editing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/editing-widgets.test.js @@ -384,6 +384,11 @@ describe( 'Widgets screen', () => { describe( 'Function widgets', () => { async function addMarquee( nbExpectedMarquees ) { + const [ firstWidgetArea ] = await findAll( { + role: 'document', + name: 'Block: Widget Area', + } ); + await firstWidgetArea.focus(); const marqueeBlock = await getBlockInGlobalInserter( 'Marquee Greeting' ); diff --git a/test/e2e/specs/editor/various/block-deletion.spec.js b/test/e2e/specs/editor/various/block-deletion.spec.js index efcf7b7d5a2825..78c63bfc64aac0 100644 --- a/test/e2e/specs/editor/various/block-deletion.spec.js +++ b/test/e2e/specs/editor/various/block-deletion.spec.js @@ -62,6 +62,53 @@ test.describe( 'Block deletion', () => { ] ); } ); + // this test should be moved to a new testing story about focus management. + test( 'deleting a block focuses the parent block', async ( { + editor, + page, + } ) => { + // Add a group with a paragraph in it. + await editor.insertBlock( { + name: 'core/group', + innerBlocks: [ + { + name: 'core/paragraph', + attributes: { content: 'Paragraph child of group' }, + }, + ], + } ); + + // Select the paragraph. + const paragraph = editor.canvas.getByRole( 'document', { + name: 'Paragraph block', + } ); + await editor.selectBlocks( paragraph ); + + // Remove the current paragraph via the Block Toolbar options menu. + await editor.showBlockToolbar(); + await editor.canvas + .getByRole( 'toolbar', { name: 'Block tools' } ) + .getByRole( 'button', { name: 'Options' } ) + .click(); + await page + .getByRole( 'menuitem', { name: 'Remove Paragraph' } ) + .click(); + + // Ensure the paragraph was removed. + await expect + .poll( editor.getBlocks ) + .toMatchObject( [ { name: 'core/group', attributes: {} } ] ); + + // Ensure the group block is focused. + await expect( + editor.canvas + .getByRole( 'document', { + name: 'Block: Group', + } ) + .last() + ).toBeFocused(); + } ); + test( 'deleting the last block via the keyboard shortcut', async ( { editor, page, From 4dc050fbad1ed6e8ad7cba7750c5eb7ce1c435d4 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Wed, 1 Mar 2023 09:28:15 +0000 Subject: [PATCH 11/24] Navigation: Don't create a fallback navigation menu if there are inner blocks (#48585) * Navigation: Don't create a fallback navigation menu if there are inner blocks * move const declarations higher --- .../src/navigation/edit/index.js | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index f13a7e603c83b5..7e07b0d6cde415 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -277,12 +277,24 @@ function Navigation( { hasUncontrolledInnerBlocks, ] ); + const isEntityAvailable = + ! isNavigationMenuMissing && isNavigationMenuResolved; + + // If the block has inner blocks, but no menu id, then these blocks are either: + // - inserted via a pattern. + // - inserted directly via Code View (or otherwise). + // - from an older version of navigation block added before the block used a wp_navigation entity. + // Consider this state as 'unsaved' and offer an uncontrolled version of inner blocks, + // that automatically saves the menu as an entity when changes are made to the inner blocks. + const hasUnsavedBlocks = hasUncontrolledInnerBlocks && ! isEntityAvailable; + useEffect( () => { if ( ref || ! hasResolvedNavigationMenus || isConvertingClassicMenu || - fallbackNavigationMenus?.length > 0 + fallbackNavigationMenus?.length > 0 || + hasUnsavedBlocks ) { return; } @@ -323,13 +335,14 @@ function Navigation( { if ( getBlockType( 'core/page-list' ) ) { defaultBlocks = [ createBlock( 'core/page-list' ) ]; } + createNavigationMenu( 'Navigation', // TODO - use the template slug in future defaultBlocks, 'publish' ); } - }, [ hasResolvedNavigationMenus ] ); + }, [ hasResolvedNavigationMenus, hasUnsavedBlocks ] ); const navRef = useRef(); @@ -349,9 +362,6 @@ function Navigation( { classicMenus?.length === 0 && ! hasUncontrolledInnerBlocks; - const isEntityAvailable = - ! isNavigationMenuMissing && isNavigationMenuResolved; - // "loading" state: // - there is a menu creation process in progress. // - there is a classic menu conversion process in progress. @@ -728,14 +738,6 @@ function Navigation( { ); - // If the block has inner blocks, but no menu id, then these blocks are either: - // - inserted via a pattern. - // - inserted directly via Code View (or otherwise). - // - from an older version of navigation block added before the block used a wp_navigation entity. - // Consider this state as 'unsaved' and offer an uncontrolled version of inner blocks, - // that automatically saves the menu as an entity when changes are made to the inner blocks. - const hasUnsavedBlocks = hasUncontrolledInnerBlocks && ! isEntityAvailable; - const isManageMenusButtonDisabled = ! hasManagePermissions || ! hasResolvedNavigationMenus; From 236e010d733c4477cfd3433b786ddbd4bed52c12 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Wed, 1 Mar 2023 10:45:50 +0100 Subject: [PATCH 12/24] Add command to run performance tests in debug mode (#48614) --- package.json | 3 ++- packages/scripts/scripts/test-e2e.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 21c06ee4008167..37a38240c1e938 100644 --- a/package.json +++ b/package.json @@ -299,11 +299,12 @@ "test": "npm-run-all lint test:unit", "test:create-block": "bash ./bin/test-create-block.sh", "test:e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", - "test:e2e:debug": "wp-scripts --inspect-brk test-e2e --config packages/e2e-tests/jest.config.js --puppeteer-devtools", + "test:e2e:debug": "wp-scripts --inspect-brk test-e2e --runInBand --no-cache --verbose --config packages/e2e-tests/jest.config.js --puppeteer-devtools", "test:e2e:playwright": "playwright test --config test/e2e/playwright.config.ts", "test:e2e:storybook": "playwright test --config test/storybook-playwright/playwright.config.ts", "test:e2e:watch": "npm run test:e2e -- --watch", "test:performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", + "test:performance:debug": "wp-scripts --inspect-brk test-e2e --runInBand --no-cache --verbose --config packages/e2e-tests/jest.performance.config.js --puppeteer-devtools", "test:php": "npm-run-all lint:php test:unit:php", "test:php:watch": "wp-env run composer run-script test:watch", "test:unit": "wp-scripts test-unit-js --config test/unit/jest.config.js", diff --git a/packages/scripts/scripts/test-e2e.js b/packages/scripts/scripts/test-e2e.js index 67927038c7eeb8..330439ce2121b7 100644 --- a/packages/scripts/scripts/test-e2e.js +++ b/packages/scripts/scripts/test-e2e.js @@ -51,6 +51,7 @@ const config = configFile ? [ '--config', JSON.stringify( require( configFile ) ) ] : []; +// Force e2e tests to run serially, not in parallel. They test against a shared Docker instance const hasRunInBand = hasArgInCLI( '--runInBand' ) || hasArgInCLI( '-i' ); const runInBand = ! hasRunInBand ? [ '--runInBand' ] : []; From 04e15c4bab67504c2142a1f3d8823a6b958a5260 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Wed, 1 Mar 2023 09:52:00 +0000 Subject: [PATCH 13/24] Fix: Add missing code on the fix page list loading PR. (#48621) --- .../components/navigation-inspector/navigation-menu.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/navigation-inspector/navigation-menu.js b/packages/edit-site/src/components/navigation-inspector/navigation-menu.js index 731cb3cf9a3b0e..437b95079bd1db 100644 --- a/packages/edit-site/src/components/navigation-inspector/navigation-menu.js +++ b/packages/edit-site/src/components/navigation-inspector/navigation-menu.js @@ -8,7 +8,7 @@ import { BlockTools, } from '@wordpress/block-editor'; import { useEffect } from '@wordpress/element'; -import { useDispatch } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; /** * Internal dependencies @@ -40,6 +40,12 @@ const ALLOWED_BLOCKS = { }; export default function NavigationMenu( { innerBlocks, onSelect } ) { + const { clientIdsTree } = useSelect( ( select ) => { + const { __unstableGetClientIdsTree } = select( blockEditorStore ); + return { + clientIdsTree: __unstableGetClientIdsTree(), + }; + } ); const { updateBlockListSettings } = useDispatch( blockEditorStore ); const { OffCanvasEditor, LeafMoreMenu } = unlock( blockEditorPrivateApis ); @@ -64,7 +70,7 @@ export default function NavigationMenu( { innerBlocks, onSelect } ) { return ( <> From 58708be1d5b834573f7e8785467cabd383f08a61 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Wed, 1 Mar 2023 10:02:25 +0000 Subject: [PATCH 14/24] Fix: Inserter does not appear on sidebar navigation. (#48623) --- .../block-editor/src/components/off-canvas-editor/branch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/off-canvas-editor/branch.js b/packages/block-editor/src/components/off-canvas-editor/branch.js index 636f67ee10fce9..25385b22c4259b 100644 --- a/packages/block-editor/src/components/off-canvas-editor/branch.js +++ b/packages/block-editor/src/components/off-canvas-editor/branch.js @@ -116,8 +116,8 @@ function ListViewBranch( props ) { return null; } - // Only show the appender at the first level and if there is a parent block. - const showAppender = level === 1 && parentId; + // Only show the appender at the first level. + const showAppender = level === 1; const filteredBlocks = blocks.filter( Boolean ); const blockCount = filteredBlocks.length; From cf132aec562cfc31e2fc446543c6024ec8209d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 1 Mar 2023 11:31:36 +0100 Subject: [PATCH 15/24] Clarify backport status of appearance-tools theme support (#48622) --- lib/class-wp-theme-json-resolver-gutenberg.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index df3d1ee7308e75..e4787b468ab785 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -319,10 +319,15 @@ public static function get_theme_data( $deprecated = array(), $options = array() // Classic themes without a theme.json don't support global duotone. $theme_support_data['settings']['color']['defaultDuotone'] = false; + // BEGIN EXPERIMENTAL. // Allow themes to enable appearance tools via theme_support. + // This feature was backported for WordPress 6.2 as of https://core.trac.wordpress.org/ticket/56487 + // and then reverted as of https://core.trac.wordpress.org/ticket/57649 + // Not to backport until the issues are resolved. if ( current_theme_supports( 'appearance-tools' ) ) { $theme_support_data['settings']['appearanceTools'] = true; } + // END EXPERIMENTAL. } $with_theme_supports = new WP_Theme_JSON_Gutenberg( $theme_support_data ); $with_theme_supports->merge( static::$theme ); From 42dad571eac32c41a7ff34f0da80fcc4e5ceb3bd Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Wed, 1 Mar 2023 12:04:15 +0100 Subject: [PATCH 16/24] react-native-editor: move parser tests to a test directory (#48615) --- .../src/{parser => test}/block-parser-code.test.js | 5 ----- .../src/{parser => test}/block-parser-more.test.js | 5 ----- .../src/{parser => test}/block-parser-paragraph.test.js | 5 ----- test/native/jest.config.js | 7 +------ 4 files changed, 1 insertion(+), 21 deletions(-) rename packages/react-native-editor/src/{parser => test}/block-parser-code.test.js (94%) rename packages/react-native-editor/src/{parser => test}/block-parser-more.test.js (94%) rename packages/react-native-editor/src/{parser => test}/block-parser-paragraph.test.js (94%) diff --git a/packages/react-native-editor/src/parser/block-parser-code.test.js b/packages/react-native-editor/src/test/block-parser-code.test.js similarity index 94% rename from packages/react-native-editor/src/parser/block-parser-code.test.js rename to packages/react-native-editor/src/test/block-parser-code.test.js index 276e73b6d7d5b7..e53433f67c5ec5 100644 --- a/packages/react-native-editor/src/parser/block-parser-code.test.js +++ b/packages/react-native-editor/src/test/block-parser-code.test.js @@ -1,8 +1,3 @@ -/** - * Internal dependencies - */ -import '../globals'; - /** * WordPress dependencies */ diff --git a/packages/react-native-editor/src/parser/block-parser-more.test.js b/packages/react-native-editor/src/test/block-parser-more.test.js similarity index 94% rename from packages/react-native-editor/src/parser/block-parser-more.test.js rename to packages/react-native-editor/src/test/block-parser-more.test.js index c2f2360fc64a2c..4b7b91d5a90c72 100644 --- a/packages/react-native-editor/src/parser/block-parser-more.test.js +++ b/packages/react-native-editor/src/test/block-parser-more.test.js @@ -1,8 +1,3 @@ -/** - * Internal dependencies - */ -import '../globals'; - /** * WordPress dependencies */ diff --git a/packages/react-native-editor/src/parser/block-parser-paragraph.test.js b/packages/react-native-editor/src/test/block-parser-paragraph.test.js similarity index 94% rename from packages/react-native-editor/src/parser/block-parser-paragraph.test.js rename to packages/react-native-editor/src/test/block-parser-paragraph.test.js index d9f451005901a4..823b85e4e29ccc 100644 --- a/packages/react-native-editor/src/parser/block-parser-paragraph.test.js +++ b/packages/react-native-editor/src/test/block-parser-paragraph.test.js @@ -1,8 +1,3 @@ -/** - * Internal dependencies - */ -import '../globals'; - /** * WordPress dependencies */ diff --git a/test/native/jest.config.js b/test/native/jest.config.js index 8492ca88746a40..14a901281f394c 100644 --- a/test/native/jest.config.js +++ b/test/native/jest.config.js @@ -31,12 +31,7 @@ module.exports = { '**/test/!(helper)*.native.[jt]s?(x)', '/packages/react-native-*/**/?(*.)+(spec|test).[jt]s?(x)', ], - testPathIgnorePatterns: [ - '/node_modules/', - '/__device-tests__/', - '/.*/build/', - '/.*/build-module/', - ], + testPathIgnorePatterns: [ '/node_modules/', '/__device-tests__/' ], testURL: 'http://localhost/', // Add the `Libraries/Utilities` subfolder to the module directories, otherwise haste/jest doesn't find Platform.js on Travis, // and add it first so https://github.com/facebook/react-native/blob/v0.60.0/Libraries/react-native/react-native-implementation.js#L324-L326 doesn't pick up the Platform npm module. From 252805380646ddbbf04c7524a10c8acf21319e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 1 Mar 2023 12:55:56 +0100 Subject: [PATCH 17/24] `WP_Theme_JSON_Gutenberg`: update comments to be aligned with core, so backports are easier (#48624) --- lib/class-wp-theme-json-gutenberg.php | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 7334cb6e97cde5..d03f7f783c4706 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -114,6 +114,7 @@ class WP_Theme_JSON_Gutenberg { * `use_default_names` preset key, and simplified the metadata structure. * @since 6.0.0 Replaced `override` with `prevent_override` and updated the * `prevent_override` value for `color.duotone` to use `color.defaultDuotone`. + * @since 6.2.0 Added 'shadow' presets. * @var array */ const PRESETS_METADATA = array( @@ -200,7 +201,8 @@ class WP_Theme_JSON_Gutenberg { * @since 6.1.0 Added the `border-*-color`, `border-*-width`, `border-*-style`, * `--wp--style--root--padding-*`, and `box-shadow` properties, * removed the `--wp--style--block-gap` property. - * @since 6.2.0 Added `min-height`. + * @since 6.2.0 Added `outline-*`, and `min-height` properties. + * * @var array */ const PROPERTIES_METADATA = array( @@ -277,14 +279,15 @@ class WP_Theme_JSON_Gutenberg { /** * Indirect metadata for style properties that are not directly output. * - * Each element is a direct mapping from a CSS property name to the - * path to the value in theme.json & block attributes. + * Each element maps from a CSS property name to an array of + * paths to the value in theme.json & block attributes. * * Indirect properties are not output directly by `compute_style_properties`, * but are used elsewhere in the processing of global styles. The indirect * property is used to validate whether or not a style value is allowed. * * @since 6.2.0 + * * @var array */ const INDIRECT_PROPERTIES_METADATA = array( @@ -317,8 +320,8 @@ class WP_Theme_JSON_Gutenberg { 'settings', 'styles', 'templateParts', - 'version', 'title', + 'version', ); /** @@ -330,7 +333,8 @@ class WP_Theme_JSON_Gutenberg { * and `typography`, and renamed others according to the new schema. * @since 6.0.0 Added `color.defaultDuotone`. * @since 6.1.0 Added `layout.definitions` and `useRootPaddingAwareAlignments`. - * @since 6.2.0 Added `dimensions.minHeight`, `position.fixed` and `position.sticky`. + * @since 6.2.0 Added `dimensions.minHeight`, 'shadow.presets', 'shadow.defaultPresets', + * `position.fixed` and `position.sticky`. * @var array */ const VALID_SETTINGS = array( @@ -407,7 +411,8 @@ class WP_Theme_JSON_Gutenberg { * @since 6.1.0 Added new side properties for `border`, * added new property `shadow`, * updated `blockGap` to be allowed at any level. - * @since 6.2.0 Added `dimensions.minHeight`. + * @since 6.2.0 Added `outline`, and `minHeight` properties. + * * @var array */ const VALID_STYLES = array( @@ -888,7 +893,6 @@ protected static function get_blocks_metadata() { } static::$blocks_metadata[ $block_name ]['elements'][ $el_name ] = implode( ',', $element_selector ); } - // If the block has style variations, append their selectors to the block metadata. if ( ! empty( $block_type->styles ) ) { $style_selectors = array(); @@ -1098,7 +1102,7 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' * * @since 6.2.0 * - * @return string + * @return string The global styles custom CSS. */ public function get_custom_css() { // Add the global styles root CSS. @@ -1114,6 +1118,7 @@ public function get_custom_css() { } } } + return $stylesheet; } @@ -2344,10 +2349,10 @@ static function( $split_feature_selector ) use ( $clean_style_variation_selector $new_feature_declarations = static::compute_style_properties( array( $feature_name => $style_variation_node[ $feature_name ] ), $settings, null, $this->theme_json ); /* - * Merge new declarations with any that already exist for - * the feature selector. This may occur when multiple block - * support features use the same custom selector. - */ + * Merge new declarations with any that already exist for + * the feature selector. This may occur when multiple block + * support features use the same custom selector. + */ if ( isset( $style_variation_declarations[ $combined_feature_selectors ] ) ) { $style_variation_declarations[ $combined_feature_selectors ] = array_merge( $style_variation_declarations[ $combined_feature_selectors ], $new_feature_declarations ); } else { @@ -2355,11 +2360,10 @@ static function( $split_feature_selector ) use ( $clean_style_variation_selector } /* - * Remove the feature from the variation's node now the - * styles will be included under the feature level selector. - */ + * Remove the feature from the variation's node now the + * styles will be included under the feature level selector. + */ unset( $style_variation_node[ $feature_name ] ); - } } // Compute declarations for remaining styles not covered by feature level selectors. From 2b247651cc2d4e5480ab3c42e9990bc8c83d60ab Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Wed, 1 Mar 2023 13:25:10 +0100 Subject: [PATCH 18/24] Update snapshots for e2e tests (#48626) --- packages/e2e-tests/jest.config.js | 4 ++ .../specs/editor/blocks/pullquote.test.js | 6 +- .../__snapshots__/align-hook.test.js.snap | 22 +++---- .../container-blocks.test.js.snap | 28 ++++----- .../__snapshots__/cpt-locking.test.js.snap | 58 +++++++++---------- .../iframed-inline-styles.test.js.snap | 2 +- .../iframed-masonry-block.test.js.snap | 2 +- .../inner-blocks-render-appender.test.js.snap | 10 ++-- .../__snapshots__/plugins-api.test.js.snap | 4 +- .../adding-patterns.test.js.snap | 8 +-- .../__snapshots__/block-grouping.test.js.snap | 42 +++++++------- .../block-hierarchy-navigation.test.js.snap | 24 ++++---- .../__snapshots__/embedding.test.js.snap | 38 ++++++------ .../inserting-blocks.test.js.snap | 16 ++--- ...ep-styles-on-block-transforms.test.js.snap | 22 +++---- .../various/__snapshots__/links.test.js.snap | 18 +++--- .../multi-block-selection.test.js.snap | 34 +++++------ .../__snapshots__/rich-text.test.js.snap | 10 ++-- .../editor/various/block-grouping.test.js | 6 +- .../__snapshots__/text-color.test.js.snap | 2 +- .../various/multi-block-selection.test.js | 4 +- .../specs/widgets/editing-widgets.test.js | 30 +++++----- 22 files changed, 197 insertions(+), 193 deletions(-) diff --git a/packages/e2e-tests/jest.config.js b/packages/e2e-tests/jest.config.js index 5f9d5b75b24ef7..0c88768f0f58aa 100644 --- a/packages/e2e-tests/jest.config.js +++ b/packages/e2e-tests/jest.config.js @@ -18,6 +18,10 @@ module.exports = { '/node_modules/', 'e2e-tests/specs/performance/', ], + snapshotFormat: { + escapeString: false, + printBasicPrototype: false, + }, reporters: [ ...baseConfig.reporters, // Report flaky tests results into artifacts for used in `report-flaky-tests` action. diff --git a/packages/e2e-tests/specs/editor/blocks/pullquote.test.js b/packages/e2e-tests/specs/editor/blocks/pullquote.test.js index 9c9b9f4513fae6..13d6431c6dbcb4 100644 --- a/packages/e2e-tests/specs/editor/blocks/pullquote.test.js +++ b/packages/e2e-tests/specs/editor/blocks/pullquote.test.js @@ -20,7 +20,7 @@ describe( 'Quote', () => { expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` " -
+

test

" @@ -30,7 +30,7 @@ describe( 'Quote', () => { expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` " -

test

+

test

" ` ); @@ -38,7 +38,7 @@ describe( 'Quote', () => { expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` " -
+

test

" diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap index e0075595e01b08..6c04d30c41be9d 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap @@ -1,43 +1,43 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Align Hook Works As Expected Block with align array Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
+" +
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with align array Correctly applies the selected alignment and correctly removes the alignment 2`] = ` " -
Test Align Hook
+
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with align true Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
+" +
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with align true Correctly applies the selected alignment and correctly removes the alignment 2`] = ` " -
Test Align Hook
+
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with default align Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
+" +
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with default align Correctly applies the selected alignment and correctly removes the alignment 2`] = ` -" -
Test Align Hook
+" +
Test Align Hook
" `; exports[`Align Hook Works As Expected Block with no alignment set Does not save any alignment related attribute or class 1`] = ` " -
Test Align Hook
+
Test Align Hook
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap index 5eec9e79ced1f6..fb3f84595e5e2b 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap @@ -3,23 +3,23 @@ exports[`Container block without paragraph support ensures we can use the alternative block appender properly 1`] = ` " -
\\"\\"/
+
" `; exports[`InnerBlocks Template Sync Ensure inner block writing flow works as expected without additional paragraphs added 1`] = ` " - -

Test Paragraph

+ +

Test Paragraph

" `; exports[`InnerBlocks Template Sync Ensures blocks without locking are kept intact even if they do not match the template 1`] = ` " - -

Content…

+ +

Content…

@@ -30,28 +30,28 @@ exports[`InnerBlocks Template Sync Ensures blocks without locking are kept intac exports[`InnerBlocks Template Sync Removes blocks that are not expected by the template if a lock all exists 1`] = ` " - -

Content…

+ +

Content…

" `; exports[`InnerBlocks Template Sync Synchronizes blocks if lock 'all' is set and the template prop is changed 1`] = ` " - -

Content…

+ +

Content…

" `; exports[`InnerBlocks Template Sync Synchronizes blocks if lock 'all' is set and the template prop is changed 2`] = ` -" - -

Content…

+" + +

Content…

- -

Two

+ +

Two

" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap index 0acc31727beeb5..5c6867e75ad7af 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap @@ -2,52 +2,52 @@ exports[`cpt locking template_lock all should insert line breaks when using enter and shift-enter 1`] = ` " -
\\"\\"/
+
- +

First line
Second line
Third line

-
+

-
+
" `; exports[`cpt locking template_lock all should not error when deleting the cotents of a paragraph 1`] = ` " -
\\"\\"/
+
- +

-
+

-
+
" `; exports[`cpt locking template_lock all unlocked group should allow blocks to be moved 1`] = ` -" -
+" +

p1

-
+

@@ -55,9 +55,9 @@ exports[`cpt locking template_lock all unlocked group should allow blocks to be `; exports[`cpt locking template_lock all unlocked group should allow blocks to be removed 1`] = ` -" -
-
+" +
+

@@ -66,21 +66,21 @@ exports[`cpt locking template_lock all unlocked group should allow blocks to be exports[`cpt locking template_lock false should allow blocks to be inserted 1`] = ` " -
\\"\\"/
+
- +

-
+

-
+
@@ -91,57 +91,57 @@ exports[`cpt locking template_lock false should allow blocks to be inserted 1`] `; exports[`cpt locking template_lock false should allow blocks to be moved 1`] = ` -" +"

p1

-
\\"\\"/
+
-
+

-
+
" `; exports[`cpt locking template_lock false should allow blocks to be removed 1`] = ` " -
\\"\\"/
+
-
+

-
+
" `; exports[`cpt locking template_lock insert should allow blocks to be moved 1`] = ` -" +"

p1

-
\\"\\"/
+
-
+

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap index 46d3e807bff832..49823edc5b1ea5 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap @@ -2,6 +2,6 @@ exports[`iframed inline styles should load inline styles in iframe 1`] = ` " -
Save
+
Save
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap index 0033b3aff44d12..a37b33cdc3f410 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap @@ -2,6 +2,6 @@ exports[`iframed masonry block should load script and dependencies in iframe 1`] = ` " -
+
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/inner-blocks-render-appender.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/inner-blocks-render-appender.test.js.snap index 480121a3ceb8f1..232e6e02b398eb 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/inner-blocks-render-appender.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/inner-blocks-render-appender.test.js.snap @@ -2,8 +2,8 @@ exports[`RenderAppender prop of InnerBlocks Users can customize the appender and can still insert blocks using exposed components 1`] = ` " -
-
+
+

@@ -12,14 +12,14 @@ exports[`RenderAppender prop of InnerBlocks Users can customize the appender and exports[`RenderAppender prop of InnerBlocks Users can dynamically customize the appender 1`] = ` " -
-
+
+

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap index e2d70612669aef..34c57bf11e7bc5 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap @@ -2,6 +2,6 @@ exports[`Using Plugins API Document Setting Custom Panel Should render a custom panel inside Document Setting sidebar 1`] = `"My Custom Panel"`; -exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"
(no title)
Plugin sidebar title
"`; +exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"
(no title)
Plugin sidebar title
"`; -exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"
(no title)
Plugin sidebar title
"`; +exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"
(no title)
Plugin sidebar title
"`; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/adding-patterns.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-patterns.test.js.snap index 3b15d7589b63a6..0daa12f8a8660d 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/adding-patterns.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-patterns.test.js.snap @@ -1,11 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`adding patterns should insert a block pattern 1`] = ` -" - " `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap index 39621047016d4d..5ffca68763f42e 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap @@ -1,13 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Block Grouping Group creation creates a group from multiple blocks of different types via block transforms 1`] = ` -" -
-

Group Heading

+" +
+

Group Heading

-
\\"\\"/
+
@@ -17,8 +17,8 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of d `; exports[`Block Grouping Group creation creates a group from multiple blocks of the same type via block transforms 1`] = ` -" -
+" +

First Paragraph

@@ -33,8 +33,8 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of t `; exports[`Block Grouping Group creation creates a group from multiple blocks of the same type via options toolbar 1`] = ` -" -
+" +

First Paragraph

@@ -49,13 +49,13 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of t `; exports[`Block Grouping Group creation groups and ungroups multiple blocks of different types via options toolbar 1`] = ` -" -
-

Group Heading

+" +
+

Group Heading

-
\\"\\"/
+
@@ -66,11 +66,11 @@ exports[`Block Grouping Group creation groups and ungroups multiple blocks of di exports[`Block Grouping Group creation groups and ungroups multiple blocks of different types via options toolbar 2`] = ` " -

Group Heading

+

Group Heading

-
\\"\\"/
+
@@ -79,17 +79,17 @@ exports[`Block Grouping Group creation groups and ungroups multiple blocks of di `; exports[`Block Grouping Preserving selected blocks attributes preserves width alignment settings of selected blocks 1`] = ` -" -
-

Group Heading

+" +
+

Group Heading

- -
\\"\\"/
+ +
- -
\\"\\"/
+ +
diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap index 7a9abf86fc42b1..b4d171f170d918 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap @@ -6,24 +6,24 @@ exports[`Navigating the block hierarchy should appear and function even without -
\\"\\"/
+
" `; exports[`Navigating the block hierarchy should navigate block hierarchy using only the keyboard 1`] = ` " -
-
+
+

First column

-
+
-
+

Third column

@@ -32,18 +32,18 @@ exports[`Navigating the block hierarchy should navigate block hierarchy using on exports[`Navigating the block hierarchy should navigate using the list view sidebar 1`] = ` " -
-
+
+

First column

-
+
-
+

Third column

@@ -51,13 +51,13 @@ exports[`Navigating the block hierarchy should navigate using the list view side `; exports[`Navigating the block hierarchy should select the wrapper div for a group 1`] = ` -" -
+" +

just a paragraph

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap index 8b3d0323430df9..328b727ac6533b 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap @@ -2,65 +2,65 @@ exports[`Embedding content should allow the user to convert unembeddable URLs to a paragraph with a link in it 1`] = ` " -

https://twitter.com/wooyaygutenberg123454312

+

https://twitter.com/wooyaygutenberg123454312

" `; exports[`Embedding content should allow the user to try embedding a failed URL again 1`] = ` -" -
+" +
https://twitter.com/wooyaygutenberg123454312
" `; exports[`Embedding content should render embeds in the correct state 1`] = ` -" -
+" +
https://twitter.com/notnownikki
- -
+ +
https://twitter.com/wooyaygutenberg123454312
- -
+ +
https://wordpress.org/gutenberg/handbook/
- -
+ +
https://twitter.com/thatbunty
- -
+ +
https://wordpress.org/gutenberg/handbook/block-api/attributes/
- -
+ +
https://www.youtube.com/watch?v=lXMskKTw3Bc
- -
+ +
https://cloudup.com/cQFlxqtY4ob
" `; exports[`Embedding content should retry embeds that could not be embedded with trailing slashes, without the trailing slashes 1`] = ` -" -
+" +
https://twitter.com/notnownikki/
" diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap index b44c552abc789a..809990c313bc53 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap @@ -54,8 +54,8 @@ lines preserved[/myshortcode] `; exports[`Inserting blocks inserts a block in proper place after having clicked \`Browse All\` from block appender 1`] = ` -" -
+" +

Paragraph inside group

@@ -71,7 +71,7 @@ exports[`Inserting blocks inserts a block in proper place after having clicked \ -

Heading

+

Heading

@@ -88,12 +88,12 @@ exports[`Inserting blocks inserts a block in proper place after having clicked \

First paragraph

- -
+ +
-

Heading

+

Heading

@@ -107,8 +107,8 @@ exports[`Inserting blocks inserts a block in proper place after having clicked \ exports[`Inserting blocks inserts blocks at root level when using the root appender while selection is in an inner block 1`] = ` " -
- +
+
diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap index be070ef9432337..45aaa187a2206a 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap @@ -1,29 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Keep styles on block transforms Should keep colors during a transform 1`] = ` -" -

Heading

+" +

Heading

" `; exports[`Keep styles on block transforms Should keep the font size during a transform from multiple blocks into multiple blocks 1`] = ` -" -

Line 1 to be made large

+" +

Line 1 to be made large

- -

Line 2 to be made large

+ +

Line 2 to be made large

- -

Line 3 to be made large

+ +

Line 3 to be made large

" `; exports[`Keep styles on block transforms Should not include styles in the group block when grouping a block 1`] = ` -" -
-

Line 1 to be made large

+" +
+

Line 1 to be made large

" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap index 6ba1f2c0148853..7b54b5bd2f598f 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap @@ -8,7 +8,7 @@ exports[`Links allows use of escape key to dismiss the url popover 1`] = ` exports[`Links can be created by selecting text and clicking Link 1`] = ` " -

This is Gutenberg

+

This is Gutenberg

" `; @@ -20,37 +20,37 @@ exports[`Links can be created by selecting text and using keyboard shortcuts 1`] exports[`Links can be created by selecting text and using keyboard shortcuts 2`] = ` " -

This is Gutenberg

+

This is Gutenberg

" `; exports[`Links can be created instantly when a URL is selected 1`] = ` " -

This is Gutenberg: https://wordpress.org/gutenberg

+

This is Gutenberg: https://wordpress.org/gutenberg

" `; exports[`Links can be created without any text selected 1`] = ` " -

This is Gutenberg: https://wordpress.org/gutenberg

+

This is Gutenberg: https://wordpress.org/gutenberg

" `; exports[`Links can be edited 1`] = ` " -

This is Gutenberg

+

This is Gutenberg

" `; exports[`Links can be edited with collapsed selection 1`] = ` " -

This is Gutenberg

+

This is Gutenberg

" `; exports[`Links can be modified using the keyboard once a link has been set 1`] = ` " -

This is Gutenberg.

+

This is Gutenberg.

" `; @@ -62,12 +62,12 @@ exports[`Links can be removed 1`] = ` exports[`Links should contain a label when it should open in a new tab 1`] = ` " -

This is WordPress

+

This is WordPress

" `; exports[`Links should contain a label when it should open in a new tab 2`] = ` " -

This is WordPress

+

This is WordPress

" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap index 7dfe4f68d86818..915b52ba94edab 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap @@ -84,20 +84,20 @@ exports[`Multi-block selection should forward delete across blocks 1`] = ` -

]2

+

]2

" `; exports[`Multi-block selection should forward delete across blocks 2`] = ` " -

1&2

+

1&2

" `; exports[`Multi-block selection should gradually multi-select 1`] = ` " -
-
+
+

1

@@ -107,14 +107,14 @@ exports[`Multi-block selection should gradually multi-select 1`] = ` -
+
" `; exports[`Multi-block selection should gradually multi-select 2`] = ` " -
+
" `; @@ -128,7 +128,7 @@ exports[`Multi-block selection should handle Enter across blocks 1`] = ` -

]2

+

]2

" `; @@ -142,7 +142,7 @@ exports[`Multi-block selection should handle Enter across blocks 2`] = ` -

2

+

2

" `; @@ -251,8 +251,8 @@ exports[`Multi-block selection should preserve dragged selection on move 1`] = ` `; exports[`Multi-block selection should properly select multiple blocks if selected nested blocks belong to different parent 1`] = ` -" -
+" +

first

@@ -261,8 +261,8 @@ exports[`Multi-block selection should properly select multiple blocks if selecte
- -
+ +

second

@@ -300,7 +300,7 @@ exports[`Multi-block selection should select separator (single element block) 1` -
+
" `; @@ -311,12 +311,12 @@ exports[`Multi-block selection should select separator (single element block) 2` `; exports[`Multi-block selection should set attributes for multiple paragraphs 1`] = ` -" -

1

+" +

1

- -

2

+ +

2

" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap index 025fa91d03c6fa..5d9c235e1c6a2e 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap @@ -31,8 +31,8 @@ exports[`RichText should handle Home and End keys 1`] = ` `; exports[`RichText should handle change in tag name gracefully 1`] = ` -" -

+" +

" `; @@ -136,17 +136,17 @@ exports[`RichText should paste paragraph contents into list 1`] = ` exports[`RichText should preserve internal formatting 1`] = ` " -

1

+

1

" `; exports[`RichText should preserve internal formatting 2`] = ` " -

1

+

1

-

1

+

1

" `; diff --git a/packages/e2e-tests/specs/editor/various/block-grouping.test.js b/packages/e2e-tests/specs/editor/various/block-grouping.test.js index dd51f31016c8d3..07dcabcbf0526d 100644 --- a/packages/e2e-tests/specs/editor/various/block-grouping.test.js +++ b/packages/e2e-tests/specs/editor/various/block-grouping.test.js @@ -148,9 +148,9 @@ describe( 'Block Grouping', () => { await clickBlockToolbarButton( 'Options' ); await clickMenuItem( 'Group' ); expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` - " -
-
+ " +
+

1

diff --git a/packages/e2e-tests/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap b/packages/e2e-tests/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap index 05823957322a11..03bd1c7ddd1d62 100644 --- a/packages/e2e-tests/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap @@ -2,7 +2,7 @@ exports[`RichText should remove highlighting element 1`] = ` " -

1

+

1

" `; diff --git a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js index 0a4ddaa08ef8a3..9e96c5b14cef49 100644 --- a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js +++ b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js @@ -359,8 +359,8 @@ describe( 'Multi-block selection', () => { await page.mouse.up(); await page.keyboard.type( 'hi' ); expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` - " -
+ " +

hih text in group

" diff --git a/packages/e2e-tests/specs/widgets/editing-widgets.test.js b/packages/e2e-tests/specs/widgets/editing-widgets.test.js index 2f4211499985e7..00d34b4ae108d7 100644 --- a/packages/e2e-tests/specs/widgets/editing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/editing-widgets.test.js @@ -468,19 +468,19 @@ describe( 'Widgets screen', () => { await saveWidgets(); let editedSerializedWidgetAreas = await getSerializedWidgetAreas(); await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Howdy", - } - ` ); + { + "sidebar-1": "Howdy", + } + ` ); await page.reload(); editedSerializedWidgetAreas = await getSerializedWidgetAreas(); await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Howdy", - } - ` ); + { + "sidebar-1": "Howdy", + } + ` ); await addMarquee( 2 ); @@ -498,10 +498,10 @@ describe( 'Widgets screen', () => { await saveWidgets(); editedSerializedWidgetAreas = await getSerializedWidgetAreas(); await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Howdy", - } - ` ); + { + "sidebar-1": "Howdy", + } + ` ); await page.reload(); const marqueesAfter = await findAll( { @@ -830,11 +830,11 @@ describe( 'Widgets screen', () => { const serializedWidgetAreas = await getSerializedWidgetAreas(); expect( serializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "
+ { + "sidebar-1": "

First Paragraph

-
+

Second Paragraph

", } From ce49c68c128616b51df78f7443114fe6b6ddd972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 1 Mar 2023 13:50:26 +0100 Subject: [PATCH 19/24] Update code position for constants and methods in `WP_Theme_JSON_Gutenberg` class (#48631) --- lib/class-wp-theme-json-gutenberg.php | 113 +++++++++++++------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index d03f7f783c4706..4d688bb5b8b83c 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -118,15 +118,6 @@ class WP_Theme_JSON_Gutenberg { * @var array */ const PRESETS_METADATA = array( - array( - 'path' => array( 'shadow', 'presets' ), - 'prevent_override' => array( 'shadow', 'defaultPresets' ), - 'use_default_names' => false, - 'value_key' => 'shadow', - 'css_vars' => '--wp--preset--shadow--$slug', - 'classes' => array(), - 'properties' => array( 'box-shadow' ), - ), array( 'path' => array( 'color', 'palette' ), 'prevent_override' => array( 'color', 'defaultPalette' ), @@ -185,6 +176,15 @@ class WP_Theme_JSON_Gutenberg { 'classes' => array(), 'properties' => array( 'padding', 'margin' ), ), + array( + 'path' => array( 'shadow', 'presets' ), + 'prevent_override' => array( 'shadow', 'defaultPresets' ), + 'use_default_names' => false, + 'value_key' => 'shadow', + 'css_vars' => '--wp--preset--shadow--$slug', + 'classes' => array(), + 'properties' => array( 'box-shadow' ), + ), ); /** @@ -261,21 +261,6 @@ class WP_Theme_JSON_Gutenberg { 'box-shadow' => array( 'shadow' ), ); - /** - * Protected style properties. - * - * These style properties are only rendered if a setting enables it - * via a value other than `null`. - * - * Each element maps the style property to the corresponding theme.json - * setting key. - * - * @since 5.9.0 - */ - const PROTECTED_PROPERTIES = array( - 'spacing.blockGap' => array( 'spacing', 'blockGap' ), - ); - /** * Indirect metadata for style properties that are not directly output. * @@ -306,6 +291,21 @@ class WP_Theme_JSON_Gutenberg { ), ); + /** + * Protected style properties. + * + * These style properties are only rendered if a setting enables it + * via a value other than `null`. + * + * Each element maps the style property to the corresponding theme.json + * setting key. + * + * @since 5.9.0 + */ + const PROTECTED_PROPERTIES = array( + 'spacing.blockGap' => array( 'spacing', 'blockGap' ), + ); + /** * The top-level keys a theme.json can have. * @@ -346,10 +346,6 @@ class WP_Theme_JSON_Gutenberg { 'style' => null, 'width' => null, ), - 'shadow' => array( - 'presets' => null, - 'defaultPresets' => null, - ), 'color' => array( 'background' => null, 'custom' => null, @@ -386,6 +382,10 @@ class WP_Theme_JSON_Gutenberg { 'padding' => null, 'units' => null, ), + 'shadow' => array( + 'presets' => null, + 'defaultPresets' => null, + ), 'typography' => array( 'fluid' => null, 'customFontSize' => null, @@ -431,7 +431,6 @@ class WP_Theme_JSON_Gutenberg { 'gradient' => null, 'text' => null, ), - 'css' => null, 'dimensions' => array( 'minHeight' => null, ), @@ -460,6 +459,7 @@ class WP_Theme_JSON_Gutenberg { 'textDecoration' => null, 'textTransform' => null, ), + 'css' => null, ); /** @@ -970,27 +970,6 @@ public function get_settings() { } } - /** - * Processes the CSS, to apply nesting. - * - * @param string $css The CSS to process. - * @param string $selector The selector to nest. - * - * @return string The processed CSS. - */ - protected function process_blocks_custom_css( $css, $selector ) { - $processed_css = ''; - - // Split CSS nested rules. - $parts = explode( '&', $css ); - foreach ( $parts as $part ) { - $processed_css .= ( ! str_contains( $part, '{' ) ) - ? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level. - : trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character. - } - return $processed_css; - } - /** * Returns the stylesheet that results of processing * the theme.json structure this object represents. @@ -1097,6 +1076,28 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' return $stylesheet; } + /** + * Processes the CSS, to apply nesting. + * + * @since 6.2.0 + * + * @param string $css The CSS to process. + * @param string $selector The selector to nest. + * @return string The processed CSS. + */ + protected function process_blocks_custom_css( $css, $selector ) { + $processed_css = ''; + + // Split CSS nested rules. + $parts = explode( '&', $css ); + foreach ( $parts as $part ) { + $processed_css .= ( ! str_contains( $part, '{' ) ) + ? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level. + : trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character. + } + return $processed_css; + } + /** * Returns the global styles custom css. * @@ -2574,13 +2575,13 @@ public function get_root_layout_rules( $selector, $block_metadata ) { * * @since 6.0.0 * - * @param array $data The data to inspect. - * @param bool|array $path Boolean or path to a boolean. - * @param bool $default Default value if the referenced path is missing. - * Default false. + * @param array $data The data to inspect. + * @param bool|array $path Boolean or path to a boolean. + * @param bool $default_value Default value if the referenced path is missing. + * Default false. * @return bool Value of boolean metadata. */ - protected static function get_metadata_boolean( $data, $path, $default = false ) { + protected static function get_metadata_boolean( $data, $path, $default_value = false ) { if ( is_bool( $path ) ) { return $path; } @@ -2592,7 +2593,7 @@ protected static function get_metadata_boolean( $data, $path, $default = false ) } } - return $default; + return $default_value; } /** From aefb9c84d2cdc29a89d4cd2478ce28f8c0daf4b0 Mon Sep 17 00:00:00 2001 From: David Calhoun <438664+dcalhoun@users.noreply.github.com> Date: Wed, 1 Mar 2023 10:00:21 -0500 Subject: [PATCH 20/24] fix: Enable access to block settings within UBE (#48435) * fix: Enable access to block settings within UBE The "Show more settings" menu item is no longer included in the block toolbar after #46709 merged. Rather than relying upon that menu item, this conditionally displays the sidebar toggle button whenever a block is selected. * fix: Disable white space stripping that breaks nested CSS selectors CSS selectors rely upon a single white space between selectors to represent an ancestor relationship. Globally removing white space in the stylesheet breaks this functionality, as it transforms the selector to target a single element with all the selectors. The white space stripping should likely be replaced with a proper CSS minification long term. * fix: Hide block actions unrelated to editing a single block Hide the entire "block settings" drop-down menu now that we no longer rely upon it to access the "Show more settings" menu option that was removed entirely. * refactor: Relocate script toggling block settings visibility This relates more to editor behavior than the post content. * fix: Apply styles and script to editor canvas iframe The editor canvas now relies upon an iframe. It is not possible to style elements within an iframe from the parent context. This copies the styles from the parent conext to the iframe. Additionally, the logic selecting the first block also failed due to the block not existing when it was invoked. This relocates that logic until after the iframe is ready. * fix: Expand conditional checks for partial DOM trees On Android, there were times where the iframe was present, but the nested window was not yet ready. * refactor: Rename for brevity * fix: Avoid React removing appended iframe styles Append the styles to the `document` element, as React will remove the mutation to the `head` element. * docs: Add change log entry --- .../GutenbergWebViewActivity.java | 10 +- .../content-functions.js | 7 - .../editor-behavior-overrides.js | 216 +++++++++++++----- .../editor-style-overrides.css | 59 ++--- .../gutenberg-web-single-block/inject-css.js | 3 +- .../FallbackJavascriptInjection.swift | 4 +- ...utenbergWebSingleBlockViewController.swift | 1 + .../react-native-bridge/ios/SourceFile.swift | 5 + packages/react-native-editor/CHANGELOG.md | 3 + 9 files changed, 201 insertions(+), 107 deletions(-) diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java index 2b3302b75e2575..c4ae7e350f4cb7 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java @@ -40,7 +40,7 @@ public class GutenbergWebViewActivity extends AppCompatActivity { public static final String ARG_BLOCK_CONTENT = "block_content"; private static final String INJECT_LOCAL_STORAGE_SCRIPT_TEMPLATE = "localStorage.setItem('WP_DATA_USER_%d','%s')"; - private static final String INJECT_CSS_SCRIPT_TEMPLATE = "window.injectCss('%s')"; + private static final String INJECT_CSS_SCRIPT_TEMPLATE = "window.injectCss('%s', '%s')"; private static final String INJECT_GET_HTML_POST_CONTENT_SCRIPT = "window.getHTMLPostContent();"; private static final String INJECT_ON_SHOW_CONTEXT_MENU_SCRIPT = "window.onShowContextMenu();"; private static final String INJECT_ON_HIDE_CONTEXT_MENU_SCRIPT = "window.onHideContextMenu();"; @@ -327,16 +327,16 @@ private void injectCssScript() { mWebView.evaluateJavascript(injectCssScript, message -> { if (message != null) { String editorStyle = getFileContentFromAssets("gutenberg-web-single-block/editor-style-overrides.css"); - editorStyle = removeWhiteSpace(removeNewLines(editorStyle)); - evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, editorStyle)); + editorStyle = removeNewLines(editorStyle); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, editorStyle, "editor-style-overrides")); String injectWPBarsCssScript = getFileContentFromAssets("gutenberg-web-single-block/wp-bar-override.css"); injectWPBarsCssScript = removeWhiteSpace(removeNewLines(injectWPBarsCssScript)); - evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectWPBarsCssScript)); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectWPBarsCssScript, "wp-bar-override")); String injectExternalCssScript = getOnGutenbergReadyExternalStyles(); injectExternalCssScript = removeWhiteSpace(removeNewLines(injectExternalCssScript)); - evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectExternalCssScript)); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectExternalCssScript, "external-styles")); } }); } diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js b/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js index d6e7d51375d441..611701c237b095 100644 --- a/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js @@ -25,19 +25,12 @@ window.getHTMLPostContent = () => { }; window.insertBlock = ( blockHTML ) => { - const { blockEditorSelect, blockEditorDispatch } = - window.getBlockEditorStore(); - // Setup the editor with the inserted block. const post = window.wp.data.select( 'core/editor' ).getCurrentPost(); window.wp.data .dispatch( 'core/editor' ) .setupEditor( post, { content: blockHTML } ); - // Select the first block. - const clientId = blockEditorSelect.getBlocks()[ 0 ].clientId; - blockEditorDispatch.selectBlock( clientId ); - window.contentIncerted = true; }; diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js index 0cfa0e9985fa02..09dcd6447824d7 100644 --- a/packages/react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js @@ -1,59 +1,167 @@ -// Listeners for native context menu visibility changes. -let isContextMenuVisible = false; -const hideContextMenuListeners = []; - -window.onShowContextMenu = () => { - isContextMenuVisible = true; -}; -window.onHideContextMenu = () => { - isContextMenuVisible = false; - while ( hideContextMenuListeners.length > 0 ) { - const listener = hideContextMenuListeners.pop(); - listener(); - } -}; - -/* -This is a fix for a text selection quirk in the UBE. -It notifies the Android app to dismiss the text selection -context menu when certain menu items are tapped. This is -done via the 'hideTextSelectionContextMenu' method, which -is sent back to the Android app, where the dismissal is -then handle. See PR for further details: -https://github.com/WordPress/gutenberg/pull/34668 -*/ -window.addEventListener( - 'click', - ( event ) => { - const selected = document.getSelection(); - if ( ! isContextMenuVisible || ! selected || ! selected.toString() ) { - return; +/** + * Detects whether the user agent is Android. + * + * @return {boolean} Whether the user agent is Android. + */ +function isAndroid() { + return !! window.navigator.userAgent.match( /Android/ ); +} + +/** + * This is a fix for a text selection quirk in the UBE. It notifies the Android + * app to dismiss the text selection context menu when certain menu items are + * tapped. This is done via the 'hideTextSelectionContextMenu' method, which + * is sent back to the Android app, where the dismissal is then handle. + * + * @return {void} + * @see https://github.com/WordPress/gutenberg/pull/34668 + */ +function manageTextSelectonContextMenu() { + // Listeners for native context menu visibility changes. + let isContextMenuVisible = false; + const hideContextMenuListeners = []; + + window.onShowContextMenu = () => { + isContextMenuVisible = true; + }; + window.onHideContextMenu = () => { + isContextMenuVisible = false; + while ( hideContextMenuListeners.length > 0 ) { + const listener = hideContextMenuListeners.pop(); + listener(); } + }; - // Check if the event is triggered by a dropdown - // toggle button. - const dropdownToggles = document.querySelectorAll( - '.components-dropdown-menu > button' - ); - let currentToggle; - for ( const node of dropdownToggles.values() ) { - if ( node.contains( event.target ) ) { - currentToggle = node; - break; + window.addEventListener( + 'click', + ( event ) => { + const selected = document.getSelection(); + if ( + ! isContextMenuVisible || + ! selected || + ! selected.toString() + ) { + return; } - } - // Hide text selection context menu when the click - // is triggered by a dropdown toggle. - // - // NOTE: The event propagation is prevented because - // it will be dispatched after the context menu - // is hidden. - if ( currentToggle ) { - event.stopPropagation(); - hideContextMenuListeners.push( () => currentToggle.click() ); - window.wpwebkit.hideTextSelectionContextMenu(); + // Check if the event is triggered by a dropdown + // toggle button. + const dropdownToggles = document.querySelectorAll( + '.components-dropdown-menu > button' + ); + let currentToggle; + for ( const node of dropdownToggles.values() ) { + if ( node.contains( event.target ) ) { + currentToggle = node; + break; + } + } + + // Hide text selection context menu when the click + // is triggered by a dropdown toggle. + // + // NOTE: The event propagation is prevented because + // it will be dispatched after the context menu + // is hidden. + if ( currentToggle ) { + event.stopPropagation(); + hideContextMenuListeners.push( () => currentToggle.click() ); + window.wpwebkit.hideTextSelectionContextMenu(); + } + }, + true + ); +} + +if ( isAndroid() ) { + manageTextSelectonContextMenu(); +} + +const editor = document.querySelector( '#editor' ); + +function _toggleBlockSelectedClass( isBlockSelected ) { + if ( isBlockSelected ) { + editor.classList.add( 'is-block-selected' ); + } else { + editor.classList.remove( 'is-block-selected' ); + } +} + +/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */ + +/** + * Toggle the `is-block-selected` class on the editor container when a block is + * selected. This is used to hide the sidebar toggle button when a block is not + * selected. + * + * @param {WPDataRegistry} registry Data registry. + * @return {WPDataRegistry} Modified data registry. + */ +function toggleBlockSelectedStyles( registry ) { + return { + dispatch: ( namespace ) => { + const namespaceName = + typeof namespace === 'string' ? namespace : namespace.name; + const actions = { ...registry.dispatch( namespaceName ) }; + + const originalSelectBlockAction = actions.selectBlock; + actions.selectBlock = ( ...args ) => { + _toggleBlockSelectedClass( true ); + return originalSelectBlockAction( ...args ); + }; + + const originalClearSelectedBlockAction = actions.clearSelectedBlock; + actions.clearSelectedBlock = ( ...args ) => { + _toggleBlockSelectedClass( false ); + return originalClearSelectedBlockAction( ...args ); + }; + + return actions; + }, + }; +} + +window.wp.data.use( toggleBlockSelectedStyles ); + +// The editor-canvas iframe relies upon `srcdoc`, which does not trigger a +// `load` event. Thus, we must poll for the iframe to be ready. +let overrideAttempts = 0; +const overrideInterval = setInterval( () => { + overrideAttempts++; + const overrideStyles = document.querySelector( '#editor-style-overrides' ); + const canvasIframe = document.querySelector( + 'iframe[name="editor-canvas"]' + ); + + if ( + overrideStyles && + canvasIframe && + canvasIframe.contentDocument && + canvasIframe.contentDocument.documentElement + ) { + clearInterval( overrideInterval ); + + // Clone the editor styles so that they can be copied to the iframe, as + // elements within an iframe cannot be styled from the parent context. + const overrideStylesClone = overrideStyles.cloneNode( true ); + overrideStylesClone.id = 'editor-styles-overrides-2'; + // Append to document rather than the head, as React will remove this + // mutation. + canvasIframe.contentDocument.documentElement.appendChild( + overrideStylesClone + ); + + // Select the first block. + const { blockEditorSelect, blockEditorDispatch } = + window.getBlockEditorStore(); + const firstBlock = blockEditorSelect.getBlocks()[ 0 ]; + if ( firstBlock ) { + blockEditorDispatch.selectBlock( firstBlock.clientId ); } - }, - true -); + } + + // Safeguard against an infinite loop. + if ( overrideAttempts > 100 ) { + clearInterval( overrideInterval ); + } +}, 300 ); diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css index 7aa208abe55373..f8f2e8fe2b4cde 100644 --- a/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css @@ -17,14 +17,22 @@ display: none; } -/* - Hiddes the top bar header by setting its height to 0 - We can\'t remove it since the block toolbar is a child of it. - */ +/* Right align post header children as we will only display one child */ .edit-post-header { - height: 0px; - padding: 0px; - overflow: hidden; + justify-content: flex-end; +} + +/* Hide post controls unrelated to editing a single block */ +.edit-post-header__toolbar, +.edit-post-layout .edit-post-header .edit-post-header__settings > *, +.interface-pinned-items > * { + display: none; +} + +/* Display the sidebar toggle button whenever a block is selected */ +.edit-post-layout .edit-post-header .edit-post-header__settings .interface-pinned-items, +.is-block-selected .edit-post-header__settings .interface-pinned-items > button:first-child { + display: flex; } /* Move the block toolbar to the top */ @@ -36,6 +44,11 @@ top: 0px; } +/* Hide block actions unrelated to editing a single block */ +.block-editor-block-settings-menu { + display: none; +} + /* Moves the whole editor to the top. There was an extra top margin after removing the WP Admin bar. @@ -69,38 +82,6 @@ display: none; } -/* - Load second button in component menu group but hide it from view. - This is to fix a Chrome-specific bug that occurs if this button is set to "display: none;" - For additional context, see: https://github.com/WordPress/gutenberg/pull/33740 -*/ -.components-dropdown-menu__menu - > .components-menu-group - > div - > button:nth-child( 2 ) { - display: block; - min-height: 0; - height: 0; - padding: 0; -} - -.components-menu-group > div > button:nth-child( 2 ) > span { - display: none; -} - -.components-button:focus:not( :disabled ) { - box-shadow: none; -} - -/* Remove \'delete block\' button inside \'...\' button in block toolbar */ -.components-dropdown-menu__menu > div:not(:first-child) { - display: none; -} - -.components-dropdown-menu__menu > div:first-child { - padding-bottom: 0; -} - /* Some Themes can overwrite values on \'editor-styles-wrapper\'. This will ensure that the top padding is correct on our single-block version of gutenberg web. diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js b/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js index 60ac677bd20f5c..483e742e780bcb 100644 --- a/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js @@ -1,8 +1,9 @@ const injectCss = ` -window.injectCss = (css) => { +window.injectCss = (css, id) => { const style = document.createElement('style'); style.innerHTML = css; style.type = 'text/css'; + style.id = id; document.head.appendChild(style); } `; diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift index 13ae9dd1f05735..ee75dc0968a586 100644 --- a/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift @@ -19,6 +19,7 @@ public struct FallbackJavascriptInjection { public let preventAutosavesScript: WKUserScript public let getHtmlContentScript = "window.getHTMLPostContent()".toJsScript() public let gutenbergObserverScript: WKUserScript + public let editorBehaviorScript: WKUserScript /// Init an instance of GutenbergWebJavascriptInjection or throws if any of the required sources doesn't exist. /// This helps to cach early any possible error due to missing source files. @@ -31,7 +32,7 @@ public struct FallbackJavascriptInjection { } func getInjectCssScript(with source: SourceFile) throws -> WKUserScript { - "window.injectCss(`\(try source.getContent())`)".toJsScript() + "window.injectCss(`\(try source.getContent())`, `\(source.getName())`)".toJsScript() } userContentScripts = [ @@ -44,6 +45,7 @@ public struct FallbackJavascriptInjection { injectEditorCssScript = try getInjectCssScript(with: .editorStyle) preventAutosavesScript = try script(with: .preventAutosaves) gutenbergObserverScript = try script(with: .gutenbergObserver) + editorBehaviorScript = try script(with: .editorBehavior) let localStorageJsonString = try SourceFile.localStorage.getContent().removingSpacesAndNewLines() let scriptString = String(format: injectLocalStorageScriptTemplate, userId, localStorageJsonString) diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift index aa83095f058f10..8d11028728a891 100644 --- a/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift @@ -76,6 +76,7 @@ open class GutenbergWebSingleBlockViewController: UIViewController { onGutenbergReadyScripts().forEach(evaluateJavascript) evaluateJavascript(jsInjection.preventAutosavesScript) evaluateJavascript(jsInjection.insertBlockScript) + evaluateJavascript(jsInjection.editorBehaviorScript) DispatchQueue.main.async { [weak self] in self?.removeCoverViewAnimated() } diff --git a/packages/react-native-bridge/ios/SourceFile.swift b/packages/react-native-bridge/ios/SourceFile.swift index 2f75e22278c0f1..2386f84580464f 100644 --- a/packages/react-native-bridge/ios/SourceFile.swift +++ b/packages/react-native-bridge/ios/SourceFile.swift @@ -29,6 +29,10 @@ public struct SourceFile { } extension SourceFile { + public func getName() -> String { + return self.name + } + public func jsScript(with argument: String? = nil) throws -> WKUserScript { let content = try getContent() let formatted = String(format: content, argument ?? []) @@ -53,4 +57,5 @@ extension SourceFile { static let preventAutosaves = SourceFile(name: "prevent-autosaves", type: .js) static let gutenbergObserver = SourceFile(name: "gutenberg-observer", type: .js) static let supportedBlocks = SourceFile(name: "supported-blocks", type: .json) + static let editorBehavior = SourceFile(name: "editor-behavior-overrides", type: .js) } diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 8b8c395a67d9e9..e34f5bfd753ee2 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -12,6 +12,9 @@ For each user feature we should also add a importance categorization label to i ## Unreleased - [*] Add metadata parameter to media upload events [#48103] +## 1.89.1 +- [*] Fix inaccessible block settings within the unsupported block editor [#48435] + ## 1.89.0 * No User facing changes * From 0e1305760947ca6876f7a45c32ce7e7833c7cac6 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Wed, 1 Mar 2023 17:03:30 +0200 Subject: [PATCH 21/24] Sync `gutenberg_build_query_vars_from_query_block` with core (#48640) --- lib/compat/wordpress-6.1/blocks.php | 142 --------------------------- lib/compat/wordpress-6.2/blocks.php | 145 ++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 142 deletions(-) diff --git a/lib/compat/wordpress-6.1/blocks.php b/lib/compat/wordpress-6.1/blocks.php index e8093961896a48..8ee0acba6b6cfe 100644 --- a/lib/compat/wordpress-6.1/blocks.php +++ b/lib/compat/wordpress-6.1/blocks.php @@ -137,148 +137,6 @@ function gutenberg_block_type_metadata_multiple_view_scripts( $metadata ) { } add_filter( 'block_type_metadata', 'gutenberg_block_type_metadata_multiple_view_scripts' ); -/** - * Helper function that constructs a WP_Query args array from - * a `Query` block properties. - * - * It's used in QueryLoop, QueryPaginationNumbers and QueryPaginationNext blocks. - * - * `build_query_vars_from_query_block` was introduced in 5.8, for 6.1 we just need - * to update that function and not create a new one. - * - * @param WP_Block $block Block instance. - * @param int $page Current query's page. - * - * @return array Returns the constructed WP_Query arguments. - */ -function gutenberg_build_query_vars_from_query_block( $block, $page ) { - $query = array( - 'post_type' => 'post', - 'order' => 'DESC', - 'orderby' => 'date', - 'post__not_in' => array(), - ); - - if ( isset( $block->context['query'] ) ) { - if ( ! empty( $block->context['query']['postType'] ) ) { - $post_type_param = $block->context['query']['postType']; - if ( is_post_type_viewable( $post_type_param ) ) { - $query['post_type'] = $post_type_param; - } - } - if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) { - $sticky = get_option( 'sticky_posts' ); - if ( 'only' === $block->context['query']['sticky'] ) { - /** - * Passing an empty array to post__in will return have_posts() as true (and all posts will be returned). - * Logic should be used before hand to determine if WP_Query should be used in the event that the array - * being passed to post__in is empty. - * - * @see https://core.trac.wordpress.org/ticket/28099 - */ - $query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 ); - $query['ignore_sticky_posts'] = 1; - } else { - $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); - } - } - if ( ! empty( $block->context['query']['exclude'] ) ) { - $excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] ); - $excluded_post_ids = array_filter( $excluded_post_ids ); - $query['post__not_in'] = array_merge( $query['post__not_in'], $excluded_post_ids ); - } - if ( - isset( $block->context['query']['perPage'] ) && - is_numeric( $block->context['query']['perPage'] ) - ) { - $per_page = absint( $block->context['query']['perPage'] ); - $offset = 0; - - if ( - isset( $block->context['query']['offset'] ) && - is_numeric( $block->context['query']['offset'] ) - ) { - $offset = absint( $block->context['query']['offset'] ); - } - - $query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset; - $query['posts_per_page'] = $per_page; - } - - // We need to migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. - if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { - $tax_query = array(); - if ( ! empty( $block->context['query']['categoryIds'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'category', - 'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ), - 'include_children' => false, - ); - } - if ( ! empty( $block->context['query']['tagIds'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'post_tag', - 'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ), - 'include_children' => false, - ); - } - $query['tax_query'] = $tax_query; - } - if ( ! empty( $block->context['query']['taxQuery'] ) ) { - $query['tax_query'] = array(); - foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { - if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) { - $query['tax_query'][] = array( - 'taxonomy' => $taxonomy, - 'terms' => array_filter( array_map( 'intval', $terms ) ), - 'include_children' => false, - ); - } - } - } - if ( - isset( $block->context['query']['order'] ) && - in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true ) - ) { - $query['order'] = strtoupper( $block->context['query']['order'] ); - } - if ( isset( $block->context['query']['orderBy'] ) ) { - $query['orderby'] = $block->context['query']['orderBy']; - } - if ( ! empty( $block->context['query']['author'] ) ) { - $query['author'] = $block->context['query']['author']; - } - if ( ! empty( $block->context['query']['search'] ) ) { - $query['s'] = $block->context['query']['search']; - } - if ( ! empty( $block->context['query']['parents'] ) && is_post_type_hierarchical( $query['post_type'] ) ) { - $query['post_parent__in'] = array_filter( array_map( 'intval', $block->context['query']['parents'] ) ); - } - } - - /** - * Filters the arguments which will be passed to `WP_Query` for the Query Loop Block. - * - * Anything to this filter should be compatible with the `WP_Query` API to form - * the query context which will be passed down to the Query Loop Block's children. - * This can help, for example, to include additional settings or meta queries not - * directly supported by the core Query Loop Block, and extend its capabilities. - * - * Please note that this will only influence the query that will be rendered on the - * front-end. The editor preview is not affected by this filter. Also, worth noting - * that the editor preview uses the REST API, so, ideally, one should aim to provide - * attributes which are also compatible with the REST API, in order to be able to - * implement identical queries on both sides. - * - * @since 6.1.0 - * - * @param array $query Array containing parameters for `WP_Query` as parsed by the block context. - * @param WP_Block $block Block instance. - * @param int $page Current query's page. - */ - return apply_filters( 'query_loop_block_query_vars', $query, $block, $page ); -} - /** * Register render template for core blocks if handling is missing in WordPress core. * diff --git a/lib/compat/wordpress-6.2/blocks.php b/lib/compat/wordpress-6.2/blocks.php index f432f6a41af8f7..94c6eaabcef9b3 100644 --- a/lib/compat/wordpress-6.2/blocks.php +++ b/lib/compat/wordpress-6.2/blocks.php @@ -26,3 +26,148 @@ function gutenberg_safe_style_attrs_6_2( $attrs ) { return $attrs; } add_filter( 'safe_style_css', 'gutenberg_safe_style_attrs_6_2' ); + +/** + * Helper function that constructs a WP_Query args array from + * a `Query` block properties. + * + * It's used in QueryLoop, QueryPaginationNumbers and QueryPaginationNext blocks. + * + * `build_query_vars_from_query_block` was introduced in 5.8, for 6.1 we just need + * to update that function and not create a new one. + * + * @param WP_Block $block Block instance. + * @param int $page Current query's page. + * + * @return array Returns the constructed WP_Query arguments. + */ +function gutenberg_build_query_vars_from_query_block( $block, $page ) { + $query = array( + 'post_type' => 'post', + 'order' => 'DESC', + 'orderby' => 'date', + 'post__not_in' => array(), + ); + + if ( isset( $block->context['query'] ) ) { + if ( ! empty( $block->context['query']['postType'] ) ) { + $post_type_param = $block->context['query']['postType']; + if ( is_post_type_viewable( $post_type_param ) ) { + $query['post_type'] = $post_type_param; + } + } + if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) { + $sticky = get_option( 'sticky_posts' ); + if ( 'only' === $block->context['query']['sticky'] ) { + /** + * Passing an empty array to post__in will return have_posts() as true (and all posts will be returned). + * Logic should be used before hand to determine if WP_Query should be used in the event that the array + * being passed to post__in is empty. + * + * @see https://core.trac.wordpress.org/ticket/28099 + */ + $query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 ); + $query['ignore_sticky_posts'] = 1; + } else { + $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); + } + } + if ( ! empty( $block->context['query']['exclude'] ) ) { + $excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] ); + $excluded_post_ids = array_filter( $excluded_post_ids ); + $query['post__not_in'] = array_merge( $query['post__not_in'], $excluded_post_ids ); + } + if ( + isset( $block->context['query']['perPage'] ) && + is_numeric( $block->context['query']['perPage'] ) + ) { + $per_page = absint( $block->context['query']['perPage'] ); + $offset = 0; + + if ( + isset( $block->context['query']['offset'] ) && + is_numeric( $block->context['query']['offset'] ) + ) { + $offset = absint( $block->context['query']['offset'] ); + } + + $query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset; + $query['posts_per_page'] = $per_page; + } + + // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. + if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { + $tax_query = array(); + if ( ! empty( $block->context['query']['categoryIds'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'category', + 'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ), + 'include_children' => false, + ); + } + if ( ! empty( $block->context['query']['tagIds'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ), + 'include_children' => false, + ); + } + $query['tax_query'] = $tax_query; + } + if ( ! empty( $block->context['query']['taxQuery'] ) ) { + $query['tax_query'] = array(); + foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { + if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) { + $query['tax_query'][] = array( + 'taxonomy' => $taxonomy, + 'terms' => array_filter( array_map( 'intval', $terms ) ), + 'include_children' => false, + ); + } + } + } + if ( + isset( $block->context['query']['order'] ) && + in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true ) + ) { + $query['order'] = strtoupper( $block->context['query']['order'] ); + } + if ( isset( $block->context['query']['orderBy'] ) ) { + $query['orderby'] = $block->context['query']['orderBy']; + } + if ( + isset( $block->context['query']['author'] ) && + (int) $block->context['query']['author'] > 0 + ) { + $query['author'] = (int) $block->context['query']['author']; + } + if ( ! empty( $block->context['query']['search'] ) ) { + $query['s'] = $block->context['query']['search']; + } + if ( ! empty( $block->context['query']['parents'] ) && is_post_type_hierarchical( $query['post_type'] ) ) { + $query['post_parent__in'] = array_filter( array_map( 'intval', $block->context['query']['parents'] ) ); + } + } + + /** + * Filters the arguments which will be passed to `WP_Query` for the Query Loop Block. + * + * Anything to this filter should be compatible with the `WP_Query` API to form + * the query context which will be passed down to the Query Loop Block's children. + * This can help, for example, to include additional settings or meta queries not + * directly supported by the core Query Loop Block, and extend its capabilities. + * + * Please note that this will only influence the query that will be rendered on the + * front-end. The editor preview is not affected by this filter. Also, worth noting + * that the editor preview uses the REST API, so, ideally, one should aim to provide + * attributes which are also compatible with the REST API, in order to be able to + * implement identical queries on both sides. + * + * @since 6.1.0 + * + * @param array $query Array containing parameters for `WP_Query` as parsed by the block context. + * @param WP_Block $block Block instance. + * @param int $page Current query's page. + */ + return apply_filters( 'query_loop_block_query_vars', $query, $block, $page ); +} From 588ef6cc582d35cee43633cf90bb0c9310f3e149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 1 Mar 2023 17:33:07 +0100 Subject: [PATCH 22/24] Fix for `WP_Theme_JSON_Resolver_Gutenberg::get_merged_data` (#48644) --- lib/class-wp-theme-json-resolver-gutenberg.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index e4787b468ab785..e433a104eac1fa 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -571,7 +571,8 @@ public static function get_merged_data( $origin = 'custom' ) { _deprecated_argument( __FUNCTION__, '5.9.0' ); } - $result = static::get_core_data(); + $result = new WP_Theme_JSON(); + $result->merge( static::get_core_data() ); if ( 'default' === $origin ) { $result->set_spacing_sizes(); return $result; From 237673a1db3cf58d0d184b40ed1908db46b45651 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 1 Mar 2023 21:30:25 +0400 Subject: [PATCH 23/24] List Item: Avoid an error when the 'onReplace' prop is undefined (#48639) --- packages/block-library/src/list-item/edit.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/list-item/edit.js b/packages/block-library/src/list-item/edit.js index 738a8ab397adf3..3f26840ad345f9 100644 --- a/packages/block-library/src/list-item/edit.js +++ b/packages/block-library/src/list-item/edit.js @@ -88,9 +88,16 @@ export default function ListItemEdit( { placeholder={ placeholder || __( 'List' ) } onSplit={ onSplit } onMerge={ onMerge } - onReplace={ ( blocks, ...args ) => { - onReplace( convertToListItems( blocks ), ...args ); - } } + onReplace={ + onReplace + ? ( blocks, ...args ) => { + onReplace( + convertToListItems( blocks ), + ...args + ); + } + : undefined + } /> { innerBlocksProps.children } From 0a6c5e89768d0e1e68f42b59349572a470d42328 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 1 Mar 2023 17:36:54 +0000 Subject: [PATCH 24/24] Bump plugin version to 15.3.0-rc.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index f2ff542e9895d3..0e5f2b3ba9b5fe 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.0 * Requires PHP: 5.6 - * Version: 15.2.3 + * Version: 15.3.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index d19e5fb97f5a66..7830f3c448a9dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "15.2.3", + "version": "15.3.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 37a38240c1e938..dc54d7361fadd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "15.2.3", + "version": "15.3.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors",