From 01bbf24a9b5e57db8b6459783eaac1ec642d9c34 Mon Sep 17 00:00:00 2001 From: Sarah Norris <1645628+mikachan@users.noreply.github.com> Date: Mon, 9 Oct 2023 17:09:04 +0100 Subject: [PATCH] Cherry-picked commits for WordPress 6.4 Beta 3 (#55039) * Add clearer labels and context to BlockPatternsSyncFilter (#54838) * Add help text & clearer labeling * Theme & Plugins * Font Library: use snake_case instead of camelCase on fontFamilies endpoint param (#54977) * use snake_case instead of camelCase on endpoint param * updating test * Fix output of Navigation block classnames in the editor. (#54992) * Block Editor: Avoid double-wrapping selectors when transforming the styles (#54981) * Block Editor: Avoid double-wrapping selectors when transforming the styles * Include space in the check * Don't display the navigation section in template parts details when a menu is missing (#54993) * Scripts: Properly use CommonJS for default Playwright config (#54988) * Fix path to `globalSetup` in default Playwright config Oversight from #54856 * `module.exports` * Fix default export usage * Add template replace flow to template inspector (#54609) * Add a modal to allow template switching * fetch template info * Allow switching to different patterns * Allow switching to different patterns * Add columns * move availble templates to the actions * filter for the correct templates * create the right data structure in the use select * move to a hook * inject theme attribute into pattern again * put the overlay over the top of the dropdown * fix the pattern to templates hook * set the template on click * Also set the blocks * remove calls to set template with the current template, since setting blocks correctly updates the content in the editor * serialize blocks so that we have correctly processed template parts * remove duplicated code * Remove unnecessary mapping * refactor * memoize the patterns * combine the useSelect * Update packages/edit-site/src/components/sidebar-edit-mode/page-panels/hooks.js Co-authored-by: Andrei Draganescu * Fix ESLint error * Only show the button is there is more than 1 pattern * Copy update * Move the hook to a subdir * check that there are patterns * move the check * remove useCallback * change condition to show the button * change condition * move to use editEntityRecord * combine filters * add comments * Update packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js Co-authored-by: Andrei Draganescu --------- Co-authored-by: Andrei Draganescu Co-authored-by: Andrei Draganescu Co-authored-by: George Mamadashvili * List View: Fix performance issue when selecting all blocks (#54900) * List View: Fix performance issue when selecting all blocks within the editor canvas in long posts * Add a comment, rename const * Move block focus to be performed only once at the root of the list view, instead of within each block * Fix left and right aligmnent in children of Post Template (#54997) * Fix left and right aligmnent in children of Post Template * Add align center styles * Fix image placeholder disappearing * Site Editor: Avoid stale navigation block values when parsing entity record (#54996) * Removed unwanted space from the string (#54654) * Update styles.js Removed unwanted space with translation * Update deleted-navigation-warning.js Unwanted space at the end of the string shows translation warning. * Update inspector-controls.js Unwanted space at the end of the string shows translation warning * Fix Deleted Navigation Menu warning string (#55033) * [Inserter]: Fix reset of registered media categories (#55012) * [Inserter]: Fix reset of registered media categories * convert `useInserterMediaCategories` to selector and make private * Try fixing the flaky 'Toolbar roving tabindex' e2e test (#54785) * Try fixing the flaky 'Toolbar roving tabindex' e2e test * Add a link in the comment * Fallback to Twitter provider when embedding X URLs (#54876) * Fallback to Twitter provider when embedding X URLs * Avoid processing empty urls when trying a different provider * Update `react-native-editor` changelog # Conflicts: # packages/react-native-editor/CHANGELOG.md * Based on the efforts in https://github.com/WordPress/gutenberg/pull/51761, remove caps case from Template Part and prefer sentence case. As all instances of this string are stand alone, it's okay to have Template capitalized as it's the start of a sentence. (#54709) * Update pattern import menu item (#54782) * Update pattern import menuitem * Revert label * Image Block: Fix browser console error when clicking "Expand on Click" (#54938) * Patterns: Remove category description in inserter panel? (#54894) * Media & Text: Fix React warning (#55038) * Block Style: Display default style labels correctly in the block sidebar (#55008) * Site Editor: Do not display 'trashed' navigation menus in Sidebar (#55072) * Site Editor: Do not display 'trashed' navigation menus in Sidebar * Extract selector into a hook Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> --------- Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * Image: Fix Lightbox display bug in Classic Themes. (#54837) * If current theme is not a block theme add a default value for $background_color and $close_button_color. * Set lightbox buttons' background & border to none on hover & focus * Change logic to support lightbox in classic themes * Update logic to avoid unnecessary calls * Add style fixes * Remove unnecessary code * Fix close button color --------- Co-authored-by: Mario Santos Co-authored-by: Ricardo Artemio Morales * Latest Posts: add screen reader title text to Read more links and use alternative to excerpt_more filter (#55029) * In the editor: adds a screen reader text span with the post title in the i18n interpolator In the frontend: removes excerpt_more filter so we don't override themes and also replaces the default ellipsis with an accessible read more link * Removing "of" preposition in favour of a semi-colon. "Read more" is already translated so using a specifier to add it to the string * Fix Image block lightbox missing alt attribute and improve accessibility (#55010) * Move lightbox open button after the image. * Fix getting the lightbox image alt attribute. * Improve docblocks. * Do not render empty role attribute. * Remove unnecessary aria-hidden attribute. * Set aria-modal attribute dynamically. * More meaningful and simpler modal dialog aria-label. * Increase Close button target size. * Add enlarged image base64 encoded placeholder. * Better check for alt attribute as a string. * Update changelog. * Move changelog entry to the block library changelog. * Set lightbox dialog aria-label dynamically. * Hide background scrim container from assistive technology. * Remove obsolete code --------- Co-authored-by: Ricardo Artemio Morales # Conflicts: # packages/block-library/CHANGELOG.md * Patterns: Add category selector to pattern creation modal (#55024) --------- Co-authored-by: Kai Hao * Iframe: Fix positioning when dragging over an iframe (#55150) * Site Editor: Fix template part area listing when a template has no edits (#55115) * Alternative: Fix template part area listing when a template has no edits * Fix typos --------- Co-authored-by: Rich Tabor Co-authored-by: Matias Benedetto Co-authored-by: tellthemachines Co-authored-by: George Mamadashvili Co-authored-by: Pascal Birchler Co-authored-by: Ben Dwyer Co-authored-by: Andrei Draganescu Co-authored-by: Andrei Draganescu Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: mujuonly Co-authored-by: Dave Smith Co-authored-by: Nik Tsekouras Co-authored-by: Carlos Garcia Co-authored-by: Ramon Co-authored-by: James Koster Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Co-authored-by: Michal Co-authored-by: Mario Santos Co-authored-by: Ricardo Artemio Morales Co-authored-by: Andrea Fercia Co-authored-by: Glen Davies Co-authored-by: Kai Hao --- lib/block-supports/behaviors.php | 49 ++++---- .../class-wp-rest-font-library-controller.php | 12 +- lib/load.php | 1 + packages/base-styles/_z-index.scss | 1 + .../src/components/block-styles/index.js | 5 +- .../src/components/iframe/index.js | 9 +- .../inserter/block-patterns-filter.js | 32 +++-- .../components/inserter/block-patterns-tab.js | 3 - .../components/inserter/media-tab/hooks.js | 54 ++------- .../src/components/inserter/style.scss | 2 +- .../src/components/list-view/block.js | 46 +------- .../src/components/list-view/branch.js | 12 +- .../src/components/list-view/index.js | 12 +- .../src/components/list-view/utils.js | 37 ++++++ packages/block-editor/src/store/actions.js | 18 ++- .../src/store/private-selectors.js | 72 ++++++++++++ packages/block-editor/src/store/reducer.js | 17 +++ .../block-editor/src/store/test/actions.js | 26 ++--- .../test/__snapshots__/wrap.js.snap | 19 ++- .../transform-styles/transforms/test/wrap.js | 9 ++ .../utils/transform-styles/transforms/wrap.js | 5 + packages/block-library/CHANGELOG.md | 7 ++ .../src/cover/edit/inspector-controls.js | 2 +- packages/block-library/src/embed/edit.js | 15 +++ .../block-library/src/embed/edit.native.js | 15 +++ packages/block-library/src/image/image.js | 2 +- packages/block-library/src/image/index.php | 110 ++++++++++-------- packages/block-library/src/image/style.scss | 25 +++- packages/block-library/src/image/view.js | 18 ++- .../block-library/src/latest-posts/edit.js | 12 +- .../block-library/src/latest-posts/index.php | 26 +++-- packages/block-library/src/media-text/edit.js | 2 +- .../edit/deleted-navigation-warning.js | 13 ++- .../src/navigation/edit/index.js | 43 ++++--- .../src/navigation/edit/inner-blocks.js | 1 + .../src/post-featured-image/style.scss | 4 + .../src/post-template/style.scss | 20 ++++ .../src/components/add-new-pattern/index.js | 4 +- .../font-library-modal/resolvers.js | 2 +- .../font-library-modal/utils/index.js | 2 +- .../test/makeFormDataFromFontFamilies.spec.js | 2 +- .../sidebar-edit-mode/template-panel/hooks.js | 97 +++++++++++++++ .../template-panel/replace-template-button.js | 89 ++++++++++++++ .../template-panel/style.scss | 18 +++ .../template-panel/template-actions.js | 39 +++++-- ...template-part-navigation-menu-list-item.js | 13 +-- .../template-part-navigation-menu.js | 14 +-- .../use-navigation-menu-content.js | 16 ++- .../use-navigation-menu-title.js | 32 +++++ packages/edit-site/src/store/selectors.js | 19 ++- packages/edit-site/src/utils/constants.js | 2 +- .../src/components/category-selector.js | 70 +++++------ .../src/components/create-pattern-modal.js | 51 +++++++- packages/patterns/src/components/style.scss | 30 ++++- packages/react-native-editor/CHANGELOG.md | 3 + packages/scripts/config/playwright.config.js | 4 +- .../scripts/config/playwright/global-setup.js | 2 +- .../installFonts.php | 4 +- .../uninstallFonts.php | 6 +- test/e2e/playwright.config.ts | 2 +- .../various/toolbar-roving-tabindex.spec.js | 4 + .../specs/site-editor/writing-flow.spec.js | 2 +- test/performance/playwright.config.ts | 4 +- 63 files changed, 917 insertions(+), 370 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-edit-mode/template-panel/hooks.js create mode 100644 packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js diff --git a/lib/block-supports/behaviors.php b/lib/block-supports/behaviors.php index 6f442d7b0d2d7c..c1b3dceceee94d 100644 --- a/lib/block-supports/behaviors.php +++ b/lib/block-supports/behaviors.php @@ -84,17 +84,19 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { $aria_label = __( 'Enlarge image', 'gutenberg' ); + $processor->next_tag( 'img' ); $alt_attribute = $processor->get_attribute( 'alt' ); - if ( null !== $alt_attribute ) { + // An empty alt attribute `alt=""` is valid for decorative images. + if ( is_string( $alt_attribute ) ) { $alt_attribute = trim( $alt_attribute ); } + // It only makes sense to append the alt text to the button aria-label when the alt text is non-empty. if ( $alt_attribute ) { /* translators: %s: Image alt text. */ $aria_label = sprintf( __( 'Enlarge image: %s', 'gutenberg' ), $alt_attribute ); } - $content = $processor->get_updated_html(); // If we don't set a default, it won't work if Lightbox is set to enabled by default. $lightbox_animation = 'zoom'; @@ -102,17 +104,15 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { $lightbox_animation = $lightbox_settings['animation']; } - // We want to store the src in the context so we can set it dynamically when the lightbox is opened. - $z = new WP_HTML_Tag_Processor( $content ); - $z->next_tag( 'img' ); - + // Note: We want to store the `src` in the context so we + // can set it dynamically when the lightbox is opened. if ( isset( $block['attrs']['id'] ) ) { $img_uploaded_src = wp_get_attachment_url( $block['attrs']['id'] ); $img_metadata = wp_get_attachment_metadata( $block['attrs']['id'] ); $img_width = $img_metadata['width']; $img_height = $img_metadata['height']; } else { - $img_uploaded_src = $z->get_attribute( 'src' ); + $img_uploaded_src = $processor->get_attribute( 'src' ); $img_width = 'none'; $img_height = 'none'; } @@ -123,7 +123,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { $scale_attr = false; } - $w = new WP_HTML_Tag_Processor( $content ); + $w = new WP_HTML_Tag_Processor( $block_content ); $w->next_tag( 'figure' ); $w->add_class( 'wp-lightbox-container' ); $w->set_attribute( 'data-wp-interactive', true ); @@ -163,19 +163,20 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { // Wrap the image in the body content with a button. $img = null; preg_match( '/]+>/', $body_content, $img ); - $button = - '' - . $img[0]; + + $button = + $img[0] + . ''; + $body_content = preg_replace( '/]+>/', $button, $body_content ); // We need both a responsive image and an enlarged image to animate @@ -183,7 +184,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { // image is a copy of the one in the body, which animates immediately // as the lightbox is opened, while the enlarged one is a full-sized // version that will likely still be loading as the animation begins. - $m = new WP_HTML_Tag_Processor( $content ); + $m = new WP_HTML_Tag_Processor( $block_content ); $m->next_tag( 'figure' ); $m->add_class( 'responsive-image' ); $m->next_tag( 'img' ); @@ -199,7 +200,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { $m->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' ); $initial_image_content = $m->get_updated_html(); - $q = new WP_HTML_Tag_Processor( $content ); + $q = new WP_HTML_Tag_Processor( $block_content ); $q->next_tag( 'figure' ); $q->add_class( 'enlarged-image' ); $q->next_tag( 'img' ); @@ -219,7 +220,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { $close_button_icon = ''; $close_button_color = esc_attr( wp_get_global_styles( array( 'color', 'text' ) ) ); - $dialog_label = $alt_attribute ? esc_attr( $alt_attribute ) : esc_attr__( 'Image', 'gutenberg' ); + $dialog_label = esc_attr__( 'Enlarged image', 'gutenberg' ); $close_button_label = esc_attr__( 'Close', 'gutenberg' ); $lightbox_html = << array( $this, 'install_fonts' ), 'permission_callback' => array( $this, 'update_font_library_permissions_check' ), 'args' => array( - 'fontFamilies' => array( + 'font_families' => array( 'required' => true, 'type' => 'string', 'validate_callback' => array( $this, 'validate_install_font_families' ), @@ -147,13 +147,13 @@ private function get_validation_errors( $font_families, $files ) { $error_messages = array(); if ( ! is_array( $font_families ) ) { - $error_messages[] = __( 'fontFamilies should be an array of font families.', 'gutenberg' ); + $error_messages[] = __( 'font_families should be an array of font families.', 'gutenberg' ); return $error_messages; } // Checks if there is at least one font family. if ( count( $font_families ) < 1 ) { - $error_messages[] = __( 'fontFamilies should have at least one font family definition.', 'gutenberg' ); + $error_messages[] = __( 'font_families should have at least one font family definition.', 'gutenberg' ); return $error_messages; } @@ -260,7 +260,7 @@ public function validate_install_font_families( $param, $request ) { */ public function uninstall_schema() { return array( - 'fontFamilies' => array( + 'font_families' => array( 'type' => 'array', 'description' => __( 'The font families to install.', 'gutenberg' ), 'required' => true, @@ -289,7 +289,7 @@ public function uninstall_schema() { * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function uninstall_fonts( $request ) { - $fonts_to_uninstall = $request->get_param( 'fontFamilies' ); + $fonts_to_uninstall = $request->get_param( 'font_families' ); $errors = array(); $successes = array(); @@ -397,7 +397,7 @@ private function needs_write_permission( $font_families ) { */ public function install_fonts( $request ) { // Get new fonts to install. - $fonts_param = $request->get_param( 'fontFamilies' ); + $fonts_param = $request->get_param( 'font_families' ); /* * As this is receiving form data, the font families are encoded as a string. diff --git a/lib/load.php b/lib/load.php index 77232efcfae1a9..72ec9e62a8d74e 100644 --- a/lib/load.php +++ b/lib/load.php @@ -244,3 +244,4 @@ function () { require __DIR__ . '/block-supports/duotone.php'; require __DIR__ . '/block-supports/shadow.php'; require __DIR__ . '/block-supports/background.php'; +require __DIR__ . '/block-supports/behaviors.php'; diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 12443a30a96656..cbe495d3787cd9 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -128,6 +128,7 @@ $z-layers: ( ".block-editor-block-rename-modal": 1000001, ".edit-site-list__rename-modal": 1000001, ".edit-site-swap-template-modal": 1000001, + ".edit-site-template-panel__replace-template-modal": 1000001, // Note: The ConfirmDialog component's z-index is being set to 1000001 in packages/components/src/confirm-dialog/styles.ts // because it uses emotion and not sass. We need it to render on top its parent popover. diff --git a/packages/block-editor/src/components/block-styles/index.js b/packages/block-editor/src/components/block-styles/index.js index b998614e4b0892..f598b35f890f15 100644 --- a/packages/block-editor/src/components/block-styles/index.js +++ b/packages/block-editor/src/components/block-styles/index.js @@ -14,7 +14,6 @@ import { Popover, } from '@wordpress/components'; import deprecated from '@wordpress/deprecated'; -import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -65,9 +64,7 @@ function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) {
{ stylesToRender.map( ( style ) => { - const buttonText = style.isDefault - ? __( 'Default' ) - : style.label || style.name; + const buttonText = style.label || style.name; return ( ' - . $img[0]; + + $button = + $img[0] + . ''; + $body_content = preg_replace( '/]+>/', $button, $body_content ); // We need both a responsive image and an enlarged image to animate @@ -220,7 +226,7 @@ function block_core_image_render_lightbox( $block_content, $block ) { // image is a copy of the one in the body, which animates immediately // as the lightbox is opened, while the enlarged one is a full-sized // version that will likely still be loading as the animation begins. - $m = new WP_HTML_Tag_Processor( $content ); + $m = new WP_HTML_Tag_Processor( $block_content ); $m->next_tag( 'figure' ); $m->add_class( 'responsive-image' ); $m->next_tag( 'img' ); @@ -236,7 +242,7 @@ function block_core_image_render_lightbox( $block_content, $block ) { $m->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' ); $initial_image_content = $m->get_updated_html(); - $q = new WP_HTML_Tag_Processor( $content ); + $q = new WP_HTML_Tag_Processor( $block_content ); $q->next_tag( 'figure' ); $q->add_class( 'enlarged-image' ); $q->next_tag( 'img' ); @@ -252,24 +258,32 @@ function block_core_image_render_lightbox( $block_content, $block ) { $q->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' ); $enlarged_image_content = $q->get_updated_html(); - $background_color = esc_attr( wp_get_global_styles( array( 'color', 'background' ) ) ); + // If the current theme does NOT have a `theme.json`, or the colors are not defined, + // we need to set the background color & close button color to some default values + // because we can't get them from the Global Styles. + $background_color = '#fff'; + $close_button_color = '#000'; + if ( wp_theme_has_theme_json() ) { + $global_styles_color = wp_get_global_styles( array( 'color' ) ); + if ( ! empty( $global_styles_color['background'] ) ) { + $background_color = esc_attr( $global_styles_color['background'] ); + } + if ( ! empty( $global_styles_color['text'] ) ) { + $close_button_color = esc_attr( $global_styles_color['text'] ); + } + } $close_button_icon = ''; - $close_button_color = esc_attr( wp_get_global_styles( array( 'color', 'text' ) ) ); - $dialog_label = $alt_attribute ? esc_attr( $alt_attribute ) : esc_attr__( 'Image' ); $close_button_label = esc_attr__( 'Close' ); $lightbox_html = << -
+
HTML; @@ -290,11 +304,13 @@ function block_core_image_render_lightbox( $block_content, $block ) { } /** - * Ensure that the view script has the `wp-interactivity` dependency. + * Ensures that the view script has the `wp-interactivity` dependency. * * @since 6.4.0 * * @global WP_Scripts $wp_scripts + * + * @return void */ function block_core_image_ensure_interactivity_dependency() { global $wp_scripts; @@ -310,6 +326,8 @@ function block_core_image_ensure_interactivity_dependency() { /** * Registers the `core/image` block on server. + * + * @return void */ function register_block_core_image() { register_block_type_from_metadata( diff --git a/packages/block-library/src/image/style.scss b/packages/block-library/src/image/style.scss index 5c3552fd80c2ee..2ef602982e57b5 100644 --- a/packages/block-library/src/image/style.scss +++ b/packages/block-library/src/image/style.scss @@ -154,6 +154,8 @@ .wp-lightbox-container { position: relative; + display: flex; + flex-direction: column; button { border: none; @@ -169,6 +171,13 @@ outline: 5px auto -webkit-focus-ring-color; outline-offset: 5px; } + + &:hover, + &:focus, + &:not(:hover):not(:active):not(.has-background) { + background: none; + border: none; + } } } @@ -186,11 +195,23 @@ .close-button { position: absolute; - top: calc(env(safe-area-inset-top) + 20px); - right: calc(env(safe-area-inset-right) + 20px); + top: calc(env(safe-area-inset-top) + 16px); // equivalent to $grid-unit-20 + right: calc(env(safe-area-inset-right) + 16px); // equivalent to $grid-unit-20 padding: 0; cursor: pointer; z-index: 5000000; + min-width: 40px; // equivalent to $button-size-next-default-40px + min-height: 40px; // equivalent to $button-size-next-default-40px + display: flex; + align-items: center; + justify-content: center; + + &:hover, + &:focus, + &:not(:hover):not(:active):not(.has-background) { + background: none; + border: none; + } } .lightbox-image-container { diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 13f20c9cd7cb68..3eb47dcc7cab4b 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -227,7 +227,17 @@ store( roleAttribute: ( { context } ) => { return context.core.image.lightboxEnabled ? 'dialog' - : ''; + : null; + }, + ariaModal: ( { context } ) => { + return context.core.image.lightboxEnabled + ? 'true' + : null; + }, + dialogLabel: ( { context } ) => { + return context.core.image.lightboxEnabled + ? context.core.image.dialogLabel + : null; }, lightboxObjectFit: ( { context } ) => { if ( context.core.image.initialized ) { @@ -237,7 +247,7 @@ store( enlargedImgSrc: ( { context } ) => { return context.core.image.initialized ? context.core.image.imageUploadedSrc - : ''; + : 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; }, }, }, @@ -360,9 +370,9 @@ function setStyles( context, event ) { naturalHeight, offsetWidth: originalWidth, offsetHeight: originalHeight, - } = event.target.nextElementSibling; + } = event.target.previousElementSibling; let { x: screenPosX, y: screenPosY } = - event.target.nextElementSibling.getBoundingClientRect(); + event.target.previousElementSibling.getBoundingClientRect(); // Natural ratio of the image clicked to open the lightbox. const naturalRatio = naturalWidth / naturalHeight; diff --git a/packages/block-library/src/latest-posts/edit.js b/packages/block-library/src/latest-posts/edit.js index 7aaf1b3ecf0eda..586ecc59432730 100644 --- a/packages/block-library/src/latest-posts/edit.js +++ b/packages/block-library/src/latest-posts/edit.js @@ -483,12 +483,17 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { .split( ' ', excerptLength ) .join( ' ' ) } { createInterpolateElement( - /* translators: excerpt truncation character, default … */ - __( ' … Read more' ), + sprintf( + /* translators: 1: The static string "Read more", 2: The post title only visible to screen readers. */ + __( '… %1$s: %2$s' ), + __( 'Read more' ), + titleTrimmed || __( '(no title)' ) + ), { a: ( // eslint-disable-next-line jsx-a11y/anchor-has-content ), + span: ( + + ), } ) } diff --git a/packages/block-library/src/latest-posts/index.php b/packages/block-library/src/latest-posts/index.php index 356ba5032689f7..d5f759c0c0e259 100644 --- a/packages/block-library/src/latest-posts/index.php +++ b/packages/block-library/src/latest-posts/index.php @@ -48,14 +48,6 @@ function render_block_core_latest_posts( $attributes ) { $block_core_latest_posts_excerpt_length = $attributes['excerptLength']; add_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 ); - $filter_latest_posts_excerpt_more = static function ( $more ) use ( $attributes ) { - $use_excerpt = 'excerpt' === $attributes['displayPostContentRadio']; - /* translators: %1$s is a URL to a post, excerpt truncation character, default … */ - return $use_excerpt ? sprintf( __( ' … Read more' ), esc_url( get_permalink() ) ) : $more; - }; - - add_filter( 'excerpt_more', $filter_latest_posts_excerpt_more ); - if ( ! empty( $attributes['categories'] ) ) { $args['category__in'] = array_column( $attributes['categories'], 'id' ); } @@ -151,6 +143,24 @@ function render_block_core_latest_posts( $attributes ) { $trimmed_excerpt = get_the_excerpt( $post ); + /* + * Adds a "Read more" link with screen reader text. + * […] is the default excerpt ending from wp_trim_excerpt() in Core. + */ + if ( str_ends_with( $trimmed_excerpt, ' […]' ) ) { + $excerpt_length = (int) apply_filters( 'excerpt_length', $block_core_latest_posts_excerpt_length ); + if ( $excerpt_length <= $block_core_latest_posts_excerpt_length ) { + $trimmed_excerpt = substr( $trimmed_excerpt, 0, -11 ); + $trimmed_excerpt .= sprintf( + /* translators: 1: A URL to a post, 2: The static string "Read more", 3: The post title only visible to screen readers. */ + __( '… %2$s: %3$s' ), + esc_url( $post_link ), + __( 'Read more' ), + esc_html( $title ) + ); + } + } + if ( post_password_required( $post ) ) { $trimmed_excerpt = __( 'This content is password protected.' ); } diff --git a/packages/block-library/src/media-text/edit.js b/packages/block-library/src/media-text/edit.js index 30181c9044c34d..f3baeb8c1756ba 100644 --- a/packages/block-library/src/media-text/edit.js +++ b/packages/block-library/src/media-text/edit.js @@ -244,7 +244,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { setAttributes( { imageFill: ! imageFill, diff --git a/packages/block-library/src/navigation/edit/deleted-navigation-warning.js b/packages/block-library/src/navigation/edit/deleted-navigation-warning.js index c787b90b76682f..6386cee71431e0 100644 --- a/packages/block-library/src/navigation/edit/deleted-navigation-warning.js +++ b/packages/block-library/src/navigation/edit/deleted-navigation-warning.js @@ -4,14 +4,19 @@ import { Warning } from '@wordpress/block-editor'; import { Button } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { createInterpolateElement } from '@wordpress/element'; function DeletedNavigationWarning( { onCreateNew } ) { return ( - { __( 'Navigation menu has been deleted or is unavailable. ' ) } - + { createInterpolateElement( + __( + 'Navigation menu has been deleted or is unavailable. ' + ), + { + button: