From 7472c0d3aa03c28be19f9814f73824970cabf257 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Wed, 7 Feb 2024 09:05:37 +0100 Subject: [PATCH 01/37] Link UI: polish lightbox pieces. (#58666) * Link UI: polish lightbox pieces. * Polish info style * Remove top margin from description --------- Co-authored-by: Tetsuaki Hamano --- .../src/components/url-input/style.scss | 6 ++-- .../url-popover/image-url-input-ui.js | 6 ++-- .../src/components/url-popover/style.scss | 30 ++++++------------- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/packages/block-editor/src/components/url-input/style.scss b/packages/block-editor/src/components/url-input/style.scss index 214866ccbab183..66f71e803595a8 100644 --- a/packages/block-editor/src/components/url-input/style.scss +++ b/packages/block-editor/src/components/url-input/style.scss @@ -15,11 +15,13 @@ $input-size: 300px; width: $input-size; } padding: $input-padding; - border: none; - border-radius: 0; margin-left: 0; margin-right: 0; + &:not(:focus) { + border-color: transparent; + } + /* Fonts smaller than 16px causes mobile safari to zoom. */ font-size: $mobile-text-min-font-size; @include break-small { diff --git a/packages/block-editor/src/components/url-popover/image-url-input-ui.js b/packages/block-editor/src/components/url-popover/image-url-input-ui.js index dca8db868bbb5a..ae59daa1f502b3 100644 --- a/packages/block-editor/src/components/url-popover/image-url-input-ui.js +++ b/packages/block-editor/src/components/url-popover/image-url-input-ui.js @@ -14,6 +14,7 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { + Icon, link as linkIcon, image, page, @@ -342,9 +343,7 @@ const ImageURLInputUI = ( { ) } { ! url && ! isEditingLink && lightboxEnabled && (
-
- { fullscreen } -
+

{ __( 'Expand on click' ) }

@@ -355,7 +354,6 @@ const ImageURLInputUI = ( {

- -
diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index eac1e00d38e6bd..2fb2a7e1683c50 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -5,6 +5,7 @@ ### Enhancements - Break up init with yielding to main to prevent long task from hydration. ([#58227](https://github.com/WordPress/gutenberg/pull/58227)) +- Support setting the namespace using a string in `data-wp-interactive`, like `data-wp-interactive="myPlugin"`. ([#58743](https://github.com/WordPress/gutenberg/pull/58743)) ## 4.0.1 (2024-01-31) diff --git a/packages/interactivity/src/vdom.ts b/packages/interactivity/src/vdom.ts index 9928012ada3f46..5a997993668094 100644 --- a/packages/interactivity/src/vdom.ts +++ b/packages/interactivity/src/vdom.ts @@ -85,7 +85,11 @@ export function toVdom( root ) { } catch ( e ) {} if ( n === islandAttr ) { island = true; - namespaces.push( value?.namespace ?? null ); + namespaces.push( + typeof value === 'string' + ? value + : value?.namespace ?? null + ); } else { directives.push( [ n, ns, value ] ); } diff --git a/test/e2e/specs/interactivity/tovdom-islands.spec.ts b/test/e2e/specs/interactivity/tovdom-islands.spec.ts index 849001274cfd53..da4839c18afb2e 100644 --- a/test/e2e/specs/interactivity/tovdom-islands.spec.ts +++ b/test/e2e/specs/interactivity/tovdom-islands.spec.ts @@ -23,10 +23,17 @@ test.describe( 'toVdom - islands', () => { await expect( el ).toBeVisible(); } ); - test( 'directives that are inside islands should be hydrated', async ( { + test( 'directives that are inside islands with json objects should be hydrated', async ( { page, } ) => { - const el = page.getByTestId( 'inside an island' ); + const el = page.getByTestId( 'inside an island with json object' ); + await expect( el ).toBeHidden(); + } ); + + test( 'directives that are inside islands with strings should be hydrated', async ( { + page, + } ) => { + const el = page.getByTestId( 'inside an island with string' ); await expect( el ).toBeHidden(); } ); From 5b28829f0d800833d38e7192ecc98548da05bf12 Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+c4rl0sbr4v0@users.noreply.github.com> Date: Wed, 7 Feb 2024 09:30:49 +0100 Subject: [PATCH 04/37] Interactivity API - Blocks: Move interactivity registration to render (#58678) * Move interactivity registration to render * Remove whitespace line * Use scripts dependant of debug active or not Co-authored-by: c4rl0sbr4v0 Co-authored-by: luisherranz --- packages/block-library/src/file/index.php | 22 +++++----- packages/block-library/src/image/index.php | 23 ++++++----- .../block-library/src/navigation/index.php | 22 +++++----- packages/block-library/src/query/index.php | 40 +++++++++---------- packages/block-library/src/search/index.php | 22 +++++----- 5 files changed, 65 insertions(+), 64 deletions(-) diff --git a/packages/block-library/src/file/index.php b/packages/block-library/src/file/index.php index 4316eac677d1e1..cf9775224988a4 100644 --- a/packages/block-library/src/file/index.php +++ b/packages/block-library/src/file/index.php @@ -38,6 +38,17 @@ static function ( $matches ) { // If it's interactive, enqueue the script module and add the directives. if ( ! empty( $attributes['displayPreview'] ) ) { + $suffix = wp_scripts_get_suffix(); + if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { + $module_url = gutenberg_url( "/build/interactivity/file{$suffix}.js" ); + } + + wp_register_script_module( + '@wordpress/block-library/file', + isset( $module_url ) ? $module_url : includes_url( "blocks/file/view{$suffix}.js" ), + array( '@wordpress/interactivity' ), + defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) + ); wp_enqueue_script_module( '@wordpress/block-library/file' ); $processor = new WP_HTML_Tag_Processor( $content ); @@ -62,16 +73,5 @@ function register_block_core_file() { 'render_callback' => 'render_block_core_file', ) ); - - if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { - $module_url = gutenberg_url( '/build/interactivity/file.min.js' ); - } - - wp_register_script_module( - '@wordpress/block-library/file', - isset( $module_url ) ? $module_url : includes_url( 'blocks/file/view.min.js' ), - array( '@wordpress/interactivity' ), - defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) - ); } add_action( 'init', 'register_block_core_file' ); diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 52fca224cfae91..38f4513beaf481 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -47,6 +47,18 @@ function render_block_core_image( $attributes, $content, $block ) { isset( $lightbox_settings['enabled'] ) && true === $lightbox_settings['enabled'] ) { + $suffix = wp_scripts_get_suffix(); + if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { + $module_url = gutenberg_url( "/build/interactivity/image{$suffix}.js" ); + } + + wp_register_script_module( + '@wordpress/block-library/image', + isset( $module_url ) ? $module_url : includes_url( "blocks/image/view{$suffix}.js" ), + array( '@wordpress/interactivity' ), + defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) + ); + wp_enqueue_script_module( '@wordpress/block-library/image' ); /* @@ -322,16 +334,5 @@ function register_block_core_image() { 'render_callback' => 'render_block_core_image', ) ); - - if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { - $module_url = gutenberg_url( '/build/interactivity/image.min.js' ); - } - - wp_register_script_module( - '@wordpress/block-library/image', - isset( $module_url ) ? $module_url : includes_url( 'blocks/image/view.min.js' ), - array( '@wordpress/interactivity' ), - defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) - ); } add_action( 'init', 'register_block_core_image' ); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 4fa954b8deb4bc..f3afb19676775b 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -588,6 +588,17 @@ private static function get_nav_element_directives( $is_interactive, $attributes */ private static function handle_view_script_module_loading( $attributes, $block, $inner_blocks ) { if ( static::is_interactive( $attributes, $inner_blocks ) ) { + $suffix = wp_scripts_get_suffix(); + if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { + $module_url = gutenberg_url( "/build/interactivity/navigation{$suffix}.js" ); + } + + wp_register_script_module( + '@wordpress/block-library/navigation', + isset( $module_url ) ? $module_url : includes_url( "blocks/navigation/view{$suffix}.js" ), + array( '@wordpress/interactivity' ), + defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) + ); wp_enqueue_script_module( '@wordpress/block-library/navigation' ); } } @@ -1097,17 +1108,6 @@ function register_block_core_navigation() { 'render_callback' => 'render_block_core_navigation', ) ); - - if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { - $module_url = gutenberg_url( '/build/interactivity/navigation.min.js' ); - } - - wp_register_script_module( - '@wordpress/block-library/navigation', - isset( $module_url ) ? $module_url : includes_url( 'blocks/navigation/view.min.js' ), - array( '@wordpress/interactivity' ), - defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) - ); } add_action( 'init', 'register_block_core_navigation' ); diff --git a/packages/block-library/src/query/index.php b/packages/block-library/src/query/index.php index a33a1b59f989c9..4826a2b0569546 100644 --- a/packages/block-library/src/query/index.php +++ b/packages/block-library/src/query/index.php @@ -24,6 +24,26 @@ function render_block_core_query( $attributes, $content, $block ) { // Enqueue the script module and add the necessary directives if the block is // interactive. if ( $is_interactive ) { + $suffix = wp_scripts_get_suffix(); + if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { + $module_url = gutenberg_url( "/build/interactivity/query{$suffix}.js" ); + } + + wp_register_script_module( + '@wordpress/block-library/query', + isset( $module_url ) ? $module_url : includes_url( "blocks/query/view{$suffix}.js" ), + array( + array( + 'id' => '@wordpress/interactivity', + 'import' => 'static', + ), + array( + 'id' => '@wordpress/interactivity-router', + 'import' => 'dynamic', + ), + ), + defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) + ); wp_enqueue_script_module( '@wordpress/block-library/query' ); $p = new WP_HTML_Tag_Processor( $content ); @@ -65,26 +85,6 @@ function register_block_core_query() { 'render_callback' => 'render_block_core_query', ) ); - - if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { - $module_url = gutenberg_url( '/build/interactivity/query.min.js' ); - } - - wp_register_script_module( - '@wordpress/block-library/query', - isset( $module_url ) ? $module_url : includes_url( 'blocks/query/view.min.js' ), - array( - array( - 'id' => '@wordpress/interactivity', - 'import' => 'static', - ), - array( - 'id' => '@wordpress/interactivity-router', - 'import' => 'dynamic', - ), - ), - defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) - ); } add_action( 'init', 'register_block_core_query' ); diff --git a/packages/block-library/src/search/index.php b/packages/block-library/src/search/index.php index 102fd89f51810d..ffdd631b016b87 100644 --- a/packages/block-library/src/search/index.php +++ b/packages/block-library/src/search/index.php @@ -80,6 +80,17 @@ function render_block_core_search( $attributes ) { // If it's interactive, enqueue the script module and add the directives. $is_expandable_searchfield = 'button-only' === $button_position; if ( $is_expandable_searchfield ) { + $suffix = wp_scripts_get_suffix(); + if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { + $module_url = gutenberg_url( "/build/interactivity/search{$suffix}.js" ); + } + + wp_register_script_module( + '@wordpress/block-library/search', + isset( $module_url ) ? $module_url : includes_url( "blocks/search/view{$suffix}.js" ), + array( '@wordpress/interactivity' ), + defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) + ); wp_enqueue_script_module( '@wordpress/block-library/search' ); $input->set_attribute( 'data-wp-bind--aria-hidden', '!context.isSearchInputVisible' ); @@ -196,17 +207,6 @@ function register_block_core_search() { 'render_callback' => 'render_block_core_search', ) ); - - if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) { - $module_url = gutenberg_url( '/build/interactivity/search.min.js' ); - } - - wp_register_script_module( - '@wordpress/block-library/search', - isset( $module_url ) ? $module_url : includes_url( 'blocks/search/view.min.js' ), - array( '@wordpress/interactivity' ), - defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ) - ); } add_action( 'init', 'register_block_core_search' ); From 5b4286a17105d4f7511da6f29361ffbf6700236e Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Wed, 7 Feb 2024 17:31:33 +0900 Subject: [PATCH 05/37] Site Editor: Break long URLs in page sidebar (#58763) Co-authored-by: t-hamano Co-authored-by: Mamaduka Co-authored-by: jasmussen Co-authored-by: annezazu --- .../src/components/sidebar-navigation-screen/style.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss index b856837b7c6b6a..44e266cdf6011a 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss @@ -43,6 +43,8 @@ .edit-site-sidebar-navigation-screen__page-link { color: $gray-600; + display: inline-block; + word-break: break-word; &:hover, &:focus { @@ -52,7 +54,6 @@ .components-external-link__icon { margin-left: $grid-unit-05; } - display: inline-block; } .edit-site-sidebar-navigation-screen__title-icon { From 30b434956321d95f2d4acef83605b85f7546d61e Mon Sep 17 00:00:00 2001 From: James Koster Date: Wed, 7 Feb 2024 08:41:27 +0000 Subject: [PATCH 06/37] DataViews: update search input placeholder (#58742) Co-authored-by: jameskoster Co-authored-by: t-hamano Co-authored-by: oandregal Co-authored-by: Mamaduka --- packages/dataviews/src/search.js | 2 +- test/e2e/specs/site-editor/new-templates-list.spec.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dataviews/src/search.js b/packages/dataviews/src/search.js index 03bcf0511892b1..13a828c330575a 100644 --- a/packages/dataviews/src/search.js +++ b/packages/dataviews/src/search.js @@ -24,7 +24,7 @@ const Search = memo( function Search( { label, view, onChangeView } ) { search: debouncedSearch, } ); }, [ debouncedSearch ] ); - const searchLabel = label || __( 'Filter list' ); + const searchLabel = label || __( 'Search' ); return ( { } ); await admin.visitSiteEditor( { path: '/wp_template/all' } ); // Global search. - await page.getByRole( 'searchbox', { name: 'Filter list' } ).click(); - await page.keyboard.type( 'tag' ); + await page.getByRole( 'searchbox', { name: 'Search' } ).fill( 'tag' ); const titles = page .getByRole( 'region', { name: 'Template' } ) .getByRole( 'link', { includeHidden: true } ); @@ -72,8 +71,9 @@ test.describe( 'Templates', () => { // Filter by author and text. await page.getByRole( 'button', { name: 'Reset filters' } ).click(); - await page.getByRole( 'searchbox', { name: 'Filter list' } ).click(); - await page.keyboard.type( 'archives' ); + await page + .getByRole( 'searchbox', { name: 'Search' } ) + .fill( 'archives' ); await expect( titles ).toHaveCount( 3 ); await page .getByRole( 'button', { name: 'Filters', exact: true } ) From 68b9cc89f4b8cea128633e15c90bdb394e252e6e Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:12:30 +0900 Subject: [PATCH 07/37] Try: Make gallery randomization work when nested (#58733) Co-authored-by: t-hamano Co-authored-by: aaronrobertshaw Co-authored-by: youknowriad Co-authored-by: ramonjd Co-authored-by: richtabor --- packages/block-library/src/gallery/index.php | 72 ++++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/packages/block-library/src/gallery/index.php b/packages/block-library/src/gallery/index.php index 342264de6fce3a..292ddeaf32ee2b 100644 --- a/packages/block-library/src/gallery/index.php +++ b/packages/block-library/src/gallery/index.php @@ -33,32 +33,18 @@ function block_core_gallery_data_id_backcompatibility( $parsed_block ) { add_filter( 'render_block_data', 'block_core_gallery_data_id_backcompatibility' ); /** - * Filter to randomize the order of image blocks. - * - * @param array $parsed_block The block being rendered. - * @return array The block object with randomized order of image blocks. - */ -function block_core_gallery_random_order( $parsed_block ) { - if ( 'core/gallery' === $parsed_block['blockName'] && ! empty( $parsed_block['attrs']['randomOrder'] ) ) { - shuffle( $parsed_block['innerBlocks'] ); - } - return $parsed_block; -} - -add_filter( 'render_block_data', 'block_core_gallery_random_order' ); - -/** - * Adds a style tag for the --wp--style--unstable-gallery-gap var. - * - * The Gallery block needs to recalculate Image block width based on - * the current gap setting in order to maintain the number of flex columns - * so a css var is added to allow this. + * Renders the `core/gallery` block on the server. * * @param array $attributes Attributes of the block being rendered. * @param string $content Content of the block being rendered. * @return string The content of the block being rendered. */ function block_core_gallery_render( $attributes, $content ) { + // Adds a style tag for the --wp--style--unstable-gallery-gap var. + // The Gallery block needs to recalculate Image block width based on + // the current gap setting in order to maintain the number of flex columns + // so a css var is added to allow this. + $gap = $attributes['style']['spacing']['blockGap'] ?? null; // Skip if gap value contains unsupported characters. // Regex for CSS value borrowed from `safecss_filter_attr`, and used here @@ -130,7 +116,51 @@ function block_core_gallery_render( $attributes, $content ) { 'context' => 'block-supports', ) ); - return (string) $processed_content; + + // The WP_HTML_Tag_Processor class calls get_updated_html() internally + // when the instance is treated as a string, but here we explicitly + // convert it to a string. + $updated_content = $processed_content->get_updated_html(); + + /* + * Randomize the order of image blocks. Ideally we should shuffle + * the `$parsed_block['innerBlocks']` via the `render_block_data` hook. + * However, this hook doesn't apply inner block updates when blocks are + * nested. + * @todo: In the future, if this hook supports updating innerBlocks in + * nested blocks, it should be refactored. + * + * @see: https://github.com/WordPress/gutenberg/pull/58733 + */ + if ( empty( $attributes['randomOrder'] ) ) { + return $updated_content; + } + + // This pattern matches figure elements with the `wp-block-image` class to + // avoid the gallery's wrapping `figure` element and extract images only. + $pattern = '/]*\bwp-block-image\b[^>]*>.*?<\/figure>/'; + + // Find all Image blocks. + preg_match_all( $pattern, $updated_content, $matches ); + if ( ! $matches ) { + return $updated_content; + } + $image_blocks = $matches[0]; + + // Randomize the order of Image blocks. + shuffle( $image_blocks ); + $i = 0; + $content = preg_replace_callback( + $pattern, + static function () use ( $image_blocks, &$i ) { + $new_image_block = $image_blocks[ $i ]; + ++$i; + return $new_image_block; + }, + $updated_content + ); + + return $content; } /** * Registers the `core/gallery` block on server. From 8f8c4d7b44427c49d0e231b3a895da2a3c448ec9 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 7 Feb 2024 10:32:19 +0100 Subject: [PATCH 08/37] Interactivity API: Fix state intialization for asynchronous private stores (#58754) * Use the universal unlock when populating initial state * Update changelog Co-authored-by: DAreRodz Co-authored-by: luisherranz --- packages/interactivity/CHANGELOG.md | 4 ++++ packages/interactivity/src/store.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 2fb2a7e1683c50..e3f4d98bad3f21 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -7,6 +7,10 @@ - Break up init with yielding to main to prevent long task from hydration. ([#58227](https://github.com/WordPress/gutenberg/pull/58227)) - Support setting the namespace using a string in `data-wp-interactive`, like `data-wp-interactive="myPlugin"`. ([#58743](https://github.com/WordPress/gutenberg/pull/58743)) +### Bug Fixes + +- Avoid initializing private stores as public when they have initial state. ([#58754](https://github.com/WordPress/gutenberg/pull/58754)) + ## 4.0.1 (2024-01-31) ### Bug Fixes diff --git a/packages/interactivity/src/store.ts b/packages/interactivity/src/store.ts index 5177c72cfda462..78b2fa259f5605 100644 --- a/packages/interactivity/src/store.ts +++ b/packages/interactivity/src/store.ts @@ -302,5 +302,5 @@ export function store( // Parse and populate the initial state. Object.entries( parseInitialState() ).forEach( ( [ namespace, state ] ) => { - store( namespace, { state } ); + store( namespace, { state }, { lock: universalUnlock } ); } ); From 180b57ad4974c7ca11740a7eaac4e569dabbe630 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 7 Feb 2024 13:52:08 +0400 Subject: [PATCH 09/37] Editor: Reuse data query in the post author components (#58760) Co-authored-by: Mamaduka Co-authored-by: youknowriad --- .../src/components/post-author/combobox.js | 60 ++---------------- .../src/components/post-author/constants.js | 8 ++- .../editor/src/components/post-author/hook.js | 63 +++++++++++++++++++ .../src/components/post-author/select.js | 47 +------------- 4 files changed, 77 insertions(+), 101 deletions(-) create mode 100644 packages/editor/src/components/post-author/hook.js diff --git a/packages/editor/src/components/post-author/combobox.js b/packages/editor/src/components/post-author/combobox.js index aee01ee5178728..0ba74b072d3956 100644 --- a/packages/editor/src/components/post-author/combobox.js +++ b/packages/editor/src/components/post-author/combobox.js @@ -2,70 +2,22 @@ * WordPress dependencies */ import { debounce } from '@wordpress/compose'; -import { useState, useMemo } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { useState } from '@wordpress/element'; +import { useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { ComboboxControl } from '@wordpress/components'; -import { decodeEntities } from '@wordpress/html-entities'; -import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; -import { AUTHORS_QUERY } from './constants'; +import { useAuthorsQuery } from './hook'; -function PostAuthorCombobox() { +export default function PostAuthorCombobox() { const [ fieldValue, setFieldValue ] = useState(); - const { authorId, authors, postAuthor } = useSelect( - ( select ) => { - const { getUser, getUsers } = select( coreStore ); - const { getEditedPostAttribute } = select( editorStore ); - const author = getUser( getEditedPostAttribute( 'author' ), { - context: 'view', - } ); - const query = { ...AUTHORS_QUERY }; - - if ( fieldValue ) { - query.search = fieldValue; - } - - return { - authorId: getEditedPostAttribute( 'author' ), - postAuthor: author, - authors: getUsers( query ), - }; - }, - [ fieldValue ] - ); const { editPost } = useDispatch( editorStore ); - - const authorOptions = useMemo( () => { - const fetchedAuthors = ( authors ?? [] ).map( ( author ) => { - return { - value: author.id, - label: decodeEntities( author.name ), - }; - } ); - - // Ensure the current author is included in the dropdown list. - const foundAuthor = fetchedAuthors.findIndex( - ( { value } ) => postAuthor?.id === value - ); - - if ( foundAuthor < 0 && postAuthor ) { - return [ - { - value: postAuthor.id, - label: decodeEntities( postAuthor.name ), - }, - ...fetchedAuthors, - ]; - } - - return fetchedAuthors; - }, [ authors, postAuthor ] ); + const { authorId, authorOptions } = useAuthorsQuery( fieldValue ); /** * Handle author selection. @@ -101,5 +53,3 @@ function PostAuthorCombobox() { /> ); } - -export default PostAuthorCombobox; diff --git a/packages/editor/src/components/post-author/constants.js b/packages/editor/src/components/post-author/constants.js index d29995e27f4e5a..46bc2d46d1b086 100644 --- a/packages/editor/src/components/post-author/constants.js +++ b/packages/editor/src/components/post-author/constants.js @@ -1,6 +1,10 @@ +export const BASE_QUERY = { + _fields: 'id,name', + context: 'view', // Allows non-admins to perform requests. +}; + export const AUTHORS_QUERY = { who: 'authors', per_page: 50, - _fields: 'id,name', - context: 'view', // Allows non-admins to perform requests. + ...BASE_QUERY, }; diff --git a/packages/editor/src/components/post-author/hook.js b/packages/editor/src/components/post-author/hook.js new file mode 100644 index 00000000000000..9189736f21502a --- /dev/null +++ b/packages/editor/src/components/post-author/hook.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { decodeEntities } from '@wordpress/html-entities'; +import { store as coreStore } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import { store as editorStore } from '../../store'; +import { AUTHORS_QUERY, BASE_QUERY } from './constants'; + +export function useAuthorsQuery( search ) { + const { authorId, authors, postAuthor } = useSelect( + ( select ) => { + const { getUser, getUsers } = select( coreStore ); + const { getEditedPostAttribute } = select( editorStore ); + const _authorId = getEditedPostAttribute( 'author' ); + const query = { ...AUTHORS_QUERY }; + + if ( search ) { + query.search = search; + } + + return { + authorId: _authorId, + authors: getUsers( query ), + postAuthor: getUser( _authorId, BASE_QUERY ), + }; + }, + [ search ] + ); + + const authorOptions = useMemo( () => { + const fetchedAuthors = ( authors ?? [] ).map( ( author ) => { + return { + value: author.id, + label: decodeEntities( author.name ), + }; + } ); + + // Ensure the current author is included in the dropdown list. + const foundAuthor = fetchedAuthors.findIndex( + ( { value } ) => postAuthor?.id === value + ); + + if ( foundAuthor < 0 && postAuthor ) { + return [ + { + value: postAuthor.id, + label: decodeEntities( postAuthor.name ), + }, + ...fetchedAuthors, + ]; + } + + return fetchedAuthors; + }, [ authors, postAuthor ] ); + + return { authorId, authorOptions }; +} diff --git a/packages/editor/src/components/post-author/select.js b/packages/editor/src/components/post-author/select.js index 24958862b50f81..03bb9be23060f1 100644 --- a/packages/editor/src/components/post-author/select.js +++ b/packages/editor/src/components/post-author/select.js @@ -2,59 +2,18 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useMemo } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { decodeEntities } from '@wordpress/html-entities'; +import { useDispatch } from '@wordpress/data'; import { SelectControl } from '@wordpress/components'; -import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; -import { AUTHORS_QUERY } from './constants'; +import { useAuthorsQuery } from './hook'; export default function PostAuthorSelect() { const { editPost } = useDispatch( editorStore ); - const { authorId, postAuthor, authors } = useSelect( ( select ) => { - const { getUser, getUsers } = select( coreStore ); - const { getEditedPostAttribute } = select( editorStore ); - const _authorId = getEditedPostAttribute( 'author' ); - - return { - authorId: _authorId, - authors: getUsers( AUTHORS_QUERY ), - postAuthor: getUser( _authorId, { - context: 'view', - } ), - }; - }, [] ); - - const authorOptions = useMemo( () => { - const fetchedAuthors = ( authors ?? [] ).map( ( author ) => { - return { - value: author.id, - label: decodeEntities( author.name ), - }; - } ); - - // Ensure the current author is included in the dropdown list. - const foundAuthor = fetchedAuthors.findIndex( - ( { value } ) => postAuthor?.id === value - ); - - if ( foundAuthor < 0 && postAuthor ) { - return [ - { - value: postAuthor.id, - label: decodeEntities( postAuthor.name ), - }, - ...fetchedAuthors, - ]; - } - - return fetchedAuthors; - }, [ authors, postAuthor ] ); + const { authorId, authorOptions } = useAuthorsQuery(); const setAuthorId = ( value ) => { const author = Number( value ); From 6d28c46cc2febed099dc254e4ff36061af54fe83 Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+c4rl0sbr4v0@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:56:30 +0100 Subject: [PATCH 10/37] Interactivity API: Remove non default suffix data wp context processing. (#58664) * Add test that should fail without the fix * Prevent processing data-wp-context-whatever * Revert remove whitespace * Update changelog * Add default test * Refactor function as requested Co-authored-by: c4rl0sbr4v0 Co-authored-by: DAreRodz --- .../directive-context/render.php | 9 ++++++++ packages/interactivity/CHANGELOG.md | 4 ++++ packages/interactivity/src/directives.js | 23 +++++++++++-------- .../interactivity/directive-context.spec.ts | 10 ++++++++ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php index c0b01bfea95fcb..428d47ec397957 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php @@ -134,3 +134,12 @@
+ +
+ + +
diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index e3f4d98bad3f21..1a566d30fa1c6e 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -11,6 +11,10 @@ - Avoid initializing private stores as public when they have initial state. ([#58754](https://github.com/WordPress/gutenberg/pull/58754)) +### Bug fixes + +- Interactivity API: Remove non default suffix data wp context processing. ([#58664](https://github.com/WordPress/gutenberg/pull/58664)) + ## 4.0.1 (2024-01-31) ### Bug Fixes diff --git a/packages/interactivity/src/directives.js b/packages/interactivity/src/directives.js index f0df1dae4b3c93..bf722dd3d5118a 100644 --- a/packages/interactivity/src/directives.js +++ b/packages/interactivity/src/directives.js @@ -102,21 +102,26 @@ export default () => { const { Provider } = inheritedContext; const inheritedValue = useContext( inheritedContext ); const currentValue = useRef( deepSignal( {} ) ); - const passedValues = context.map( ( { value } ) => value ); + const defaultEntry = context.find( + ( { suffix } ) => suffix === 'default' + ); currentValue.current = useMemo( () => { - const newValue = context - .map( ( c ) => deepSignal( { [ c.namespace ]: c.value } ) ) - .reduceRight( mergeDeepSignals ); - + if ( ! defaultEntry ) return null; + const { namespace, value } = defaultEntry; + const newValue = deepSignal( { [ namespace ]: value } ); mergeDeepSignals( newValue, inheritedValue ); mergeDeepSignals( currentValue.current, newValue, true ); return currentValue.current; - }, [ inheritedValue, ...passedValues ] ); + }, [ inheritedValue, defaultEntry ] ); - return ( - { children } - ); + if ( currentValue.current ) { + return ( + + { children } + + ); + } }, { priority: 5 } ); diff --git a/test/e2e/specs/interactivity/directive-context.spec.ts b/test/e2e/specs/interactivity/directive-context.spec.ts index f94784865cb757..95300dc53bf864 100644 --- a/test/e2e/specs/interactivity/directive-context.spec.ts +++ b/test/e2e/specs/interactivity/directive-context.spec.ts @@ -189,4 +189,14 @@ test.describe( 'data-wp-context', () => { await page.getByTestId( 'async navigate' ).click(); await expect( element ).toHaveText( 'changed from async action' ); } ); + test( 'should bail out if the context is not a default directive', async ( { + page, + } ) => { + // This test is to ensure that the context directive is only applied to the default directive + // and not to any other directive. + const defaultElement = page.getByTestId( 'default suffix context' ); + await expect( defaultElement ).toHaveText( 'default' ); + const element = page.getByTestId( 'non-default suffix context' ); + await expect( element ).toHaveText( '' ); + } ); } ); From 345a938ef9e1b335a123901987e58a713f589a47 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Wed, 7 Feb 2024 16:29:58 +0530 Subject: [PATCH 11/37] Update workflows to use gradle/actions/setup-gradle (#58628) (#58713) * Update workflows to use gradle/actions/setup-gradle (#58628) * Update workflows to use gradle/actions/setup-gradle action Unlinked contributors: shreyash3087. Co-authored-by: geriux Co-authored-by: fluiddot Co-authored-by: t-hamano Co-authored-by: desrosj --- .github/workflows/rnmobile-android-runner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 7f7e641e2d2224..e40938eef8e586 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -47,7 +47,7 @@ jobs: run: npm run native test:e2e:setup - name: Gradle cache - uses: gradle/gradle-build-action@3b1b3b9a2104c2b47fbae53f3938079c00c9bb87 # v3.0.0 + uses: gradle/actions/setup-gradle@ec92e829475ac0c2315ea8f9eced72db85bb337a # v3.0.0 - name: AVD cache uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 From 8227f64724d3d22c64ede3002764b911fce0a950 Mon Sep 17 00:00:00 2001 From: James Koster Date: Wed, 7 Feb 2024 11:19:29 +0000 Subject: [PATCH 12/37] Add outline to template preview (#58738) Co-authored-by: jameskoster Co-authored-by: oandregal --- .../page-templates-template-parts/style.scss | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/edit-site/src/components/page-templates-template-parts/style.scss b/packages/edit-site/src/components/page-templates-template-parts/style.scss index 72e12d9808dddf..c4c2e3a6f2dbbe 100644 --- a/packages/edit-site/src/components/page-templates-template-parts/style.scss +++ b/packages/edit-site/src/components/page-templates-template-parts/style.scss @@ -37,6 +37,22 @@ border-radius: 3px 3px 0 0; } } + + &.is-viewtype-table { + border-radius: $radius-block-ui; + position: relative; + + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); + border-radius: $radius-block-ui; + } + } } .page-templates-description { From 87c5697df786d168f585968c4b71c794f186b72b Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 7 Feb 2024 20:20:47 +0900 Subject: [PATCH 13/37] InputBase: Add `isBorderless` prop (#58750) * InputBase: Add `isBorderless` prop * Omit from public InputControl props * Update changelog * Update snapshots Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: ciampo --- packages/components/CHANGELOG.md | 1 + .../test/__snapshots__/index.test.js.snap | 16 ++++++++-------- .../components/src/input-control/backdrop.tsx | 7 ++++++- .../src/input-control/input-base.tsx | 19 ++++++++++++++----- .../styles/input-control-styles.tsx | 9 ++++++--- .../components/src/input-control/types.ts | 11 ++++++++++- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 49adb06a0a6db3..fe71930db85dd3 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -40,6 +40,7 @@ - `Composite`: Removing Reakit `Composite` implementation ([#58620](https://github.com/WordPress/gutenberg/pull/58620)). - Removing Reakit as a dependency of the components package ([#58631](https://github.com/WordPress/gutenberg/pull/58631)). - `CustomSelect`: add unit tests ([#58583](https://github.com/WordPress/gutenberg/pull/58583)). +- `InputBase`: Add `isBorderless` prop ([#58750](https://github.com/WordPress/gutenberg/pull/58750)). ## 25.16.0 (2024-01-24) diff --git a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap index 9827e818b332fb..85aa4b82bf31ea 100644 --- a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap +++ b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap @@ -188,9 +188,9 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = ` class="components-base-control__field emotion-2 emotion-3" >