From faa73df5cd2f47709e3b6acb4d286b778f17c4f6 Mon Sep 17 00:00:00 2001 From: Sarah Norris <1645628+mikachan@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:51:52 +0100 Subject: [PATCH] Cherry-picked commits for WordPress 6.4 Beta 3 v2 (#55193) * Site Editor Styles Screen: Fix dancing styles previews (#55183) * Pulling across changes from https://github.com/WordPress/wordpress-develop/pull/5441 (#55181) Removed var * Add `aria-label` attribute to navigation block only when it is open (#54816) * Add `aria-label` only when is open * Remove unnecessary `label` property in edit * Escape translation * Move navigation context to `wp_json_encode` * Add `wp_json_encode` flags * Paste: fix MS Word list paste (#55127) * Paste: fix MS Word list paste * Match mso-list:Ignore * Fix inline paste * Fix scrollbars on pattern transforms (#55069) * Fix scrollbars on pattern transforms * Fix single pattern previews * Improve classname semantics * Remove modal title * Reset styles on window resize (#55077) Co-authored-by: Ricardo Artemio Morales --------- Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: Ramon Co-authored-by: Mario Santos <34552881+SantosGuillamot@users.noreply.github.com> Co-authored-by: Ella <4710635+ellatrix@users.noreply.github.com> Co-authored-by: Daniel Richards Co-authored-by: Ricardo Artemio Morales --- .../pattern-transformations-menu.js | 5 +-- .../src/components/block-switcher/style.scss | 6 ++++ packages/block-library/src/image/index.php | 1 + packages/block-library/src/image/view.js | 21 ++++++++++--- .../block-library/src/latest-posts/edit.js | 7 +++-- .../block-library/src/latest-posts/index.php | 5 ++- .../src/navigation/edit/index.js | 1 - .../block-library/src/navigation/index.php | 25 +++++++++++---- packages/block-library/src/navigation/view.js | 7 +++++ packages/block-library/src/query/index.php | 3 +- .../src/api/raw-handling/ms-list-converter.js | 31 +++++++------------ .../src/api/raw-handling/ms-list-ignore.js | 27 ++++++++++++++++ .../src/api/raw-handling/paste-handler.js | 2 ++ .../raw-handling/test/ms-list-converter.js | 18 +++++------ .../sidebar-navigation-screen/style.scss | 13 ++++++++ .../blocks-raw-handling.test.js.snap | 4 ++- test/integration/blocks-raw-handling.test.js | 1 + .../fixtures/documents/ms-word-list-in.html | 28 +++++++++++++++++ .../fixtures/documents/ms-word-list-out.html | 25 +++++++++++++++ 19 files changed, 177 insertions(+), 53 deletions(-) create mode 100644 packages/blocks/src/api/raw-handling/ms-list-ignore.js create mode 100644 test/integration/fixtures/documents/ms-word-list-in.html create mode 100644 test/integration/fixtures/documents/ms-word-list-out.html diff --git a/packages/block-editor/src/components/block-switcher/pattern-transformations-menu.js b/packages/block-editor/src/components/block-switcher/pattern-transformations-menu.js index 83eecd329d8c4c..f9a4b7190a6dd8 100644 --- a/packages/block-editor/src/components/block-switcher/pattern-transformations-menu.js +++ b/packages/block-editor/src/components/block-switcher/pattern-transformations-menu.js @@ -60,10 +60,7 @@ function PreviewPatternsPopover( { patterns, onSelect } ) { className="block-editor-block-switcher__preview__popover" position="bottom right" > -
-
- { __( 'Preview' ) } -
+
set_attribute( 'data-wp-init', 'effects.core.image.setCurrentSrc' ); $w->set_attribute( 'data-wp-on--load', 'actions.core.image.handleLoad' ); $w->set_attribute( 'data-wp-effect', 'effects.core.image.setButtonStyles' ); + $w->set_attribute( 'data-wp-effect--setStylesOnResize', 'effects.core.image.setStylesOnResize' ); $body_content = $w->get_updated_html(); // Wrap the image in the body content with a button. diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 3eb47dcc7cab4b..3f2242ad737f02 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -105,7 +105,10 @@ store( context.core.image.scrollDelta = 0; context.core.image.lightboxEnabled = true; - setStyles( context, event ); + setStyles( + context, + event.target.previousElementSibling + ); context.core.image.scrollTopReset = window.pageYOffset || @@ -338,6 +341,15 @@ store( context.core.image.imageButtonHeight = offsetHeight; } }, + setStylesOnResize: ( { state, context, ref } ) => { + if ( + context.core.image.lightboxEnabled && + ( state.core.image.windowWidth || + state.core.image.windowHeight ) + ) { + setStyles( context, ref ); + } + }, }, }, }, @@ -362,7 +374,7 @@ store( * @param {Object} context - An Interactivity API context * @param {Object} event - A triggering event */ -function setStyles( context, event ) { +function setStyles( context, ref ) { // The reference img element lies adjacent // to the event target button in the DOM. let { @@ -370,9 +382,8 @@ function setStyles( context, event ) { naturalHeight, offsetWidth: originalWidth, offsetHeight: originalHeight, - } = event.target.previousElementSibling; - let { x: screenPosX, y: screenPosY } = - event.target.previousElementSibling.getBoundingClientRect(); + } = ref; + let { x: screenPosX, y: screenPosY } = ref.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 586ecc59432730..0efe538b01f629 100644 --- a/packages/block-library/src/latest-posts/edit.js +++ b/packages/block-library/src/latest-posts/edit.js @@ -484,9 +484,10 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) { .join( ' ' ) } { createInterpolateElement( sprintf( - /* translators: 1: The static string "Read more", 2: The post title only visible to screen readers. */ - __( '… %1$s: %2$s' ), - __( 'Read more' ), + /* translators: 1: Hidden accessibility text: Post title */ + __( + '… Read more: %1$s' + ), titleTrimmed || __( '(no title)' ) ), { diff --git a/packages/block-library/src/latest-posts/index.php b/packages/block-library/src/latest-posts/index.php index d5f759c0c0e259..adc51d0c4fecb9 100644 --- a/packages/block-library/src/latest-posts/index.php +++ b/packages/block-library/src/latest-posts/index.php @@ -152,10 +152,9 @@ function render_block_core_latest_posts( $attributes ) { 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' ), + /* translators: 1: A URL to a post, 2: Hidden accessibility text: Post title */ + __( '… Read more: %2$s' ), esc_url( $post_link ), - __( 'Read more' ), esc_html( $title ) ); } diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index 7c29f18d4940d4..f12d83e2fe2eae 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -884,7 +884,6 @@ function Navigation( { array( + 'navigation' => array( + 'overlayOpenedBy' => array(), + 'type' => 'overlay', + 'roleAttribute' => '', + 'ariaLabel' => __( 'Menu' ), + ), + ), + ), + JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP + ); $nav_element_directives = ' data-wp-interactive - data-wp-context=\'{ "core": { "navigation": { "overlayOpenedBy": {}, "type": "overlay", "roleAttribute": "" } } }\' + data-wp-context=\'' . $nav_element_context . '\' '; $open_button_directives = ' data-wp-on--click="actions.core.navigation.openMenuOnClick" @@ -714,6 +727,7 @@ function render_block_core_navigation( $attributes, $content, $block ) { '; $responsive_dialog_directives = ' data-wp-bind--aria-modal="selectors.core.navigation.ariaModal" + data-wp-bind--aria-label="selectors.core.navigation.ariaLabel" data-wp-bind--role="selectors.core.navigation.roleAttribute" data-wp-effect="effects.core.navigation.focusFirstElement" '; @@ -723,11 +737,11 @@ function render_block_core_navigation( $attributes, $content, $block ) { } $responsive_container_markup = sprintf( - ' -
+ ' +
-
- +
+
%2$s
@@ -741,7 +755,6 @@ function render_block_core_navigation( $attributes, $content, $block ) { esc_attr( implode( ' ', $responsive_container_classes ) ), esc_attr( implode( ' ', $open_button_classes ) ), esc_attr( safecss_filter_attr( $colors['overlay_inline_styles'] ) ), - __( 'Menu' ), $toggle_button_content, $toggle_close_button_content, $open_button_directives, diff --git a/packages/block-library/src/navigation/view.js b/packages/block-library/src/navigation/view.js index 6a8e4979983b8a..c0853b2814e2b3 100644 --- a/packages/block-library/src/navigation/view.js +++ b/packages/block-library/src/navigation/view.js @@ -87,6 +87,13 @@ wpStore( { ? 'true' : null; }, + ariaLabel: ( store ) => { + const { context, selectors } = store; + return context.core.navigation.type === 'overlay' && + selectors.core.navigation.isMenuOpen( store ) + ? context.core.navigation.ariaLabel + : null; + }, isMenuOpen: ( { context } ) => // The menu is opened if either `click`, `hover` or `focus` is true. Object.values( diff --git a/packages/block-library/src/query/index.php b/packages/block-library/src/query/index.php index c35bf2ba00af21..1b05e9c92c95e3 100644 --- a/packages/block-library/src/query/index.php +++ b/packages/block-library/src/query/index.php @@ -34,7 +34,8 @@ function render_block_core_query( $attributes, $content, $block ) { 'loadedText' => __( 'Page Loaded.' ), ), ), - ) + ), + JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP ) ); $content = $p->get_updated_html(); diff --git a/packages/blocks/src/api/raw-handling/ms-list-converter.js b/packages/blocks/src/api/raw-handling/ms-list-converter.js index 8b45a5ab53fdb7..fdbc48398a1cc6 100644 --- a/packages/blocks/src/api/raw-handling/ms-list-converter.js +++ b/packages/blocks/src/api/raw-handling/ms-list-converter.js @@ -3,6 +3,12 @@ */ const { parseInt } = window; +/** + * Internal dependencies + */ +import { deepFilterHTML } from './utils'; +import msListIgnore from './ms-list-ignore'; + function isList( node ) { return node.nodeName === 'OL' || node.nodeName === 'UL'; } @@ -14,23 +20,10 @@ export default function msListConverter( node, doc ) { const style = node.getAttribute( 'style' ); - if ( ! style ) { - return; - } - - // Quick check. - if ( style.indexOf( 'mso-list' ) === -1 ) { - return; - } - - const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec( style ); - - if ( ! matches ) { + if ( ! style || ! style.includes( 'mso-list' ) ) { return; } - let level = parseInt( matches[ 1 ], 10 ) - 1 || 0; - const prevNode = node.previousElementSibling; // Add new list if no previous. @@ -53,13 +46,11 @@ export default function msListConverter( node, doc ) { let receivingNode = listNode; - // Remove the first span with list info. - node.removeChild( node.firstChild ); - // Add content. - while ( node.firstChild ) { - listItem.appendChild( node.firstChild ); - } + listItem.innerHTML = deepFilterHTML( node.innerHTML, [ msListIgnore ] ); + + const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec( style ); + let level = matches ? parseInt( matches[ 1 ], 10 ) - 1 || 0 : 0; // Change pointer depending on indentation level. while ( level-- ) { diff --git a/packages/blocks/src/api/raw-handling/ms-list-ignore.js b/packages/blocks/src/api/raw-handling/ms-list-ignore.js new file mode 100644 index 00000000000000..d1ed421e3b76c5 --- /dev/null +++ b/packages/blocks/src/api/raw-handling/ms-list-ignore.js @@ -0,0 +1,27 @@ +/** + * Looks for comments, and removes them. + * + * @param {Node} node The node to be processed. + * @return {void} + */ +export default function msListIgnore( node ) { + if ( node.nodeType !== node.ELEMENT_NODE ) { + return; + } + + const style = node.getAttribute( 'style' ); + + if ( ! style || ! style.includes( 'mso-list' ) ) { + return; + } + + const rules = style.split( ';' ).reduce( ( acc, rule ) => { + const [ key, value ] = rule.split( ':' ); + acc[ key.trim().toLowerCase() ] = value.trim().toLowerCase(); + return acc; + }, {} ); + + if ( rules[ 'mso-list' ] === 'ignore' ) { + node.remove(); + } +} diff --git a/packages/blocks/src/api/raw-handling/paste-handler.js b/packages/blocks/src/api/raw-handling/paste-handler.js index c4ad40e0b1f509..849ce681959cd9 100644 --- a/packages/blocks/src/api/raw-handling/paste-handler.js +++ b/packages/blocks/src/api/raw-handling/paste-handler.js @@ -17,6 +17,7 @@ import isInlineContent from './is-inline-content'; import phrasingContentReducer from './phrasing-content-reducer'; import headRemover from './head-remover'; import msListConverter from './ms-list-converter'; +import msListIgnore from './ms-list-ignore'; import listReducer from './list-reducer'; import imageCorrector from './image-corrector'; import blockquoteNormaliser from './blockquote-normaliser'; @@ -49,6 +50,7 @@ function filterInlineHTML( HTML, preserveWhiteSpace ) { HTML = deepFilterHTML( HTML, [ headRemover, googleDocsUIDRemover, + msListIgnore, phrasingContentReducer, commentRemover, ] ); diff --git a/packages/blocks/src/api/raw-handling/test/ms-list-converter.js b/packages/blocks/src/api/raw-handling/test/ms-list-converter.js index a7c58dfa03010a..5ae7da68f16a92 100644 --- a/packages/blocks/src/api/raw-handling/test/ms-list-converter.js +++ b/packages/blocks/src/api/raw-handling/test/ms-list-converter.js @@ -7,7 +7,7 @@ import { deepFilterHTML } from '../utils'; describe( 'msListConverter', () => { it( 'should convert unordered list', () => { const input = - '

* test

'; + '

* test

'; const output = '
  • test
'; expect( deepFilterHTML( input, [ msListConverter ] ) ).toEqual( output @@ -16,7 +16,7 @@ describe( 'msListConverter', () => { it( 'should convert ordered list', () => { const input = - '

1 test

'; + '

1 test

'; const output = '
  1. test
'; expect( deepFilterHTML( input, [ msListConverter ] ) ).toEqual( output @@ -25,11 +25,11 @@ describe( 'msListConverter', () => { it( 'should convert indented list', () => { const input1 = - '

* test

'; + '

* test

'; const input2 = - '

* test

'; + '

* test

'; const input3 = - '

* test

'; + '

* test

'; const output = '
  • test
    • test
  • test
'; expect( @@ -39,13 +39,13 @@ describe( 'msListConverter', () => { it( 'should convert deep indented list', () => { const input1 = - '

* test

'; + '

* test

'; const input2 = - '

* test

'; + '

* test

'; const input3 = - '

* test

'; + '

* test

'; const input4 = - '

* test

'; + '

* test

'; const output = '
  • test
    • test
      • test
  • test
'; expect( 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 687326fbebd332..4efdbad33a5430 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss @@ -76,6 +76,19 @@ } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-style-variations-container { + @include break-medium() { + // Safari does not currently support `scrollbar-gutter: stable`, so at + // particular viewport sizes it's possible for previews to render prior to a + // scrollbar appearing. This then causes a scrollbar to appear, which reduces + // the width of the container and can cause the preview's width to change. + // As a result, the preview can go into an endless loop of resizing, causing + // the preview elements to appear to "dance". A workaround is to provide a + // max-width for the container, which prevents the introduction of the scrollbar + // from causing the preview's width to change. + // See: https://github.com/WordPress/gutenberg/issues/55112 + max-width: 292px; + } + .edit-site-global-styles-variations_item-preview { border: $gray-900 $border-width solid; } diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 178a57b8755535..6a39ca9ed7d659 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -26,7 +26,9 @@ exports[`Blocks raw handling pasteHandler iframe-embed 1`] = `""`; exports[`Blocks raw handling pasteHandler markdown 1`] = `"This is a heading with italic
This is a paragraph with a link, bold, and strikethrough.
Preserve
line breaks please.
Lists
A
Bulleted Indented
List
One
Two
Three
Table
First Header
Second Header
Content from cell 1
Content from cell 2
Content in the first column
Content in the second column



Table with empty cells.
Quote
First
Second
Code
Inline code tags should work.
This is a code block."`; -exports[`Blocks raw handling pasteHandler ms-word 1`] = `"This is a title
 
This is a subtitle
 
This is a heading level 1
 
This is a heading level 2
 
This is a paragraph with a link.
 
·      A
·      Bulleted
o   Indented
·      List
 
1      One
2      Two
3      Three
 
One
Two
Three
1
2
3
I
II
III
 
An image:
 

This is an anchor link that leads to the next paragraph.
This is the paragraph with the anchor.
This is an anchor link that leads nowhere.
This is a paragraph with an anchor with no link pointing to it.
This is a reference to a footnote[1].
This is a reference to an endnote[i].


[1] This is a footnote.


[i] This is an endnote."`; +exports[`Blocks raw handling pasteHandler ms-word 1`] = `"This is a title
 
This is a subtitle
 
This is a heading level 1
 
This is a heading level 2
 
This is a paragraph with a link.
 
A
Bulleted
Indented
List
 
One
Two
Three
 
One
Two
Three
1
2
3
I
II
III
 
An image:
 

This is an anchor link that leads to the next paragraph.
This is the paragraph with the anchor.
This is an anchor link that leads nowhere.
This is a paragraph with an anchor with no link pointing to it.
This is a reference to a footnote[1].
This is a reference to an endnote[i].


[1] This is a footnote.


[i] This is an endnote."`; + +exports[`Blocks raw handling pasteHandler ms-word-list 1`] = `"This is a headline?
This is a text:
One
Two
Three
Lorem Ipsum.
 "`; exports[`Blocks raw handling pasteHandler ms-word-online 1`] = `"This is a heading 
This is a paragraph with a link

Bulleted 
Indented 
List 
 
One 
Two 
Three 

One 
Two 
Three 




II 
III 
 
An image: 
 "`; diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index 2a31d0b0ceaa28..229fa0ba7761c8 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -383,6 +383,7 @@ describe( 'Blocks raw handling', () => { 'google-docs-table-with-comments', 'google-docs-with-comments', 'ms-word', + 'ms-word-list', 'ms-word-styled', 'ms-word-online', 'evernote', diff --git a/test/integration/fixtures/documents/ms-word-list-in.html b/test/integration/fixtures/documents/ms-word-list-in.html new file mode 100644 index 00000000000000..8cf79b8f7e5db7 --- /dev/null +++ b/test/integration/fixtures/documents/ms-word-list-in.html @@ -0,0 +1,28 @@ +

This is a headline?

+ +

This is a text:

+ +

·       +One

+ +

·       +Two

+ +

·       +Three

+ + + +

Lorem Ipsum.

+ +

 

\ No newline at end of file diff --git a/test/integration/fixtures/documents/ms-word-list-out.html b/test/integration/fixtures/documents/ms-word-list-out.html new file mode 100644 index 00000000000000..f57946f64bc985 --- /dev/null +++ b/test/integration/fixtures/documents/ms-word-list-out.html @@ -0,0 +1,25 @@ + +

This is a headline?

+ + + +

This is a text:

+ + + +
    +
  • One
  • + + + +
  • Two
  • + + + +
  • Three
  • +
+ + + +

Lorem Ipsum.

+ \ No newline at end of file