From 1ae4eeb77b1e6461467f3aac96ccad5ab9da516c Mon Sep 17 00:00:00 2001 From: Mike Auteri Date: Thu, 6 Jan 2022 01:28:31 -0500 Subject: [PATCH 001/149] Improve user experience with blocks editor when a block is not registered (#37646) * Improve user experience with blocks editor when a block is not registered. Mimic that of edit when a block is missing with core/missing block. * Remove change to .gitignore. * Move code from createBlock to synchronizeBlocksWithTemplate, which is a more appropriate location. * Added new unit test to check that unregistered blocks from template are replaced with core/missing block. * Fix E2E test and replace with core/missing block to replace unregistered block. * Move BlockName check to end of function and allow legacy block check to run before replacing with core/missing block. * Remove extra line break. --- packages/blocks/src/api/templates.js | 13 ++++++++++++- packages/blocks/src/api/test/templates.js | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/blocks/src/api/templates.js b/packages/blocks/src/api/templates.js index 69a46f2831bbda..6c363dae825645 100644 --- a/packages/blocks/src/api/templates.js +++ b/packages/blocks/src/api/templates.js @@ -108,7 +108,7 @@ export function synchronizeBlocksWithTemplate( blocks = [], template ) { attributes ); - const [ + let [ blockName, blockAttributes, ] = convertLegacyBlockNameAndAttributes( @@ -116,6 +116,17 @@ export function synchronizeBlocksWithTemplate( blocks = [], template ) { normalizedAttributes ); + // If a Block is undefined at this point, use the core/missing block as + // a placeholder for a better user experience. + if ( undefined === getBlockType( blockName ) ) { + blockAttributes = { + originalName: name, + originalContent: '', + originalUndelimitedContent: '', + }; + blockName = 'core/missing'; + } + return createBlock( blockName, blockAttributes, diff --git a/packages/blocks/src/api/test/templates.js b/packages/blocks/src/api/test/templates.js index 7dbee7062cb862..91598f4df1b877 100644 --- a/packages/blocks/src/api/test/templates.js +++ b/packages/blocks/src/api/test/templates.js @@ -43,6 +43,13 @@ describe( 'templates', () => { category: 'text', title: 'test block', } ); + + registerBlockType( 'core/missing', { + attributes: {}, + save: noop, + category: 'text', + title: 'missing block', + } ); } ); describe( 'doBlocksMatchTemplate', () => { @@ -201,5 +208,17 @@ describe( 'templates', () => { synchronizeBlocksWithTemplate( blockList, template ) ).toEqual( [ block1 ] ); } ); + + it( 'should replace unregistered blocks from template with core/missing block', () => { + const template = [ + [ 'core/test-block' ], + [ 'core/test-block-2' ], + [ 'core/test-faker' ], + ]; + + expect( + synchronizeBlocksWithTemplate( [], template )[ 2 ].name + ).toEqual( 'core/missing' ); + } ); } ); } ); From 0666dee9235aedd3d1fa51c733d0c1e146227452 Mon Sep 17 00:00:00 2001 From: them-es Date: Thu, 6 Jan 2022 07:36:00 +0100 Subject: [PATCH 002/149] [WP 5.9] Fix: HTML tags like inline images in nav links break submenu layout (#37665) * HTML tags like inline images in nav links break submenu layout Fixes https://github.com/WordPress/gutenberg/issues/37656 * Fixed a Typo * Update index.php * Update based on suggestion by @tellthemachines * Update based on suggestion by @tellthemachines --- packages/block-library/src/navigation-submenu/index.php | 4 ++-- packages/block-library/src/page-list/index.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/index.php b/packages/block-library/src/navigation-submenu/index.php index 8e5918f01198e2..a0eac8146f9e6d 100644 --- a/packages/block-library/src/navigation-submenu/index.php +++ b/packages/block-library/src/navigation-submenu/index.php @@ -191,7 +191,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) { $aria_label = sprintf( /* translators: Accessibility text. %s: Parent page title. */ __( '%s submenu' ), - $label + wp_strip_all_tags( $label ) ); $html = '
  • '; @@ -231,7 +231,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) { if ( $show_submenu_indicators ) { // The submenu icon is rendered in a button here - // so that there's a clickable elment to open the submenu. + // so that there's a clickable element to open the submenu. $html .= ''; } } else { diff --git a/packages/block-library/src/page-list/index.php b/packages/block-library/src/page-list/index.php index 00119a945bec9d..b7c1359980ebe7 100644 --- a/packages/block-library/src/page-list/index.php +++ b/packages/block-library/src/page-list/index.php @@ -177,7 +177,7 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click, $aria_label = sprintf( /* translators: Accessibility text. %s: Parent page title. */ __( '%s submenu' ), - $title + wp_strip_all_tags( $title ) ); $markup .= '
  • '; From 71ebbf416f9c65ed7a6cf5a69feb78217503515e Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 6 Jan 2022 08:49:57 +0000 Subject: [PATCH 003/149] Docs: Fix type of saved content - part two (#37740) --- lib/class-wp-widget-block.php | 2 +- packages/block-library/src/image/index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-widget-block.php b/lib/class-wp-widget-block.php index c5da06b4e2214d..2656b445ebfd35 100644 --- a/lib/class-wp-widget-block.php +++ b/lib/class-wp-widget-block.php @@ -101,7 +101,7 @@ public function widget( $args, $instance ) { * * @since 9.3.0 * - * @param array $content The HTML content of the current block widget. + * @param string $content The HTML content of the current block widget. * * @return string The classname to use in the block widget's container HTML. */ diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index f8f7066a970d88..7c1836f69e2d1a 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -10,7 +10,7 @@ * adding a data-id attribute to the element if core/gallery has added on pre-render. * * @param array $attributes The block attributes. - * @param array $content The block content. + * @param string $content The block content. * @return string Returns the block content with the data-id attribute added. */ function render_block_core_image( $attributes, $content ) { From b9a0419b2b9578b1e36b640e332dd714d2080222 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 6 Jan 2022 09:58:01 +0000 Subject: [PATCH 004/149] Fix PHPCS failure (#37742) --- packages/block-library/src/image/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 7c1836f69e2d1a..685b2d50117a56 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -9,7 +9,7 @@ * Renders the `core/image` block on the server, * adding a data-id attribute to the element if core/gallery has added on pre-render. * - * @param array $attributes The block attributes. + * @param array $attributes The block attributes. * @param string $content The block content. * @return string Returns the block content with the data-id attribute added. */ From b3be067ba92ec0c5323ce0346eb6e0f73359cdf4 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 6 Jan 2022 12:04:16 +0100 Subject: [PATCH 005/149] Replace `clipboard.js` with native Clipboard API (#37713) * Refactor `useCopyToClipboard` hook to use the native `clipboard` APIs * Refactor `useCopyOnClick` hook to use the native `clipboard` APIs * Remove unused `clipboard` dependency * Add `useCopyToClipboard` unit tests * Add `useCopyOnClick` tests * Remove selection clearance and focus management * CHANGELOG * Update package-loc.json --- package-lock.json | 34 --------- packages/compose/CHANGELOG.md | 4 ++ packages/compose/package.json | 1 - .../src/hooks/use-copy-on-click/index.js | 70 ++++++++++-------- .../src/hooks/use-copy-on-click/test/index.js | 71 +++++++++++++++++++ .../src/hooks/use-copy-to-clipboard/index.js | 42 +++++------ .../hooks/use-copy-to-clipboard/test/index.js | 60 ++++++++++++++++ 7 files changed, 192 insertions(+), 90 deletions(-) create mode 100644 packages/compose/src/hooks/use-copy-on-click/test/index.js create mode 100644 packages/compose/src/hooks/use-copy-to-clipboard/test/index.js diff --git a/package-lock.json b/package-lock.json index fcc63e51a11cea..206193450e48a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16408,7 +16408,6 @@ "@wordpress/is-shallow-equal": "file:packages/is-shallow-equal", "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/priority-queue": "file:packages/priority-queue", - "clipboard": "^2.0.8", "lodash": "^4.17.21", "mousetrap": "^1.6.5", "react-resize-aware": "^3.1.0", @@ -28078,16 +28077,6 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "clipboard": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", - "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -30562,11 +30551,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -35928,14 +35912,6 @@ "minimist": "^1.2.5" } }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "requires": { - "delegate": "^3.1.2" - } - }, "got": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", @@ -54062,11 +54038,6 @@ } } }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -57923,11 +57894,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" - }, "tinycolor2": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index 437fe56f1f13df..e7c68c609e0c55 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Refactored `useCopyToClipboard` and (deprecated) `useCopyOnClick` hooks to use native Clipboard API instead of third-party dependency `clipboard.js`, removing it from the repo ([#37713](https://github.com/WordPress/gutenberg/pull/37713)). + ## 5.0.0 (2021-07-29) ### Breaking Change diff --git a/packages/compose/package.json b/packages/compose/package.json index 4e715c56d899ca..7a405765188ccf 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -38,7 +38,6 @@ "@wordpress/is-shallow-equal": "file:../is-shallow-equal", "@wordpress/keycodes": "file:../keycodes", "@wordpress/priority-queue": "file:../priority-queue", - "clipboard": "^2.0.8", "lodash": "^4.17.21", "mousetrap": "^1.6.5", "react-resize-aware": "^3.1.0", diff --git a/packages/compose/src/hooks/use-copy-on-click/index.js b/packages/compose/src/hooks/use-copy-on-click/index.js index 383be2b957342c..3340cbb50d1153 100644 --- a/packages/compose/src/hooks/use-copy-on-click/index.js +++ b/packages/compose/src/hooks/use-copy-on-click/index.js @@ -1,12 +1,7 @@ -/** - * External dependencies - */ -import Clipboard from 'clipboard'; - /** * WordPress dependencies */ -import { useRef, useEffect, useState } from '@wordpress/element'; +import { useEffect, useState } from '@wordpress/element'; import deprecated from '@wordpress/deprecated'; /* eslint-disable jsdoc/no-undefined-types */ @@ -30,45 +25,60 @@ export default function useCopyOnClick( ref, text, timeout = 4000 ) { alternative: 'wp.compose.useCopyToClipboard', } ); - /** @type {import('react').MutableRefObject} */ - const clipboard = useRef(); const [ hasCopied, setHasCopied ] = useState( false ); useEffect( () => { /** @type {number | undefined} */ let timeoutId; + /** @type Array) */ + let triggers = []; if ( ! ref.current ) { return; } - // Clipboard listens to click events. - clipboard.current = new Clipboard( ref.current, { - text: () => ( typeof text === 'function' ? text() : text ), - } ); + // `triggers` is always an array, regardless of the value of the `ref` param. + if ( typeof ref.current === 'string' ) { + // expect `ref` to be a DOM selector + triggers = Array.from( document.querySelectorAll( ref.current ) ); + } else if ( 'length' in ref.current ) { + // Expect `ref` to be a `NodeList` + triggers = Array.from( ref.current ); + } else { + // Expect `ref` to be a single `Element` + triggers = [ ref.current ]; + } - clipboard.current.on( 'success', ( { clearSelection, trigger } ) => { - // Clearing selection will move focus back to the triggering button, - // ensuring that it is not reset to the body, and further that it is - // kept within the rendered node. - clearSelection(); + /** + * @param {Event} e + */ + const copyTextToClipboard = ( e ) => { + const trigger = /** @type {HTMLElement | null} */ ( e.target ); + const currentWindow = trigger?.ownerDocument.defaultView || window; + const textToCopy = typeof text === 'function' ? text() : text || ''; - // Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680 - if ( trigger ) { - /** @type {HTMLElement} */ ( trigger ).focus(); - } + currentWindow?.navigator?.clipboard + ?.writeText( textToCopy ) + .then( () => { + if ( timeout ) { + setHasCopied( true ); + clearTimeout( timeoutId ); + timeoutId = setTimeout( + () => setHasCopied( false ), + timeout + ); + } + } ); + }; - if ( timeout ) { - setHasCopied( true ); - clearTimeout( timeoutId ); - timeoutId = setTimeout( () => setHasCopied( false ), timeout ); - } - } ); + triggers.forEach( ( t ) => + t.addEventListener( 'click', copyTextToClipboard ) + ); return () => { - if ( clipboard.current ) { - clipboard.current.destroy(); - } + triggers.forEach( ( t ) => + t.removeEventListener( 'click', copyTextToClipboard ) + ); clearTimeout( timeoutId ); }; }, [ text, timeout, setHasCopied ] ); diff --git a/packages/compose/src/hooks/use-copy-on-click/test/index.js b/packages/compose/src/hooks/use-copy-on-click/test/index.js new file mode 100644 index 00000000000000..9e9634b60797d4 --- /dev/null +++ b/packages/compose/src/hooks/use-copy-on-click/test/index.js @@ -0,0 +1,71 @@ +/** + * External dependencies + */ +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; + +/** + * WordPress dependencies + */ +import { useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import useCopyOnClick from '../'; + +const ExampleComponent = ( { text, ...props } ) => { + const ref = useRef(); + + const hasCopied = useCopyOnClick( ref, text, 1000 ); + + return ( + + ); +}; + +let clipboardValue; + +const originalClipboard = global.navigator.clipboard; +const mockClipboard = { + writeText: jest.fn().mockImplementation( ( text ) => { + return new Promise( ( resolve ) => { + clipboardValue = text; + resolve(); + } ); + } ), +}; + +global.navigator.clipboard = mockClipboard; + +describe( 'useCopyOnClick', () => { + beforeEach( () => { + clipboardValue = undefined; + } ); + + afterAll( () => { + global.navigator.clipboard = originalClipboard; + } ); + + it( 'should copy the text to the clipboard and display a warning notice', async () => { + const textToBeCopied = 'mango'; + render( ); + + expect( console ).toHaveWarned(); + + const triggerButton = screen.getByText( 'Click to copy' ); + fireEvent.click( triggerButton ); + + await waitFor( () => + expect( clipboardValue ).toEqual( textToBeCopied ) + ); + + // Check that the displayed text changes as a way of testing + // the `hasCopied` logic + expect( screen.getByText( 'Copied' ) ).toBeInTheDocument(); + await waitFor( () => + expect( screen.getByText( 'Click to copy' ) ).toBeInTheDocument() + ); + } ); +} ); diff --git a/packages/compose/src/hooks/use-copy-to-clipboard/index.js b/packages/compose/src/hooks/use-copy-to-clipboard/index.js index a7c40199f16d72..73105982bd9d28 100644 --- a/packages/compose/src/hooks/use-copy-to-clipboard/index.js +++ b/packages/compose/src/hooks/use-copy-to-clipboard/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import Clipboard from 'clipboard'; - /** * WordPress dependencies */ @@ -39,32 +34,29 @@ export default function useCopyToClipboard( text, onSuccess ) { // fresh when the callback is called. const textRef = useUpdatedRef( text ); const onSuccessRef = useUpdatedRef( onSuccess ); - return useRefEffect( ( node ) => { - // Clipboard listens to click events. - const clipboard = new Clipboard( node, { - text() { - return typeof textRef.current === 'function' + return useRefEffect( ( trigger ) => { + if ( ! trigger ) { + return; + } + + const copyTextToClipboard = () => { + const currentWindow = trigger.ownerDocument.defaultView || window; + const textToCopy = + typeof textRef.current === 'function' ? textRef.current() : textRef.current || ''; - }, - } ); - clipboard.on( 'success', ( { clearSelection } ) => { - // Clearing selection will move focus back to the triggering - // button, ensuring that it is not reset to the body, and - // further that it is kept within the rendered node. - clearSelection(); - // Handle ClipboardJS focus bug, see - // https://github.com/zenorocha/clipboard.js/issues/680 - node.focus(); + currentWindow?.navigator?.clipboard + ?.writeText( textToCopy ) + .then( () => { + onSuccessRef?.current?.(); + } ); + }; - if ( onSuccessRef.current ) { - onSuccessRef.current(); - } - } ); + trigger.addEventListener( 'click', copyTextToClipboard ); return () => { - clipboard.destroy(); + trigger.removeEventListener( 'click', copyTextToClipboard ); }; }, [] ); } diff --git a/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js b/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js new file mode 100644 index 00000000000000..34a4a9160dba66 --- /dev/null +++ b/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js @@ -0,0 +1,60 @@ +/** + * External dependencies + */ +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import useCopyToClipboard from '../'; + +const ExampleComponent = ( { onSuccess, text, ...props } ) => { + const ref = useCopyToClipboard( text, onSuccess ); + + return ( + + ); +}; + +let clipboardValue; + +const originalClipboard = global.navigator.clipboard; +const mockClipboard = { + writeText: jest.fn().mockImplementation( ( text ) => { + return new Promise( ( resolve ) => { + clipboardValue = text; + resolve(); + } ); + } ), +}; + +global.navigator.clipboard = mockClipboard; + +describe( 'useCopyToClipboard', () => { + beforeEach( () => { + clipboardValue = undefined; + } ); + + afterAll( () => { + global.navigator.clipboard = originalClipboard; + } ); + + it( 'should copy the text to the clipboard', async () => { + const successCallback = jest.fn(); + const textToBeCopied = 'mango'; + render( + + ); + + const triggerButton = screen.getByText( 'Click to copy' ); + fireEvent.click( triggerButton ); + + await waitFor( () => expect( successCallback ).toHaveBeenCalled() ); + expect( clipboardValue ).toEqual( textToBeCopied ); + } ); +} ); From e5b1cff5ecbe648d358b2f28187a70e8729d7654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Walb=C3=B8=20Johnsg=C3=A5rd?= Date: Thu, 6 Jan 2022 13:47:57 +0100 Subject: [PATCH 006/149] Site logo: Fix range control on landscape logos (#37733) * Site logo: Fix range control on landscape logos Make sure the minimum width is an integer when calculating the minimum logo size. This fixes a bug where the range controller returned numbers that wasn't an integer on landscape logos. * Make sure minHeight is a integer --- packages/block-library/src/site-logo/edit.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index fa482e65a44199..18f151a48508d9 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -166,9 +166,10 @@ const SiteLogo = ( { const currentWidth = width || defaultWidth; const ratio = naturalWidth / naturalHeight; const currentHeight = currentWidth / ratio; - const minWidth = naturalWidth < naturalHeight ? MIN_SIZE : MIN_SIZE * ratio; + const minWidth = + naturalWidth < naturalHeight ? MIN_SIZE : Math.ceil( MIN_SIZE * ratio ); const minHeight = - naturalHeight < naturalWidth ? MIN_SIZE : MIN_SIZE / ratio; + naturalHeight < naturalWidth ? MIN_SIZE : Math.ceil( MIN_SIZE / ratio ); // With the current implementation of ResizableBox, an image needs an // explicit pixel value for the max-width. In absence of being able to From 489acbfd7c4f30012020c4fc3e2fd28840a80206 Mon Sep 17 00:00:00 2001 From: George Hotelling Date: Thu, 6 Jan 2022 09:54:30 -0500 Subject: [PATCH 007/149] Add menu-item-home class to Navigation for front page (#37301) * Add menu-item-home class to Navigation for the front page Closes #29423 --- packages/block-library/src/page-list/edit.js | 13 +++++++++++-- packages/block-library/src/page-list/index.php | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/page-list/edit.js b/packages/block-library/src/page-list/edit.js index 0818fe0b0446ef..f6f3b2c033bd92 100644 --- a/packages/block-library/src/page-list/edit.js +++ b/packages/block-library/src/page-list/edit.js @@ -29,7 +29,7 @@ import { ItemSubmenuIcon } from '../navigation-link/icons'; const MAX_PAGE_COUNT = 100; export default function PageListEdit( { context, clientId } ) { - const { pagesByParentId, totalPages } = usePagesByParentId(); + const { pagesByParentId, totalPages } = usePageData(); const isNavigationChild = 'showSubmenuIcon' in context; const allowConvertToLinks = @@ -94,7 +94,14 @@ export default function PageListEdit( { context, clientId } ) { ); } -function usePagesByParentId() { +function useFrontPageId() { + return useSelect( ( select ) => { + const site = select( coreStore ).getEntityRecord( 'root', 'site' ); + return site?.show_on_front === 'page' && site?.page_on_front; + }, [] ); +} + +function usePageData() { const { pages } = useSelect( ( select ) => { const { getEntityRecords } = select( coreStore ); @@ -137,6 +144,7 @@ const PageItems = memo( function PageItems( { depth = 0, } ) { const pages = pagesByParentId.get( parentId ); + const frontPageId = useFrontPageId(); if ( ! pages?.length ) { return []; @@ -155,6 +163,7 @@ const PageItems = memo( function PageItems( { 'open-on-hover-click': ! context.openSubmenusOnClick && context.showSubmenuIcon, + 'menu-item-home': page.id === frontPageId, } ) } > { hasChildren && context.openSubmenusOnClick ? ( diff --git a/packages/block-library/src/page-list/index.php b/packages/block-library/src/page-list/index.php index b7c1359980ebe7..4cbebe75ae4b58 100644 --- a/packages/block-library/src/page-list/index.php +++ b/packages/block-library/src/page-list/index.php @@ -173,6 +173,11 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click, } } + $front_page_id = (int) get_option( 'page_on_front' ); + if ( (int) $page['page_id'] === $front_page_id ) { + $css_class .= ' menu-item-home'; + } + $title = wp_kses( $page['title'], wp_kses_allowed_html( 'post' ) ); $aria_label = sprintf( /* translators: Accessibility text. %s: Parent page title. */ From 7a8d9fa45e26b0a34610c02c2ec4b68116f24fd9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 6 Jan 2022 16:09:02 +0100 Subject: [PATCH 008/149] Restore canvas padding for classic themes (#37741) --- packages/edit-post/src/classic.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/edit-post/src/classic.scss b/packages/edit-post/src/classic.scss index cf3a016d38f6b7..8cba8020e0b912 100644 --- a/packages/edit-post/src/classic.scss +++ b/packages/edit-post/src/classic.scss @@ -6,6 +6,18 @@ margin-right: auto; } +// Add a default 8px padding for classic themes around the canvas. +// Themes with theme.json can control this themselves. +// For full-wide blocks, we compensate for the base padding. +// These margins should match the padding value above. +html :where(.editor-styles-wrapper) { + padding: 8px; + .block-editor-block-list__layout.is-root-container > .wp-block[data-align="full"] { + margin-left: -8px; + margin-right: -8px; + } +} + // Deprecated style needed for the block widths and alignments. // for themes that don't support the new layout (theme.json). html :where(.wp-block) { From fd9aef8f59693039b1f43ed5d4f9595cfea6a689 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Thu, 6 Jan 2022 07:21:40 -0800 Subject: [PATCH 009/149] Add link to source for block reference (#37750) --- bin/api-docs/gen-block-lib-list.js | 17 ++- docs/reference-guides/core-blocks.md | 178 +++++++++++++-------------- 2 files changed, 105 insertions(+), 90 deletions(-) diff --git a/bin/api-docs/gen-block-lib-list.js b/bin/api-docs/gen-block-lib-list.js index 46684fa867dfbb..fb7e94e447d990 100644 --- a/bin/api-docs/gen-block-lib-list.js +++ b/bin/api-docs/gen-block-lib-list.js @@ -122,6 +122,20 @@ function augmentSupports( supports ) { return supports; } +/** + * Returns URL to the block directory source. + * + * @param {string} filename + * + * @return {string} URL + */ +function getSourceFromFile( filename ) { + const pkgdir = + 'https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/'; + const blockdir = path.basename( path.dirname( filename ) ); + return pkgdir + blockdir; +} + /** * Reads block.json file and returns markdown formatted entry. * @@ -132,6 +146,7 @@ function augmentSupports( supports ) { function readBlockJSON( filename ) { const blockjson = require( filename ); + const sourcefile = getSourceFromFile( filename ); const supportsAugmented = augmentSupports( blockjson.supports ); const supportsList = processObjWithInnerKeys( supportsAugmented ); const attributes = getTruthyKeys( blockjson.attributes ); @@ -139,7 +154,7 @@ function readBlockJSON( filename ) { return ` ## ${ blockjson.title } -${ blockjson.description } +${ blockjson.description } ([Source](${ sourcefile })) - **Name:** ${ blockjson.name } - **Category:** ${ blockjson.category } diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index f62f5c6e3f1869..de597435421e30 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -10,7 +10,7 @@ Items marked with a strikeout (~~strikeout~~) are explicitly disabled. ## Archives -Display a monthly archive of your posts. +Display a monthly archive of your posts. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/archives)) - **Name:** core/archives - **Category:** widgets @@ -19,7 +19,7 @@ Display a monthly archive of your posts. ## Audio -Embed a simple audio player. +Embed a simple audio player. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/audio)) - **Name:** core/audio - **Category:** media @@ -28,7 +28,7 @@ Embed a simple audio player. ## Reusable block -Create and save content to reuse across your site. Update the block, and the changes apply everywhere it’s used. +Create and save content to reuse across your site. Update the block, and the changes apply everywhere it’s used. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/block)) - **Name:** core/block - **Category:** reusable @@ -37,7 +37,7 @@ Create and save content to reuse across your site. Update the block, and the cha ## Button -Prompt visitors to take action with a button-style link. +Prompt visitors to take action with a button-style link. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/button)) - **Name:** core/button - **Category:** design @@ -46,7 +46,7 @@ Prompt visitors to take action with a button-style link. ## Buttons -Prompt visitors to take action with a group of button-style links. +Prompt visitors to take action with a group of button-style links. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/buttons)) - **Name:** core/buttons - **Category:** design @@ -55,7 +55,7 @@ Prompt visitors to take action with a group of button-style links. ## Calendar -A calendar of your site’s posts. +A calendar of your site’s posts. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/calendar)) - **Name:** core/calendar - **Category:** widgets @@ -64,7 +64,7 @@ A calendar of your site’s posts. ## Categories -Display a list of all categories. +Display a list of all categories. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/categories)) - **Name:** core/categories - **Category:** widgets @@ -73,7 +73,7 @@ Display a list of all categories. ## Code -Display code snippets that respect your spacing and tabs. +Display code snippets that respect your spacing and tabs. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/code)) - **Name:** core/code - **Category:** text @@ -82,7 +82,7 @@ Display code snippets that respect your spacing and tabs. ## Column -A single column within a columns block. +A single column within a columns block. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/column)) - **Name:** core/column - **Category:** text @@ -91,7 +91,7 @@ A single column within a columns block. ## Columns -Display content in multiple columns, with blocks added to each column. +Display content in multiple columns, with blocks added to each column. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/columns)) - **Name:** core/columns - **Category:** design @@ -100,7 +100,7 @@ Display content in multiple columns, with blocks added to each column. ## Comment Author Avatar -Add the avatar of this comment's author. +Add the avatar of this comment's author. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-author-avatar)) - **Name:** core/comment-author-avatar - **Category:** theme @@ -109,7 +109,7 @@ Add the avatar of this comment's author. ## Comment Author Name -Add the author name of this comment. +Add the author name of this comment. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-author-name)) - **Name:** core/comment-author-name - **Category:** theme @@ -118,7 +118,7 @@ Add the author name of this comment. ## Comment Content -Displays the contents of a comment. +Displays the contents of a comment. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-content)) - **Name:** core/comment-content - **Category:** theme @@ -127,7 +127,7 @@ Displays the contents of a comment. ## Comment Date -Add the date of this comment. +Add the date of this comment. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-date)) - **Name:** core/comment-date - **Category:** theme @@ -136,7 +136,7 @@ Add the date of this comment. ## Comment Edit Link -Displays a link to edit the comment in the WordPress Dashboard. This link is only visible to users with the edit comment capability. +Displays a link to edit the comment in the WordPress Dashboard. This link is only visible to users with the edit comment capability. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-edit-link)) - **Name:** core/comment-edit-link - **Category:** theme @@ -145,7 +145,7 @@ Displays a link to edit the comment in the WordPress Dashboard. This link is onl ## Comment Reply Link -Displays a link to reply to a comment. +Displays a link to reply to a comment. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-reply-link)) - **Name:** core/comment-reply-link - **Category:** theme @@ -154,7 +154,7 @@ Displays a link to reply to a comment. ## Comment Template -Contains the block elements used to render a comment, like the title, date, author, avatar and more. +Contains the block elements used to render a comment, like the title, date, author, avatar and more. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comment-template)) - **Name:** core/comment-template - **Category:** design @@ -163,7 +163,7 @@ Contains the block elements used to render a comment, like the title, date, auth ## Comments Pagination -Displays a paginated navigation to next/previous set of comments, when applicable. +Displays a paginated navigation to next/previous set of comments, when applicable. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-pagination)) - **Name:** core/comments-pagination - **Category:** theme @@ -172,7 +172,7 @@ Displays a paginated navigation to next/previous set of comments, when applicabl ## Next Page -Displays the next comments page link. +Displays the next comments page link. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-pagination-next)) - **Name:** core/comments-pagination-next - **Category:** theme @@ -181,7 +181,7 @@ Displays the next comments page link. ## Page Numbers -Displays a list of page numbers for comments pagination. +Displays a list of page numbers for comments pagination. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-pagination-numbers)) - **Name:** core/comments-pagination-numbers - **Category:** theme @@ -190,7 +190,7 @@ Displays a list of page numbers for comments pagination. ## Previous Page -Displays the previous comments page link. +Displays the previous comments page link. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-pagination-previous)) - **Name:** core/comments-pagination-previous - **Category:** theme @@ -199,7 +199,7 @@ Displays the previous comments page link. ## Comments Query Loop -An advanced block that allows displaying post comments based on different query parameters and visual configurations. +An advanced block that allows displaying post comments based on different query parameters and visual configurations. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-query-loop)) - **Name:** core/comments-query-loop - **Category:** theme @@ -208,7 +208,7 @@ An advanced block that allows displaying post comments based on different query ## Cover -Add an image or video with a text overlay — great for headers. +Add an image or video with a text overlay — great for headers. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/cover)) - **Name:** core/cover - **Category:** media @@ -217,7 +217,7 @@ Add an image or video with a text overlay — great for headers. ## Embed -Add a block that displays content pulled from other sites, like Twitter or YouTube. +Add a block that displays content pulled from other sites, like Twitter or YouTube. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/embed)) - **Name:** core/embed - **Category:** embed @@ -226,7 +226,7 @@ Add a block that displays content pulled from other sites, like Twitter or YouTu ## File -Add a link to a downloadable file. +Add a link to a downloadable file. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/file)) - **Name:** core/file - **Category:** media @@ -235,7 +235,7 @@ Add a link to a downloadable file. ## Classic -Use the classic WordPress editor. +Use the classic WordPress editor. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/freeform)) - **Name:** core/freeform - **Category:** text @@ -244,7 +244,7 @@ Use the classic WordPress editor. ## Gallery -Display multiple images in a rich gallery. +Display multiple images in a rich gallery. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/gallery)) - **Name:** core/gallery - **Category:** media @@ -253,7 +253,7 @@ Display multiple images in a rich gallery. ## Group -Combine blocks into a group. +Combine blocks into a group. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/group)) - **Name:** core/group - **Category:** design @@ -262,7 +262,7 @@ Combine blocks into a group. ## Heading -Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content. +Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/heading)) - **Name:** core/heading - **Category:** text @@ -271,7 +271,7 @@ Introduce new sections and organize content to help visitors (and search engines ## Home Link -Create a link that always points to the homepage of the site. Usually not necessary if there is already a site title link present in the header. +Create a link that always points to the homepage of the site. Usually not necessary if there is already a site title link present in the header. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/home-link)) - **Name:** core/home-link - **Category:** design @@ -280,7 +280,7 @@ Create a link that always points to the homepage of the site. Usually not necess ## Custom HTML -Add custom HTML code and preview it as you edit. +Add custom HTML code and preview it as you edit. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/html)) - **Name:** core/html - **Category:** widgets @@ -289,7 +289,7 @@ Add custom HTML code and preview it as you edit. ## Image -Insert an image to make a visual statement. +Insert an image to make a visual statement. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/image)) - **Name:** core/image - **Category:** media @@ -298,7 +298,7 @@ Insert an image to make a visual statement. ## Latest Comments -Display a list of your most recent comments. +Display a list of your most recent comments. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/latest-comments)) - **Name:** core/latest-comments - **Category:** widgets @@ -307,7 +307,7 @@ Display a list of your most recent comments. ## Latest Posts -Display a list of your most recent posts. +Display a list of your most recent posts. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/latest-posts)) - **Name:** core/latest-posts - **Category:** widgets @@ -316,7 +316,7 @@ Display a list of your most recent posts. ## List -Create a bulleted or numbered list. +Create a bulleted or numbered list. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/list)) - **Name:** core/list - **Category:** text @@ -325,7 +325,7 @@ Create a bulleted or numbered list. ## Login/out -Show login & logout links. +Show login & logout links. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/loginout)) - **Name:** core/loginout - **Category:** theme @@ -334,7 +334,7 @@ Show login & logout links. ## Media & Text -Set media and words side-by-side for a richer layout. +Set media and words side-by-side for a richer layout. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/media-text)) - **Name:** core/media-text - **Category:** media @@ -343,7 +343,7 @@ Set media and words side-by-side for a richer layout. ## Unsupported -Your site doesn’t include support for this block. +Your site doesn’t include support for this block. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/missing)) - **Name:** core/missing - **Category:** text @@ -352,7 +352,7 @@ Your site doesn’t include support for this block. ## More -Content before this block will be shown in the excerpt on your archives page. +Content before this block will be shown in the excerpt on your archives page. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/more)) - **Name:** core/more - **Category:** design @@ -361,7 +361,7 @@ Content before this block will be shown in the excerpt on your archives page. ## Navigation -A collection of blocks that allow visitors to get around your site. +A collection of blocks that allow visitors to get around your site. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/navigation)) - **Name:** core/navigation - **Category:** theme @@ -370,7 +370,7 @@ A collection of blocks that allow visitors to get around your site. ## Navigation Area -Define a navigation area for your theme. The navigation block associated with this area will be automatically displayed. +Define a navigation area for your theme. The navigation block associated with this area will be automatically displayed. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/navigation-area)) - **Name:** core/navigation-area - **Category:** theme @@ -379,7 +379,7 @@ Define a navigation area for your theme. The navigation block associated with th ## Custom Link -Add a page, link, or another item to your navigation. +Add a page, link, or another item to your navigation. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/navigation-link)) - **Name:** core/navigation-link - **Category:** design @@ -388,7 +388,7 @@ Add a page, link, or another item to your navigation. ## Submenu -Add a submenu to your navigation. +Add a submenu to your navigation. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/navigation-submenu)) - **Name:** core/navigation-submenu - **Category:** design @@ -397,7 +397,7 @@ Add a submenu to your navigation. ## Page Break -Separate your content into a multi-page experience. +Separate your content into a multi-page experience. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/nextpage)) - **Name:** core/nextpage - **Category:** design @@ -406,7 +406,7 @@ Separate your content into a multi-page experience. ## Page List -Display a list of all pages. +Display a list of all pages. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/page-list)) - **Name:** core/page-list - **Category:** widgets @@ -415,7 +415,7 @@ Display a list of all pages. ## Paragraph -Start with the building block of all narrative. +Start with the building block of all narrative. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/paragraph)) - **Name:** core/paragraph - **Category:** text @@ -424,7 +424,7 @@ Start with the building block of all narrative. ## Pattern -Show a block pattern. +Show a block pattern. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/pattern)) - **Name:** core/pattern - **Category:** theme @@ -433,7 +433,7 @@ Show a block pattern. ## Post Author -Add the author of this post. +Add the author of this post. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author)) - **Name:** core/post-author - **Category:** theme @@ -442,7 +442,7 @@ Add the author of this post. ## Post Author Name -The author name. +The author name. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author-name)) - **Name:** core/post-author-name - **Category:** theme @@ -451,7 +451,7 @@ The author name. ## Post Comment (deprecated) -This block is deprecated. Please use the Comments Query Loop block instead. +This block is deprecated. Please use the Comments Query Loop block instead. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-comment)) - **Name:** core/post-comment - **Category:** theme @@ -460,7 +460,7 @@ This block is deprecated. Please use the Comments Query Loop block instead. ## Post Comments -Display a post's comments. +Display a post's comments. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-comments)) - **Name:** core/post-comments - **Category:** theme @@ -469,7 +469,7 @@ Display a post's comments. ## Post Comments Count -Display a post's comments count. +Display a post's comments count. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-comments-count)) - **Name:** core/post-comments-count - **Category:** theme @@ -478,7 +478,7 @@ Display a post's comments count. ## Post Comments Form -Display a post's comments form. +Display a post's comments form. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-comments-form)) - **Name:** core/post-comments-form - **Category:** theme @@ -487,7 +487,7 @@ Display a post's comments form. ## Post Comments Link -Displays the link to the current post comments. +Displays the link to the current post comments. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-comments-link)) - **Name:** core/post-comments-link - **Category:** theme @@ -496,7 +496,7 @@ Displays the link to the current post comments. ## Post Content -Displays the contents of a post or page. +Displays the contents of a post or page. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-content)) - **Name:** core/post-content - **Category:** theme @@ -505,7 +505,7 @@ Displays the contents of a post or page. ## Post Date -Add the date of this post. +Add the date of this post. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-date)) - **Name:** core/post-date - **Category:** theme @@ -514,7 +514,7 @@ Add the date of this post. ## Post Excerpt -Display a post's excerpt. +Display a post's excerpt. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-excerpt)) - **Name:** core/post-excerpt - **Category:** theme @@ -523,7 +523,7 @@ Display a post's excerpt. ## Post Featured Image -Display a post's featured image. +Display a post's featured image. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-featured-image)) - **Name:** core/post-featured-image - **Category:** theme @@ -532,7 +532,7 @@ Display a post's featured image. ## Post Navigation Link -Displays the next or previous post link that is adjacent to the current post. +Displays the next or previous post link that is adjacent to the current post. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-navigation-link)) - **Name:** core/post-navigation-link - **Category:** theme @@ -541,7 +541,7 @@ Displays the next or previous post link that is adjacent to the current post. ## Post Template -Contains the block elements used to render a post, like the title, date, featured image, content or excerpt, and more. +Contains the block elements used to render a post, like the title, date, featured image, content or excerpt, and more. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-template)) - **Name:** core/post-template - **Category:** theme @@ -550,7 +550,7 @@ Contains the block elements used to render a post, like the title, date, feature ## Post Terms -Post terms. +Post terms. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-terms)) - **Name:** core/post-terms - **Category:** theme @@ -559,7 +559,7 @@ Post terms. ## Post Title -Displays the title of a post, page, or any other content-type. +Displays the title of a post, page, or any other content-type. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-title)) - **Name:** core/post-title - **Category:** theme @@ -568,7 +568,7 @@ Displays the title of a post, page, or any other content-type. ## Preformatted -Add text that respects your spacing and tabs, and also allows styling. +Add text that respects your spacing and tabs, and also allows styling. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/preformatted)) - **Name:** core/preformatted - **Category:** text @@ -577,7 +577,7 @@ Add text that respects your spacing and tabs, and also allows styling. ## Pullquote -Give special visual emphasis to a quote from your text. +Give special visual emphasis to a quote from your text. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/pullquote)) - **Name:** core/pullquote - **Category:** text @@ -586,7 +586,7 @@ Give special visual emphasis to a quote from your text. ## Query Loop -An advanced block that allows displaying post types based on different query parameters and visual configurations. +An advanced block that allows displaying post types based on different query parameters and visual configurations. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query)) - **Name:** core/query - **Category:** theme @@ -595,7 +595,7 @@ An advanced block that allows displaying post types based on different query par ## Pagination -Displays a paginated navigation to next/previous set of posts, when applicable. +Displays a paginated navigation to next/previous set of posts, when applicable. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-pagination)) - **Name:** core/query-pagination - **Category:** theme @@ -604,7 +604,7 @@ Displays a paginated navigation to next/previous set of posts, when applicable. ## Next Page -Displays the next posts page link. +Displays the next posts page link. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-pagination-next)) - **Name:** core/query-pagination-next - **Category:** theme @@ -613,7 +613,7 @@ Displays the next posts page link. ## Page Numbers -Displays a list of page numbers for pagination +Displays a list of page numbers for pagination ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-pagination-numbers)) - **Name:** core/query-pagination-numbers - **Category:** theme @@ -622,7 +622,7 @@ Displays a list of page numbers for pagination ## Previous Page -Displays the previous posts page link. +Displays the previous posts page link. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-pagination-previous)) - **Name:** core/query-pagination-previous - **Category:** theme @@ -631,7 +631,7 @@ Displays the previous posts page link. ## Query Title -Display the query title. +Display the query title. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-title)) - **Name:** core/query-title - **Category:** theme @@ -640,7 +640,7 @@ Display the query title. ## Quote -Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar +Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/quote)) - **Name:** core/quote - **Category:** text @@ -649,7 +649,7 @@ Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Ju ## RSS -Display entries from any RSS or Atom feed. +Display entries from any RSS or Atom feed. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/rss)) - **Name:** core/rss - **Category:** widgets @@ -658,7 +658,7 @@ Display entries from any RSS or Atom feed. ## Search -Help visitors find your content. +Help visitors find your content. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/search)) - **Name:** core/search - **Category:** widgets @@ -667,7 +667,7 @@ Help visitors find your content. ## Separator -Create a break between ideas or sections with a horizontal separator. +Create a break between ideas or sections with a horizontal separator. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/separator)) - **Name:** core/separator - **Category:** design @@ -676,7 +676,7 @@ Create a break between ideas or sections with a horizontal separator. ## Shortcode -Insert additional custom elements with a WordPress shortcode. +Insert additional custom elements with a WordPress shortcode. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/shortcode)) - **Name:** core/shortcode - **Category:** widgets @@ -685,7 +685,7 @@ Insert additional custom elements with a WordPress shortcode. ## Site Logo -Display a graphic to represent this site. Update the block, and the changes apply everywhere it’s used. This is different than the site icon, which is the smaller image visible in your dashboard, browser tabs, etc used to help others recognize this site. +Display a graphic to represent this site. Update the block, and the changes apply everywhere it’s used. This is different than the site icon, which is the smaller image visible in your dashboard, browser tabs, etc used to help others recognize this site. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/site-logo)) - **Name:** core/site-logo - **Category:** theme @@ -694,7 +694,7 @@ Display a graphic to represent this site. Update the block, and the changes appl ## Site Tagline -Describe in a few words what the site is about. The tagline can be used in search results or when sharing on social networks even if it's not displayed in the theme design. +Describe in a few words what the site is about. The tagline can be used in search results or when sharing on social networks even if it's not displayed in the theme design. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/site-tagline)) - **Name:** core/site-tagline - **Category:** theme @@ -703,7 +703,7 @@ Describe in a few words what the site is about. The tagline can be used in searc ## Site Title -Displays the name of this site. Update the block, and the changes apply everywhere it’s used. This will also appear in the browser title bar and in search results. +Displays the name of this site. Update the block, and the changes apply everywhere it’s used. This will also appear in the browser title bar and in search results. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/site-title)) - **Name:** core/site-title - **Category:** theme @@ -712,7 +712,7 @@ Displays the name of this site. Update the block, and the changes apply everywhe ## Social Icon -Display an icon linking to a social media profile or site. +Display an icon linking to a social media profile or site. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/social-link)) - **Name:** core/social-link - **Category:** widgets @@ -721,7 +721,7 @@ Display an icon linking to a social media profile or site. ## Social Icons -Display icons linking to your social media profiles or sites. +Display icons linking to your social media profiles or sites. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/social-links)) - **Name:** core/social-links - **Category:** widgets @@ -730,7 +730,7 @@ Display icons linking to your social media profiles or sites. ## Spacer -Add white space between blocks and customize its height. +Add white space between blocks and customize its height. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/spacer)) - **Name:** core/spacer - **Category:** design @@ -739,7 +739,7 @@ Add white space between blocks and customize its height. ## Table -Create structured content in rows and columns to display information. +Create structured content in rows and columns to display information. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/table)) - **Name:** core/table - **Category:** text @@ -748,7 +748,7 @@ Create structured content in rows and columns to display information. ## Table of Contents -Summarize your post with a list of headings. Add HTML anchors to Heading blocks to link them here. +Summarize your post with a list of headings. Add HTML anchors to Heading blocks to link them here. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/table-of-contents)) - **Name:** core/table-of-contents - **Category:** layout @@ -757,7 +757,7 @@ Summarize your post with a list of headings. Add HTML anchors to Heading blocks ## Tag Cloud -A cloud of your most used tags. +A cloud of your most used tags. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/tag-cloud)) - **Name:** core/tag-cloud - **Category:** widgets @@ -766,7 +766,7 @@ A cloud of your most used tags. ## Template Part -Edit the different global regions of your site, like the header, footer, sidebar, or create your own. +Edit the different global regions of your site, like the header, footer, sidebar, or create your own. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/template-part)) - **Name:** core/template-part - **Category:** theme @@ -775,7 +775,7 @@ Edit the different global regions of your site, like the header, footer, sidebar ## Term Description -Display the description of categories, tags and custom taxonomies when viewing an archive. +Display the description of categories, tags and custom taxonomies when viewing an archive. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/term-description)) - **Name:** core/term-description - **Category:** theme @@ -784,7 +784,7 @@ Display the description of categories, tags and custom taxonomies when viewing a ## Text Columns (deprecated) -This block is deprecated. Please use the Columns block instead. +This block is deprecated. Please use the Columns block instead. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/text-columns)) - **Name:** core/text-columns - **Category:** design @@ -793,7 +793,7 @@ This block is deprecated. Please use the Columns block instead. ## Verse -Insert poetry. Use special spacing formats. Or quote song lyrics. +Insert poetry. Use special spacing formats. Or quote song lyrics. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/verse)) - **Name:** core/verse - **Category:** text @@ -802,7 +802,7 @@ Insert poetry. Use special spacing formats. Or quote song lyrics. ## Video -Embed a video from your media library or upload a new one. +Embed a video from your media library or upload a new one. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/video)) - **Name:** core/video - **Category:** media From 49a4554687c5a6a8ebce01f6d2af0c5c9a7d6812 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 6 Jan 2022 16:42:32 +0100 Subject: [PATCH 010/149] Replace TT1-Blocks with Empty Theme in the wp-env of gutenberg and CI (#37446) Co-authored-by: Bernie Reiter --- .gitignore | 1 + .wp-env.json | 2 +- bin/plugin/commands/performance.js | 28 ++++++-- bin/plugin/utils/.wp-env.performance.json | 13 ++++ docs/explanations/architecture/performance.md | 43 +++++++++++- .../editor/various/font-size-picker.test.js | 68 ++++++++++++++++--- .../various/post-editor-template-mode.test.js | 2 +- .../specs/performance/site-editor.test.js | 2 +- .../site-editor/document-settings.test.js | 6 +- .../site-editor/multi-entity-editing.test.js | 4 +- .../site-editor/multi-entity-saving.test.js | 31 ++++----- .../site-editor/settings-sidebar.test.js | 8 +-- .../site-editor/site-editor-export.test.js | 2 +- .../site-editor/site-editor-inserter.test.js | 2 +- .../specs/site-editor/template-part.test.js | 21 +++--- .../specs/site-editor/template-revert.test.js | 5 +- packages/edit-site/src/store/test/actions.js | 4 +- packages/env/lib/parse-xdebug-mode.js | 2 +- ...erg-rest-global-styles-controller-test.php | 6 +- .../block-template-parts/header.html | 3 + test/emptytheme/block-templates/index.html | 9 +++ test/emptytheme/block-templates/singular.html | 5 ++ test/emptytheme/functions.php | 23 +++++++ test/emptytheme/index.php | 0 test/emptytheme/style.css | 15 ++++ test/emptytheme/theme.json | 10 +++ 26 files changed, 245 insertions(+), 70 deletions(-) create mode 100644 bin/plugin/utils/.wp-env.performance.json create mode 100644 test/emptytheme/block-template-parts/header.html create mode 100644 test/emptytheme/block-templates/index.html create mode 100644 test/emptytheme/block-templates/singular.html create mode 100644 test/emptytheme/functions.php create mode 100644 test/emptytheme/index.php create mode 100644 test/emptytheme/style.css create mode 100644 test/emptytheme/theme.json diff --git a/.gitignore b/.gitignore index 48cca7fcb886a4..9166d2c547584e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ coverage *.log yarn.lock /artifacts +/perf-envs .cache *.tsbuildinfo diff --git a/.wp-env.json b/.wp-env.json index a684b91dfb76cb..aa8cb2c628e7b4 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -1,7 +1,7 @@ { "core": "WordPress/WordPress", "plugins": [ "." ], - "themes": [ "WordPress/theme-experiments/tt1-blocks#tt1-blocks@0.4.7" ], + "themes": [ "./test/emptytheme" ], "env": { "tests": { "mappings": { diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js index 96f8674098ea77..ed18e6d9ecf065 100644 --- a/bin/plugin/commands/performance.js +++ b/bin/plugin/commands/performance.js @@ -3,7 +3,7 @@ */ const fs = require( 'fs' ); const path = require( 'path' ); -const { mapValues } = require( 'lodash' ); +const { mapValues, kebabCase } = require( 'lodash' ); /** * Internal dependencies @@ -213,7 +213,7 @@ async function runPerformanceTests( branches, options ) { } // 1- Preparing the tests directory. - log( '\n>> Preparing the tests directory' ); + log( '\n>> Preparing the tests directories' ); log( ' >> Cloning the repository' ); const baseDirectory = await git.clone( config.gitRepositoryURL ); const performanceTestDirectory = getRandomTemporaryPath(); @@ -236,19 +236,33 @@ async function runPerformanceTests( branches, options ) { 'npm install && npm run build:packages', performanceTestDirectory ); + log( ' >> Creating the environment folders' ); + await runShellScript( 'mkdir perf-envs', performanceTestDirectory ); // 2- Preparing the environment directories per branch. log( '\n>> Preparing an environment directory per branch' ); const branchDirectories = {}; for ( const branch of branches ) { log( ' >> Branch: ' + branch ); - const environmentDirectory = getRandomTemporaryPath(); + const environmentDirectory = + performanceTestDirectory + '/perf-envs/' + kebabCase( branch ); // @ts-ignore branchDirectories[ branch ] = environmentDirectory; + await runShellScript( 'mkdir ' + environmentDirectory ); await runShellScript( - 'cp -R ' + baseDirectory + ' ' + environmentDirectory + 'cp -R ' + baseDirectory + ' ' + environmentDirectory + '/plugin' + ); + await setUpGitBranch( branch, environmentDirectory + '/plugin' ); + await runShellScript( + 'cp ' + + path.resolve( + performanceTestDirectory, + 'bin/plugin/utils/.wp-env.performance.json' + ) + + ' ' + + environmentDirectory + + '/.wp-env.json' ); - await setUpGitBranch( branch, environmentDirectory ); if ( options.wpVersion ) { // In order to match the topology of ZIP files at wp.org, remap .0 @@ -316,7 +330,7 @@ async function runPerformanceTests( branches, options ) { log( ' >> Branch: ' + branch + ', Suite: ' + testSuite ); log( ' >> Starting the environment.' ); await runShellScript( - 'npm run wp-env start', + '../../node_modules/.bin/wp-env start', environmentDirectory ); log( ' >> Running the test.' ); @@ -326,7 +340,7 @@ async function runPerformanceTests( branches, options ) { ); log( ' >> Stopping the environment' ); await runShellScript( - 'npm run wp-env stop', + '../../node_modules/.bin/wp-env stop', environmentDirectory ); } diff --git a/bin/plugin/utils/.wp-env.performance.json b/bin/plugin/utils/.wp-env.performance.json new file mode 100644 index 00000000000000..cbe7ddd341409e --- /dev/null +++ b/bin/plugin/utils/.wp-env.performance.json @@ -0,0 +1,13 @@ +{ + "core": "WordPress/WordPress", + "plugins": [ "./plugin" ], + "themes": [ "../../test/emptytheme" ], + "env": { + "tests": { + "mappings": { + "wp-content/mu-plugins": "../../packages/e2e-tests/mu-plugins", + "wp-content/plugins/gutenberg-test-plugins": "../../packages/e2e-tests/plugins" + } + } + } +} diff --git a/docs/explanations/architecture/performance.md b/docs/explanations/architecture/performance.md index 5a9f56ee0996f9..30f75ff72b09da 100644 --- a/docs/explanations/architecture/performance.md +++ b/docs/explanations/architecture/performance.md @@ -4,7 +4,7 @@ Performance is a key feature for editor applications and the Block editor is not ## Metrics -To ensure the block editor stays performant across releases and development, we monitor some key metrics using [performance testing](/docs/contributors/code/testing-overview.md#performance-testing). +To ensure the block editor stays performant across releases and development, we monitor some key metrics using [performance benchmark job](#the-performance-benchmark-job). **Loading Time:** The time it takes to load an editor page. This includes time the server takes to respond, times to first paint, first contentful paint, DOM content load complete, load complete and first block render. **Typing Time:** The time it takes for the browser to respond while typing on the editor. @@ -24,6 +24,47 @@ Rendering asynchronously in this context means that if a change is triggered in Based on the idea that **when editing a given block, it is very rare that an update to that block affects other parts of the content**, the block editor canvas only renders the selected block is synchronous mode, all the remaining blocks are rendered asynchronously. This ensures that the editor stays responsive as the post grows. +## The performance benchmark job + +A tool to compare performance accross multiple branches/tags/commits is provided. You can run it locally like so: `./bin/plugin/cli.js perf [branches]`, example: + +``` +./bin/plugin/cli.js perf trunk v8.1.0 v8.0.0 +``` + +To get the most accurate results, it's is important to use the exact same version of the tests and environment (theme...) when running the tests, the only thing that need to be different between the branches is the Gutenberg plugin version (or branch used to build the plugin). + +To achieve that the command first prepares the following folder structure: + + │ + ├── packages/e2e-tests/specs/performance/* + | The actual performance tests to run + │ + ├── test/emptytheme + | The theme used for the tests environment. (site editor) + │ + │── perf-envs/branch1/.wp-env.json + │ The wp-env config file for branch1 (similar to all other branches except the plugin folder). + │── perf-envs/branch1/plugin + │ A built clone of the Gutenberg plugin for branch1 (git checkout branch1) + │ + ├── perf-envs/branchX + │ The structure of perf-envs/branch1 is duplicated for all other branches. + │ + └── ... + The remaining files of the Gutenberg repository (packages..., all what's necessary to actually run the performance tests job) + +Once the directory above is in place, the performance command loop over the performance test suites (post editor and site editor) and does the following: + + 1- Start the environment for branch1 + 2- Run the performance test for the current suite + 3- Stop the environment for branch1 + 4- Repeat the first 3 steps for all other branches + 5- Repeat the previous 4 steps 3 times. + 6- Compute medians for all the performance metrics of the current suite. + +Once all the test suites are executed, a summary report is printed. + ## Going further - [Journey towards a performant editor](https://riad.blog/2020/02/14/a-journey-towards-a-performant-web-editor/) diff --git a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js index 8f90b9c40c51ef..f308a56e0e7a3a 100644 --- a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js +++ b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js @@ -7,7 +7,6 @@ import { createNewPost, pressKeyWithModifier, pressKeyTimes, - activateTheme, openTypographyToolsPanelMenu, } from '@wordpress/e2e-test-utils'; @@ -100,21 +99,68 @@ describe( 'Font Size Picker', () => { ` ); } ); } ); + // A different control is rendered based on the available font sizes number. describe( 'More font sizes', () => { - beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); - } ); - afterAll( async () => { - await activateTheme( 'twentytwentyone' ); + beforeEach( async () => { + await page.evaluate( () => { + wp.data.dispatch( 'core/block-editor' ).updateSettings( + // eslint-disable-next-line no-undef + lodash.merge( + wp.data.select( 'core/block-editor' ).getSettings(), + { + __experimentalFeatures: { + typography: { + fontSizes: { + default: [ + { + name: 'Tiny', + slug: 'tiny', + size: '11px', + }, + , + { + name: 'Small', + slug: 'small', + size: '13px', + }, + { + name: 'Medium', + slug: 'medium', + size: '20px', + }, + { + name: 'Large', + slug: 'large', + size: '36px', + }, + { + name: 'Extra Large', + slug: 'x-large', + size: '42px', + }, + { + name: 'Huge', + slug: 'huge', + size: '48px', + }, + ], + }, + }, + }, + } + ) + ); + } ); } ); + it( 'should apply a named font size using the font size buttons', async () => { // Create a paragraph block with some content. await clickBlockAppender(); await page.keyboard.type( 'Paragraph to be made "large"' ); await openFontSizeSelectControl(); - await pressKeyTimes( 'ArrowDown', 4 ); + await pressKeyTimes( 'ArrowDown', 5 ); await page.keyboard.press( 'Enter' ); expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` @@ -131,11 +177,11 @@ describe( 'Font Size Picker', () => { ); await openFontSizeSelectControl(); - await pressKeyTimes( 'ArrowDown', 3 ); + await pressKeyTimes( 'ArrowDown', 4 ); await page.keyboard.press( 'Enter' ); expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` - " -

    Paragraph with font size reset using tools panel menu

    + " +

    Paragraph with font size reset using tools panel menu

    " ` ); @@ -158,7 +204,7 @@ describe( 'Font Size Picker', () => { ); await openFontSizeSelectControl(); - await pressKeyTimes( 'ArrowDown', 2 ); + await pressKeyTimes( 'ArrowDown', 3 ); await page.keyboard.press( 'Enter' ); expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` " diff --git a/packages/e2e-tests/specs/editor/various/post-editor-template-mode.test.js b/packages/e2e-tests/specs/editor/various/post-editor-template-mode.test.js index cf229daa06a40c..17eff7ecc26a44 100644 --- a/packages/e2e-tests/specs/editor/various/post-editor-template-mode.test.js +++ b/packages/e2e-tests/specs/editor/various/post-editor-template-mode.test.js @@ -102,7 +102,7 @@ describe( 'Post Editor Template mode', () => { } ); it( 'Allow to switch to template mode, edit the template and check the result', async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await createNewPost(); // Create a random post. await page.type( '.editor-post-title__input', 'Just an FSE Post' ); diff --git a/packages/e2e-tests/specs/performance/site-editor.test.js b/packages/e2e-tests/specs/performance/site-editor.test.js index 2008b95bd77ba8..f38f53b75400d9 100644 --- a/packages/e2e-tests/specs/performance/site-editor.test.js +++ b/packages/e2e-tests/specs/performance/site-editor.test.js @@ -31,7 +31,7 @@ jest.setTimeout( 1000000 ); describe( 'Site Editor Performance', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template', 'auto-draft' ); await trashAllPosts( 'wp_template_part' ); diff --git a/packages/e2e-tests/specs/site-editor/document-settings.test.js b/packages/e2e-tests/specs/site-editor/document-settings.test.js index 02b87c325f3abf..36a54adc6149bd 100644 --- a/packages/e2e-tests/specs/site-editor/document-settings.test.js +++ b/packages/e2e-tests/specs/site-editor/document-settings.test.js @@ -26,7 +26,7 @@ async function getDocumentSettingsSecondaryTitle() { describe( 'Document Settings', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -43,7 +43,7 @@ describe( 'Document Settings', () => { it( 'should display the selected templates name in the document header', async () => { // Navigate to a template await siteEditor.visit( { - postId: 'tt1-blocks//index', + postId: 'emptytheme//index', postType: 'wp_template', } ); @@ -79,7 +79,7 @@ describe( 'Document Settings', () => { it( "should display the selected template part's name in the document header", async () => { // Navigate to a template part await siteEditor.visit( { - postId: 'tt1-blocks//header', + postId: 'emptytheme//header', postType: 'wp_template_part', } ); diff --git a/packages/e2e-tests/specs/site-editor/multi-entity-editing.test.js b/packages/e2e-tests/specs/site-editor/multi-entity-editing.test.js index 3dc6252a8b714d..73731a855c7a02 100644 --- a/packages/e2e-tests/specs/site-editor/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/site-editor/multi-entity-editing.test.js @@ -134,7 +134,7 @@ const removeErrorMocks = () => { describe( 'Multi-entity editor states', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -152,7 +152,7 @@ describe( 'Multi-entity editor states', () => { // Skip reason: This should be rewritten to use other methods to switching to different templates. it.skip( 'should not dirty an entity by switching to it in the template dropdown', async () => { await siteEditor.visit( { - postId: 'tt1-blocks//header', + postId: 'emptytheme//header', postType: 'wp_template_part', } ); await page.waitForFunction( () => diff --git a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js index 65975e832aa016..cadb037a4847dc 100644 --- a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js @@ -46,7 +46,7 @@ describe( 'Multi-entity save flow', () => { let originalSiteTitle, originalBlogDescription; beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); await trashAllPosts( 'wp_block' ); @@ -165,6 +165,11 @@ describe( 'Multi-entity save flow', () => { '//*[@id="a11y-speak-polite"][contains(text(), "Post published")]' ); + // Unselect the blocks to avoid clicking the block toolbar. + await page.evaluate( () => { + wp.data.dispatch( 'core/block-editor' ).clearSelectedBlock(); + } ); + // Update the post. await page.click( '.editor-post-title' ); await page.keyboard.type( '...more title!' ); @@ -259,7 +264,7 @@ describe( 'Multi-entity save flow', () => { it( 'Save flow should work as expected', async () => { // Navigate to site editor. await siteEditor.visit( { - postId: 'tt1-blocks//index', + postId: 'emptytheme//index', postType: 'wp_template', } ); await siteEditor.disableWelcomeGuide(); @@ -297,7 +302,7 @@ describe( 'Multi-entity save flow', () => { it( 'Save flow should allow re-saving after changing the same block attribute', async () => { // Navigate to site editor. await siteEditor.visit( { - postId: 'tt1-blocks//index', + postId: 'emptytheme//index', postType: 'wp_template', } ); await siteEditor.disableWelcomeGuide(); @@ -308,26 +313,18 @@ describe( 'Multi-entity save flow', () => { // Open the block settings. await page.click( 'button[aria-label="Settings"]' ); - // Click on font size selector. - await page.click( 'button[aria-label="Font size"]' ); - - // Click on a different font size. - const extraSmallFontSize = await page.waitForXPath( - '//li[contains(text(), "Extra small")]' + // Change the font size + await page.click( + '.components-font-size-picker__controls button[aria-label="Small"]' ); - await extraSmallFontSize.click(); // Save all changes. await saveAllChanges(); - // Click on font size selector again. - await page.click( 'button[aria-label="Font size"]' ); - - // Select another font size. - const normalFontSize = await page.waitForXPath( - '//li[contains(text(), "Normal")]' + // Change the font size + await page.click( + '.components-font-size-picker__controls button[aria-label="Medium"]' ); - await normalFontSize.click(); // Assert that the save button has been re-enabled. const saveButton = await page.waitForSelector( diff --git a/packages/e2e-tests/specs/site-editor/settings-sidebar.test.js b/packages/e2e-tests/specs/site-editor/settings-sidebar.test.js index a8672395266b92..3f36c6e4cb2494 100644 --- a/packages/e2e-tests/specs/site-editor/settings-sidebar.test.js +++ b/packages/e2e-tests/specs/site-editor/settings-sidebar.test.js @@ -42,7 +42,7 @@ async function getTemplateCard() { describe( 'Settings sidebar', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -70,7 +70,7 @@ describe( 'Settings sidebar', () => { const templateCardBeforeNavigation = await getTemplateCard(); await siteEditor.visit( { - postId: 'tt1-blocks//404', + postId: 'emptytheme//singular', postType: 'wp_template', } ); const templateCardAfterNavigation = await getTemplateCard(); @@ -80,8 +80,8 @@ describe( 'Settings sidebar', () => { description: 'Displays posts.', } ); expect( templateCardAfterNavigation ).toMatchObject( { - title: '404', - description: 'Displays when no content is found.', + title: 'Singular', + description: 'Displays a single post or page.', } ); } ); } ); diff --git a/packages/e2e-tests/specs/site-editor/site-editor-export.test.js b/packages/e2e-tests/specs/site-editor/site-editor-export.test.js index 724886ab66adfd..6145f569cfadc4 100644 --- a/packages/e2e-tests/specs/site-editor/site-editor-export.test.js +++ b/packages/e2e-tests/specs/site-editor/site-editor-export.test.js @@ -30,7 +30,7 @@ async function waitForFileExists( filePath, timeout = 10000 ) { describe( 'Site Editor Templates Export', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); diff --git a/packages/e2e-tests/specs/site-editor/site-editor-inserter.test.js b/packages/e2e-tests/specs/site-editor/site-editor-inserter.test.js index fb1ddf69a2cc29..e9181b94070f8f 100644 --- a/packages/e2e-tests/specs/site-editor/site-editor-inserter.test.js +++ b/packages/e2e-tests/specs/site-editor/site-editor-inserter.test.js @@ -10,7 +10,7 @@ import { siteEditor } from './utils'; describe( 'Site Editor Inserter', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); diff --git a/packages/e2e-tests/specs/site-editor/template-part.test.js b/packages/e2e-tests/specs/site-editor/template-part.test.js index cd98b24947ed3f..2f812e8701602b 100644 --- a/packages/e2e-tests/specs/site-editor/template-part.test.js +++ b/packages/e2e-tests/specs/site-editor/template-part.test.js @@ -21,7 +21,7 @@ const templatePartNameInput = describe( 'Template Part', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -40,7 +40,7 @@ describe( 'Template Part', () => { async function navigateToHeader() { // Switch to editing the header template part. await siteEditor.visit( { - postId: 'tt1-blocks//header', + postId: 'emptytheme//header', postType: 'wp_template_part', } ); } @@ -61,7 +61,7 @@ describe( 'Template Part', () => { // Switch back to the Index template. await siteEditor.visit( { - postId: 'tt1-blocks//index', + postId: 'emptytheme//index', postType: 'wp_template', } ); } @@ -93,12 +93,9 @@ describe( 'Template Part', () => { expect( paragraphInTemplatePart ).not.toBeNull(); } - async function awaitHeaderAndFooterLoad() { + async function awaitHeaderLoad() { await canvas().waitForSelector( - '.wp-block-template-part.site-header.block-editor-block-list__layout' - ); - await canvas().waitForSelector( - '.wp-block-template-part.site-footer.block-editor-block-list__layout' + 'header.wp-block-template-part.block-editor-block-list__layout' ); } @@ -172,7 +169,7 @@ describe( 'Template Part', () => { } ); it( 'Should convert selected block to template part', async () => { - await awaitHeaderAndFooterLoad(); + await awaitHeaderLoad(); const initialTemplateParts = await canvas().$$( '.wp-block-template-part' ); @@ -210,7 +207,7 @@ describe( 'Template Part', () => { } ); it( 'Should convert multiple selected blocks to template part', async () => { - await awaitHeaderAndFooterLoad(); + await awaitHeaderLoad(); const initialTemplateParts = await canvas().$$( '.wp-block-template-part' ); @@ -277,7 +274,7 @@ describe( 'Template Part', () => { it( 'Should insert new template part on creation', async () => { let siteEditorCanvas = canvas(); - await awaitHeaderAndFooterLoad(); + await awaitHeaderLoad(); // Create new template part. await insertBlock( 'Template Part' ); @@ -319,7 +316,7 @@ describe( 'Template Part', () => { // Reload the page so as the new template part is available in the existing template parts. await siteEditor.visit(); siteEditorCanvas = canvas(); - await awaitHeaderAndFooterLoad(); + await awaitHeaderLoad(); // Try to insert the template part we created. await insertBlock( 'Template Part' ); const chooseExistingButton = await siteEditorCanvas.waitForXPath( diff --git a/packages/e2e-tests/specs/site-editor/template-revert.test.js b/packages/e2e-tests/specs/site-editor/template-revert.test.js index d77bb339bd9b51..34e1cba4dbfcb4 100644 --- a/packages/e2e-tests/specs/site-editor/template-revert.test.js +++ b/packages/e2e-tests/specs/site-editor/template-revert.test.js @@ -89,7 +89,7 @@ const assertTemplatesAreDeleted = async () => { describe( 'Template Revert', () => { beforeAll( async () => { - await activateTheme( 'tt1-blocks' ); + await activateTheme( 'emptytheme' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -164,7 +164,7 @@ describe( 'Template Revert', () => { expect( contentBefore ).toBe( contentAfter ); } ); - it( 'should show the original content after revert, clicking undo then redo in the header toolbar', async () => { + it.skip( 'should show the original content after revert, clicking undo then redo in the header toolbar', async () => { const contentBefore = await getEditedPostContent(); await addDummyText(); @@ -172,6 +172,7 @@ describe( 'Template Revert', () => { await revertTemplate(); await save(); await undoRevertInHeaderToolbar(); + // there's a bug which probably also exists where the redo button stays disabled. await clickRedoInHeaderToolbar(); const contentAfter = await getEditedPostContent(); diff --git a/packages/edit-site/src/store/test/actions.js b/packages/edit-site/src/store/test/actions.js index 06ba5979b5023e..8e5ebc09a8a5f6 100644 --- a/packages/edit-site/src/store/test/actions.js +++ b/packages/edit-site/src/store/test/actions.js @@ -96,10 +96,10 @@ describe( 'actions', () => { selectorName: '__experimentalGetTemplateForLink', args: [ page.path ], } ); - expect( it.next( { id: 'tt1-blocks//single' } ).value ).toEqual( { + expect( it.next( { id: 'emptytheme//single' } ).value ).toEqual( { type: 'SET_PAGE', page, - templateId: 'tt1-blocks//single', + templateId: 'emptytheme//single', } ); expect( it.next().done ).toBe( true ); } ); diff --git a/packages/env/lib/parse-xdebug-mode.js b/packages/env/lib/parse-xdebug-mode.js index c057012e23f9f9..927b4f6e3f2334 100644 --- a/packages/env/lib/parse-xdebug-mode.js +++ b/packages/env/lib/parse-xdebug-mode.js @@ -26,7 +26,7 @@ module.exports = function parseXdebugMode( value ) { throwXdebugModeError( value ); } - if ( value.length === 0 ) { + if ( value.length === 0 || value === 'undefined' ) { return 'debug'; } diff --git a/phpunit/class-gutenberg-rest-global-styles-controller-test.php b/phpunit/class-gutenberg-rest-global-styles-controller-test.php index fa5687af9ad923..f546d88dbb7c50 100644 --- a/phpunit/class-gutenberg-rest-global-styles-controller-test.php +++ b/phpunit/class-gutenberg-rest-global-styles-controller-test.php @@ -24,7 +24,7 @@ private function find_and_normalize_global_styles_by_id( $global_styles, $id ) { public function set_up() { parent::set_up(); - switch_theme( 'tt1-blocks' ); + switch_theme( 'emptytheme' ); } /** @@ -45,9 +45,9 @@ public static function wpSetupBeforeClass( $factory ) { 'post_status' => 'publish', 'post_title' => __( 'Custom Styles', 'default' ), 'post_type' => 'wp_global_styles', - 'post_name' => 'wp-global-styles-tt1-blocks', + 'post_name' => 'wp-global-styles-emptytheme', 'tax_input' => array( - 'wp_theme' => 'tt1-blocks', + 'wp_theme' => 'emptytheme', ), ), true diff --git a/test/emptytheme/block-template-parts/header.html b/test/emptytheme/block-template-parts/header.html new file mode 100644 index 00000000000000..388c223268a37a --- /dev/null +++ b/test/emptytheme/block-template-parts/header.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/emptytheme/block-templates/index.html b/test/emptytheme/block-templates/index.html new file mode 100644 index 00000000000000..356981eb585b60 --- /dev/null +++ b/test/emptytheme/block-templates/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/emptytheme/block-templates/singular.html b/test/emptytheme/block-templates/singular.html new file mode 100644 index 00000000000000..45d77e8279e498 --- /dev/null +++ b/test/emptytheme/block-templates/singular.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/emptytheme/functions.php b/test/emptytheme/functions.php new file mode 100644 index 00000000000000..5ee5593c5c8e4e --- /dev/null +++ b/test/emptytheme/functions.php @@ -0,0 +1,23 @@ +get( 'Version' ) ); +} + +add_action( 'wp_enqueue_scripts', 'emptytheme_scripts' ); diff --git a/test/emptytheme/index.php b/test/emptytheme/index.php new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/emptytheme/style.css b/test/emptytheme/style.css new file mode 100644 index 00000000000000..74cd7d858ad5c2 --- /dev/null +++ b/test/emptytheme/style.css @@ -0,0 +1,15 @@ +/* +Theme Name: Emptytheme +Theme URI: https://github.com/wordpress/theme-experiments/ +Author: the WordPress team +Description: The base for a block-based theme. +Requires at least: 5.3 +Tested up to: 5.5 +Requires PHP: 5.6 +Version: 1.0 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Text Domain: emptytheme +Emptytheme WordPress Theme, (C) 2021 WordPress.org +Emptytheme is distributed under the terms of the GNU GPL. +*/ diff --git a/test/emptytheme/theme.json b/test/emptytheme/theme.json new file mode 100644 index 00000000000000..4f478f46c4bb7b --- /dev/null +++ b/test/emptytheme/theme.json @@ -0,0 +1,10 @@ +{ + "version": 2, + "settings": { + "appearanceTools": true, + "layout": { + "contentSize": "840px", + "wideSize": "1100px" + } + } +} \ No newline at end of file From ef0e22af675b4a2fddd9af75dd85272fa9cbf37e Mon Sep 17 00:00:00 2001 From: Mustaque Ahmed Date: Thu, 6 Jan 2022 22:32:13 +0530 Subject: [PATCH 011/149] Refactor SuggestionsList to use hooks and change class to function component (#36924) * Refactor SuggestionsList to use hooks and change class to function component Introduced functional component. In the component I'm using useState, useEffect. Renamed a few variables to get rid of syntax errors. Tested the component and it is working as expected. * fix scrollIntoView import issue and fix component test case There was an error saying scrollIntoView function not found. I was not importing it properly now in this commit I have renamed scrollIntoView function from dom-scroll-into-view package is renamed as scrollView. I had to do this because there is already props with the same name ie scrollIntoView. Component test case was failing because of issue on the same lines that is now fixed. There was another error related to not using act from react-dom/test-utils package in test case. I have fixed it. All component test case are passing now. * Address review comments - Add `noop` to reduce number of functions creation - Move emptyList to a const then use it - Move `handleMouseDown` to top of the file to avoid recreating it on every render * refactor `noop`, set default value `scrollingIntoView` false and use `useRefEffect` * add changelog entry * set `onHover` and `onSelect` default value undefined and use optional chaining --- packages/components/CHANGELOG.md | 1 + .../src/form-token-field/suggestions-list.js | 229 +++++++++--------- .../src/form-token-field/test/index.js | 6 +- 3 files changed, 114 insertions(+), 122 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 5ad84cd04a9849..65c089c899b634 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -36,6 +36,7 @@ - Add support for rendering the `ColorPalette` in a `Dropdown` when opened in the sidebar ([#37067](https://github.com/WordPress/gutenberg/pull/37067)) - Show an incremental sequence of numbers (1/2/3/4/5) as a label of the font size, when we have at most five font sizes, where at least one the them contains a complex css value(clamp, var, etc..). We do this because complex css values cannot be calculated properly and the incremental sequence of numbers as labels can help the user better mentally map the different available font sizes. ([#37038](https://github.com/WordPress/gutenberg/pull/37038)) - Add support for proper borders to color indicators ([#37500](https://github.com/WordPress/gutenberg/pull/37500)) +- Refactor `SuggestionsList` class component to functional component([#36924](https://github.com/WordPress/gutenberg/pull/36924/)) ## 19.1.4 (2021-12-13) diff --git a/packages/components/src/form-token-field/suggestions-list.js b/packages/components/src/form-token-field/suggestions-list.js index 1ad0ace0a3b89e..b7eee38e95e243 100644 --- a/packages/components/src/form-token-field/suggestions-list.js +++ b/packages/components/src/form-token-field/suggestions-list.js @@ -2,157 +2,146 @@ * External dependencies */ import { map } from 'lodash'; -import scrollIntoView from 'dom-scroll-into-view'; +import scrollView from 'dom-scroll-into-view'; import classnames from 'classnames'; /** * WordPress dependencies */ -import { Component } from '@wordpress/element'; -import { withSafeTimeout } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; +import { withSafeTimeout, useRefEffect } from '@wordpress/compose'; -class SuggestionsList extends Component { - constructor() { - super( ...arguments ); - this.handleMouseDown = this.handleMouseDown.bind( this ); - this.bindList = this.bindList.bind( this ); - } +const emptyList = Object.freeze( [] ); - componentDidUpdate() { - // only have to worry about scrolling selected suggestion into view - // when already expanded - if ( - this.props.selectedIndex > -1 && - this.props.scrollIntoView && - this.list.children[ this.props.selectedIndex ] - ) { - this.scrollingIntoView = true; - scrollIntoView( - this.list.children[ this.props.selectedIndex ], - this.list, - { - onlyScrollIfNeeded: true, - } - ); +const handleMouseDown = ( e ) => { + // By preventing default here, we will not lose focus of when clicking a suggestion + e.preventDefault(); +}; - this.props.setTimeout( () => { - this.scrollingIntoView = false; - }, 100 ); - } - } +function SuggestionsList( { + selectedIndex, + scrollIntoView, + match = '', + onHover, + onSelect, + suggestions = emptyList, + displayTransform, + instanceId, + setTimeout, +} ) { + const [ scrollingIntoView, setScrollingIntoView ] = useState( false ); - bindList( ref ) { - this.list = ref; - } + const listRef = useRefEffect( + ( listNode ) => { + // only have to worry about scrolling selected suggestion into view + // when already expanded + if ( + selectedIndex > -1 && + scrollIntoView && + listNode.children[ selectedIndex ] + ) { + setScrollingIntoView( true ); + scrollView( listNode.children[ selectedIndex ], listNode, { + onlyScrollIfNeeded: true, + } ); + setTimeout( () => { + setScrollingIntoView( false ); + }, 100 ); + } + }, + [ selectedIndex, scrollIntoView ] + ); - handleHover( suggestion ) { + const handleHover = ( suggestion ) => { return () => { - if ( ! this.scrollingIntoView ) { - this.props.onHover( suggestion ); + if ( ! scrollingIntoView ) { + onHover?.( suggestion ); } }; - } + }; - handleClick( suggestion ) { + const handleClick = ( suggestion ) => { return () => { - this.props.onSelect( suggestion ); + onSelect?.( suggestion ); }; - } + }; - handleMouseDown( e ) { - // By preventing default here, we will not lose focus of when clicking a suggestion - e.preventDefault(); - } - - computeSuggestionMatch( suggestion ) { - const match = this.props - .displayTransform( this.props.match || '' ) - .toLocaleLowerCase(); - if ( match.length === 0 ) { + const computeSuggestionMatch = ( suggestion ) => { + const matchText = displayTransform( match || '' ).toLocaleLowerCase(); + if ( matchText.length === 0 ) { return null; } - suggestion = this.props.displayTransform( suggestion ); - const indexOfMatch = suggestion.toLocaleLowerCase().indexOf( match ); + suggestion = displayTransform( suggestion ); + const indexOfMatch = suggestion + .toLocaleLowerCase() + .indexOf( matchText ); return { suggestionBeforeMatch: suggestion.substring( 0, indexOfMatch ), suggestionMatch: suggestion.substring( indexOfMatch, - indexOfMatch + match.length + indexOfMatch + matchText.length ), suggestionAfterMatch: suggestion.substring( - indexOfMatch + match.length + indexOfMatch + matchText.length ), }; - } + }; - render() { - // We set `tabIndex` here because otherwise Firefox sets focus on this - // div when tabbing off of the input in `TokenField` -- not really sure - // why, since usually a div isn't focusable by default - // TODO does this still apply now that it's a
      and not a
      ? - return ( -
        - { map( this.props.suggestions, ( suggestion, index ) => { - const match = this.computeSuggestionMatch( suggestion ); - const classeName = classnames( - 'components-form-token-field__suggestion', - { - 'is-selected': index === this.props.selectedIndex, - } - ); + // We set `tabIndex` here because otherwise Firefox sets focus on this + // div when tabbing off of the input in `TokenField` -- not really sure + // why, since usually a div isn't focusable by default + // TODO does this still apply now that it's a
          and not a
          ? + return ( +
            + { map( suggestions, ( suggestion, index ) => { + const matchText = computeSuggestionMatch( suggestion ); + const className = classnames( + 'components-form-token-field__suggestion', + { + 'is-selected': index === selectedIndex, + } + ); - /* eslint-disable jsx-a11y/click-events-have-key-events */ - return ( -
          • - { match ? ( - - { match.suggestionBeforeMatch } - - { match.suggestionMatch } - - { match.suggestionAfterMatch } - - ) : ( - this.props.displayTransform( suggestion ) - ) } -
          • - ); - /* eslint-enable jsx-a11y/click-events-have-key-events */ - } ) } -
          - ); - } + /* eslint-disable jsx-a11y/click-events-have-key-events */ + return ( +
        • + { matchText ? ( + + { matchText.suggestionBeforeMatch } + + { matchText.suggestionMatch } + + { matchText.suggestionAfterMatch } + + ) : ( + displayTransform( suggestion ) + ) } +
        • + ); + /* eslint-enable jsx-a11y/click-events-have-key-events */ + } ) } +
        + ); } -SuggestionsList.defaultProps = { - match: '', - onHover: () => {}, - onSelect: () => {}, - suggestions: Object.freeze( [] ), -}; - export default withSafeTimeout( SuggestionsList ); diff --git a/packages/components/src/form-token-field/test/index.js b/packages/components/src/form-token-field/test/index.js index f166b5b201c09f..0a9ee88d9c4d67 100644 --- a/packages/components/src/form-token-field/test/index.js +++ b/packages/components/src/form-token-field/test/index.js @@ -2,7 +2,7 @@ * External dependencies */ import { filter, map } from 'lodash'; -import TestUtils from 'react-dom/test-utils'; +import TestUtils, { act } from 'react-dom/test-utils'; import ReactDOM from 'react-dom'; /** @@ -262,7 +262,9 @@ describe( 'FormTokenField', () => { // before sending a hover event, we need to wait for // SuggestionList#_scrollingIntoView to become false - jest.advanceTimersByTime( 100 ); + act( () => { + jest.advanceTimersByTime( 100 ); + } ); TestUtils.Simulate.mouseEnter( hoverSuggestion ); expect( getSelectedSuggestion() ).toEqual( [ 'wi', 'th' ] ); From 1e56c54f832b8c7284f1516d81f6511927f739ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rostislav=20Woln=C3=BD?= Date: Fri, 7 Jan 2022 10:06:06 +0100 Subject: [PATCH 012/149] Use useCallback hook from @wordpress/elements in color-picker (#37745) Using useCallback directly from react may cause that another version of react then one use in @wordpress/elements will be loaded. --- packages/components/src/color-picker/component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/color-picker/component.tsx b/packages/components/src/color-picker/component.tsx index 4f9f0c7da59e78..dc0b3a46fa73f6 100644 --- a/packages/components/src/color-picker/component.tsx +++ b/packages/components/src/color-picker/component.tsx @@ -2,14 +2,14 @@ * External dependencies */ // eslint-disable-next-line no-restricted-imports -import { Ref, useCallback } from 'react'; +import { Ref } from 'react'; import { colord, extend, Colord } from 'colord'; import namesPlugin from 'colord/plugins/names'; /** * WordPress dependencies */ -import { useState, useMemo } from '@wordpress/element'; +import { useCallback, useState, useMemo } from '@wordpress/element'; import { settings } from '@wordpress/icons'; import { useDebounce } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; From a3466dd63362d126f98a27408c0989e2e2753593 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 7 Jan 2022 11:47:53 +0100 Subject: [PATCH 013/149] Suggest picking a category on the pre-publish panel (#37703) --- .../maybe-category-panel.js | 88 +++++++++++++++++++ .../post-publish-panel/prepublish.js | 2 + 2 files changed, 90 insertions(+) create mode 100644 packages/editor/src/components/post-publish-panel/maybe-category-panel.js diff --git a/packages/editor/src/components/post-publish-panel/maybe-category-panel.js b/packages/editor/src/components/post-publish-panel/maybe-category-panel.js new file mode 100644 index 00000000000000..d7471bee18e422 --- /dev/null +++ b/packages/editor/src/components/post-publish-panel/maybe-category-panel.js @@ -0,0 +1,88 @@ +/** + * External dependencies + */ +import { some } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { PanelBody } from '@wordpress/components'; +import { store as coreStore } from '@wordpress/core-data'; +import { useState, useEffect } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import HierarchicalTermSelector from '../post-taxonomies/hierarchical-term-selector'; +import { store as editorStore } from '../../store'; + +function MaybeCategoryPanel() { + const hasNoCategory = useSelect( ( select ) => { + const postType = select( editorStore ).getCurrentPostType(); + const categoriesTaxonomy = select( coreStore ).getTaxonomy( + 'category' + ); + const defaultCategorySlug = 'uncategorized'; + const defaultCategory = select( coreStore ).getEntityRecords( + 'taxonomy', + 'category', + { + slug: defaultCategorySlug, + } + )?.[ 0 ]; + const postTypeSupportsCategories = + categoriesTaxonomy && + some( categoriesTaxonomy.types, ( type ) => type === postType ); + const categories = + categoriesTaxonomy && + select( editorStore ).getEditedPostAttribute( + categoriesTaxonomy.rest_base + ); + + // This boolean should return true if everything is loaded + // ( categoriesTaxonomy, defaultCategory ) + // and the post has not been assigned a category different than "uncategorized". + return ( + !! categoriesTaxonomy && + !! defaultCategory && + postTypeSupportsCategories && + ( categories?.length === 0 || + ( categories?.length === 1 && + defaultCategory.id === categories[ 0 ] ) ) + ); + }, [] ); + const [ shouldShowPanel, setShouldShowPanel ] = useState( false ); + useEffect( () => { + // We use state to avoid hiding the panel if the user edits the categories + // and adds one within the panel itself (while visible). + if ( hasNoCategory ) { + setShouldShowPanel( true ); + } + }, [ hasNoCategory ] ); + + if ( ! shouldShowPanel ) { + return null; + } + + const panelBodyTitle = [ + __( 'Suggestion:' ), + + { __( 'Assign a category' ) } + , + ]; + + return ( + +

        + { __( + 'Categories provide a helpful way to group related posts together and to quickly tell readers what a post is about.' + ) } +

        + +
        + ); +} + +export default MaybeCategoryPanel; diff --git a/packages/editor/src/components/post-publish-panel/prepublish.js b/packages/editor/src/components/post-publish-panel/prepublish.js index c2c3c2dbd54eee..52fe35fefa7cc3 100644 --- a/packages/editor/src/components/post-publish-panel/prepublish.js +++ b/packages/editor/src/components/post-publish-panel/prepublish.js @@ -24,6 +24,7 @@ import PostScheduleLabel from '../post-schedule/label'; import MaybeTagsPanel from './maybe-tags-panel'; import MaybePostFormatPanel from './maybe-post-format-panel'; import { store as editorStore } from '../../store'; +import MaybeCategoryPanel from './maybe-category-panel'; function PostPublishPanelPrepublish( { children } ) { const { @@ -145,6 +146,7 @@ function PostPublishPanelPrepublish( { children } ) { ) } + { children }
      ); From c9425ae1236c0eefe9ba37c94e82aab8ca373338 Mon Sep 17 00:00:00 2001 From: Alex Stine Date: Fri, 7 Jan 2022 05:57:24 -0500 Subject: [PATCH 014/149] Accessibility improvements for Block Inserter (#37357) Co-authored-by: Riad Benguella --- .../secondary-sidebar/inserter-sidebar.js | 23 +++++++++++--- .../components/secondary-sidebar/style.scss | 4 --- .../secondary-sidebar/inserter-sidebar.js | 23 +++++++++++--- .../components/secondary-sidebar/style.scss | 4 --- .../src/components/layout/style.scss | 4 --- .../secondary-sidebar/inserter-sidebar.js | 31 ++++++++++++++----- 6 files changed, 62 insertions(+), 27 deletions(-) diff --git a/packages/edit-post/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-post/src/components/secondary-sidebar/inserter-sidebar.js index c0f4e79dffddf0..30698c838bf83a 100644 --- a/packages/edit-post/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-post/src/components/secondary-sidebar/inserter-sidebar.js @@ -2,13 +2,15 @@ * WordPress dependencies */ import { useDispatch, useSelect } from '@wordpress/data'; -import { Button } from '@wordpress/components'; +import { Button, VisuallyHidden } from '@wordpress/components'; import { __experimentalLibrary as Library } from '@wordpress/block-editor'; import { close } from '@wordpress/icons'; import { useViewportMatch, __experimentalUseDialog as useDialog, } from '@wordpress/compose'; +import { __ } from '@wordpress/i18n'; +import { useEffect, useRef } from '@wordpress/element'; /** * Internal dependencies @@ -28,23 +30,36 @@ export default function InserterSidebar() { const { setIsInserterOpened } = useDispatch( editPostStore ); const isMobileViewport = useViewportMatch( 'medium', '<' ); + const TagName = ! isMobileViewport ? VisuallyHidden : 'div'; const [ inserterDialogRef, inserterDialogProps ] = useDialog( { onClose: () => setIsInserterOpened( false ), + focusOnMount: null, } ); + const inserterContentRef = useRef(); + useEffect( () => { + inserterContentRef.current + .querySelector( '.block-editor-inserter__search input' ) + .focus(); + }, [] ); + return (
      -
      +
      -
      + +
      setIsInserterOpened( false ), + focusOnMount: null, } ); + const inserterContentRef = useRef(); + useEffect( () => { + inserterContentRef.current + .querySelector( '.block-editor-inserter__search input' ) + .focus(); + }, [] ); + return (
      -
      +
      -
      + +
      { - return () => setIsInserterOpened( false ); + return setIsInserterOpened( false ); }, [ setIsInserterOpened ] ); + const TagName = ! isMobileViewport ? VisuallyHidden : 'div'; const [ inserterDialogRef, inserterDialogProps ] = useDialog( { onClose: closeInserter, + focusOnMount: null, } ); + const inserterContentRef = useRef(); + useEffect( () => { + inserterContentRef.current + .querySelector( '.block-editor-inserter__search input' ) + .focus(); + }, [] ); + return (
      -
      -
      -
      + + - ); -}; - -let clipboardValue; - -const originalClipboard = global.navigator.clipboard; -const mockClipboard = { - writeText: jest.fn().mockImplementation( ( text ) => { - return new Promise( ( resolve ) => { - clipboardValue = text; - resolve(); - } ); - } ), -}; - -global.navigator.clipboard = mockClipboard; - -describe( 'useCopyOnClick', () => { - beforeEach( () => { - clipboardValue = undefined; - } ); - - afterAll( () => { - global.navigator.clipboard = originalClipboard; - } ); - - it( 'should copy the text to the clipboard and display a warning notice', async () => { - const textToBeCopied = 'mango'; - render( ); - - expect( console ).toHaveWarned(); - - const triggerButton = screen.getByText( 'Click to copy' ); - fireEvent.click( triggerButton ); - - await waitFor( () => - expect( clipboardValue ).toEqual( textToBeCopied ) - ); - - // Check that the displayed text changes as a way of testing - // the `hasCopied` logic - expect( screen.getByText( 'Copied' ) ).toBeInTheDocument(); - await waitFor( () => - expect( screen.getByText( 'Click to copy' ) ).toBeInTheDocument() - ); - } ); -} ); diff --git a/packages/compose/src/hooks/use-copy-to-clipboard/index.js b/packages/compose/src/hooks/use-copy-to-clipboard/index.js index 73105982bd9d28..a7c40199f16d72 100644 --- a/packages/compose/src/hooks/use-copy-to-clipboard/index.js +++ b/packages/compose/src/hooks/use-copy-to-clipboard/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import Clipboard from 'clipboard'; + /** * WordPress dependencies */ @@ -34,29 +39,32 @@ export default function useCopyToClipboard( text, onSuccess ) { // fresh when the callback is called. const textRef = useUpdatedRef( text ); const onSuccessRef = useUpdatedRef( onSuccess ); - return useRefEffect( ( trigger ) => { - if ( ! trigger ) { - return; - } - - const copyTextToClipboard = () => { - const currentWindow = trigger.ownerDocument.defaultView || window; - const textToCopy = - typeof textRef.current === 'function' + return useRefEffect( ( node ) => { + // Clipboard listens to click events. + const clipboard = new Clipboard( node, { + text() { + return typeof textRef.current === 'function' ? textRef.current() : textRef.current || ''; + }, + } ); - currentWindow?.navigator?.clipboard - ?.writeText( textToCopy ) - .then( () => { - onSuccessRef?.current?.(); - } ); - }; + clipboard.on( 'success', ( { clearSelection } ) => { + // Clearing selection will move focus back to the triggering + // button, ensuring that it is not reset to the body, and + // further that it is kept within the rendered node. + clearSelection(); + // Handle ClipboardJS focus bug, see + // https://github.com/zenorocha/clipboard.js/issues/680 + node.focus(); - trigger.addEventListener( 'click', copyTextToClipboard ); + if ( onSuccessRef.current ) { + onSuccessRef.current(); + } + } ); return () => { - trigger.removeEventListener( 'click', copyTextToClipboard ); + clipboard.destroy(); }; }, [] ); } diff --git a/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js b/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js deleted file mode 100644 index 34a4a9160dba66..00000000000000 --- a/packages/compose/src/hooks/use-copy-to-clipboard/test/index.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * External dependencies - */ -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; - -/** - * Internal dependencies - */ -import useCopyToClipboard from '../'; - -const ExampleComponent = ( { onSuccess, text, ...props } ) => { - const ref = useCopyToClipboard( text, onSuccess ); - - return ( - - ); -}; - -let clipboardValue; - -const originalClipboard = global.navigator.clipboard; -const mockClipboard = { - writeText: jest.fn().mockImplementation( ( text ) => { - return new Promise( ( resolve ) => { - clipboardValue = text; - resolve(); - } ); - } ), -}; - -global.navigator.clipboard = mockClipboard; - -describe( 'useCopyToClipboard', () => { - beforeEach( () => { - clipboardValue = undefined; - } ); - - afterAll( () => { - global.navigator.clipboard = originalClipboard; - } ); - - it( 'should copy the text to the clipboard', async () => { - const successCallback = jest.fn(); - const textToBeCopied = 'mango'; - render( - - ); - - const triggerButton = screen.getByText( 'Click to copy' ); - fireEvent.click( triggerButton ); - - await waitFor( () => expect( successCallback ).toHaveBeenCalled() ); - expect( clipboardValue ).toEqual( textToBeCopied ); - } ); -} ); From 9f9498938b74a7f10b755c575b8edfe5f073a2d8 Mon Sep 17 00:00:00 2001 From: Ryan Welcher Date: Fri, 7 Jan 2022 11:47:30 -0500 Subject: [PATCH 020/149] Add checkbox for updating schemas if appropriate. (#37780) --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 45bad9c0612a1a..31c4cfec6ab490 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -26,3 +26,4 @@ - [ ] My code has proper inline documentation. - [ ] I've included developer documentation if appropriate. - [ ] I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all `*.native.js` files for terms that need renaming or removal). +- [] I've updated related schemas if appropriate.
      - +
      ``` diff --git a/docs/how-to-guides/themes/create-block-theme.md b/docs/how-to-guides/themes/create-block-theme.md index 8ba9de733a1442..2753f759abc44f 100644 --- a/docs/how-to-guides/themes/create-block-theme.md +++ b/docs/how-to-guides/themes/create-block-theme.md @@ -1,13 +1,10 @@ # Create a block theme -The purpose of this tutorial is to show how to create a block theme and help theme developers transition to full site editing. -It is recommended that you first read the [block theme overview](/docs/how-to-guides/themes/block-theme-overview.md). +The purpose of this tutorial is to show how to create a block theme and help theme developers transition to full site editing. It is recommended that you first read the [block theme overview](/docs/how-to-guides/themes/block-theme-overview.md). You will learn about the required files, how to combine templates and template parts, how to add presets for global styles, and how to add blocks and export the templates in the site editor. -Full site editing is an experimental feature, and the workflow in this tutorial is likely to change. - -This tutorial is up to date with Gutenberg version 11.0.0. +Block themes require WordPress 5.9. To use block themes in earlier versions of WordPress requires the Gutenberg plugin version 11.0 or newer. ## Table of Contents @@ -32,6 +29,7 @@ The theme may optionally include a `functions.php` file and a [theme.json file]( Template parts are optional. If they are included they must be placed inside a `parts` folder. File structure: + ``` theme |__ style.css @@ -139,15 +137,15 @@ theme ``` ## Creating the templates and template parts + Before continuing, install and activate your theme. There are several ways to create templates and template parts: -- Manually, by creating HTML files containing block markup. -- Using the site editor. -- Using the template editing mode in the block editor. +- Manually, by creating HTML files containing block markup. +- Using the site editor. +- Using the template editing mode in the block editor. -The fourth way is temporary and involves going to the Appearance menu > Templates, and is not recommended because of its limitations. ### Manual template creation @@ -197,7 +195,9 @@ All block attributes are placed inside these curly brackets. If you wanted the p ```html -

      Proudly powered by WordPress.

      +

      + Proudly powered by WordPress. +

      ``` @@ -238,15 +238,14 @@ Edit and save the template in the same way as in the site editor. Templates and template parts that have been created or edited in the site editor or template editing mode are saved to the database as custom post types. To export them as theme files, follow these steps: -- In the site editor, open the **More tools and options** menu. -- Select the **Export** option to download a zip file containing the files. Unpack the files. -- Copy the updated `index.html` file from `theme/templates/` to your theme's `templates` folder. -- Copy template part one and two from `theme/parts/` to your theme's `parts` folder. -- Rename the template parts to `header.html` and `footer.html`, respectively. -- Open `index.html` and update the template part slugs in the block markup. +- In the site editor, open the **More tools and options** menu. +- Select the **Export** option to download a zip file containing the files. Unpack the files. +- Copy the updated `index.html` file from `theme/templates/` to your theme's `templates` folder. +- Copy template parts from `theme/parts/` to your theme's `parts` folder. -Saved templates have precedence over theme files. To use the updated theme files, go to **Appearance > Templates** and -**Appearance > Template parts** and delete the saved templates. +Saved templates have precedence over theme files. + +To learn more about the Site Editor, see the [support article](https://wordpress.org/support/article/site-editor/) ### Additional templates @@ -287,11 +286,13 @@ Example markup: ```html -
      - - - -
      +
      + + + + + +
      ``` @@ -299,19 +300,20 @@ The query pagination block can only be used inside the query loop. Place it insi ```html -
      - - - - - - -
      - - -
      - - +
      + + + + + + + +
      + + + +
      +
      ``` @@ -341,14 +343,14 @@ Add a group block that will work as a container for your post: Add your preferred blocks inside the group block. Some new blocks that are available are: -- Post content: `` -- Post title: `` -- Post author: `` -- Post date: `` -- Post featured image: `` -- Post tags: `` -- Post categories: `` -- Next and previous post: `` +- Post content: `` +- Post title: `` +- Post author: `` +- Post date: `` +- Post featured image: `` +- Post tags: `` +- Post categories: `` +- Next and previous post: `` Save the HTML file, or save and export the post template if you are working in the site editor. @@ -382,34 +384,29 @@ Create a file called `theme.json` and save it inside the main theme folder. Start by adding two curly brackets to the file: ```json -{ - -} +{} ``` -Add the version number for the theme.json format. For Gutenberg 10.6, the version number is 1: +Add the version number for the theme.json format. For WordPress 5.9, the version number is 2: ```json { - "version": 1, + "version": 2 } ``` Next, add three main sections: -- Settings -Where you will enable features and create presets for styles. -- Styles -Where you apply styles to the website, elements, and blocks. -- templateParts -For assigning template part files to template areas. +- Settings -Where you will enable features and create presets for styles. +- Styles -Where you apply styles to the website, elements, and blocks. +- templateParts -For assigning template part files to template areas. ```json { - "version": 1, - "settings": { - }, - "styles": { - }, - "templateParts": [ - ] + "version": 2, + "settings": {}, + "styles": {}, + "templateParts": [] } ``` @@ -421,8 +418,8 @@ For a list of features that can be enabled or disabled, see the [documentation f There are two different ways that a block can support a feature: -- By displaying a control in the block settings sidebar. -- By allowing defaults to be set using `theme.json`. +- By displaying a control in the block settings sidebar. +- By allowing defaults to be set using `theme.json`.
      It is not possible to add controls to a block that does not support them by using theme.json. @@ -436,7 +433,7 @@ To enable border styles, add a `border` object under `settings` with the followi ```json { - "version": 1, + "version": 2, "settings": { "border": { "color": true, @@ -452,7 +449,7 @@ To enable link colors, add a `color` setting and set `link` to true: ```json { - "version": 1, + "version": 2, "settings": { "border": { "color": true, @@ -461,7 +458,7 @@ To enable link colors, add a `color` setting and set `link` to true: "width": true }, "color": { - "link": true, + "link": true } } } @@ -471,7 +468,7 @@ To enable padding, margin and custom spacing units, include a setting for spacin ```json { - "version": 1, + "version": 2, "settings": { "border": { "color": true, @@ -497,7 +494,7 @@ If you want to disable gradients, which are enabled by default, set `gradient` t ```json { - "version": 1, + "version": 2, "settings": { "border": { "color": true, @@ -514,8 +511,6 @@ If you want to disable gradients, which are enabled by default, set `gradient` t } ``` - - ### Content width and theme support for wide and full-width blocks The `layout` setting enables width settings for group blocks and template parts @@ -526,15 +521,15 @@ block alignments or widths. You can also set more precise widths to blocks insid The keys used by `layout` are: -- `contentSize` Default width for the blocks. -- `wideSize` Wide width. +- `contentSize` Default width for the blocks. +- `wideSize` Wide width. The example uses pixels, but you can use any valid CSS value and unit. (The code example is truncated to illustrate where to add the option.) ```json { - "version": 1, + "version": 2, "settings": { ... "layout": { @@ -552,16 +547,16 @@ You can add multiple color palettes: a default palette for all blocks, and color The keys used by `palette` are: -- `slug` A unique identifier for the color. -- `color` The hex color value. -- `name` The visible name in the editor. Optional. +- `slug` A unique identifier for the color. +- `color` The hex color value. +- `name` The visible name in the editor. Optional. Multiple colors are added as an array using square brackets: `[]`. Add a default color palette inside `settings`, under `color`: ```json { - "version": 1, + "version": 2, "settings": { ... "color": { @@ -636,9 +631,9 @@ To add custom font sizes, create a new section called `typography` under `settin The keys used by `fontSizes` are: -- `slug` A unique identifier for the size. -- `size` The size value. This can be unitless or use any valid CSS value. -- `name` The visible name in the editor. +- `slug` A unique identifier for the size. +- `size` The size value. This can be unitless or use any valid CSS value. +- `name` The visible name in the editor. ```json "typography": { @@ -783,9 +778,7 @@ Since the theme has custom padding enabled, you can add `padding` within the `sp ### Template parts In the templeParts section, assign the two template parts that you created to their template areas. -Add two keys: --`name`, the file name of the template part file without the file extension, --`area`, the name of the template area. +Add three keys: -`name`, the file name of the template part file without the file extension, -`area`, the name of the template area, and `title` the visible name in the editor. There are three template areas to choose from: Header, footer, and general. @@ -793,11 +786,13 @@ There are three template areas to choose from: Header, footer, and general. "templateParts": [ { "name": "header", - "area": "header" + "area": "header", + "title": "Header" }, { "name": "footer", - "area": "footer" + "area": "footer", + "title": "Footer" } ] ``` @@ -848,8 +843,6 @@ The key is `postTypes`, followed by the name of the post type: ## Example themes You can find a basic starter theme called "emptytheme" and other example themes -on the [Experimental themes GitHub repository](https://github.com/WordPress/theme-experiments). -When using a theme as reference, take note of which Gutenberg version the theme is built for, -because the experimental features are updated frequently. +on the [Theme Experiments GitHub repository](https://github.com/WordPress/theme-experiments). When using a theme as reference, take note of which Gutenberg version the theme is built for, because the experimental features are updated frequently. The theme directory lists block themes under the tag [full site editing](https://wordpress.org/themes/tags/full-site-editing/). From a585bb7286d5f00dfb9a73075cdee0edcf46bd04 Mon Sep 17 00:00:00 2001 From: Matthew Kevins Date: Mon, 10 Jan 2022 11:08:10 +1000 Subject: [PATCH 024/149] Mobile Release v1.69.0 (#37767) * Release script: Update react-native-editor version to 1.69.0 * Release script: Update with changes from 'npm run core preios' * Update native editor changelog for v1.69.0 --- packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/CHANGELOG.md | 2 ++ packages/react-native-editor/ios/Podfile.lock | 8 ++++---- packages/react-native-editor/package.json | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index 8dca9b07b2da4a..49b7783b15a6c0 100644 --- a/packages/react-native-aztec/package.json +++ b/packages/react-native-aztec/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-aztec", - "version": "1.68.0", + "version": "1.69.0", "description": "Aztec view for react-native.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json index d04b27e4a8903a..e0dafbfd6a4faf 100644 --- a/packages/react-native-bridge/package.json +++ b/packages/react-native-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-bridge", - "version": "1.68.0", + "version": "1.69.0", "description": "Native bridge library used to integrate the block editor into a native App.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 50e75b82a44af2..370ab02d93ddfc 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -10,6 +10,8 @@ For each user feature we should also add a importance categorization label to i --> ## Unreleased + +## 1.69.0 - [*] Give multi-line block names central alignment in inserter [#37185] - [**] Fix empty line apperaing when splitting heading blocks on Android 12 [#37279] - [**] Fix missing translations by refactoring the editor initialization code [#37073] diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index bf06bd90b2ee18..78a92ecaf423d4 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - ReactCommon/turbomodule/core (= 0.66.2) - fmt (6.2.1) - glog (0.3.5) - - Gutenberg (1.68.0): + - Gutenberg (1.69.0): - React-Core (= 0.66.2) - React-CoreModules (= 0.66.2) - React-RCTImage (= 0.66.2) @@ -312,7 +312,7 @@ PODS: - React-Core - RNSVG (9.13.7-wp-2): - React-Core - - RNTAztecView (1.68.0): + - RNTAztecView (1.69.0): - React-Core - WordPress-Aztec-iOS (~> 1.19.7) - WordPress-Aztec-iOS (1.19.7) @@ -478,7 +478,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: 18438b1c04ce502ed681cd19db3f4508964c082a fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 5337263514dd6f09803962437687240c5dc39aa4 - Gutenberg: 5db4fee03946ebc20f35a38f99cab2c42a8d753d + Gutenberg: aa24b9f5cc3c8893b7c8eac029ebb8c6ffcfcfe6 RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9 RCTRequired: 5e9e85f48da8dd447f5834ce14c6799ea8c7f41a RCTTypeSafety: aba333d04d88d1f954e93666a08d7ae57a87ab30 @@ -517,7 +517,7 @@ SPEC CHECKSUMS: RNReanimated: 7d8459391b2f3e1dc6dea919307db4adf4c1d254 RNScreens: ec0e85d1babdd61d7ec78c98072d9e6b62d96ff6 RNSVG: b3b9c40381636e5116894398d72a830be15b7258 - RNTAztecView: e502408a3c3cb98f513346a179febb91bcd3e528 + RNTAztecView: e291f5ff7161f1640b15bce2907e9cd89e17fbf9 WordPress-Aztec-iOS: 144f124148079084860368dfd27cb96e0952853e Yoga: 9a08effa851c1d8cc1647691895540bc168ea65f diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 4db2f36958ee17..7b521633996df8 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-editor", - "version": "1.68.0", + "version": "1.69.0", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From d9b406bdb21fe13eac3aa93ce9d9004241531425 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Mon, 10 Jan 2022 07:18:16 +0000 Subject: [PATCH 025/149] BaseControl: Fix VisualLabel styles (#37747) * BaseControl: Fix VisualLabel styles * Update snapshots * Reuse styles * Add changelong entry --- .../test/__snapshots__/control.js.snap | 13 ++++-- packages/components/CHANGELOG.md | 4 ++ packages/components/src/base-control/index.js | 13 +++++- .../styles/base-control-styles.js | 11 ++++- .../test/__snapshots__/index.js.snap | 45 ++++++++++--------- 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap index 61d1f210199a60..488c01e33f1c17 100644 --- a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap +++ b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap @@ -40,6 +40,11 @@ exports[`ColorPaletteControl matches the snapshot 1`] = ` } .emotion-6 { + display: inline-block; + margin-bottom: calc(4px * 2); +} + +.emotion-8 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -56,11 +61,11 @@ exports[`ColorPaletteControl matches the snapshot 1`] = ` justify-content: space-between; } -.emotion-6>*+*:not( marquee ) { +.emotion-8>*+*:not( marquee ) { margin-top: calc(4px * 3); } -.emotion-6>* { +.emotion-8>* { min-height: 0; } @@ -81,14 +86,14 @@ exports[`ColorPaletteControl matches the snapshot 1`] = ` className="block-editor-color-gradient-control__color-indicator" > Test Color
      diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 65c089c899b634..876c46b448ce33 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fix + +- Add missing styles to the `BaseControl.VisualLabel` component. ([#37747](https://github.com/WordPress/gutenberg/pull/37747)) + ## 19.2.0 (2022-01-04) ### Experimental diff --git a/packages/components/src/base-control/index.js b/packages/components/src/base-control/index.js index 7f70ce5eea9fe5..86746d6174fd61 100644 --- a/packages/components/src/base-control/index.js +++ b/packages/components/src/base-control/index.js @@ -12,6 +12,7 @@ import { StyledField, StyledLabel, StyledHelp, + StyledVisualLabel, } from './styles/base-control-styles'; /** @@ -95,8 +96,16 @@ function BaseControl( { * @return {JSX.Element} Element */ BaseControl.VisualLabel = ( { className, children } ) => { - className = classnames( 'components-base-control__label', className ); - return { children }; + return ( + + { children } + + ); }; export default BaseControl; diff --git a/packages/components/src/base-control/styles/base-control-styles.js b/packages/components/src/base-control/styles/base-control-styles.js index e47410d44d260d..9255c818583da1 100644 --- a/packages/components/src/base-control/styles/base-control-styles.js +++ b/packages/components/src/base-control/styles/base-control-styles.js @@ -2,6 +2,7 @@ * External dependencies */ import styled from '@emotion/styled'; +import { css } from '@emotion/react'; /** * Internal dependencies @@ -22,13 +23,21 @@ export const StyledField = styled.div` } `; -export const StyledLabel = styled.label` +const labelStyles = css` display: inline-block; margin-bottom: ${ space( 2 ) }; `; +export const StyledLabel = styled.label` + ${ labelStyles } +`; + export const StyledHelp = styled.p` font-size: ${ font( 'helpText.fontSize' ) }; font-style: normal; color: ${ COLORS.mediumGray.text }; `; + +export const StyledVisualLabel = styled.span` + ${ labelStyles } +`; diff --git a/packages/components/src/toggle-group-control/test/__snapshots__/index.js.snap b/packages/components/src/toggle-group-control/test/__snapshots__/index.js.snap index 679369cb776cd4..8be9ab4663236b 100644 --- a/packages/components/src/toggle-group-control/test/__snapshots__/index.js.snap +++ b/packages/components/src/toggle-group-control/test/__snapshots__/index.js.snap @@ -15,6 +15,11 @@ exports[`ToggleGroupControl should render correctly 1`] = ` } .emotion-4 { + display: inline-block; + margin-bottom: calc(4px * 2); +} + +.emotion-6 { background: #fff; border: 1px solid; border-color: #757575; @@ -32,23 +37,23 @@ exports[`ToggleGroupControl should render correctly 1`] = ` } @media ( prefers-reduced-motion: reduce ) { - .emotion-4 { + .emotion-6 { transition-duration: 0ms; } } -.emotion-4:hover { +.emotion-6:hover { border-color: #757575; } -.emotion-4:focus-within { +.emotion-6:focus-within { border-color: var( --wp-admin-theme-color-darker-10, #007cba); box-shadow: 0 0 0 0.5px var( --wp-admin-theme-color, #00669b); outline: none; z-index: 1; } -.emotion-6 { +.emotion-8 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -61,7 +66,7 @@ exports[`ToggleGroupControl should render correctly 1`] = ` flex: 1; } -.emotion-8 { +.emotion-10 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -100,20 +105,20 @@ exports[`ToggleGroupControl should render correctly 1`] = ` } @media ( prefers-reduced-motion: reduce ) { - .emotion-8 { + .emotion-10 { transition-duration: 0ms; } } -.emotion-8::-moz-focus-inner { +.emotion-10::-moz-focus-inner { border: 0; } -.emotion-8:active { +.emotion-10:active { background: #fff; } -.emotion-9 { +.emotion-11 { font-size: 13px; line-height: 1; position: absolute; @@ -125,7 +130,7 @@ exports[`ToggleGroupControl should render correctly 1`] = ` transform: translate( -50%, -50% ); } -.emotion-11 { +.emotion-13 { font-size: 13px; font-weight: bold; height: 0; @@ -141,14 +146,14 @@ exports[`ToggleGroupControl should render correctly 1`] = ` >
      Test Toggle Group Control
      - ); + edit: function () { + return

      Hello world (from the editor)

      ; }, - save() { - const blockProps = useBlockProps.save( { style: blockStyle } ); - - return ( -
      - Hello World (from the frontend). -
      - ); + save: function () { + return

      Hola mundo (from the frontend)

      ; }, } ); ``` {% Plain %} +Add the following to `block.js` + ```js -( function ( blocks, element, blockEditor ) { +( function ( blocks, element ) { var el = element.createElement; - var useBlockProps = blockEditor.useBlockProps; - - var blockStyle = { - backgroundColor: '#900', - color: '#fff', - padding: '20px', - }; blocks.registerBlockType( 'gutenberg-examples/example-01-basic', { - apiVersion: 2, - title: 'Example: Basic', - icon: 'universal-access-alt', - category: 'design', - example: {}, edit: function () { - var blockProps = useBlockProps( { style: blockStyle } ); - return el( - 'p', - blockProps, - 'Hello World (from the editor).' - ); + return el( 'p', {}, 'Hello World (from the editor).' ); }, save: function () { - var blockProps = useBlockProps.save( { style: blockStyle } ); - return el( - 'p', - blockProps, - 'Hello World (from the frontend).' - ); + return el( 'p', {}, 'Hola mundo (from the frontend).' ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.wp.element ); ``` {% end %} -_By now you should be able to see `Hello World (from the editor).` in the admin side and `Hello World (from the frontend).` on the frontend side._ +NOTE: If using the JSX version, you need to run `npm run build` and it will create the JavaScript file that is loaded in the editor at `build/index.js` + +### Step 4: Confirm + +Open your editor and try adding your new block. It will show in the inserter using the `title`. +When inserted you will see the `Hello World (from the editor)` message. + +When you save the post and view it published, you will see the `Hola mundo (from the frontend)` message. + +**Troubleshooting** - If you run into any issues, here are a few things to try: + +- Check the filenames are correct and loading properly, +- Check the developer console in your browser for errors, +- If using JSX remember to build after each change + +## Conclusion + +This shows the most basic static block. The [gutenberg-examples](https://github.com/WordPress/gutenberg-examples) repository has complete examples for both. + +- [Basic example with JSX build](https://github.com/WordPress/gutenberg-examples/tree/trunk/01-basic-esnext) + +- [Basic example plain JavaScript](https://github.com/WordPress/gutenberg-examples/tree/trunk/01-basic), + +**NOTE:** The examples include a more complete block setup with translation features included, it is recommended to follow those examples for a production block. The internationalization features were left out of this guide for simplicity and focusing on the very basics of a block. + +### Additional + +A couple of things to note when creating your blocks: + +- A block name must be prefixed with a namespace specific to your plugin. This helps prevent conflicts when more than one plugin registers a block with the same name. In this example, the namespace is `gutenberg-examples`. + +- Block names _must_ include only lowercase alphanumeric characters or dashes and start with a letter. Example: `my-plugin/my-custom-block`. -Once a block is registered, you should immediately see that it becomes available as an option in the editor inserter dialog, using values from `title`, `icon`, and `category` to organize its display. You can choose an icon from any included in the built-in [Dashicons icon set](https://developer.wordpress.org/resource/dashicons/), or provide a [custom svg element](/docs/reference-guides/block-api/block-registration.md#icon-optional). +### Resources -A block name must be prefixed with a namespace specific to your plugin. This helps prevent conflicts when more than one plugin registers a block with the same name. In this example, the namespace is `gutenberg-examples`. +- block.json [metadata reference](/docs/reference-guides/block-api/block-metadata.md) documentation -Block names _must_ include only lowercase alphanumeric characters or dashes and start with a letter. Example: `my-plugin/my-custom-block`. +- Block [edit and save function reference](/docs/reference-guides/block-api/block-edit-save.md) -The `edit` and `save` functions describe the structure of your block in the context of the editor and the saved content respectively. While the difference is not obvious in this simple example, in the following sections we'll explore how these are used to enable customization of the block in the editor preview. +- [Dashicons icon set](https://developer.wordpress.org/resource/dashicons/) diff --git a/docs/manifest.json b/docs/manifest.json index 09e018c1d9af35..8a39dea5fcdb46 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -114,7 +114,7 @@ "parent": "how-to-guides" }, { - "title": "Writing Your First Block Type", + "title": "Create a basic block", "slug": "writing-your-first-block-type", "markdown_source": "../docs/how-to-guides/block-tutorial/writing-your-first-block-type.md", "parent": "block-tutorial" diff --git a/packages/create-block-tutorial-template/CHANGELOG.md b/packages/create-block-tutorial-template/CHANGELOG.md index 41ee24887857f0..e19bda8105ec9f 100644 --- a/packages/create-block-tutorial-template/CHANGELOG.md +++ b/packages/create-block-tutorial-template/CHANGELOG.md @@ -5,6 +5,7 @@ ### Enhancement - Speed up scaffolding process by omitting WordPress dependencies in the template ([#37639](https://github.com/WordPress/gutenberg/pull/37639)). +- Update link to block registration reference ([#37674](https://github.com/WordPress/gutenberg/pull/37674)) ## 1.3.0 (2021-07-21) diff --git a/packages/create-block-tutorial-template/templates/$slug.php.mustache b/packages/create-block-tutorial-template/templates/$slug.php.mustache index 2de3d4dd0e9afb..3194175ebef618 100644 --- a/packages/create-block-tutorial-template/templates/$slug.php.mustache +++ b/packages/create-block-tutorial-template/templates/$slug.php.mustache @@ -26,7 +26,7 @@ * Behind the scenes, it registers also all assets so they can be enqueued * through the block editor in the corresponding context. * - * @see https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/ + * @see https://developer.wordpress.org/reference/functions/register_block_type/ */ function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() { register_block_type( __DIR__ ); diff --git a/packages/create-block/CHANGELOG.md b/packages/create-block/CHANGELOG.md index e29da97599dd0c..fc39fdd09b5e37 100644 --- a/packages/create-block/CHANGELOG.md +++ b/packages/create-block/CHANGELOG.md @@ -9,6 +9,7 @@ ### Enhancement - Speed up scaffolding process by omitting WordPress dependencies in the template ([#37639](https://github.com/WordPress/gutenberg/pull/37639)). +- Update link to block registration reference ([#37674](https://github.com/WordPress/gutenberg/pull/37674)) ### Internal diff --git a/packages/create-block/lib/templates/esnext/$slug.php.mustache b/packages/create-block/lib/templates/esnext/$slug.php.mustache index 2de3d4dd0e9afb..3194175ebef618 100644 --- a/packages/create-block/lib/templates/esnext/$slug.php.mustache +++ b/packages/create-block/lib/templates/esnext/$slug.php.mustache @@ -26,7 +26,7 @@ * Behind the scenes, it registers also all assets so they can be enqueued * through the block editor in the corresponding context. * - * @see https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/ + * @see https://developer.wordpress.org/reference/functions/register_block_type/ */ function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() { register_block_type( __DIR__ ); From 8cc38b91a5d58b841ae6e09307396427840a215b Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 10 Jan 2022 15:56:06 +0100 Subject: [PATCH 033/149] Try: Polish post takeover modal. (#37821) --- .../src/components/post-locked-modal/index.js | 24 ++++++++--------- .../components/post-locked-modal/style.scss | 27 +++++-------------- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/packages/editor/src/components/post-locked-modal/index.js b/packages/editor/src/components/post-locked-modal/index.js index b6e25e502fe50a..bf9bd8bf91540d 100644 --- a/packages/editor/src/components/post-locked-modal/index.js +++ b/packages/editor/src/components/post-locked-modal/index.js @@ -158,13 +158,13 @@ export default function PostLockedModal() { const allPostsUrl = getWPAdminURL( 'edit.php', { post_type: get( postType, [ 'slug' ] ), } ); - const allPostsLabel = __( 'Exit the Editor' ); + const allPostsLabel = __( 'Exit editor' ); return ( -
      +

      { userDisplayName ? sprintf( /* translators: %s: user's display name */ @@ -193,7 +193,7 @@ export default function PostLockedModal() { : __( 'Another user now has editing control of this post. Don’t worry, your changes up to this moment have been saved.' ) } -

      +

      - +
      diff --git a/packages/editor/src/components/post-locked-modal/style.scss b/packages/editor/src/components/post-locked-modal/style.scss index 1de50edcd63f48..d1142b2290826b 100644 --- a/packages/editor/src/components/post-locked-modal/style.scss +++ b/packages/editor/src/components/post-locked-modal/style.scss @@ -1,29 +1,16 @@ .editor-post-locked-modal { - height: auto; - padding-right: 10px; - padding-left: 10px; - padding-top: 10px; - max-width: 480px; - - .components-modal__header { - height: 36px; - } - - .components-modal__content { - height: auto; - } + max-width: 400px; } .editor-post-locked-modal__buttons { - margin-top: 10px; - - .components-button { - margin-right: 5px; - } + margin-top: $grid-unit-30; + display: flex; + justify-content: flex-end; + gap: $grid-unit-10; } .editor-post-locked-modal__avatar { float: left; - margin: 5px; - margin-right: 15px; + margin: $grid-unit-10; + margin-right: $grid-unit-15; } From b2a27d04fa402bd715b4bc3e0c6c20ece8c5e105 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 10 Jan 2022 16:22:24 +0100 Subject: [PATCH 034/149] Fix overlay menu errant focus style on scrim. (#37824) --- packages/block-library/src/navigation/style.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/block-library/src/navigation/style.scss b/packages/block-library/src/navigation/style.scss index a0f2bf68caaa53..961762f861442b 100644 --- a/packages/block-library/src/navigation/style.scss +++ b/packages/block-library/src/navigation/style.scss @@ -622,6 +622,14 @@ button.wp-block-navigation-item__content { // The menu adds wrapping containers. .wp-block-navigation__responsive-close { width: 100%; + + // This element is not keyboard accessible, and is focusable only using the mouse. + // It is part of the MicroModal library that adds a scrim outside of a modal dialog that is not fullscreen, + // where clicking that scrim closes the overlay just like the close button. + // It should not have a visible focus rectangle. + &:focus { + outline: none; + } } .is-menu-open .wp-block-navigation__responsive-close, From e6412b4594ce5b70be9e14ee4b50f70db49fd510 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 10 Jan 2022 16:22:36 +0100 Subject: [PATCH 035/149] Fix issue template typo (#37825) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 31c4cfec6ab490..45b44e741e23ee 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -26,4 +26,4 @@ - [ ] My code has proper inline documentation. - [ ] I've included developer documentation if appropriate. - [ ] I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all `*.native.js` files for terms that need renaming or removal). -- [] I've updated related schemas if appropriate. From 1a199c810b29d48cf71b30d474309cb91d3583c9 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Mon, 10 Jan 2022 07:31:38 -0800 Subject: [PATCH 036/149] Add missing end to codetabs (#37827) --- .../block-tutorial/applying-styles-with-stylesheets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md index 6c71b160b2f3db..8fbbe082654835 100644 --- a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md +++ b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md @@ -96,6 +96,8 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { } )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); ``` +{% end %} + ## Method 2: Block classname The inline style works well for a small amount of CSS to apply. If you have much more than the above you will likely find that it is easier to manage with them in a separate stylesheet file. From 400d244573b1401de6c94c8db6ac118007cb3de4 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Mon, 10 Jan 2022 15:47:09 +0000 Subject: [PATCH 037/149] Update: Improve escaping on the search block (#37829) --- packages/block-library/src/search/index.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/search/index.php b/packages/block-library/src/search/index.php index cc5c276c16168d..289f9a3120c5e8 100644 --- a/packages/block-library/src/search/index.php +++ b/packages/block-library/src/search/index.php @@ -45,13 +45,13 @@ function render_block_core_search( $attributes ) { $label_markup = sprintf( '', $input_id, - empty( $attributes['label'] ) ? __( 'Search' ) : $attributes['label'] + empty( $attributes['label'] ) ? __( 'Search' ) : esc_html( $attributes['label'] ) ); if ( $show_label && ! empty( $attributes['label'] ) ) { $label_markup = sprintf( '', $input_id, - $attributes['label'] + esc_html( $attributes['label'] ) ); } @@ -60,7 +60,7 @@ function render_block_core_search( $attributes ) { $input_markup = sprintf( '', $input_id, - $input_classes, + esc_attr( $input_classes ), esc_attr( get_search_query() ), esc_attr( $attributes['placeholder'] ), $inline_styles['input'] @@ -76,7 +76,7 @@ function render_block_core_search( $attributes ) { } if ( ! $use_icon_button ) { if ( ! empty( $attributes['buttonText'] ) ) { - $button_internal_markup = $attributes['buttonText']; + $button_internal_markup = esc_html( $attributes['buttonText'] ); } } else { $button_classes .= ' has-icon'; @@ -88,7 +88,7 @@ function render_block_core_search( $attributes ) { $button_markup = sprintf( '', - $button_classes, + esc_attr( $button_classes ), $inline_styles['button'], $button_internal_markup ); @@ -97,7 +97,7 @@ function render_block_core_search( $attributes ) { $field_markup_classes = $is_button_inside ? $border_color_classes : ''; $field_markup = sprintf( '
      %s
      ', - $field_markup_classes, + esc_attr( $field_markup_classes ), $inline_styles['wrapper'], $input_markup . $button_markup ); @@ -295,9 +295,9 @@ function styles_for_block_core_search( $attributes ) { } return array( - 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', implode( ' ', $input_styles ) ) : '', - 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', implode( ' ', $button_styles ) ) : '', - 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', implode( ' ', $wrapper_styles ) ) : '', + 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $input_styles ) ) ) : '', + 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $button_styles ) ) ) : '', + 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $wrapper_styles ) ) ) : '', ); } From 0499b71650c716072aebf7ce9937381d89254cd6 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Mon, 10 Jan 2022 15:55:58 +0000 Subject: [PATCH 038/149] Bump plugin version to 12.3.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index d50095aa177c23..f9b8ca3e52cb5b 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.7 * Requires PHP: 5.6 - * Version: 12.3.0 + * Version: 12.3.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index fcc63e51a11cea..5caafa21f40152 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "12.3.0", + "version": "12.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3e3aab62117a99..ee31dc1b18a350 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "12.3.0", + "version": "12.3.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index 8c0960cad1591e..f0474ca6551d44 100644 --- a/readme.txt +++ b/readme.txt @@ -56,4 +56,4 @@ The four phases of the project are Editing, Customization, Collaboration, and Mu == Changelog == -To read the changelog for Gutenberg 12.3.0, please navigate to the release page. +To read the changelog for Gutenberg 12.3.1, please navigate to the release page. From 13cd83ccd32e93a30ea45e8876a54568bcb58e60 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Mon, 10 Jan 2022 16:14:27 +0000 Subject: [PATCH 039/149] Update Changelog for 12.3.1 --- changelog.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelog.txt b/changelog.txt index 7f6f954c7a558b..13d20e44ffc454 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,17 @@ == Changelog == += 12.3.1 = + + +### Bug Fixes + +- Restore canvas padding for classic themes (#37741). +- Site logo: Fix range control on landscape logos (#37733). +- RichText: Fix dead key input on Windows (#37777). +- Update: Improve escaping on the search block (#37829). +- Fix: Impossible to clear colors if color palettes are removed. (#37791). + + = 12.3.0 = ### Features From dd38255726d6cf4bdc46ccdd6d3a7a1cd47ffb0f Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 10 Jan 2022 13:20:23 -0500 Subject: [PATCH 040/149] Block API: Separate validation stage during block parsing (#37763) When initially parsing and loading blocks we attempt to validate their parsed attributes and apply auto-fixes when invalid. Previously this has taken place inline inside of `parseRawBlock()`. In this patch we're separating out the validation stage to aid in understanding what actions take place during the validation and to allow `parseRawBlock()` to avoid swapping the value of `parsedBlock` while running. With this patch each separate stage in the parse is stored in a separate `const` variable which enables easier debugging and comparison. Additionaly the condition for printing warnings on block invalidation have been updated to more clearly reflect the logic triggering them: that there were problems during validation that were or were not resolved through the block deprecation updating stage. --- .../parser/apply-block-deprecated-versions.js | 4 +- packages/blocks/src/api/parser/index.js | 85 ++++++++++++------- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/packages/blocks/src/api/parser/apply-block-deprecated-versions.js b/packages/blocks/src/api/parser/apply-block-deprecated-versions.js index 42d664dd668edb..7a7b2c34d2055d 100644 --- a/packages/blocks/src/api/parser/apply-block-deprecated-versions.js +++ b/packages/blocks/src/api/parser/apply-block-deprecated-versions.js @@ -70,7 +70,7 @@ export function applyBlockDeprecatedVersions( block, rawBlock, blockType ) { // Ignore the deprecation if it produces a block which is not valid. let [ isValid ] = validateBlock( migratedBlock, deprecatedBlockType ); - // If the migrated block is not valid intiailly, try the built-in fixes. + // If the migrated block is not valid initially, try the built-in fixes. if ( ! isValid ) { migratedBlock = applyBuiltInValidationFixes( migratedBlock, @@ -80,7 +80,7 @@ export function applyBlockDeprecatedVersions( block, rawBlock, blockType ) { } // An invalid block does not imply incorrect HTML but the fact block - // source information could be lost on reserialization. + // source information could be lost on re-serialization. if ( ! isValid ) { continue; } diff --git a/packages/blocks/src/api/parser/index.js b/packages/blocks/src/api/parser/index.js index 0b78d46e4a9d5b..38c21482b5a238 100644 --- a/packages/blocks/src/api/parser/index.js +++ b/packages/blocks/src/api/parser/index.js @@ -143,6 +143,38 @@ function createMissingBlockType( rawBlock ) { }; } +/** + * Validates a block and wraps with validation meta. + * + * The name here is regrettable but `validateBlock` is already taken. + * + * @param {WPBlock} unvalidatedBlock + * @param {import('../registration').WPBlockType} blockType + * @return {WPBlock} validated block, with auto-fixes if initially invalid + */ +function applyBlockValidation( unvalidatedBlock, blockType ) { + // Attempt to validate the block. + const [ isValid ] = validateBlock( unvalidatedBlock, blockType ); + + if ( isValid ) { + return { ...unvalidatedBlock, isValid, validationIssues: [] }; + } + + // If the block is invalid, attempt some built-in fixes + // like custom classNames handling. + const fixedBlock = applyBuiltInValidationFixes( + unvalidatedBlock, + blockType + ); + // Attempt to validate the block once again after the built-in fixes. + const [ isFixedValid, validationIssues ] = validateBlock( + unvalidatedBlock, + blockType + ); + + return { ...fixedBlock, isValid: isFixedValid, validationIssues }; +} + /** * Given a raw block returned by grammar parsing, returns a fully parsed block. * @@ -186,7 +218,7 @@ export function parseRawBlock( rawBlock ) { .filter( ( innerBlock ) => !! innerBlock ); // Get the fully parsed block. - let parsedBlock = createBlock( + const parsedBlock = createBlock( normalizedBlock.blockName, getBlockAttributes( blockType, @@ -197,47 +229,36 @@ export function parseRawBlock( rawBlock ) { ); parsedBlock.originalContent = normalizedBlock.innerHTML; - // Attempt to validate the block. - let [ isValid, validationIssues ] = validateBlock( parsedBlock, blockType ); - - // If the block is invalid, attempt some built-in fixes - // like custom classNames handling. - if ( ! isValid ) { - parsedBlock = applyBuiltInValidationFixes( parsedBlock, blockType ); - // Attempt to validate the block once again after the built-in fixes. - [ isValid, validationIssues ] = validateBlock( parsedBlock, blockType ); - } - parsedBlock.isValid = isValid; - parsedBlock.validationIssues = validationIssues; + const validatedBlock = applyBlockValidation( parsedBlock, blockType ); + const { validationIssues } = validatedBlock; // Run the block deprecation and migrations. // This is performed on both invalid and valid blocks because // migration using the `migrate` functions should run even // if the output is deemed valid. - parsedBlock = applyBlockDeprecatedVersions( - parsedBlock, + const updatedBlock = applyBlockDeprecatedVersions( + validatedBlock, normalizedBlock, blockType ); - if ( validationIssues && validationIssues.length > 0 ) { - if ( parsedBlock.isValid ) { - /* eslint-disable no-console */ - console.groupCollapsed( 'Updated Block: %s', blockType.name ); - console.info( - 'Block successfully updated for `%s` (%o).\n\nNew content generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', - blockType.name, - blockType, - getSaveContent( blockType, parsedBlock.attributes ), - parsedBlock.originalContent - ); - console.groupEnd(); - /* eslint-enable no-console */ - } else { - validationIssues.forEach( ( { log, args } ) => log( ...args ) ); - } + + if ( ! validatedBlock.isValid && updatedBlock.isValid ) { + /* eslint-disable no-console */ + console.groupCollapsed( 'Updated Block: %s', blockType.name ); + console.info( + 'Block successfully updated for `%s` (%o).\n\nNew content generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', + blockType.name, + blockType, + getSaveContent( blockType, updatedBlock.attributes ), + updatedBlock.originalContent + ); + console.groupEnd(); + /* eslint-enable no-console */ + } else if ( ! validatedBlock.isValid && ! updatedBlock.isValid ) { + validationIssues.forEach( ( { log, args } ) => log( ...args ) ); } - return parsedBlock; + return updatedBlock; } /** From c9a3921a111d96d7ef7ed2e6614e8d60ab2f5bc4 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 10 Jan 2022 19:58:19 +0100 Subject: [PATCH 041/149] Try: Polish code styles to properly apply border properties. (#37818) * Try: Polish code styles to properly apply border properties. * Remove box-sizing rule. --- packages/block-library/src/code/theme.scss | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/code/theme.scss b/packages/block-library/src/code/theme.scss index 7ddee2f8ad1bdf..6bf155dde65e12 100644 --- a/packages/block-library/src/code/theme.scss +++ b/packages/block-library/src/code/theme.scss @@ -1,6 +1,9 @@ +.wp-block-code { + border: 1px solid #ccc; + border-radius: 4px; +} + .wp-block-code > code { - font-family: $editor-html-font; + font-family: Menlo, Consolas, monaco, monospace; padding: 0.8em 1em; - border: 1px solid $gray-300; - border-radius: 4px; } From 55832e5ba9546de65cf6048f8cb7fbedcc28aab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Walb=C3=B8=20Johnsg=C3=A5rd?= Date: Mon, 10 Jan 2022 20:26:05 +0100 Subject: [PATCH 042/149] Link control: Translate empty link string (#36975) --- .../block-editor/src/components/link-control/link-preview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/link-control/link-preview.js b/packages/block-editor/src/components/link-control/link-preview.js index 53e9950880e933..f8d59b8e90a526 100644 --- a/packages/block-editor/src/components/link-control/link-preview.js +++ b/packages/block-editor/src/components/link-control/link-preview.js @@ -98,7 +98,7 @@ export default function LinkPreview( { ) : ( - Link is empty + { __( 'Link is empty' ) } ) } From 403a9194d4db02e02f6e0fe127669c9061beb4ee Mon Sep 17 00:00:00 2001 From: Kjell Reigstad Date: Mon, 10 Jan 2022 15:39:49 -0500 Subject: [PATCH 043/149] Tidy up comments styling. (#37709) --- .../block-library/src/post-comments/style.scss | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/post-comments/style.scss b/packages/block-library/src/post-comments/style.scss index 094e340d827f28..8adb65b61aa2c0 100644 --- a/packages/block-library/src/post-comments/style.scss +++ b/packages/block-library/src/post-comments/style.scss @@ -14,9 +14,9 @@ padding-left: 3.25em; p { - font-size: 0.875em; + font-size: 1em; line-height: 1.8; - margin: 0.36em 0 1.4em; + margin: 1em 0; } } @@ -35,6 +35,7 @@ display: block; float: left; height: 2.5em; + margin-top: 0.5em; margin-right: 0.75em; width: 2.5em; } @@ -45,12 +46,17 @@ } .comment-meta { + font-size: 0.875em; line-height: 1.5; margin-left: -3.25em; + + b { + font-weight: normal; + } } .comment-body .commentmetadata { - font-size: 0.75em; + font-size: 0.875em; } .comment-form-comment, @@ -82,7 +88,7 @@ } .reply { - font-size: 0.75em; + font-size: 0.875em; margin-bottom: 1.4em; } From 123c9cc29059d4e8ac71c6d357d8946625114728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:44:13 +0100 Subject: [PATCH 044/149] Reduce specificity of legacy font sizes defined by core (#37819) --- packages/block-library/src/common.scss | 4 ++-- packages/block-library/src/editor.scss | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/common.scss b/packages/block-library/src/common.scss index 46b2cd7b3b559e..7d2892f57cead9 100644 --- a/packages/block-library/src/common.scss +++ b/packages/block-library/src/common.scss @@ -22,11 +22,11 @@ } .has-normal-font-size { - font-size: var(--wp--preset--font-size--normal) !important; + font-size: var(--wp--preset--font-size--normal); } .has-huge-font-size { - font-size: var(--wp--preset--font-size--huge) !important; + font-size: var(--wp--preset--font-size--huge); } // Text alignments. diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index bbaf122206b410..58a40f5d30270d 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -72,11 +72,11 @@ } .editor-styles-wrapper .has-normal-font-size { - font-size: var(--wp--preset--font-size--normal) !important; + font-size: var(--wp--preset--font-size--normal); } .editor-styles-wrapper .has-huge-font-size { - font-size: var(--wp--preset--font-size--huge) !important; + font-size: var(--wp--preset--font-size--huge); } /** From d164bbe40c84fa943a0e43d86dd8b4678e5f8290 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 11 Jan 2022 11:44:44 +1300 Subject: [PATCH 045/149] Gallery block: pass any custom attributes through the gallery v2 migration script (#37812) * Pass any custom attributes through the gallery v2 migration script * Switch to using omit to remove deprecated attributes and pass through everything else * Fix the block fixtures to match with the align attribute which is now being passed through correctly Co-authored-by: Glen Davies --- packages/block-library/src/gallery/deprecated.js | 7 ++----- .../fixtures/blocks/core__gallery__deprecated-1.json | 1 + .../blocks/core__gallery__deprecated-1.serialized.html | 4 ++-- .../fixtures/blocks/core__gallery__deprecated-2.json | 1 + .../blocks/core__gallery__deprecated-2.serialized.html | 4 ++-- .../fixtures/blocks/core__gallery__deprecated-3.json | 1 + .../blocks/core__gallery__deprecated-3.serialized.html | 4 ++-- .../fixtures/blocks/core__gallery__deprecated-4.json | 1 + .../blocks/core__gallery__deprecated-4.serialized.html | 4 ++-- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index 001bbba8ea8366..c4877377cbb796 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { map, some } from 'lodash'; +import { map, some, omit } from 'lodash'; /** * WordPress dependencies @@ -97,11 +97,8 @@ function runV2Migration( attributes ) { return [ { - caption: attributes.caption, - columns: attributes.columns, - imageCrop: attributes.imageCrop, + ...omit( attributes, [ 'images', 'ids' ] ), linkTo, - sizeSlug: attributes.sizeSlug, allowResize: false, }, imageBlocks, diff --git a/test/integration/fixtures/blocks/core__gallery__deprecated-1.json b/test/integration/fixtures/blocks/core__gallery__deprecated-1.json index d274a72a649ef4..15346fe17b7607 100644 --- a/test/integration/fixtures/blocks/core__gallery__deprecated-1.json +++ b/test/integration/fixtures/blocks/core__gallery__deprecated-1.json @@ -7,6 +7,7 @@ "columns": 2, "imageCrop": true, "linkTo": "none", + "align": "wide", "allowResize": false }, "innerBlocks": [ diff --git a/test/integration/fixtures/blocks/core__gallery__deprecated-1.serialized.html b/test/integration/fixtures/blocks/core__gallery__deprecated-1.serialized.html index 45a1ef9a673716..d0210e6ab6796f 100644 --- a/test/integration/fixtures/blocks/core__gallery__deprecated-1.serialized.html +++ b/test/integration/fixtures/blocks/core__gallery__deprecated-1.serialized.html @@ -1,5 +1,5 @@ - -
      ) } diff --git a/packages/editor/src/components/post-locked-modal/style.scss b/packages/editor/src/components/post-locked-modal/style.scss index d1142b2290826b..c65a555fb69219 100644 --- a/packages/editor/src/components/post-locked-modal/style.scss +++ b/packages/editor/src/components/post-locked-modal/style.scss @@ -4,9 +4,6 @@ .editor-post-locked-modal__buttons { margin-top: $grid-unit-30; - display: flex; - justify-content: flex-end; - gap: $grid-unit-10; } .editor-post-locked-modal__avatar { From d1da59150105d1c4a6e71beb671d2a3fe38faba8 Mon Sep 17 00:00:00 2001 From: Thomas Roberts <5656702+opr@users.noreply.github.com> Date: Tue, 11 Jan 2022 10:25:21 +0000 Subject: [PATCH 056/149] Stop keypresses being caught by other elements when they happen in a CustomSelectControl (#30557) * Stop the keydown event from propagating in CustomSelect component * Stop the synthetic event propagating instead of native This stops other listeners receiving this event, whereas stopping the native event still somehow allowed propagation. * Move keyDown handler into useCallback and use optional chaining * Add unit tests for CustomSelectControl * Update changelog * Add inline comment about role and remove unneeded class name * Move mocked function into test * Add correct spacing to changelog * Add options as an array of key value pairs * Use accessible roles instead of looking for elements by className --- packages/components/CHANGELOG.md | 1 + .../src/custom-select-control/index.js | 14 +++++- .../src/custom-select-control/test/index.js | 46 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/components/src/custom-select-control/test/index.js diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 876c46b448ce33..e659790312886a 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug Fix - Add missing styles to the `BaseControl.VisualLabel` component. ([#37747](https://github.com/WordPress/gutenberg/pull/37747)) +- Prevent keyDown events from propagating up in `CustomSelectControl` ([#30557](https://github.com/WordPress/gutenberg/pull/30557)) ## 19.2.0 (2022-01-04) diff --git a/packages/components/src/custom-select-control/index.js b/packages/components/src/custom-select-control/index.js index 90b5bbf2115e20..9c13cc6b0e6619 100644 --- a/packages/components/src/custom-select-control/index.js +++ b/packages/components/src/custom-select-control/index.js @@ -9,6 +9,8 @@ import classnames from 'classnames'; */ import { Icon, check, chevronDown } from '@wordpress/icons'; import { __, sprintf } from '@wordpress/i18n'; +import { useCallback } from '@wordpress/element'; + /** * Internal dependencies */ @@ -98,6 +100,15 @@ export default function CustomSelectControl( { className: 'components-custom-select-control__menu', 'aria-hidden': ! isOpen, } ); + + const onKeyDownHandler = useCallback( + ( e ) => { + e.stopPropagation(); + menuProps?.onKeyDown?.( e ); + }, + [ menuProps ] + ); + // We need this here, because the null active descendant is not fully ARIA compliant. if ( menuProps[ 'aria-activedescendant' ]?.startsWith( 'downshift-null' ) @@ -141,7 +152,8 @@ export default function CustomSelectControl( { className="components-custom-select-control__button-icon" /> -
        + { /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ } +
          { isOpen && items.map( ( item, index ) => ( // eslint-disable-next-line react/jsx-key diff --git a/packages/components/src/custom-select-control/test/index.js b/packages/components/src/custom-select-control/test/index.js new file mode 100644 index 00000000000000..42e551abf8c7d1 --- /dev/null +++ b/packages/components/src/custom-select-control/test/index.js @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { render, fireEvent, screen } from '@testing-library/react'; + +/** + * WordPress dependencies + */ +import { CustomSelectControl } from '@wordpress/components'; + +describe( 'CustomSelectControl', () => { + it( 'Captures the keypress event and does not let it propagate', () => { + const onKeyDown = jest.fn(); + const options = [ + { + key: 'one', + name: 'Option one', + }, + { + key: 'two', + name: 'Option two', + }, + { + key: 'three', + name: 'Option three', + }, + ]; + + render( +
          + +
          + ); + const toggleButton = screen.getByRole( 'button' ); + fireEvent.click( toggleButton ); + + const customSelect = screen.getByRole( 'listbox' ); + fireEvent.keyDown( customSelect ); + + expect( onKeyDown ).toHaveBeenCalledTimes( 0 ); + } ); +} ); From f8c0ee306c2d0327a7387b0570a5f7c1a164fcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Jan 2022 11:25:33 +0100 Subject: [PATCH 057/149] Block.json schema: update fontSize and lineHeight props (#37853) --- schemas/json/block.json | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/schemas/json/block.json b/schemas/json/block.json index e592a0ca4de237..7efbb55f410568 100644 --- a/schemas/json/block.json +++ b/schemas/json/block.json @@ -268,11 +268,6 @@ "description": "When the style picker is shown, a dropdown is displayed so the user can select a default style for this block type. If you prefer not to show the dropdown, set this property to false.", "default": true }, - "fontSize": { - "type": "boolean", - "description": "This value signals that a block supports the font-size CSS style property. When it does, the block editor will show an UI control for the user to set its value.\n\nThe values shown in this control are the ones declared by the theme via the editor-font-sizes theme support, or the default ones if none is provided.\n\nWhen the block declares support for fontSize, the attributes definition is extended to include two new attributes: fontSize and style", - "default": false - }, "html": { "type": "boolean", "description": "By default, a block’s markup can be edited individually. To disable this behavior, set html to false.", @@ -283,11 +278,6 @@ "description": "By default, all blocks will appear in the inserter. To hide a block so that it can only be inserted programmatically, set inserter to false.", "default": true }, - "lineHeight": { - "type": "boolean", - "description": "This value signals that a block supports the line-height CSS style property. When it does, the block editor will show an UI control for the user to set its value if the theme declares support.\n\nWhen the block declares support for lineHeight, the attributes definition is extended to include a new attribute style of object type with no default assigned. It stores the custom value set by the user. The block can apply a default style by specifying its own style attribute with a default", - "default": false - }, "multiple": { "type": "boolean", "description": "A non-multiple block can be inserted into each post, one time only. For example, the built-in ‘More’ block cannot be inserted again if it already exists in the post being edited. A non-multiple block’s icon is automatically dimmed (unclickable) to prevent multiple instances.", @@ -355,6 +345,22 @@ ] } } + }, + "typography": { + "type": "object", + "description": "This value signals that a block supports some of the CSS style properties related to typography. When it does, the block editor will show UI controls for the user to set their values, if the theme declares support.\n\nWhen the block declares support for a specific typography property, the attributes definition is extended to include the style attribute.", + "properties": { + "fontSize": { + "type": "boolean", + "description": "This value signals that a block supports the font-size CSS style property. When it does, the block editor will show an UI control for the user to set its value.\n\nThe values shown in this control are the ones declared by the theme via the editor-font-sizes theme support, or the default ones if none is provided.\n\nWhen the block declares support for fontSize, the attributes definition is extended to include two new attributes: fontSize and style", + "default": false + }, + "lineHeight": { + "type": "boolean", + "description": "This value signals that a block supports the line-height CSS style property. When it does, the block editor will show an UI control for the user to set its value if the theme declares support.\n\nWhen the block declares support for lineHeight, the attributes definition is extended to include a new attribute style of object type with no default assigned. It stores the custom value set by the user. The block can apply a default style by specifying its own style attribute with a default", + "default": false + } + } } }, "additionalProperties": true From 3c188ab1d4e062ceca5386bf10c0441391407b5e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 11 Jan 2022 10:41:57 +0000 Subject: [PATCH 058/149] Categories block escape late (#37835) * Escape late on output * Escape built classname --- packages/block-library/src/categories/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/categories/index.php b/packages/block-library/src/categories/index.php index 5492712d5106a2..61fc138ca28574 100644 --- a/packages/block-library/src/categories/index.php +++ b/packages/block-library/src/categories/index.php @@ -31,7 +31,7 @@ function render_block_core_categories( $attributes ) { $id = 'wp-block-categories-' . $block_id; $args['id'] = $id; $args['show_option_none'] = __( 'Select Category' ); - $wrapper_markup = '
          %2$s
          '; + $wrapper_markup = '
          %2$s
          '; $items_markup = wp_dropdown_categories( $args ); $type = 'dropdown'; @@ -50,7 +50,7 @@ function render_block_core_categories( $attributes ) { $type = 'list'; } - $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => "wp-block-categories-{$type}" ) ); + $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => esc_attr( "wp-block-categories-{$type}" ) ) ); return sprintf( $wrapper_markup, From 33fb3ccff69e628c16063ab613a82947a36e3896 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Tue, 11 Jan 2022 10:47:18 +0000 Subject: [PATCH 059/149] Tag Cloud Block: Add outline style (#37092) * Add a pill style to the tag cloud block * add a hover style * Add an active and hover state * simplify the block style * remove text-decoration from tag cloud * Update color to currentColor * Make the gaps ch instead of px * rename normal to medium * Unset the font size so it inherits from the theme * rename pull to outline --- packages/block-library/src/tag-cloud/index.php | 9 +++++++++ packages/block-library/src/tag-cloud/style.scss | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/block-library/src/tag-cloud/index.php b/packages/block-library/src/tag-cloud/index.php index 0658998d4e8cb8..751294d969e325 100644 --- a/packages/block-library/src/tag-cloud/index.php +++ b/packages/block-library/src/tag-cloud/index.php @@ -51,5 +51,14 @@ function register_block_core_tag_cloud() { 'render_callback' => 'render_block_core_tag_cloud', ) ); + + register_block_style( + 'core/tag-cloud', + array( + 'name' => 'outline', + 'label' => __( 'Outline', 'gutenberg' ), + 'style_handle' => 'outline', + ) + ); } add_action( 'init', 'register_block_core_tag_cloud' ); diff --git a/packages/block-library/src/tag-cloud/style.scss b/packages/block-library/src/tag-cloud/style.scss index 1d1c63364147a9..46625741ae49a4 100644 --- a/packages/block-library/src/tag-cloud/style.scss +++ b/packages/block-library/src/tag-cloud/style.scss @@ -18,4 +18,13 @@ margin-left: 5px; text-decoration: none; } + + &.is-style-outline a { + border: 1px solid currentColor; + font-size: unset !important; // !important Needed to override the inline styles. + margin-bottom: 1ch; + margin-right: 1ch; + padding: 1ch 2ch; + text-decoration: none !important; // !important needed to override generic post content link decoration. + } } From 10ba74945b1db1567b029749a0c3942f58f7cecb Mon Sep 17 00:00:00 2001 From: James Koster Date: Tue, 11 Jan 2022 11:23:02 +0000 Subject: [PATCH 060/149] Update the Post Author block description (#37836) * Update the post author block description to be more contextually agnostic --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/post-author/block.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index de597435421e30..07ba399dabceb0 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -433,7 +433,7 @@ Show a block pattern. ([Source](https://github.com/WordPress/gutenberg/tree/trun ## Post Author -Add the author of this post. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author)) +Display post author details such as name, avatar, and bio. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author)) - **Name:** core/post-author - **Category:** theme diff --git a/packages/block-library/src/post-author/block.json b/packages/block-library/src/post-author/block.json index e94b604937226a..74824c615ab748 100644 --- a/packages/block-library/src/post-author/block.json +++ b/packages/block-library/src/post-author/block.json @@ -4,7 +4,7 @@ "name": "core/post-author", "title": "Post Author", "category": "theme", - "description": "Add the author of this post.", + "description": "Display post author details such as name, avatar, and bio.", "textdomain": "default", "attributes": { "textAlign": { From 73003d198de9b1bcc6a4b6cc9ee36b0b501b7d5a Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Tue, 11 Jan 2022 12:39:14 +0100 Subject: [PATCH 061/149] ExternalLink: Update icon to be smaller, have no margin. (#37859) * ExternalLink: Update icon to be smaller, have no margin. * Add URL to changelog. --- packages/components/CHANGELOG.md | 4 ++++ .../src/external-link/styles/external-link-styles.js | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index e659790312886a..c03e959a54be86 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Refine `ExternalLink` to be same size as the text, to appear more as a glyph than an icon. ([#37859](https://github.com/WordPress/gutenberg/pull/37859)) + ### Bug Fix - Add missing styles to the `BaseControl.VisualLabel` component. ([#37747](https://github.com/WordPress/gutenberg/pull/37747)) diff --git a/packages/components/src/external-link/styles/external-link-styles.js b/packages/components/src/external-link/styles/external-link-styles.js index 06fc737aadffd3..6b64fd61c8bad4 100644 --- a/packages/components/src/external-link/styles/external-link-styles.js +++ b/packages/components/src/external-link/styles/external-link-styles.js @@ -9,9 +9,9 @@ import styled from '@emotion/styled'; import { Icon } from '@wordpress/icons'; export const StyledIcon = styled( Icon )` - width: 1.4em; - height: 1.4em; - margin: -0.2em 0.1em 0; + width: 1em; + height: 1em; + margin: 0; vertical-align: middle; fill: currentColor; `; From 22edce2f9a1177abcdbc8ea744f49c5933396d3c Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 11 Jan 2022 13:52:35 +0200 Subject: [PATCH 062/149] Fix enqueueing additional styles for blocks only when rendered (#37848) * Fix enqueueing additional styles for blocks only when rendered * phpcs fix * backport changes from core --- lib/blocks.php | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/blocks.php b/lib/blocks.php index eae7c0abde892b..0094ef32230b99 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -605,10 +605,9 @@ function wp_enqueue_block_style( $block_name, $args ) { * @param string $content When the callback is used for the render_block filter, * the content needs to be returned so the function parameter * is to ensure the content exists. - * - * @return string + * @return string Block content. */ - $callback = function( $content ) use ( $args ) { + $callback = static function( $content ) use ( $args ) { // Register the stylesheet. if ( ! empty( $args['src'] ) ) { wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] ); @@ -639,10 +638,42 @@ function wp_enqueue_block_style( $block_name, $args ) { $hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts'; if ( wp_should_load_separate_core_block_assets() ) { - $hook = "render_block_$block_name"; + /** + * Callback function to register and enqueue styles. + * + * @param string $content The block content. + * @param array $block The full block, including name and attributes. + * @return string Block content. + */ + $callback_separate = static function( $content, $block ) use ( $block_name, $callback ) { + if ( ! empty( $block['blockName'] ) && $block_name === $block['blockName'] ) { + return $callback( $content ); + } + return $content; + }; + + /* + * The filter's callback here is an anonymous function because + * using a named function in this case is not possible. + * + * The function cannot be unhooked, however, users are still able + * to dequeue the stylesheets registered/enqueued by the callback + * which is why in this case, using an anonymous function + * was deemed acceptable. + */ + add_filter( 'render_block', $callback_separate, 10, 2 ); + return; } - // Enqueue assets in the frontend. + /* + * The filter's callback here is an anonymous function because + * using a named function in this case is not possible. + * + * The function cannot be unhooked, however, users are still able + * to dequeue the stylesheets registered/enqueued by the callback + * which is why in this case, using an anonymous function + * was deemed acceptable. + */ add_filter( $hook, $callback ); // Enqueue assets in the editor. From bb74294ccaaefc3ba7e879d7921fc1aaecca0123 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 11 Jan 2022 11:57:28 +0000 Subject: [PATCH 063/149] Move escaping to point of output (#37834) --- packages/block-library/src/archives/index.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/archives/index.php b/packages/block-library/src/archives/index.php index 2f4ad1045ad0c4..14e1e5d416a054 100644 --- a/packages/block-library/src/archives/index.php +++ b/packages/block-library/src/archives/index.php @@ -23,7 +23,7 @@ function render_block_core_archives( $attributes ) { $class .= ' wp-block-archives-dropdown'; - $dropdown_id = esc_attr( uniqid( 'wp-block-archives-' ) ); + $dropdown_id = uniqid( 'wp-block-archives-' ); $title = __( 'Archives' ); /** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */ @@ -62,11 +62,9 @@ function render_block_core_archives( $attributes ) { break; } - $label = esc_html( $label ); - - $block_content = ' - '; + $block_content = ' + '; return sprintf( '
          %2$s
          ', @@ -90,9 +88,7 @@ function render_block_core_archives( $attributes ) { $archives = wp_get_archives( $archives_args ); - $classnames = esc_attr( $class ); - - $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); + $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => esc_attr( $class ) ) ); if ( empty( $archives ) ) { return sprintf( From 7a00aa3aeca4f866ede81a5966ac433ee21ebe09 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Tue, 11 Jan 2022 14:20:02 +0200 Subject: [PATCH 064/149] [Block Library - Query Loop]: Check for `zero` `queryId` on initialization (#37867) --- packages/block-library/src/query/edit/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index af62af287c5443..bf8e95d06e21a8 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -79,7 +79,7 @@ export function QueryContent( { attributes, setAttributes } ) { // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. useEffect( () => { - if ( ! queryId ) { + if ( ! Number.isFinite( queryId ) ) { __unstableMarkNextChangeAsNotPersistent(); setAttributes( { queryId: instanceId } ); } From 8debd02dab82ddb2a4fa6ae7394c1b6d8645223a Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Tue, 11 Jan 2022 13:44:09 +0100 Subject: [PATCH 065/149] Simplify and unify a few modal dialogs. (#37857) --- packages/block-library/src/gallery/editor.scss | 16 ++++++++-------- packages/block-library/src/page-list/editor.scss | 9 ++++----- .../src/components/post-locked-modal/style.scss | 4 +++- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index d0ef7ffbff1c36..9e3534030632ad 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -193,13 +193,13 @@ figure.wp-block-gallery { } .wp-block-update-gallery-modal { - max-width: 400px; - .wp-block-update-gallery-modal-buttons { - display: flex; - justify-content: flex-end; - - .components-button { - margin-left: $grid-unit-15; - } + @include break-small() { + max-width: $break-mobile; } } + +.wp-block-update-gallery-modal-buttons { + display: flex; + justify-content: flex-end; + gap: $grid-unit-15; +} diff --git a/packages/block-library/src/page-list/editor.scss b/packages/block-library/src/page-list/editor.scss index c065d5a042e6db..0692cf3b3e1634 100644 --- a/packages/block-library/src/page-list/editor.scss +++ b/packages/block-library/src/page-list/editor.scss @@ -39,16 +39,15 @@ // Modal that shows conversion option. .wp-block-page-list-modal { - max-width: 400px; + @include break-small() { + max-width: $break-mobile; + } } .wp-block-page-list-modal-buttons { display: flex; justify-content: flex-end; - - .components-button { - margin-left: $grid-unit-15; - } + gap: $grid-unit-15; } // Simulate open on click behaviour in the editor by opening on focus instead. diff --git a/packages/editor/src/components/post-locked-modal/style.scss b/packages/editor/src/components/post-locked-modal/style.scss index c65a555fb69219..3de55b3d5d6cbf 100644 --- a/packages/editor/src/components/post-locked-modal/style.scss +++ b/packages/editor/src/components/post-locked-modal/style.scss @@ -1,5 +1,7 @@ .editor-post-locked-modal { - max-width: 400px; + @include break-small() { + max-width: $break-mobile; + } } .editor-post-locked-modal__buttons { From 906f86ef8c6dffc34eeee8c7e700f8744333198d Mon Sep 17 00:00:00 2001 From: Alex Stine Date: Tue, 11 Jan 2022 08:04:26 -0500 Subject: [PATCH 066/149] Try possibly better method for Block Inserter Search focus (#37793) * Try useImperativeHandle. * Pass the prop to focus. * Implement reviewer feedback. * More reviewer feedback. Apply to edit-site/edit-widgets. --- .../src/components/inserter/library.js | 29 +++++++----- .../src/components/inserter/menu.js | 44 +++++++++++++------ .../secondary-sidebar/inserter-sidebar.js | 12 ++--- .../secondary-sidebar/inserter-sidebar.js | 12 ++--- .../secondary-sidebar/inserter-sidebar.js | 12 ++--- 5 files changed, 60 insertions(+), 49 deletions(-) diff --git a/packages/block-editor/src/components/inserter/library.js b/packages/block-editor/src/components/inserter/library.js index b0262756488dbb..0200189a257ccb 100644 --- a/packages/block-editor/src/components/inserter/library.js +++ b/packages/block-editor/src/components/inserter/library.js @@ -7,6 +7,7 @@ import { noop } from 'lodash'; * WordPress dependencies */ import { useSelect } from '@wordpress/data'; +import { forwardRef } from '@wordpress/element'; /** * Internal dependencies @@ -14,17 +15,20 @@ import { useSelect } from '@wordpress/data'; import InserterMenu from './menu'; import { store as blockEditorStore } from '../../store'; -function InserterLibrary( { - rootClientId, - clientId, - isAppender, - showInserterHelpPanel, - showMostUsedBlocks = false, - __experimentalInsertionIndex, - __experimentalFilterValue, - onSelect = noop, - shouldFocusBlock = false, -} ) { +function InserterLibrary( + { + rootClientId, + clientId, + isAppender, + showInserterHelpPanel, + showMostUsedBlocks = false, + __experimentalInsertionIndex, + __experimentalFilterValue, + onSelect = noop, + shouldFocusBlock = false, + }, + ref +) { const destinationRootClientId = useSelect( ( select ) => { const { getBlockRootClientId } = select( blockEditorStore ); @@ -47,8 +51,9 @@ function InserterLibrary( { __experimentalInsertionIndex={ __experimentalInsertionIndex } __experimentalFilterValue={ __experimentalFilterValue } shouldFocusBlock={ shouldFocusBlock } + ref={ ref } /> ); } -export default InserterLibrary; +export default forwardRef( InserterLibrary ); diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index 0e691f8e4a1950..a52cf3665f8b70 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -1,7 +1,14 @@ /** * WordPress dependencies */ -import { useState, useCallback, useMemo } from '@wordpress/element'; +import { + forwardRef, + useState, + useCallback, + useMemo, + useImperativeHandle, + useRef, +} from '@wordpress/element'; import { VisuallyHidden, SearchControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; @@ -19,17 +26,20 @@ import useInsertionPoint from './hooks/use-insertion-point'; import InserterTabs from './tabs'; import { store as blockEditorStore } from '../../store'; -function InserterMenu( { - rootClientId, - clientId, - isAppender, - __experimentalInsertionIndex, - onSelect, - showInserterHelpPanel, - showMostUsedBlocks, - __experimentalFilterValue = '', - shouldFocusBlock = true, -} ) { +function InserterMenu( + { + rootClientId, + clientId, + isAppender, + __experimentalInsertionIndex, + onSelect, + showInserterHelpPanel, + showMostUsedBlocks, + __experimentalFilterValue = '', + shouldFocusBlock = true, + }, + ref +) { const [ filterValue, setFilterValue ] = useState( __experimentalFilterValue ); @@ -168,6 +178,13 @@ function InserterMenu( { [ blocksTab, patternsTab, reusableBlocksTab ] ); + const searchRef = useRef(); + useImperativeHandle( ref, () => ( { + focusSearch: () => { + searchRef.current.focus(); + }, + } ) ); + return (
          @@ -182,6 +199,7 @@ function InserterMenu( { value={ filterValue } label={ __( 'Search for blocks and patterns' ) } placeholder={ __( 'Search' ) } + ref={ searchRef } /> { !! filterValue && ( { - inserterContentRef.current - .querySelector( '.block-editor-inserter__search input' ) - .focus(); + libraryRef.current.focusSearch(); }, [] ); return ( @@ -56,10 +54,7 @@ export default function InserterSidebar() { onClick={ () => setIsInserterOpened( false ) } /> -
          +
          diff --git a/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js index 9ad1fba89c2317..e6989260ac0969 100644 --- a/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js @@ -31,11 +31,9 @@ export default function InserterSidebar() { focusOnMount: null, } ); - const inserterContentRef = useRef(); + const libraryRef = useRef(); useEffect( () => { - inserterContentRef.current - .querySelector( '.block-editor-inserter__search input' ) - .focus(); + libraryRef.current.focusSearch(); }, [] ); return ( @@ -51,10 +49,7 @@ export default function InserterSidebar() { onClick={ () => setIsInserterOpened( false ) } /> -
          +
          diff --git a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js index a7da78aa3e62c4..b01481748ee887 100644 --- a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js @@ -34,11 +34,9 @@ export default function InserterSidebar() { focusOnMount: null, } ); - const inserterContentRef = useRef(); + const libraryRef = useRef(); useEffect( () => { - inserterContentRef.current - .querySelector( '.block-editor-inserter__search input' ) - .focus(); + libraryRef.current.focusSearch(); }, [] ); return ( @@ -54,15 +52,13 @@ export default function InserterSidebar() { label={ __( 'Close block inserter' ) } /> -
          +
          From 43f9ad7e3dbffd90a330229c2a731d368c95f2cf Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 11 Jan 2022 13:53:10 +0000 Subject: [PATCH 067/149] PostLockedModal: Display preview link as part of the text (#37852) * PostLockedModal: Display preview link as part of the text * Avoid code duplication --- .../src/components/post-locked-modal/index.js | 125 ++++++++++-------- 1 file changed, 72 insertions(+), 53 deletions(-) diff --git a/packages/editor/src/components/post-locked-modal/index.js b/packages/editor/src/components/post-locked-modal/index.js index 9ee8283bc5c672..3576dc91dc5dd0 100644 --- a/packages/editor/src/components/post-locked-modal/index.js +++ b/packages/editor/src/components/post-locked-modal/index.js @@ -7,10 +7,16 @@ import { get } from 'lodash'; * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { Modal, Button, Flex, FlexItem } from '@wordpress/components'; +import { + Modal, + Button, + ExternalLink, + Flex, + FlexItem, +} from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { addQueryArgs } from '@wordpress/url'; -import { useEffect } from '@wordpress/element'; +import { useEffect, createInterpolateElement } from '@wordpress/element'; import { addAction, removeAction } from '@wordpress/hooks'; import { useInstanceId } from '@wordpress/compose'; import { store as coreStore } from '@wordpress/core-data'; @@ -19,7 +25,6 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import { getWPAdminURL } from '../../utils/url'; -import PostPreviewButton from '../post-preview-button'; import { store as editorStore } from '../../store'; export default function PostLockedModal() { @@ -34,6 +39,7 @@ export default function PostLockedModal() { postLockUtils, activePostLock, postType, + previewLink, } = useSelect( ( select ) => { const { isPostLocked, @@ -42,6 +48,7 @@ export default function PostLockedModal() { getCurrentPostId, getActivePostLock, getEditedPostAttribute, + getEditedPostPreviewLink, getEditorSettings, } = select( editorStore ); const { getPostType } = select( coreStore ); @@ -53,6 +60,7 @@ export default function PostLockedModal() { postLockUtils: getEditorSettings().postLockUtils, activePostLock: getActivePostLock(), postType: getPostType( getEditedPostAttribute( 'type' ) ), + previewLink: getEditedPostPreviewLink(), }; }, [] ); @@ -179,66 +187,77 @@ export default function PostLockedModal() { className="editor-post-locked-modal__avatar" /> ) } - { !! isTakeover && ( -
          +
          + { !! isTakeover && (

          - { userDisplayName - ? sprintf( - /* translators: %s: user's display name */ - __( - '%s now has editing control of this post. Don’t worry, your changes up to this moment have been saved.' - ), - userDisplayName - ) - : __( - 'Another user now has editing control of this post. Don’t worry, your changes up to this moment have been saved.' - ) } + { createInterpolateElement( + userDisplayName + ? sprintf( + /* translators: %s: user's display name */ + __( + '%s now has editing control of this posts (). Don’t worry, your changes up to this moment have been saved.' + ), + userDisplayName + ) + : __( + 'Another user now has editing control of this post (). Don’t worry, your changes up to this moment have been saved.' + ), + { + strong: , + PreviewLink: ( + + { __( 'preview' ) } + + ), + } + ) }

          - -
          - -
          -
          - ) } - { ! isTakeover && ( -
          + ) } + { ! isTakeover && (

          - { userDisplayName - ? sprintf( - /* translators: %s: user's display name */ - __( - '%s is currently working on this post, which means you cannot make changes, unless you take over.' - ), - userDisplayName - ) - : __( - 'Another user is currently working on this post, which means you cannot make changes, unless you take over.' - ) } + { createInterpolateElement( + userDisplayName + ? sprintf( + /* translators: %s: user's display name */ + __( + '%s is currently working on this post (), which means you cannot make changes, unless you take over.' + ), + userDisplayName + ) + : __( + 'Another user is currently working on this post (), which means you cannot make changes, unless you take over.' + ), + { + strong: , + PreviewLink: ( + + { __( 'preview' ) } + + ), + } + ) }

          + ) } - - - - + + { ! isTakeover && ( - - - - -
          - ) } + ) } + + + + +
          ); } From 15bef9d200e48b0f6f3d2bab8ac0cbdc705ad0fb Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:14:40 +0100 Subject: [PATCH 068/149] Add unlock icon. (#37855) --- packages/icons/src/index.js | 1 + packages/icons/src/library/unlock.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 packages/icons/src/library/unlock.js diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index 8cd13de78edec1..9e59bd94affd84 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -229,6 +229,7 @@ export { default as trendingUp } from './library/trending-up'; export { default as typography } from './library/typography'; export { default as undo } from './library/undo'; export { default as ungroup } from './library/ungroup'; +export { default as unlock } from './library/unlock'; export { default as update } from './library/update'; export { default as upload } from './library/upload'; export { default as verse } from './library/verse'; diff --git a/packages/icons/src/library/unlock.js b/packages/icons/src/library/unlock.js new file mode 100644 index 00000000000000..a2d50384838865 --- /dev/null +++ b/packages/icons/src/library/unlock.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/primitives'; + +const unlock = ( + + + +); + +export default unlock; From c3e1c1390379f44d6a9756d82b2a3992ec587050 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 11 Jan 2022 17:25:33 +0100 Subject: [PATCH 069/149] [RNMobile] Introduce improvements to i18n related scripts (#37787) * Prevent ignoring error logs from i18n command * Fix linting issues when generating i18n index file * Remove string replacement on makepot command output * Update log message on generate pot files script --- packages/react-native-editor/bin/generate-pot-files.sh | 7 ++++--- .../react-native-editor/bin/i18n-translations-download.js | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/react-native-editor/bin/generate-pot-files.sh b/packages/react-native-editor/bin/generate-pot-files.sh index ec8e39ffd161d5..e17a7ce97c9ecb 100755 --- a/packages/react-native-editor/bin/generate-pot-files.sh +++ b/packages/react-native-editor/bin/generate-pot-files.sh @@ -114,8 +114,9 @@ function make_pot () { # In order to detect parse errors, we need to use the "--debug" option, otherwise "make-pot" command doesn't output errors. local full_command="$makepot_command $source --debug $arguments" if [[ -z ${DEBUG:-} ]]; then - # When DEBUG flag is not enabled, we only print the parse errors. - $full_command 2> >(grep 'Could not parse file' | sed 's/Debug[[:space:]][(]make-pot[)]/Warning/g' >&2) + # When DEBUG flag is not enabled, we ignore extra debug information except important warnings. + local ignore_pattern="Parsing file\|Debug (commands)\|Debug (bootstrap)\|Debug (hooks)" + $full_command 2> >(grep -v "$ignore_pattern" >&2) else $full_command fi @@ -151,7 +152,7 @@ function generate_pot_files() { mkdir -p $output_path if [ -n "$subtract_pot_files" ]; then - echo "--- Strings from ${plugins_to_subtract[@]} plugins will be subtracted ---" + echo "-- Strings from ${plugins_to_subtract[@]} plugins will be subtracted --" fi echo -e "\nExtract used strings from Android source-map:" diff --git a/packages/react-native-editor/bin/i18n-translations-download.js b/packages/react-native-editor/bin/i18n-translations-download.js index 64898bcd8b3c57..e2e64603435399 100644 --- a/packages/react-native-editor/bin/i18n-translations-download.js +++ b/packages/react-native-editor/bin/i18n-translations-download.js @@ -197,7 +197,7 @@ const getUsedStrings = ( usedStringsFile, domain ) => { const generateIndexFile = ( translations, pluginDir ) => { const indexNative = `/* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */ - /* eslint-disable prettier/prettier */ +/* eslint-disable prettier/prettier */ const translations = { ${ translations @@ -211,8 +211,8 @@ const generateIndexFile = ( translations, pluginDir ) => { export const getTranslation = ( locale ) => translations[ locale ]; - /* eslint-enable prettier/prettier */ - `; +/* eslint-enable prettier/prettier */ +`; fs.writeFile( path.join( pluginDir, 'index.js' ), From 29ec9e0261c1c915bb75db4c4679f91225f685d1 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 11 Jan 2022 16:32:41 +0000 Subject: [PATCH 070/149] Late escape Table of Contents block (#37882) * First pass * Add additional escape of page url --- packages/block-library/src/table-of-contents/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/table-of-contents/index.php b/packages/block-library/src/table-of-contents/index.php index a957b5d4bc3a1a..6408bb53c0175d 100644 --- a/packages/block-library/src/table-of-contents/index.php +++ b/packages/block-library/src/table-of-contents/index.php @@ -261,14 +261,14 @@ function ( $child_node ) use ( $entry_class, $page_url ) { $entry = sprintf( '%3$s', - $entry_class, + esc_attr( $entry_class ), esc_url( $href ), esc_html( $content ) ); } else { $entry = sprintf( '%2$s', - $entry_class, + esc_attr( $entry_class ), esc_html( $content ) ); } @@ -279,7 +279,7 @@ function ( $child_node ) use ( $entry_class, $page_url ) { $child_node['children'] ? block_core_table_of_contents_render_list( $child_node['children'], - $page_url + esc_url( $page_url ) ) : null ); From 6b936c9f348daabcf2bbd57ccf0fe52bdc8b6d2a Mon Sep 17 00:00:00 2001 From: James Koster Date: Tue, 11 Jan 2022 17:43:04 +0000 Subject: [PATCH 071/149] removed -> deleted (#37888) Update the label on the Snackbar that appears when you delete a template. --- packages/edit-site/src/store/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index bd0922d00f2eda..b43b1e5b83fca6 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -138,7 +138,7 @@ export function* removeTemplate( template ) { 'createSuccessNotice', sprintf( /* translators: The template/part's name. */ - __( '"%s" removed.' ), + __( '"%s" deleted.' ), template.title.rendered ), { type: 'snackbar' } From 62a21b8050fcee111e045260e818810b60f9474e Mon Sep 17 00:00:00 2001 From: Staci Cooper <63313398+stacimc@users.noreply.github.com> Date: Tue, 11 Jan 2022 17:20:47 -0800 Subject: [PATCH 072/149] Remove logic to discard unsaved changes when last Site Logo removed (#37895) This effect ran on unmount and used `getGlobalBlockCount` to determine if all Site Logo blocks have been removed, then discards any unsaved changes to the Logo and Icon. This does not work correctly in the Site Editor context, and would fire erroneously when switching between template parts, breaking the ability to 'Undo'/'Redo'. --- packages/block-library/src/site-logo/edit.js | 33 +------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index 18f151a48508d9..aad0d8b8e2ca0f 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -358,7 +358,7 @@ export default function LogoEdit( { setAttributes, isSelected, } ) { - const { className: styleClass, width, shouldSyncIcon } = attributes; + const { width, shouldSyncIcon } = attributes; const [ logoUrl, setLogoUrl ] = useState(); const ref = useRef(); @@ -406,39 +406,8 @@ export default function LogoEdit( { }; }, [] ); - const { getGlobalBlockCount } = useSelect( blockEditorStore ); const { editEntityRecord } = useDispatch( coreStore ); - useEffect( () => { - // Cleanup function to discard unsaved changes to the icon and logo when - // the block is removed. - return () => { - // Do nothing if the block is being rendered in the styles preview or the - // block inserter. - if ( - styleClass?.includes( - 'block-editor-block-types-list__site-logo-example' - ) || - styleClass?.includes( - 'block-editor-block-styles__block-preview-container' - ) - ) { - return; - } - - const logoBlockCount = getGlobalBlockCount( 'core/site-logo' ); - - // Only discard unsaved changes if we are removing the last Site Logo block - // on the page. - if ( logoBlockCount === 0 ) { - editEntityRecord( 'root', 'site', undefined, { - site_logo: undefined, - site_icon: undefined, - } ); - } - }; - }, [] ); - const setLogo = ( newValue, shouldForceSync = false ) => { // `shouldForceSync` is used to force syncing when the attribute // may not have updated yet. From 3a99ec3c2dbb9cc0b9a023597960459817475b48 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 12 Jan 2022 14:27:06 +1300 Subject: [PATCH 073/149] Gallery block: Remove warning notice about mobile version required (#37842) Co-authored-by: Glen Davies --- package-lock.json | 1 - packages/block-library/package.json | 1 - packages/block-library/src/gallery/edit.js | 7 ----- .../src/gallery/use-mobile-warning.js | 28 ------------------- packages/edit-post/src/index.js | 1 - 5 files changed, 38 deletions(-) delete mode 100644 packages/block-library/src/gallery/use-mobile-warning.js diff --git a/package-lock.json b/package-lock.json index c8fbc22c09966d..54fdd24cbe59fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16252,7 +16252,6 @@ "@wordpress/html-entities": "file:packages/html-entities", "@wordpress/i18n": "file:packages/i18n", "@wordpress/icons": "file:packages/icons", - "@wordpress/interface": "file:packages/interface", "@wordpress/is-shallow-equal": "file:packages/is-shallow-equal", "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/notices": "file:packages/notices", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 57f50b3d2bd1f3..721af01c6f9531 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -52,7 +52,6 @@ "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", - "@wordpress/interface": "file:../interface", "@wordpress/is-shallow-equal": "file:../is-shallow-equal", "@wordpress/keycodes": "file:../keycodes", "@wordpress/notices": "file:../notices", diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 492275995ca269..434ac572cb9c52 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -53,11 +53,6 @@ import useShortCodeTransform from './use-short-code-transform'; import useGetNewImages from './use-get-new-images'; import useGetMedia from './use-get-media'; -/** - * Internal dependencies - */ -import useMobileWarning from './use-mobile-warning'; - const MAX_COLUMNS = 8; const linkOptions = [ { value: LINK_DESTINATION_ATTACHMENT, label: __( 'Attachment Page' ) }, @@ -149,8 +144,6 @@ function GalleryEdit( props ) { const newImages = useGetNewImages( images, imageData ); - useMobileWarning( newImages ); - useEffect( () => { newImages?.forEach( ( newImage ) => { updateBlockAttributes( newImage.clientId, { diff --git a/packages/block-library/src/gallery/use-mobile-warning.js b/packages/block-library/src/gallery/use-mobile-warning.js deleted file mode 100644 index 95d0f4c86432fc..00000000000000 --- a/packages/block-library/src/gallery/use-mobile-warning.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { store as interfaceStore } from '@wordpress/interface'; -import { store as noticesStore } from '@wordpress/notices'; - -export default function useMobileWarning( newImages ) { - const { createWarningNotice } = useDispatch( noticesStore ); - const { toggleFeature } = useDispatch( interfaceStore ); - const isMobileWarningActive = useSelect( ( select ) => { - const { isFeatureActive } = select( interfaceStore ); - return isFeatureActive( 'core/edit-post', 'mobileGalleryWarning' ); - }, [] ); - - if ( ! isMobileWarningActive || ! newImages ) { - return; - } - - createWarningNotice( - __( - 'If you want to edit the gallery you just added in the mobile app, to avoid losing any data please make sure you use version 18.2 of the app or above.' - ), - { type: 'snackbar', explicitDismiss: true } - ); - toggleFeature( 'core/edit-post', 'mobileGalleryWarning' ); -} diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index 21a24505d3e9bf..e59607223c34aa 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -109,7 +109,6 @@ export function initializeEditor( dispatch( interfaceStore ).setFeatureDefaults( 'core/edit-post', { fixedToolbar: false, welcomeGuide: true, - mobileGalleryWarning: true, fullscreenMode: true, showIconLabels: false, themeStyles: true, From 74740aa97314ec65ca2d1d7bdeda904b790289dc Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 12 Jan 2022 06:22:48 +0000 Subject: [PATCH 074/149] Initial pass (#37873) --- packages/block-library/src/page-list/index.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/page-list/index.php b/packages/block-library/src/page-list/index.php index 4cbebe75ae4b58..a9b9802ec1d668 100644 --- a/packages/block-library/src/page-list/index.php +++ b/packages/block-library/src/page-list/index.php @@ -185,18 +185,18 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click, wp_strip_all_tags( $title ) ); - $markup .= '
        • '; + $markup .= '
        • '; if ( isset( $page['children'] ) && $is_navigation_child && $open_submenus_on_click ) { - $markup .= ''; } else { - $markup .= '' . $title . ''; + $markup .= '' . esc_html( $title ) . ''; } if ( isset( $page['children'] ) ) { if ( $is_navigation_child && $show_submenu_icons && ! $open_submenus_on_click ) { - $markup .= ''; } @@ -316,8 +316,8 @@ function render_block_core_page_list( $attributes, $content, $block ) { $wrapper_attributes = get_block_wrapper_attributes( array( - 'class' => $css_classes, - 'style' => $style_attribute, + 'class' => esc_attr( $css_classes ), + 'style' => esc_attr( $style_attribute ), ) ); From d3c8a44c3c79ec7d7531c0f65e7a84b62410fe63 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 12 Jan 2022 06:25:49 +0000 Subject: [PATCH 075/149] Late escape Query blocks (#37877) * Initial pass * Revert escape of title Addresses https://github.com/WordPress/gutenberg/pull/37877#pullrequestreview-849252038 --- packages/block-library/src/query-pagination-next/index.php | 2 +- packages/block-library/src/query-pagination-previous/index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/query-pagination-next/index.php b/packages/block-library/src/query-pagination-next/index.php index bbda6af829b544..ccda8e48ab8418 100644 --- a/packages/block-library/src/query-pagination-next/index.php +++ b/packages/block-library/src/query-pagination-next/index.php @@ -51,7 +51,7 @@ function render_block_core_query_pagination_next( $attributes, $content, $block '%3$s', esc_url( add_query_arg( $page_key, $page + 1 ) ), $wrapper_attributes, - $label + esc_html( $label ) ); } wp_reset_postdata(); // Restore original Post Data. diff --git a/packages/block-library/src/query-pagination-previous/index.php b/packages/block-library/src/query-pagination-previous/index.php index e7d3c168c79110..a22d2c756e7a76 100644 --- a/packages/block-library/src/query-pagination-previous/index.php +++ b/packages/block-library/src/query-pagination-previous/index.php @@ -41,7 +41,7 @@ function render_block_core_query_pagination_previous( $attributes, $content, $bl '%3$s', esc_url( add_query_arg( $page_key, $page - 1 ) ), $wrapper_attributes, - $label + esc_html( $label ) ); } return $content; From 8aa94cc17b774a239430d12ab3aeaab1aa86519f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Wed, 12 Jan 2022 08:20:27 +0100 Subject: [PATCH 076/149] Testing: Allow type imports for React everywhere (#37862) --- .eslintrc.js | 18 +++++++++++++----- packages/components/src/card/types.ts | 1 - .../components/src/color-picker/component.tsx | 3 +-- .../src/color-picker/use-deprecated-props.ts | 1 - .../src/confirm-dialog/component.tsx | 1 - .../src/confirm-dialog/stories/index.js | 7 +++++-- .../components/src/confirm-dialog/types.ts | 1 - packages/components/src/divider/component.tsx | 1 - packages/components/src/elevation/types.ts | 1 - packages/components/src/flex/types.ts | 1 - packages/components/src/flyout/types.ts | 1 - packages/components/src/grid/types.ts | 1 - packages/components/src/h-stack/types.ts | 1 - packages/components/src/heading/component.tsx | 1 - packages/components/src/icon/index.tsx | 1 - .../components/src/input-control/index.tsx | 1 - .../src/input-control/input-base.tsx | 1 - .../src/input-control/input-field.tsx | 1 - .../src/input-control/reducer/actions.ts | 1 - .../src/input-control/reducer/reducer.ts | 1 - .../src/input-control/reducer/state.ts | 1 - .../styles/input-control-styles.tsx | 1 - packages/components/src/input-control/types.ts | 1 - .../src/item-group/item-group/component.tsx | 1 - .../src/item-group/item/component.tsx | 1 - .../components/src/item-group/item/hook.ts | 1 - .../navigator/navigator-provider/component.tsx | 1 - .../navigator/navigator-screen/component.tsx | 1 - packages/components/src/navigator/types.ts | 1 - .../components/src/resizable-box/index.tsx | 1 - .../src/resizable-box/resize-tooltip/index.tsx | 3 +-- .../src/resizable-box/resize-tooltip/label.tsx | 1 - .../components/src/scrollable/stories/index.js | 9 ++++++--- .../components/src/select-control/index.tsx | 1 - packages/components/src/spacer/component.tsx | 1 - packages/components/src/spacer/types.ts | 1 - .../components/src/text/get-line-height.ts | 1 - packages/components/src/text/types.ts | 1 - .../toggle-group-control-option/component.tsx | 1 - .../toggle-group-control/component.tsx | 1 - .../src/toggle-group-control/types.ts | 1 - .../tools-panel-header/component.tsx | 1 - .../tools-panel/tools-panel-item/component.tsx | 1 - .../src/tools-panel/tools-panel/component.tsx | 1 - packages/components/src/tools-panel/types.ts | 1 - .../src/ui/context/wordpress-component.ts | 1 - .../components/src/ui/control-group/types.ts | 1 - packages/components/src/ui/form-group/types.ts | 1 - .../components/src/ui/shortcut/component.tsx | 1 - packages/components/src/ui/tooltip/types.ts | 1 - packages/components/src/ui/utils/font-size.ts | 1 - .../src/ui/utils/get-valid-children.ts | 1 - packages/components/src/unit-control/index.tsx | 1 - packages/components/src/unit-control/types.ts | 1 - .../src/unit-control/unit-select-control.tsx | 1 - .../src/utils/hooks/use-combined-ref.ts | 1 - .../src/utils/hooks/use-latest-ref.ts | 1 - packages/components/src/v-stack/types.ts | 1 - packages/components/src/z-stack/component.tsx | 1 - .../compose/src/higher-order/pure/index.tsx | 1 - .../higher-order/with-instance-id/index.tsx | 1 - .../higher-order/with-safe-timeout/index.tsx | 1 - .../compose/src/hooks/use-ref-effect/index.ts | 1 - .../create-higher-order-component/index.ts | 1 - packages/element/src/react.js | 2 +- packages/react-i18n/src/index.tsx | 2 -- 66 files changed, 27 insertions(+), 76 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7b696b6bd9202f..0bdd21dc09c43a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -81,11 +81,6 @@ module.exports = { importNames: [ 'memoize' ], message: 'Please use `memize` instead.', }, - { - name: 'react', - message: - 'Please use React API through `@wordpress/element` instead.', - }, { name: 'reakit', message: @@ -110,6 +105,19 @@ module.exports = { ], }, ], + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + paths: [ + { + name: 'react', + message: + 'Please use React API through `@wordpress/element` instead.', + allowTypeImports: true, + }, + ], + }, + ], 'no-restricted-syntax': [ 'error', // NOTE: We can't include the forward slash in our regex or diff --git a/packages/components/src/card/types.ts b/packages/components/src/card/types.ts index b1df4a97f8d964..aaa20739ed1fb6 100644 --- a/packages/components/src/card/types.ts +++ b/packages/components/src/card/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/color-picker/component.tsx b/packages/components/src/color-picker/component.tsx index dc0b3a46fa73f6..34708694dd5106 100644 --- a/packages/components/src/color-picker/component.tsx +++ b/packages/components/src/color-picker/component.tsx @@ -1,8 +1,7 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports -import { Ref } from 'react'; +import type { Ref } from 'react'; import { colord, extend, Colord } from 'colord'; import namesPlugin from 'colord/plugins/names'; diff --git a/packages/components/src/color-picker/use-deprecated-props.ts b/packages/components/src/color-picker/use-deprecated-props.ts index d8c9223d265868..5f89ac121040ca 100644 --- a/packages/components/src/color-picker/use-deprecated-props.ts +++ b/packages/components/src/color-picker/use-deprecated-props.ts @@ -10,7 +10,6 @@ import { RgbColor, RgbaColor, } from 'colord'; -// eslint-disable-next-line no-restricted-imports import type { ComponentProps } from 'react'; import memoize from 'memize'; diff --git a/packages/components/src/confirm-dialog/component.tsx b/packages/components/src/confirm-dialog/component.tsx index bfa5590ab20d8b..ec8573cdadbb96 100644 --- a/packages/components/src/confirm-dialog/component.tsx +++ b/packages/components/src/confirm-dialog/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref, KeyboardEvent } from 'react'; /** diff --git a/packages/components/src/confirm-dialog/stories/index.js b/packages/components/src/confirm-dialog/stories/index.js index 36f82dca1297dd..8d91b676f2f7e9 100644 --- a/packages/components/src/confirm-dialog/stories/index.js +++ b/packages/components/src/confirm-dialog/stories/index.js @@ -1,10 +1,13 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports -import React, { useState } from 'react'; import { text } from '@storybook/addon-knobs'; +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + /** * Internal dependencies */ diff --git a/packages/components/src/confirm-dialog/types.ts b/packages/components/src/confirm-dialog/types.ts index 1ff696d806892b..69127c39dfa253 100644 --- a/packages/components/src/confirm-dialog/types.ts +++ b/packages/components/src/confirm-dialog/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { MouseEvent, KeyboardEvent, ReactNode } from 'react'; export type DialogInputEvent = diff --git a/packages/components/src/divider/component.tsx b/packages/components/src/divider/component.tsx index 15a61adab5c2ac..8deac3ddef071f 100644 --- a/packages/components/src/divider/component.tsx +++ b/packages/components/src/divider/component.tsx @@ -3,7 +3,6 @@ */ // eslint-disable-next-line no-restricted-imports import { Separator } from 'reakit'; -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/elevation/types.ts b/packages/components/src/elevation/types.ts index fb07d3349803eb..8fc6a71ee4a8a2 100644 --- a/packages/components/src/elevation/types.ts +++ b/packages/components/src/elevation/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; export type Props = { diff --git a/packages/components/src/flex/types.ts b/packages/components/src/flex/types.ts index 1cdc698183c689..5eb6c0914194b9 100644 --- a/packages/components/src/flex/types.ts +++ b/packages/components/src/flex/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/flyout/types.ts b/packages/components/src/flyout/types.ts index cf9c8bf1549082..0a7a861e62580e 100644 --- a/packages/components/src/flyout/types.ts +++ b/packages/components/src/flyout/types.ts @@ -3,7 +3,6 @@ */ // eslint-disable-next-line no-restricted-imports import type { PopoverStateReturn } from 'reakit'; -// eslint-disable-next-line no-restricted-imports import type { CSSProperties, FunctionComponentElement } from 'react'; /** diff --git a/packages/components/src/grid/types.ts b/packages/components/src/grid/types.ts index 1830f85c6942cb..9fc109f6ea5f96 100644 --- a/packages/components/src/grid/types.ts +++ b/packages/components/src/grid/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; type ResponsiveCSSValue< T > = Array< T | undefined > | T; diff --git a/packages/components/src/h-stack/types.ts b/packages/components/src/h-stack/types.ts index 2dcdf4e83ff62b..e16a46746162ed 100644 --- a/packages/components/src/h-stack/types.ts +++ b/packages/components/src/h-stack/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/heading/component.tsx b/packages/components/src/heading/component.tsx index b83a96e3b0c8e1..e20bc81df3a645 100644 --- a/packages/components/src/heading/component.tsx +++ b/packages/components/src/heading/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/icon/index.tsx b/packages/components/src/icon/index.tsx index e4f10d0e7fdbe5..8a24788785bec8 100644 --- a/packages/components/src/icon/index.tsx +++ b/packages/components/src/icon/index.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ComponentType, HTMLProps, SVGProps } from 'react'; /** diff --git a/packages/components/src/input-control/index.tsx b/packages/components/src/input-control/index.tsx index cb20755bc54c9b..20cc5abb163f02 100644 --- a/packages/components/src/input-control/index.tsx +++ b/packages/components/src/input-control/index.tsx @@ -3,7 +3,6 @@ */ import { noop } from 'lodash'; import classNames from 'classnames'; -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/input-control/input-base.tsx b/packages/components/src/input-control/input-base.tsx index 59fc18e5d93b52..fc96a9f27bcb44 100644 --- a/packages/components/src/input-control/input-base.tsx +++ b/packages/components/src/input-control/input-base.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/input-control/input-field.tsx b/packages/components/src/input-control/input-field.tsx index 88596a8853e07c..04025c0bb2599a 100644 --- a/packages/components/src/input-control/input-field.tsx +++ b/packages/components/src/input-control/input-field.tsx @@ -3,7 +3,6 @@ */ import { noop } from 'lodash'; import { useDrag } from 'react-use-gesture'; -// eslint-disable-next-line no-restricted-imports import type { SyntheticEvent, ChangeEvent, diff --git a/packages/components/src/input-control/reducer/actions.ts b/packages/components/src/input-control/reducer/actions.ts index 66ca918de77070..687a4905d0bb8f 100644 --- a/packages/components/src/input-control/reducer/actions.ts +++ b/packages/components/src/input-control/reducer/actions.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { SyntheticEvent } from 'react'; /** diff --git a/packages/components/src/input-control/reducer/reducer.ts b/packages/components/src/input-control/reducer/reducer.ts index 362739e758a42b..c67c99baeca2f4 100644 --- a/packages/components/src/input-control/reducer/reducer.ts +++ b/packages/components/src/input-control/reducer/reducer.ts @@ -2,7 +2,6 @@ * External dependencies */ import { isEmpty } from 'lodash'; -// eslint-disable-next-line no-restricted-imports import type { SyntheticEvent } from 'react'; /** diff --git a/packages/components/src/input-control/reducer/state.ts b/packages/components/src/input-control/reducer/state.ts index 455cce5f00f1da..be7dd3547300b5 100644 --- a/packages/components/src/input-control/reducer/state.ts +++ b/packages/components/src/input-control/reducer/state.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Reducer } from 'react'; /** diff --git a/packages/components/src/input-control/styles/input-control-styles.tsx b/packages/components/src/input-control/styles/input-control-styles.tsx index dac503b85fdc07..6436ebb8192621 100644 --- a/packages/components/src/input-control/styles/input-control-styles.tsx +++ b/packages/components/src/input-control/styles/input-control-styles.tsx @@ -3,7 +3,6 @@ */ import { css, SerializedStyles } from '@emotion/react'; import styled from '@emotion/styled'; -// eslint-disable-next-line no-restricted-imports import type { CSSProperties, ReactNode } from 'react'; /** diff --git a/packages/components/src/input-control/types.ts b/packages/components/src/input-control/types.ts index 1e9477243474f9..d4ae31a78c1056 100644 --- a/packages/components/src/input-control/types.ts +++ b/packages/components/src/input-control/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties, ReactNode, diff --git a/packages/components/src/item-group/item-group/component.tsx b/packages/components/src/item-group/item-group/component.tsx index e58eae897658cb..30af333ac306e7 100644 --- a/packages/components/src/item-group/item-group/component.tsx +++ b/packages/components/src/item-group/item-group/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/item-group/item/component.tsx b/packages/components/src/item-group/item/component.tsx index 18f6ae0eb99534..7aa021ec83565f 100644 --- a/packages/components/src/item-group/item/component.tsx +++ b/packages/components/src/item-group/item/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/item-group/item/hook.ts b/packages/components/src/item-group/item/hook.ts index d842a29b1eb036..37bca0272f80a2 100644 --- a/packages/components/src/item-group/item/hook.ts +++ b/packages/components/src/item-group/item/hook.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ElementType } from 'react'; /** diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx index df17ba55b05591..56b7ea9f6f96d7 100644 --- a/packages/components/src/navigator/navigator-provider/component.tsx +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; import { css } from '@emotion/react'; diff --git a/packages/components/src/navigator/navigator-screen/component.tsx b/packages/components/src/navigator/navigator-screen/component.tsx index 85631b0b5227a5..f787b0d5600397 100644 --- a/packages/components/src/navigator/navigator-screen/component.tsx +++ b/packages/components/src/navigator/navigator-screen/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; // eslint-disable-next-line no-restricted-imports import { motion, MotionProps } from 'framer-motion'; diff --git a/packages/components/src/navigator/types.ts b/packages/components/src/navigator/types.ts index acc5aecb840dff..761861f7ccc9b1 100644 --- a/packages/components/src/navigator/types.ts +++ b/packages/components/src/navigator/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ReactNode } from 'react'; type NavigatorPathOptions = { diff --git a/packages/components/src/resizable-box/index.tsx b/packages/components/src/resizable-box/index.tsx index f1572b69f74b76..ca6da661ab92d8 100644 --- a/packages/components/src/resizable-box/index.tsx +++ b/packages/components/src/resizable-box/index.tsx @@ -9,7 +9,6 @@ import { forwardRef } from '@wordpress/element'; import classnames from 'classnames'; import { Resizable } from 're-resizable'; import type { ResizableProps } from 're-resizable'; -// eslint-disable-next-line no-restricted-imports import type { ReactNode, Ref } from 'react'; /** diff --git a/packages/components/src/resizable-box/resize-tooltip/index.tsx b/packages/components/src/resizable-box/resize-tooltip/index.tsx index 386992ea0cd808..7b21f3088108b8 100644 --- a/packages/components/src/resizable-box/resize-tooltip/index.tsx +++ b/packages/components/src/resizable-box/resize-tooltip/index.tsx @@ -3,13 +3,12 @@ */ import { noop } from 'lodash'; import classnames from 'classnames'; +import type { Ref } from 'react'; /** * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; -// eslint-disable-next-line no-restricted-imports -import type { Ref } from 'react'; /** * Internal dependencies diff --git a/packages/components/src/resizable-box/resize-tooltip/label.tsx b/packages/components/src/resizable-box/resize-tooltip/label.tsx index 0b30e6d04dfa02..cab03ada487231 100644 --- a/packages/components/src/resizable-box/resize-tooltip/label.tsx +++ b/packages/components/src/resizable-box/resize-tooltip/label.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/scrollable/stories/index.js b/packages/components/src/scrollable/stories/index.js index d90e6a72a7ef0a..bd1604af63e528 100644 --- a/packages/components/src/scrollable/stories/index.js +++ b/packages/components/src/scrollable/stories/index.js @@ -2,8 +2,11 @@ * External dependencies */ import { boolean, select } from '@storybook/addon-knobs'; -/* eslint-disable-next-line no-restricted-imports */ -import React from 'react'; + +/** + * WordPress dependencies + */ +import { useRef } from '@wordpress/element'; /** * Internal dependencies @@ -20,7 +23,7 @@ export default { }; export const _default = () => { - const targetRef = React.useRef( null ); + const targetRef = useRef( null ); const onButtonClick = () => { targetRef.current?.focus(); diff --git a/packages/components/src/select-control/index.tsx b/packages/components/src/select-control/index.tsx index 7f68f56721aac9..7ee32b6f55cb3a 100644 --- a/packages/components/src/select-control/index.tsx +++ b/packages/components/src/select-control/index.tsx @@ -3,7 +3,6 @@ */ import { isEmpty, noop } from 'lodash'; import classNames from 'classnames'; -// eslint-disable-next-line no-restricted-imports import type { ChangeEvent, FocusEvent, Ref } from 'react'; /** diff --git a/packages/components/src/spacer/component.tsx b/packages/components/src/spacer/component.tsx index 3f10b316be5298..be243ce0663710 100644 --- a/packages/components/src/spacer/component.tsx +++ b/packages/components/src/spacer/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/spacer/types.ts b/packages/components/src/spacer/types.ts index c5a6afee1ca2e0..c1b75f5f0cf7cf 100644 --- a/packages/components/src/spacer/types.ts +++ b/packages/components/src/spacer/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ReactNode } from 'react'; /** diff --git a/packages/components/src/text/get-line-height.ts b/packages/components/src/text/get-line-height.ts index 5a9b92d5784d3b..88bf9d1558e6f5 100644 --- a/packages/components/src/text/get-line-height.ts +++ b/packages/components/src/text/get-line-height.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/text/types.ts b/packages/components/src/text/types.ts index 63a94694ee9980..ff98a27f6625a7 100644 --- a/packages/components/src/text/types.ts +++ b/packages/components/src/text/types.ts @@ -6,7 +6,6 @@ import type { Props as TruncateProps } from '../truncate/types'; /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; type TextAdjustLineHeightForInnerControls = diff --git a/packages/components/src/toggle-group-control/toggle-group-control-option/component.tsx b/packages/components/src/toggle-group-control/toggle-group-control-option/component.tsx index d42f7d8ab9c3c5..c7a4d470066641 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control-option/component.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control-option/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; // eslint-disable-next-line no-restricted-imports import { Radio } from 'reakit'; diff --git a/packages/components/src/toggle-group-control/toggle-group-control/component.tsx b/packages/components/src/toggle-group-control/toggle-group-control/component.tsx index a4059ecef6eeac..0f70adb8d163a8 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control/component.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; // eslint-disable-next-line no-restricted-imports import { RadioGroup, useRadioState } from 'reakit'; diff --git a/packages/components/src/toggle-group-control/types.ts b/packages/components/src/toggle-group-control/types.ts index b14099c1ad35dd..9b3a8ea78d6d5d 100644 --- a/packages/components/src/toggle-group-control/types.ts +++ b/packages/components/src/toggle-group-control/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { MutableRefObject, ReactNode, ReactText } from 'react'; // eslint-disable-next-line no-restricted-imports import type { RadioStateReturn } from 'reakit'; diff --git a/packages/components/src/tools-panel/tools-panel-header/component.tsx b/packages/components/src/tools-panel/tools-panel-header/component.tsx index 14c0d0a5a8d064..b36dd4488ab4e0 100644 --- a/packages/components/src/tools-panel/tools-panel-header/component.tsx +++ b/packages/components/src/tools-panel/tools-panel-header/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/tools-panel/tools-panel-item/component.tsx b/packages/components/src/tools-panel/tools-panel-item/component.tsx index a0a1791295e978..4931686a07dd5e 100644 --- a/packages/components/src/tools-panel/tools-panel-item/component.tsx +++ b/packages/components/src/tools-panel/tools-panel-item/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/tools-panel/tools-panel/component.tsx b/packages/components/src/tools-panel/tools-panel/component.tsx index f7f16240cea184..bd6e4bb5fa1ced 100644 --- a/packages/components/src/tools-panel/tools-panel/component.tsx +++ b/packages/components/src/tools-panel/tools-panel/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/tools-panel/types.ts b/packages/components/src/tools-panel/types.ts index 92e4282f68e128..b7898b6ba0ba43 100644 --- a/packages/components/src/tools-panel/types.ts +++ b/packages/components/src/tools-panel/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ReactNode } from 'react'; type ResetAllFilter = () => void; diff --git a/packages/components/src/ui/context/wordpress-component.ts b/packages/components/src/ui/context/wordpress-component.ts index 2bf4372ec6b6e2..2fd97b518bda0c 100644 --- a/packages/components/src/ui/context/wordpress-component.ts +++ b/packages/components/src/ui/context/wordpress-component.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type * as React from 'react'; /** diff --git a/packages/components/src/ui/control-group/types.ts b/packages/components/src/ui/control-group/types.ts index d36592224c066a..c7211eb35283a5 100644 --- a/packages/components/src/ui/control-group/types.ts +++ b/packages/components/src/ui/control-group/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/ui/form-group/types.ts b/packages/components/src/ui/form-group/types.ts index a02fa343b459f0..2b03a375181a2d 100644 --- a/packages/components/src/ui/form-group/types.ts +++ b/packages/components/src/ui/form-group/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties, ReactNode, ReactText } from 'react'; /** diff --git a/packages/components/src/ui/shortcut/component.tsx b/packages/components/src/ui/shortcut/component.tsx index f5bbb6a5d791ee..af4fa02a694167 100644 --- a/packages/components/src/ui/shortcut/component.tsx +++ b/packages/components/src/ui/shortcut/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref } from 'react'; /** diff --git a/packages/components/src/ui/tooltip/types.ts b/packages/components/src/ui/tooltip/types.ts index 446afcdb298b8d..7c50dca3a29371 100644 --- a/packages/components/src/ui/tooltip/types.ts +++ b/packages/components/src/ui/tooltip/types.ts @@ -3,7 +3,6 @@ */ // eslint-disable-next-line no-restricted-imports import type { TooltipInitialState, TooltipProps } from 'reakit'; -// eslint-disable-next-line no-restricted-imports import type { ReactElement, ReactNode } from 'react'; /** diff --git a/packages/components/src/ui/utils/font-size.ts b/packages/components/src/ui/utils/font-size.ts index 7a5e41ace540d0..1393426991c604 100644 --- a/packages/components/src/ui/utils/font-size.ts +++ b/packages/components/src/ui/utils/font-size.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties, ReactText } from 'react'; /** diff --git a/packages/components/src/ui/utils/get-valid-children.ts b/packages/components/src/ui/utils/get-valid-children.ts index de738e2fe00184..b969cd7fc63999 100644 --- a/packages/components/src/ui/utils/get-valid-children.ts +++ b/packages/components/src/ui/utils/get-valid-children.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ReactNode, ReactNodeArray } from 'react'; /** diff --git a/packages/components/src/unit-control/index.tsx b/packages/components/src/unit-control/index.tsx index bcfa89d1bb1fa6..27c4cdb566ebca 100644 --- a/packages/components/src/unit-control/index.tsx +++ b/packages/components/src/unit-control/index.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { FocusEventHandler, KeyboardEvent, diff --git a/packages/components/src/unit-control/types.ts b/packages/components/src/unit-control/types.ts index 8e15ac6f85b84f..ba55d63c44fa24 100644 --- a/packages/components/src/unit-control/types.ts +++ b/packages/components/src/unit-control/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { SyntheticEvent } from 'react'; /** diff --git a/packages/components/src/unit-control/unit-select-control.tsx b/packages/components/src/unit-control/unit-select-control.tsx index feca4a00710b21..c1980b9c564602 100644 --- a/packages/components/src/unit-control/unit-select-control.tsx +++ b/packages/components/src/unit-control/unit-select-control.tsx @@ -3,7 +3,6 @@ */ import { noop } from 'lodash'; import classnames from 'classnames'; -// eslint-disable-next-line no-restricted-imports import type { ChangeEvent } from 'react'; /** diff --git a/packages/components/src/utils/hooks/use-combined-ref.ts b/packages/components/src/utils/hooks/use-combined-ref.ts index 26b38922d74087..332818662a1c9d 100644 --- a/packages/components/src/utils/hooks/use-combined-ref.ts +++ b/packages/components/src/utils/hooks/use-combined-ref.ts @@ -5,7 +5,6 @@ import { useRef, useEffect } from '@wordpress/element'; /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { MutableRefObject, RefCallback } from 'react'; type Ref< T > = MutableRefObject< T | null > | RefCallback< T | null >; diff --git a/packages/components/src/utils/hooks/use-latest-ref.ts b/packages/components/src/utils/hooks/use-latest-ref.ts index a7167edb0d0b58..d8b4b20fa7e763 100644 --- a/packages/components/src/utils/hooks/use-latest-ref.ts +++ b/packages/components/src/utils/hooks/use-latest-ref.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { RefObject } from 'react'; /** diff --git a/packages/components/src/v-stack/types.ts b/packages/components/src/v-stack/types.ts index e20fa816af0606..4f62c0441dad49 100644 --- a/packages/components/src/v-stack/types.ts +++ b/packages/components/src/v-stack/types.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { CSSProperties } from 'react'; /** diff --git a/packages/components/src/z-stack/component.tsx b/packages/components/src/z-stack/component.tsx index 5e594101dab653..1f365300bdc4dc 100644 --- a/packages/components/src/z-stack/component.tsx +++ b/packages/components/src/z-stack/component.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { Ref, ReactNode } from 'react'; /** diff --git a/packages/compose/src/higher-order/pure/index.tsx b/packages/compose/src/higher-order/pure/index.tsx index 5567e564b8055e..869c22b6d85cb5 100644 --- a/packages/compose/src/higher-order/pure/index.tsx +++ b/packages/compose/src/higher-order/pure/index.tsx @@ -13,7 +13,6 @@ import type { SimpleHigherOrderComponent } from '../../utils/create-higher-order /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ComponentType, ComponentClass } from 'react'; /** diff --git a/packages/compose/src/higher-order/with-instance-id/index.tsx b/packages/compose/src/higher-order/with-instance-id/index.tsx index 8a1281ed92288e..9d3307f5672fc3 100644 --- a/packages/compose/src/higher-order/with-instance-id/index.tsx +++ b/packages/compose/src/higher-order/with-instance-id/index.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { ComponentType } from 'react'; /** diff --git a/packages/compose/src/higher-order/with-safe-timeout/index.tsx b/packages/compose/src/higher-order/with-safe-timeout/index.tsx index 0430a1259b3add..898e8bf5ef9fca 100644 --- a/packages/compose/src/higher-order/with-safe-timeout/index.tsx +++ b/packages/compose/src/higher-order/with-safe-timeout/index.tsx @@ -2,7 +2,6 @@ * External dependencies */ import { without } from 'lodash'; -// eslint-disable-next-line no-restricted-imports import type { ComponentType } from 'react'; /** diff --git a/packages/compose/src/hooks/use-ref-effect/index.ts b/packages/compose/src/hooks/use-ref-effect/index.ts index 549cf0ffa5d1c2..98a97ea294e7f5 100644 --- a/packages/compose/src/hooks/use-ref-effect/index.ts +++ b/packages/compose/src/hooks/use-ref-effect/index.ts @@ -1,7 +1,6 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports import type { DependencyList, RefCallback } from 'react'; /** diff --git a/packages/compose/src/utils/create-higher-order-component/index.ts b/packages/compose/src/utils/create-higher-order-component/index.ts index 1a96b7913e14fb..54d8e71fb22e6c 100644 --- a/packages/compose/src/utils/create-higher-order-component/index.ts +++ b/packages/compose/src/utils/create-higher-order-component/index.ts @@ -2,7 +2,6 @@ * External dependencies */ import { camelCase, upperFirst } from 'lodash'; -// eslint-disable-next-line no-restricted-imports import type { ComponentType } from 'react'; /** diff --git a/packages/element/src/react.js b/packages/element/src/react.js index f21fe4574c24fb..a658228b9a7281 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -1,7 +1,7 @@ /** * External dependencies */ -// eslint-disable-next-line no-restricted-imports +// eslint-disable-next-line @typescript-eslint/no-restricted-imports import { Children, cloneElement, diff --git a/packages/react-i18n/src/index.tsx b/packages/react-i18n/src/index.tsx index 4ffc0e5d240214..8776d24d4cbfda 100644 --- a/packages/react-i18n/src/index.tsx +++ b/packages/react-i18n/src/index.tsx @@ -1,8 +1,6 @@ /** * External dependencies */ -// Disable reason: Type-only import, this is fine. See https://github.com/typescript-eslint/typescript-eslint/issues/2661 -// eslint-disable-next-line no-restricted-imports import type { ComponentType, FunctionComponent, From 8c75d8e51e48d0cfd8c0995405001aa1b0dc5b65 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 12 Jan 2022 09:57:04 +0100 Subject: [PATCH 077/149] Add the WP version in which some JS APIs will be removed (#37854) --- packages/editor/src/components/deprecated.js | 2 ++ packages/editor/src/store/actions.js | 1 + packages/editor/src/store/selectors.js | 1 + packages/server-side-render/src/index.js | 1 + 4 files changed, 5 insertions(+) diff --git a/packages/editor/src/components/deprecated.js b/packages/editor/src/components/deprecated.js index 86f3f0b1d52901..29b08acb1c064b 100644 --- a/packages/editor/src/components/deprecated.js +++ b/packages/editor/src/components/deprecated.js @@ -67,6 +67,7 @@ function deprecateComponent( name, Wrapped, staticsToHoist = [] ) { deprecated( 'wp.editor.' + name, { since: '5.3', alternative: 'wp.blockEditor.' + name, + version: '6.2', } ); return ; @@ -87,6 +88,7 @@ function deprecateFunction( name, func ) { deprecated( 'wp.editor.' + name, { since: '5.3', alternative: 'wp.blockEditor.' + name, + version: '6.2', } ); return func( ...args ); diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index cfd48989477547..b7eb511716efc1 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -629,6 +629,7 @@ const getBlockEditorAction = ( name ) => since: '5.3', alternative: "`wp.data.dispatch( 'core/block-editor' )." + name + '`', + version: '6.2', } ); yield controls.dispatch( blockEditorStore, name, ...args ); }; diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index cf94892a5e3e8e..dc115a7cd008e5 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1256,6 +1256,7 @@ function getBlockEditorSelector( name ) { deprecated( "`wp.data.select( 'core/editor' )." + name + '`', { since: '5.3', alternative: "`wp.data.select( 'core/block-editor' )." + name + '`', + version: '6.2', } ); return select( blockEditorStore )[ name ]( ...args ); diff --git a/packages/server-side-render/src/index.js b/packages/server-side-render/src/index.js index 49cbeb7625c919..80e0033707cd90 100644 --- a/packages/server-side-render/src/index.js +++ b/packages/server-side-render/src/index.js @@ -50,6 +50,7 @@ const ExportedServerSideRender = withSelect( ( select ) => { if ( window && window.wp && window.wp.components ) { window.wp.components.ServerSideRender = forwardRef( ( props, ref ) => { deprecated( 'wp.components.ServerSideRender', { + version: '6.2', since: '5.3', alternative: 'wp.serverSideRender', } ); From 621df1fc6558b19f04363c6323f826db989e5986 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Wed, 12 Jan 2022 11:15:58 +0200 Subject: [PATCH 078/149] [History]: Fix redo after update/publish with transient edits (#37840) * [History]: Fix redo after update/publish with transient edits * test --- packages/core-data/src/reducer.js | 9 ++++++++ .../specs/editor/various/undo.test.js | 21 +++++++++++++++++ .../specs/site-editor/template-revert.test.js | 23 +++++++++++-------- test/emptytheme/block-templates/index.html | 13 ++++++----- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/packages/core-data/src/reducer.js b/packages/core-data/src/reducer.js index 130407e6f277af..693c4e58ef46e1 100644 --- a/packages/core-data/src/reducer.js +++ b/packages/core-data/src/reducer.js @@ -431,7 +431,16 @@ export function undo( state = UNDO_INITIAL_STATE, action ) { // to continue as if we were creating an explicit undo level. This // will result in an extra undo level being appended with the flattened // undo values. + // We also have to take into account if the `lastEditAction` had opted out + // of being tracked in undo history, like the action that persists the latest + // content right before saving. In that case we have to update the `lastEditAction` + // to avoid returning early before applying the existing flattened undos. isCreateUndoLevel = true; + if ( ! lastEditAction.meta.undo ) { + lastEditAction.meta.undo = { + edits: {}, + }; + } action = lastEditAction; } else { return nextState; diff --git a/packages/e2e-tests/specs/editor/various/undo.test.js b/packages/e2e-tests/specs/editor/various/undo.test.js index 8c2f8ecfa9105a..9402ce8624c1a1 100644 --- a/packages/e2e-tests/specs/editor/various/undo.test.js +++ b/packages/e2e-tests/specs/editor/various/undo.test.js @@ -420,4 +420,25 @@ describe( 'undo', () => { // Expect "1". expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'should be able to undo and redo when transient changes have been made and we update/publish', async () => { + // Typing consecutive characters in a `Paragraph` block updates the same + // block attribute as in the previous action and results in transient edits + // and skipping `undo` history steps. + const text = 'tonis'; + await clickBlockAppender(); + await page.keyboard.type( text ); + await publishPost(); + await pressKeyWithModifier( 'primary', 'z' ); + expect( await getEditedPostContent() ).toBe( '' ); + await page.waitForSelector( + '.editor-history__redo[aria-disabled="false"]' + ); + await page.click( '.editor-history__redo[aria-disabled="false"]' ); + expect( await getEditedPostContent() ).toMatchInlineSnapshot( ` + " +

          tonis

          + " + ` ); + } ); } ); diff --git a/packages/e2e-tests/specs/site-editor/template-revert.test.js b/packages/e2e-tests/specs/site-editor/template-revert.test.js index 34e1cba4dbfcb4..3189fa120c5bf5 100644 --- a/packages/e2e-tests/specs/site-editor/template-revert.test.js +++ b/packages/e2e-tests/specs/site-editor/template-revert.test.js @@ -22,29 +22,31 @@ const { disableWelcomeGuide, } = siteEditor; -const assertSaveButtonIsDisabled = () => +const assertSaveButtonIsDisabled = async () => page.waitForSelector( '.edit-site-save-button__button[aria-disabled="true"]' ); -const assertSaveButtonIsEnabled = () => +const assertSaveButtonIsEnabled = async () => page.waitForSelector( '.edit-site-save-button__button[aria-disabled="false"]' ); -const waitForNotice = () => page.waitForSelector( '.components-snackbar' ); - const clickButtonInNotice = async () => { const selector = '.components-snackbar button'; await page.waitForSelector( selector ); await page.click( selector ); }; -const clickUndoInHeaderToolbar = () => +const clickUndoInHeaderToolbar = async () => page.click( '.edit-site-header__toolbar button[aria-label="Undo"]' ); -const clickRedoInHeaderToolbar = () => - page.click( '.edit-site-header__toolbar button[aria-label="Redo"]' ); +const clickRedoInHeaderToolbar = async () => { + await page.waitForSelector( + '.edit-site-header__toolbar button[aria-label="Redo"][aria-disabled="false"]' + ); + return page.click( '.edit-site-header__toolbar button[aria-label="Redo"]' ); +}; const undoRevertInHeaderToolbar = async () => { await clickUndoInHeaderToolbar(); @@ -72,7 +74,9 @@ const save = async () => { const revertTemplate = async () => { await page.click( '.edit-site-document-actions__get-info' ); await page.click( '.edit-site-template-details__revert-button' ); - await waitForNotice(); + await page.waitForXPath( + '//*[contains(@class, "components-snackbar") and contains(text(), "Template reverted")]' + ); await assertSaveButtonIsEnabled(); }; @@ -164,7 +168,7 @@ describe( 'Template Revert', () => { expect( contentBefore ).toBe( contentAfter ); } ); - it.skip( 'should show the original content after revert, clicking undo then redo in the header toolbar', async () => { + it( 'should show the original content after revert, clicking undo then redo in the header toolbar', async () => { const contentBefore = await getEditedPostContent(); await addDummyText(); @@ -172,7 +176,6 @@ describe( 'Template Revert', () => { await revertTemplate(); await save(); await undoRevertInHeaderToolbar(); - // there's a bug which probably also exists where the redo button stays disabled. await clickRedoInHeaderToolbar(); const contentAfter = await getEditedPostContent(); diff --git a/test/emptytheme/block-templates/index.html b/test/emptytheme/block-templates/index.html index 356981eb585b60..464f1f429afd6d 100644 --- a/test/emptytheme/block-templates/index.html +++ b/test/emptytheme/block-templates/index.html @@ -1,9 +1,10 @@ - - - - - - \ No newline at end of file +
          + + + + +
          + From c76767baac7cc2cfc7ae71d985cc5ae83aabfa21 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 12 Jan 2022 17:43:50 +0800 Subject: [PATCH 079/149] Fix flaky test by using waitForResponse to ensure the url details request completes (#37901) * Fix flaky test by using waitForResponse to ensure the url details request completes and 404s * Handle promises in parallel * Fix other issues with test --- .../specs/editor/blocks/navigation.test.js | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 181cb60132b489..49269f6e547853 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -435,20 +435,7 @@ describe( 'Navigation', () => { expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); } ); - it.skip( 'allows pages to be created from the navigation block and their links added to menu', async () => { - // The URL Details endpoint 404s for the created page, since it will - // be a draft that is inaccessible publicly. To avoid this we mock - // out the endpoint response to be empty which will be handled gracefully - // in the UI whilst avoiding any 404s. - await setUpResponseMocking( [ - { - match: ( request ) => - request.url().includes( `rest_route` ) && - request.url().includes( `url-details` ), - onRequestMatch: createJSONResponse( [] ), - }, - ] ); - + it( 'allows pages to be created from the navigation block and their links added to menu', async () => { await createNewPost(); await insertBlock( 'Navigation' ); const startEmptyButton = await page.waitForXPath( START_EMPTY_XPATH ); @@ -466,16 +453,24 @@ describe( 'Navigation', () => { ); await input.type( pageTitle ); - // Wait for the create button to appear and click it. + // When creating a page, the URLControl makes a request to the + // url-details endpoint to fetch information about the page. + // Because the draft is inaccessible publicly, this request + // returns a 404 response. Wait for the response and expect + // the error to have occurred. const createPageButton = await page.waitForSelector( '.block-editor-link-control__search-create' ); - await createPageButton.click(); - - const draftLink = await page.waitForSelector( - '.wp-block-navigation-item__content' + const responsePromise = page.waitForResponse( + ( response ) => + response.url().includes( 'url-details' ) && + response.status() === 404 + ); + const createPagePromise = createPageButton.click(); + await Promise.all( [ responsePromise, createPagePromise ] ); + expect( console ).toHaveErroredWith( + 'Failed to load resource: the server responded with a status of 404 (Not Found)' ); - await draftLink.click(); // Creating a draft is async, so wait for a sign of completion. In this // case the link that shows in the URL popover once a link is added. From 344ee8fab4684a74493ab5de168771f1444027ac Mon Sep 17 00:00:00 2001 From: Alex Stine Date: Wed, 12 Jan 2022 04:54:32 -0500 Subject: [PATCH 080/149] Accessibility improvements for List View (#37798) * Add more descriptive label for Options button. * Improve sidebar caps and Close button text. * Fix focus for List View close solution 1. * Use another focusReturnRef. Apply to edit-site/edit-widgets. * Update close button string in e2e tests. Co-authored-by: tellthemachines --- .../src/components/list-view/block.js | 10 ++++++++++ .../specs/site-editor/document-settings.test.js | 2 +- .../site-editor/multi-entity-saving.test.js | 2 +- .../secondary-sidebar/list-view-sidebar.js | 17 ++++++++++++----- .../secondary-sidebar/list-view-sidebar.js | 17 ++++++++++++----- .../secondary-sidebar/list-view-sidebar.js | 17 ++++++++++++----- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 66996dd69a1739..a7746463c5adfd 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -19,6 +19,7 @@ import { memo, } from '@wordpress/element'; import { useDispatch } from '@wordpress/data'; +import { sprintf, __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -32,6 +33,7 @@ import ListViewBlockContents from './block-contents'; import BlockSettingsDropdown from '../block-settings-menu/block-settings-dropdown'; import { useListViewContext } from './context'; import { store as blockEditorStore } from '../../store'; +import useBlockDisplayInformation from '../use-block-display-information'; function ListViewBlock( { block, @@ -143,6 +145,13 @@ function ListViewBlock( { 'has-single-cell': hideBlockActions, } ); + const blockInformation = useBlockDisplayInformation( clientId ); + const settingsAriaLabel = sprintf( + // translators: %s: The title of the block. + __( 'Options for %s block' ), + blockInformation.title + ); + return ( { ); headerTemplatePartListViewButton.click(); await page.click( - 'button[aria-label="Close list view sidebar"]' + 'button[aria-label="Close List View Sidebar"]' ); // Evaluate the document settings secondary title diff --git a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js index cadb037a4847dc..f6dbbce7c897e7 100644 --- a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js @@ -275,7 +275,7 @@ describe( 'Multi-entity save flow', () => { '//a[contains(@class, "block-editor-list-view-block-select-button")][contains(., "Header")]' ); headerTemplatePartListViewButton.click(); - await page.click( 'button[aria-label="Close list view sidebar"]' ); + await page.click( 'button[aria-label="Close List View Sidebar"]' ); // Insert something to dirty the editor. await insertBlock( 'Paragraph' ); diff --git a/packages/edit-post/src/components/secondary-sidebar/list-view-sidebar.js b/packages/edit-post/src/components/secondary-sidebar/list-view-sidebar.js index 3f4f6107b36134..9076101bc399bd 100644 --- a/packages/edit-post/src/components/secondary-sidebar/list-view-sidebar.js +++ b/packages/edit-post/src/components/secondary-sidebar/list-view-sidebar.js @@ -32,7 +32,8 @@ export default function ListViewSidebar() { } const focusOnMountRef = useFocusOnMount( 'firstElement' ); - const focusReturnRef = useFocusReturn(); + const headerFocusReturnRef = useFocusReturn(); + const contentFocusReturnRef = useFocusReturn(); function closeOnEscape( event ) { if ( event.keyCode === ESCAPE && ! event.defaultPrevented ) { event.preventDefault(); @@ -50,17 +51,23 @@ export default function ListViewSidebar() { className="edit-post-editor__list-view-panel" onKeyDown={ closeOnEscape } > -
          - { __( 'List view' ) } +
          + { __( 'List View' ) }
          -
          - { __( 'List view' ) } +
          + { __( 'List View' ) }
          -
          - { __( 'List view' ) } +
          + { __( 'List View' ) }
          Date: Wed, 12 Jan 2022 10:50:57 +0000 Subject: [PATCH 081/149] Initial pass (#37879) --- packages/block-library/src/search/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/search/index.php b/packages/block-library/src/search/index.php index 289f9a3120c5e8..08f03c269c6b75 100644 --- a/packages/block-library/src/search/index.php +++ b/packages/block-library/src/search/index.php @@ -44,8 +44,8 @@ function render_block_core_search( $attributes ) { $label_markup = sprintf( '', - $input_id, - empty( $attributes['label'] ) ? __( 'Search' ) : esc_html( $attributes['label'] ) + esc_attr( $input_id ), + empty( $attributes['label'] ) ? esc_html__( 'Search' ) : esc_html( $attributes['label'] ) ); if ( $show_label && ! empty( $attributes['label'] ) ) { $label_markup = sprintf( From 72854b4d6b09bd7fb7f996a5c55dd3cc0613ddf8 Mon Sep 17 00:00:00 2001 From: Gerardo Pacheco Date: Wed, 12 Jan 2022 12:39:38 +0100 Subject: [PATCH 082/149] Mobile - Gallery block - Fix issue migrating old format and missing fixedHeight context, use of images prop instead of the attributes (#37889) --- packages/block-library/src/gallery/deprecated.js | 4 ++++ packages/block-library/src/gallery/gallery.native.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index c4877377cbb796..e71b87d2ab7915 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -192,6 +192,10 @@ const v6 = { type: 'boolean', default: true, }, + fixedHeight: { + type: 'boolean', + default: true, + }, linkTo: { type: 'string', }, diff --git a/packages/block-library/src/gallery/gallery.native.js b/packages/block-library/src/gallery/gallery.native.js index ccdf86f3ea3728..d8760918f1edf3 100644 --- a/packages/block-library/src/gallery/gallery.native.js +++ b/packages/block-library/src/gallery/gallery.native.js @@ -35,6 +35,7 @@ export const Gallery = ( props ) => { const { mediaPlaceholder, attributes, + images, isNarrow, onBlur, insertBlocksAfter, @@ -49,7 +50,6 @@ export const Gallery = ( props ) => { }, [ sizes ] ); const { - images, align, columns = defaultColumnsNumber( images.length ), } = attributes; From 43ab543bc69915e11a798917b660538721567d3e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 12 Jan 2022 12:34:23 +0000 Subject: [PATCH 083/149] Late escape RSS block (#37878) * Initial pass * Remove escaping using incorrect method * Remove double escape of link --- packages/block-library/src/rss/index.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/block-library/src/rss/index.php b/packages/block-library/src/rss/index.php index b0a31bf2bbd6d0..fb4f952fdac394 100644 --- a/packages/block-library/src/rss/index.php +++ b/packages/block-library/src/rss/index.php @@ -16,11 +16,11 @@ function render_block_core_rss( $attributes ) { $rss = fetch_feed( $attributes['feedURL'] ); if ( is_wp_error( $rss ) ) { - return '
          ' . __( 'RSS Error:' ) . ' ' . $rss->get_error_message() . '
          '; + return '
          ' . esc_html__( 'RSS Error:' ) . ' ' . esc_html( $rss->get_error_message() ) . '
          '; } if ( ! $rss->get_item_quantity() ) { - return '
          ' . __( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '
          '; + return '
          ' . esc_html__( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '
          '; } $rss_items = $rss->get_items( 0, $attributes['itemsToShow'] ); @@ -31,11 +31,11 @@ function render_block_core_rss( $attributes ) { $title = __( '(no title)' ); } $link = $item->get_link(); - $link = esc_url( $link ); + if ( $link ) { - $title = "{$title}"; + $title = '' . esc_html( $title ) . ''; } - $title = "
          {$title}
          "; + $title = '
          ' . esc_html( $title ) . '
          '; $date = ''; if ( $attributes['displayDate'] ) { @@ -44,8 +44,8 @@ function render_block_core_rss( $attributes ) { if ( $date ) { $date = sprintf( ' ', - date_i18n( get_option( 'c' ), $date ), - date_i18n( get_option( 'date_format' ), $date ) + esc_attr( date_i18n( get_option( 'c' ), $date ) ), + esc_html( date_i18n( get_option( 'date_format' ), $date ) ) ); } } @@ -57,7 +57,7 @@ function render_block_core_rss( $attributes ) { $author = $author->get_name(); $author = '' . sprintf( /* translators: %s: the author. */ - __( 'by %s' ), + esc_html__( 'by %s' ), esc_html( strip_tags( $author ) ) ) . ''; } @@ -66,7 +66,7 @@ function render_block_core_rss( $attributes ) { $excerpt = ''; if ( $attributes['displayExcerpt'] ) { $excerpt = html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) ); - $excerpt = esc_attr( wp_trim_words( $excerpt, $attributes['excerptLength'], ' […]' ) ); + $excerpt = wp_trim_words( $excerpt, $attributes['excerptLength'], ' […]' ); // Change existing [...] to […]. if ( '[...]' === substr( $excerpt, -5 ) ) { @@ -76,7 +76,7 @@ function render_block_core_rss( $attributes ) { $excerpt = '
          ' . esc_html( $excerpt ) . '
          '; } - $list_items .= "
        • {$title}{$date}{$author}{$excerpt}
        • "; + $list_items .= '
        • ' . esc_html( $title . $date . $author . $excerpt ) . '
        • '; } $classnames = array(); From c6ca200b048f188b94452c4e7585c1b3a86c6d46 Mon Sep 17 00:00:00 2001 From: Siobhan Bamber Date: Wed, 12 Jan 2022 13:35:17 +0000 Subject: [PATCH 084/149] [RNMobile] Add Contrast Checker to Text-Based Blocks (#34902) With this PR, a contrast checker is added to the text-based blocks in the native apps. This checker will display the following notice when users pick a custom text/background colours with poor contrast: > This colour combination may be hard for people to read. Try using a brighter background colour and/or a darker text colour. --- packages/base-styles/_colors.native.scss | 3 + .../panel-color-gradient-settings.native.js | 13 +- .../contrast-checker/index.native.js | 113 ++++++++++++++++++ .../contrast-checker/style.native.scss | 26 ++++ .../src/components/index.native.js | 1 + .../src/hooks/color-panel.native.js | 63 ++++++++++ packages/react-native-editor/CHANGELOG.md | 1 + 7 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 packages/block-editor/src/components/contrast-checker/index.native.js create mode 100644 packages/block-editor/src/components/contrast-checker/style.native.scss create mode 100644 packages/block-editor/src/hooks/color-panel.native.js diff --git a/packages/base-styles/_colors.native.scss b/packages/base-styles/_colors.native.scss index ba76d005b622a3..c21de46e6a4595 100644 --- a/packages/base-styles/_colors.native.scss +++ b/packages/base-styles/_colors.native.scss @@ -80,6 +80,9 @@ $gray-80: #2c3338; $gray-90: #1d2327; $gray-100: #101517; +$yellow-30: #deb100; +$yellow-50: #9d6e00; + // neutral (light) - black is a base color in light mode $light-primary: #000d; //rgba(0, 0, 0, 0.87); $light-secondary: #0009; //rgba(0, 0, 0, 0.6); diff --git a/packages/block-editor/src/components/colors-gradients/panel-color-gradient-settings.native.js b/packages/block-editor/src/components/colors-gradients/panel-color-gradient-settings.native.js index b00b643dfb99a4..55d2938db0b594 100644 --- a/packages/block-editor/src/components/colors-gradients/panel-color-gradient-settings.native.js +++ b/packages/block-editor/src/components/colors-gradients/panel-color-gradient-settings.native.js @@ -14,7 +14,11 @@ import { useMemo } from '@wordpress/element'; */ import { blockSettingsScreens } from '../block-settings'; -export default function PanelColorGradientSettings( { settings, title } ) { +export default function PanelColorGradientSettings( { + settings, + title, + children, +} ) { const navigation = useNavigation(); const mappedSettings = useMemo( () => { @@ -46,5 +50,10 @@ export default function PanelColorGradientSettings( { settings, title } ) { ); }, [ settings ] ); - return { mappedSettings }; + return ( + <> + { mappedSettings } + { children } + + ); } diff --git a/packages/block-editor/src/components/contrast-checker/index.native.js b/packages/block-editor/src/components/contrast-checker/index.native.js new file mode 100644 index 00000000000000..edd60473fcc36e --- /dev/null +++ b/packages/block-editor/src/components/contrast-checker/index.native.js @@ -0,0 +1,113 @@ +/** + * External dependencies + */ +import { Text, View } from 'react-native'; +import { colord, extend } from 'colord'; +import namesPlugin from 'colord/plugins/names'; +import a11yPlugin from 'colord/plugins/a11y'; + +/** + * WordPress dependencies + */ +import { speak } from '@wordpress/a11y'; +import { __ } from '@wordpress/i18n'; +import { useEffect } from '@wordpress/element'; +import { usePreferredColorSchemeStyle } from '@wordpress/compose'; +import { Icon, warning } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import styles from './style.scss'; + +extend( [ namesPlugin, a11yPlugin ] ); + +function ContrastCheckerMessage( { + colordBackgroundColor, + colordTextColor, + backgroundColor, + textColor, + msgStyle, +} ) { + const msg = + colordBackgroundColor.brightness() < colordTextColor.brightness() + ? __( + 'This color combination may be hard for people to read. Try using a darker background color and/or a brighter text color.' + ) + : __( + 'This color combination may be hard for people to read. Try using a brighter background color and/or a darker text color.' + ); + + // Note: The `Notice` component can speak messages via its `spokenMessage` + // prop, but the contrast checker requires granular control over when the + // announcements are made. Notably, the message will be re-announced if a + // new color combination is selected and the contrast is still insufficient. + useEffect( () => { + speak( __( 'This color combination may be hard for people to read.' ) ); + }, [ backgroundColor, textColor ] ); + + const iconStyle = usePreferredColorSchemeStyle( + styles[ 'block-editor-contrast-checker__icon' ], + styles[ 'block-editor-contrast-checker__icon-dark' ] + ); + + return ( + + + { msg } + + ); +} + +function ContrastChecker( { + backgroundColor, + fallbackBackgroundColor, + fallbackTextColor, + fontSize, // font size value in pixels + isLargeText, + textColor, +} ) { + const msgStyle = usePreferredColorSchemeStyle( + styles[ 'block-editor-contrast-checker__notice' ], + styles[ 'block-editor-contrast-checker__notice-dark' ] + ); + + if ( + ! ( backgroundColor || fallbackBackgroundColor ) || + ! ( textColor || fallbackTextColor ) + ) { + return null; + } + + const colordBackgroundColor = colord( + backgroundColor || fallbackBackgroundColor + ); + const colordTextColor = colord( textColor || fallbackTextColor ); + + const hasTransparency = + colordBackgroundColor.alpha() !== 1 || colordTextColor.alpha() !== 1; + + if ( + hasTransparency || + colordTextColor.isReadable( colordBackgroundColor, { + level: 'AA', + size: + isLargeText || ( isLargeText !== false && fontSize >= 24 ) + ? 'large' + : 'small', + } ) + ) { + return null; + } + + return ( + + ); +} + +export default ContrastChecker; diff --git a/packages/block-editor/src/components/contrast-checker/style.native.scss b/packages/block-editor/src/components/contrast-checker/style.native.scss new file mode 100644 index 00000000000000..5b86e88f9f4cc4 --- /dev/null +++ b/packages/block-editor/src/components/contrast-checker/style.native.scss @@ -0,0 +1,26 @@ +.block-editor-contrast-checker { + flex-direction: row; + align-items: center; + padding: 8px 0; + justify-content: space-between; +} + +.block-editor-contrast-checker__notice { + font-size: 11px; + font-weight: 500; + color: $yellow-50; + flex: 1; +} + +.block-editor-contrast-checker__notice-dark { + color: $yellow-30; +} + +.block-editor-contrast-checker__icon { + color: $yellow-50; + margin-right: 5px; +} + +.block-editor-contrast-checker__icon-dark { + color: $yellow-30; +} diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index ff9456282bd230..3da9ce79c7bc50 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -54,6 +54,7 @@ export { default as __experimentalPanelColorGradientSettings } from './colors-gr export { default as useSetting } from './use-setting'; export { default as __experimentalUseNoRecursiveRenders } from './use-no-recursive-renders'; export { default as Warning } from './warning'; +export { default as ContrastChecker } from './contrast-checker'; export { BottomSheetSettings, diff --git a/packages/block-editor/src/hooks/color-panel.native.js b/packages/block-editor/src/hooks/color-panel.native.js new file mode 100644 index 00000000000000..fd24db05a57b54 --- /dev/null +++ b/packages/block-editor/src/hooks/color-panel.native.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useEffect, useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { useGlobalStyles } from '@wordpress/components'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import PanelColorGradientSettings from '../components/colors-gradients/panel-color-gradient-settings'; +import ContrastChecker from '../components/contrast-checker'; +import InspectorControls from '../components/inspector-controls'; + +const ColorPanel = ( { settings } ) => { + const globalStyles = useGlobalStyles(); + + const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState(); + const [ detectedTextColor, setDetectedTextColor ] = useState(); + + const { baseGlobalStyles } = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + return { + baseGlobalStyles: getSettings() + ?.__experimentalGlobalStylesBaseStyles?.color, + }; + } ); + + useEffect( () => { + // The following logic is used to determine current text/background colors: + // 1. The globalStyles object is queried to determine whether a color has been + // set via a block's settings. + // 2. If a block-based theme is in use and no globalStyles exist, the theme's + // default/base colors are used. + // 3. If no globalStyles exist and a theme isn't block-based, there is no way + // to determine the default text/background color and the checker won't run. + const textColor = globalStyles?.color || baseGlobalStyles?.text; + const backgroundColor = + globalStyles?.backgroundColor || baseGlobalStyles?.background; + + setDetectedTextColor( textColor ); + setDetectedBackgroundColor( backgroundColor ); + }, [ globalStyles, baseGlobalStyles ] ); + + return ( + + + + + + ); +}; + +export default ColorPanel; diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 370ab02d93ddfc..bd1c20821200e2 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,6 +11,7 @@ For each user feature we should also add a importance categorization label to i ## Unreleased +- [*] Add contrast checker to text-based blocks [#34902] ## 1.69.0 - [*] Give multi-line block names central alignment in inserter [#37185] - [**] Fix empty line apperaing when splitting heading blocks on Android 12 [#37279] From eddbea3fc06f7af393725bf6ac11a8573814de88 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 12 Jan 2022 13:48:42 +0000 Subject: [PATCH 085/149] Bump plugin version to 12.4.0-rc.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index fa23b016d33479..29d391620fbc63 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.7 * Requires PHP: 5.6 - * Version: 12.3.2 + * Version: 12.4.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 54fdd24cbe59fd..f6241b6f45b0cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "12.3.2", + "version": "12.4.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 406447e3ad9f38..cd37b8d4d3f754 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "12.3.2", + "version": "12.4.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index 0acd41fd3292c6..a793bfea314c3c 100644 --- a/readme.txt +++ b/readme.txt @@ -56,4 +56,4 @@ The four phases of the project are Editing, Customization, Collaboration, and Mu == Changelog == -To read the changelog for Gutenberg 12.3.2, please navigate to the release page. +To read the changelog for Gutenberg 12.4.0-rc.1, please navigate to the release page. From 4f53f74f598405d3d5c5a8fa29d767c41b057f61 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 12 Jan 2022 16:11:22 +0000 Subject: [PATCH 086/149] Update Changelog for 12.4.0-rc.1 --- changelog.txt | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/changelog.txt b/changelog.txt index a6da0f0e7b0bcf..ad741af22e51a5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,178 @@ == Changelog == += 12.4.0-rc.1 = + + + +### Enhancements + +#### Accessibility +- Accessibility improvements for Block Inserter. ([37357](https://github.com/WordPress/gutenberg/pull/37357)) +- Accessibility improvements for List View Part 1. ([37798](https://github.com/WordPress/gutenberg/pull/37798)) +- Improve successful draft save notification for screen readers. ([37683](https://github.com/WordPress/gutenberg/pull/37683)) +- Try possibly better method for Block Inserter Search focus. ([37793](https://github.com/WordPress/gutenberg/pull/37793)) + +#### Block Library +- Audio: Add uploading state. ([37739](https://github.com/WordPress/gutenberg/pull/37739)) +- Post Excerpt: Add to and from Post Content transformations. ([37651](https://github.com/WordPress/gutenberg/pull/37651)) +- Search: Improve escaping on the search block. ([37829](https://github.com/WordPress/gutenberg/pull/37829)) +- Page List: Add menu-item-home class to Navigation for front page. ([37301](https://github.com/WordPress/gutenberg/pull/37301)) +- Tag Cloud: Add outline style. ([37092](https://github.com/WordPress/gutenberg/pull/37092)) + +#### Components +- ExternalLink: Update icon to be smaller, have no margin. ([37859](https://github.com/WordPress/gutenberg/pull/37859)) + +#### Post Editor +- PostLockedModal: Display preview link as part of the text. ([37852](https://github.com/WordPress/gutenberg/pull/37852)) +- Try: Polish post takeover modal. ([37821](https://github.com/WordPress/gutenberg/pull/37821)) +- Suggest picking a category on the pre-publish panel. ([37703](https://github.com/WordPress/gutenberg/pull/37703)) + +#### Block Editor +- Inserter: Update categories for theme blocks. ([37723](https://github.com/WordPress/gutenberg/pull/37723)) + +#### Site Editor +- Add keyboard shortcut help modal. ([37650](https://github.com/WordPress/gutenberg/pull/37650)) +- Update copy on Snackbar that appears when a template is deleted. ([37888](https://github.com/WordPress/gutenberg/pull/37888)) + +#### Icons +- Add unlock icon. ([37855](https://github.com/WordPress/gutenberg/pull/37855)) + +### Bug Fixes + +#### Block Library +- Code: Remove color from code theme.scss. ([37816](https://github.com/WordPress/gutenberg/pull/37816)) +- Code: Try: Polish code styles to properly apply border properties. ([37818](https://github.com/WordPress/gutenberg/pull/37818)) +- Columns: Avoid using CSS variables for block gap styles. ([37436](https://github.com/WordPress/gutenberg/pull/37436)) +- Comments Pagination Next: Fix accidental division by zero. ([37788](https://github.com/WordPress/gutenberg/pull/37788)) +- Gallery: Pass any custom attributes through the gallery v2 migration script. ([37812](https://github.com/WordPress/gutenberg/pull/37812)) +- Gallery: Remove warning notice about mobile version required. ([37842](https://github.com/WordPress/gutenberg/pull/37842)) +- Navigation: HTML tags like inline images in nav links break submenu layout. ([37665](https://github.com/WordPress/gutenberg/pull/37665)) +- Navigation: Set the default for --navigation-layout-align to "flex-start" when using vertical orientation. ([37696](https://github.com/WordPress/gutenberg/pull/37696)) +- Navigation: Fix overlay menu errant focus style on scrim. ([37824](https://github.com/WordPress/gutenberg/pull/37824)) +- Page List: Show UI warning if Pages cannot be retrieved in Page List block. ([37486](https://github.com/WordPress/gutenberg/pull/37486)) +- Page List: Update page list flex variables to match navigation. ([37718](https://github.com/WordPress/gutenberg/pull/37718)) +- Post Comments: Tidy up Post Comments default styling. ([37709](https://github.com/WordPress/gutenberg/pull/37709)) +- Post Content: Check for nextpage to display page links for paginated posts. ([37672](https://github.com/WordPress/gutenberg/pull/37672)) +- Post Excerpt: Fix previews. ([37648](https://github.com/WordPress/gutenberg/pull/37648)) +- Query Loop: Use `gap` for the `grid` view. ([37711](https://github.com/WordPress/gutenberg/pull/37711)) +- Query Loop: Check for `zero` `queryId` on initialization. ([37867](https://github.com/WordPress/gutenberg/pull/37867)) +- Site logo: Fix range control on landscape logos. ([37733](https://github.com/WordPress/gutenberg/pull/37733)) +- Simplify and unify a few modal dialogs. ([37857](https://github.com/WordPress/gutenberg/pull/37857)) +- Fix enqueueing additional styles for blocks only when rendered. ([37848](https://github.com/WordPress/gutenberg/pull/37848)) +- Fix typo (hanle -> handle). ([37849](https://github.com/WordPress/gutenberg/pull/37849)) +- Revert "[Paragraph Block] add font family support". ([37815](https://github.com/WordPress/gutenberg/pull/37815)) + +#### Colors +- Coloring panel is unusable in RTL. ([37644](https://github.com/WordPress/gutenberg/pull/37644)) +- Impossible to clear colors if color palettes are removed. ([37791](https://github.com/WordPress/gutenberg/pull/37791)) +- Use useCallback hook from @wordpress/elements in color-picker. ([37745](https://github.com/WordPress/gutenberg/pull/37745)) + +#### Components +- BaseControl: Fix VisualLabel styles. ([37747](https://github.com/WordPress/gutenberg/pull/37747)) +- ConfirmDialog: Use hooks from @wordpress/elements. ([37771](https://github.com/WordPress/gutenberg/pull/37771)) +- CustomSelectControl: Stop keypresses being caught by other elements when they happen. ([30557](https://github.com/WordPress/gutenberg/pull/30557)) + +#### Post Editor +- Restore canvas padding for classic themes. ([37741](https://github.com/WordPress/gutenberg/pull/37741)) + +#### History +- Fix broken 'Redo' by removing faulty logic for discarding unsaved Logo changes. ([37895](https://github.com/WordPress/gutenberg/pull/37895)) +- Fix redo after update/publish with transient edits. ([37840](https://github.com/WordPress/gutenberg/pull/37840)) + +#### Templates API +- Fix Home template description typo. ([37843](https://github.com/WordPress/gutenberg/pull/37843)) +- Improve user experience with blocks editor when a block is not registered. ([37646](https://github.com/WordPress/gutenberg/pull/37646)) + +#### Block Editor +- Fix LinkPicker freeze when virtual keyboard is hidden. ([37782](https://github.com/WordPress/gutenberg/pull/37782)) +- RichText: Fix dead key input on Windows. ([37777](https://github.com/WordPress/gutenberg/pull/37777)) +- Link control: Translate empty link string. ([36975](https://github.com/WordPress/gutenberg/pull/36975)) +- Add `post-type-x` classname to iframe. ([37429](https://github.com/WordPress/gutenberg/pull/37429)) + +#### Global Styles +- Reduce specificity of legacy font sizes defined by core. ([37819](https://github.com/WordPress/gutenberg/pull/37819)) + +#### Accessibility +- Fix aria-modal attribution with multiple navs on page. ([37813](https://github.com/WordPress/gutenberg/pull/37813)) + +#### Template Editor +- Template Mode: Trim long post titles in large viewports. ([37720](https://github.com/WordPress/gutenberg/pull/37720)) + +#### Site Editor +- Add the "Help" link to the tools menu. ([37647](https://github.com/WordPress/gutenberg/pull/37647)) +- Contextualize "Export" string to differentiate it from other occurrences in WP Core. ([37660](https://github.com/WordPress/gutenberg/pull/37660)) + + +### Documentation + +- Block.json Schema: Update fontSize and lineHeight props. ([37853](https://github.com/WordPress/gutenberg/pull/37853)) +- Theme.json Schema: Fix appearanceTools in theme.json schema. ([37762](https://github.com/WordPress/gutenberg/pull/37762)) +- Theme.json Schema: Update theme.json schema to allow for per-block management of settings. ([36746](https://github.com/WordPress/gutenberg/pull/36746)) +- Add checkbox for updating schemas if appropriate. ([37780](https://github.com/WordPress/gutenberg/pull/37780)) + - Fix issue template typo. ([37825](https://github.com/WordPress/gutenberg/pull/37825)) +- Add automated theme.json reference documentation. ([37569](https://github.com/WordPress/gutenberg/pull/37569)) +- Add link to block source for reference. ([37750](https://github.com/WordPress/gutenberg/pull/37750)) +- Add mising end tag for codetabs in stylesheet guide. ([37827](https://github.com/WordPress/gutenberg/pull/37827)) +- Fix broken URL on block variation page. ([37702](https://github.com/WordPress/gutenberg/pull/37702)) +- Fix type of saved $content. ([37688](https://github.com/WordPress/gutenberg/pull/37688)) + - Fix type of saved content - part two. ([37740](https://github.com/WordPress/gutenberg/pull/37740)) + - Fix PHPCS failure. ([37742](https://github.com/WordPress/gutenberg/pull/37742)) +- Update create block type how to guide for block.json. ([37674](https://github.com/WordPress/gutenberg/pull/37674)) +- Update stylesheets guide with using block.json file. ([37679](https://github.com/WordPress/gutenberg/pull/37679)) +- OSX Setup guide: Wrap `lts/*` in quotes for `nvm` commands. ([37722](https://github.com/WordPress/gutenberg/pull/37722)) +- Remove "experimental" from full site editing documentation. ([37655](https://github.com/WordPress/gutenberg/pull/37655)) +- Update copyright year to 2022 in `license.md`. ([37689](https://github.com/WordPress/gutenberg/pull/37689)) +- Update wp-plugin.md. ([37846](https://github.com/WordPress/gutenberg/pull/37846)) +- Updated ColorIndicator readme. ([37638](https://github.com/WordPress/gutenberg/pull/37638)) +- Update the Post Author block description. ([37836](https://github.com/WordPress/gutenberg/pull/37836)) +- Fixing broken links and adding colon. ([37664](https://github.com/WordPress/gutenberg/pull/37664)) + + +### Code Quality + +- Add the WP version in which some JS APIs will be removed. ([37854](https://github.com/WordPress/gutenberg/pull/37854)) + +#### Block Library +- Late escape Categories block. ([37835](https://github.com/WordPress/gutenberg/pull/37835)) +- Late escape Page List block. ([37873](https://github.com/WordPress/gutenberg/pull/37873)) +- Late escape Query blocks. ([37877](https://github.com/WordPress/gutenberg/pull/37877)) +- Late escape RSS block. ([37878](https://github.com/WordPress/gutenberg/pull/37878)) +- Late escape Table of Contents block. ([37882](https://github.com/WordPress/gutenberg/pull/37882)) +- Late escape Search block. ([37879](https://github.com/WordPress/gutenberg/pull/37879)) +- Move escaping to point of output in Archives block. ([37834](https://github.com/WordPress/gutenberg/pull/37834)) +- Post Content: No need to pass default get_the_content args. ([37701](https://github.com/WordPress/gutenberg/pull/37701)) + +#### Post Editor +- PostLockedModal: Update action buttons markup. ([37837](https://github.com/WordPress/gutenberg/pull/37837)) + +#### Parsing +- Block API: Separate validation stage during block parsing. ([37763](https://github.com/WordPress/gutenberg/pull/37763)) + +#### Components +- Refactor SuggestionsList to use hooks and change class to function component. ([36924](https://github.com/WordPress/gutenberg/pull/36924)) + + +### Tools + +#### Testing +- Allow type imports for React everywhere. ([37862](https://github.com/WordPress/gutenberg/pull/37862)) +- Change the performance job folder structure to avoid nested node_modules. ([37775](https://github.com/WordPress/gutenberg/pull/37775)) +- Fix flaky test by using waitForResponse to ensure the URL details request completes. ([37901](https://github.com/WordPress/gutenberg/pull/37901)) +- Marking test that consistently fails as skipped. ([37729](https://github.com/WordPress/gutenberg/pull/37729)) + +#### Build Tooling +- wp-env: Replace TT1-Blocks with Empty Theme in the wp-env of gutenberg and CI. ([37446](https://github.com/WordPress/gutenberg/pull/37446)) +- wp-env: Show `--help` when no subcommand is passed. ([32755](https://github.com/WordPress/gutenberg/pull/32755)) +- Scripts: Scan `block.json` files to detect entry points for the build process. ([37661](https://github.com/WordPress/gutenberg/pull/37661)) +- Scripts: Add `plugin-zip` command to create a zip file for a WordPress plugin. ([37687](https://github.com/WordPress/gutenberg/pull/37687)) + +#### Create Block +- Allow custom folder name for a block. ([37612](https://github.com/WordPress/gutenberg/pull/37612)) +- Speed up scaffolding by omitting WordPress dependencies. ([37639](https://github.com/WordPress/gutenberg/pull/37639)) + + + + = 12.3.2 = ### Bug Fixes From bea24fbd7ec829ed84c5dd30e5416052440f5171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 12 Jan 2022 18:02:38 +0100 Subject: [PATCH 087/149] Load the global styles before the theme styles in the editor (#37885) Fixes https://github.com/WordPress/gutenberg/issues/37839 This follows what we do in the front-end, where theme styles are loaded after global styles by default. --- lib/global-styles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/global-styles.php b/lib/global-styles.php index 0f71bea0fd1a15..fdcf44214b7601 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -79,7 +79,7 @@ function_exists( 'gutenberg_is_edit_site_page' ) && } } - $settings['styles'] = array_merge( $styles_without_existing_global_styles, $new_global_styles ); + $settings['styles'] = array_merge( $new_global_styles, $styles_without_existing_global_styles ); } // Copied from get_block_editor_settings() at wordpress-develop/block-editor.php. From 8203ef47a34aac03d7c13df00f720c1cac2894fa Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 12 Jan 2022 18:55:43 +0100 Subject: [PATCH 088/149] E2E Tests: Add coverage for reusable blocks save button state regression (#33151) Add E2E test coverage for #33072. --- .../editor/various/reusable-blocks.test.js | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js index 0cf2ed53210993..39ec1d62fba41f 100644 --- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js @@ -15,6 +15,7 @@ import { openDocumentSettingsSidebar, saveDraft, createReusableBlock, + publishPost, } from '@wordpress/e2e-test-utils'; const reusableBlockNameInputSelector = @@ -23,11 +24,22 @@ const reusableBlockInspectorNameInputSelector = '.block-editor-block-inspector .components-text-control__input'; const saveAll = async () => { - await page.click( '.editor-post-publish-button__button.has-changes-dot' ); - await page.waitForSelector( - 'button.editor-entities-saved-states__save-button' + const publishButtonSelector = + '.editor-post-publish-button__button.has-changes-dot'; + // Wait for the Publish button to become enabled in case the editor is autosaving ATM: + const publishButton = await page.waitForSelector( + publishButtonSelector + '[aria-disabled="false"]' ); - await page.click( 'button.editor-entities-saved-states__save-button' ); + await publishButton.click(); + + const saveButtonSelector = + 'button.editor-entities-saved-states__save-button'; + const saveButton = await page.waitForSelector( saveButtonSelector ); + await saveButton.click(); +}; + +const saveAllButDontPublish = async () => { + await saveAll(); // no need to publish the post. const cancelPublish = await page.waitForSelector( @@ -81,7 +93,7 @@ describe( 'Reusable blocks', () => { await page.keyboard.type( 'Oh! ' ); // Save the reusable block - await saveAll(); + await saveAllButDontPublish(); // Check that its content is up to date const text = await page.$eval( @@ -112,6 +124,41 @@ describe( 'Reusable blocks', () => { expect( paragraphContent ).toMatch( 'Oh! Hello there!' ); } ); + // Check for regressions of https://github.com/WordPress/gutenberg/issues/33072. + it( 'can be saved when modified inside of a published post', async () => { + await createReusableBlock( + 'Guten Berg!', + 'Alternative greeting block' + ); + + // Make sure the reusable block has loaded properly before attempting to publish the post. + await page.waitForSelector( 'p[aria-label="Paragraph block"]' ); + + await publishPost(); + + // Close publish panel. + const closePublishPanelSelector = + '.editor-post-publish-panel__header button[aria-label="Close panel"]'; + await page.waitForSelector( closePublishPanelSelector ); + await page.click( closePublishPanelSelector ); + + await page.waitForSelector( 'p[aria-label="Paragraph block"]' ); + await page.focus( 'p[aria-label="Paragraph block"]' ); + + // Change the block's content + await page.keyboard.type( 'Einen ' ); + + // Save the reusable block and update the post + await saveAll(); + + // Check that its content is up to date + const paragraphContent = await page.$eval( + 'p[aria-label="Paragraph block"]', + ( element ) => element.innerText + ); + expect( paragraphContent ).toMatch( 'Einen Guten Berg!' ); + } ); + it( 'can be inserted after refresh', async () => { await createReusableBlock( 'Awesome Paragraph', 'Awesome block' ); From 80ffd8c6e6daf43abb3398b74280a7c5ab6257dc Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 13 Jan 2022 09:22:40 +1300 Subject: [PATCH 089/149] Navigation Block : remove use of --wp--style--block-gap css variable for block gap support (#37543) Co-authored-by: Glen Davies Co-authored-by: ramonjd --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/navigation/block.json | 6 +++++- packages/block-library/src/navigation/style.scss | 9 ++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 07ba399dabceb0..7909e928911943 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -365,7 +365,7 @@ A collection of blocks that allow visitors to get around your site. ([Source](ht - **Name:** core/navigation - **Category:** theme -- **Supports:** align (full, wide), anchor, inserter, spacing (units), typography (fontSize, lineHeight), ~~html~~ +- **Supports:** align (full, wide), anchor, inserter, spacing (blockGap, units), typography (fontSize, lineHeight), ~~html~~ - **Attributes:** __unstableLocation, backgroundColor, customBackgroundColor, customOverlayBackgroundColor, customOverlayTextColor, customTextColor, openSubmenusOnClick, overlayBackgroundColor, overlayMenu, overlayTextColor, ref, rgbBackgroundColor, rgbTextColor, showSubmenuIcon, textColor ## Navigation Area diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index 6759cde277fa27..96a049e9f0bad0 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -92,7 +92,11 @@ } }, "spacing": { - "units": [ "px", "em", "rem", "vh", "vw" ] + "blockGap": true, + "units": [ "px", "em", "rem", "vh", "vw" ], + "__experimentalDefaultControls": { + "blockGap": true + } }, "__experimentalLayout": { "allowSwitching": false, diff --git a/packages/block-library/src/navigation/style.scss b/packages/block-library/src/navigation/style.scss index 961762f861442b..0139ba5fff9d74 100644 --- a/packages/block-library/src/navigation/style.scss +++ b/packages/block-library/src/navigation/style.scss @@ -306,11 +306,14 @@ button.wp-block-navigation-item__content { */ // Menu items with no background. +.wp-block-navigation__responsive-container, +.wp-block-navigation__responsive-close, +.wp-block-navigation__responsive-dialog, .wp-block-navigation, .wp-block-navigation .wp-block-page-list, .wp-block-navigation__container, .wp-block-navigation__responsive-container-content { - gap: var(--wp--style--block-gap, 2em); + gap: inherit; } // Menu items with background. @@ -321,7 +324,7 @@ button.wp-block-navigation-item__content { &, .wp-block-navigation .wp-block-page-list, .wp-block-navigation__container { - gap: var(--wp--style--block-gap, 0.5em); + gap: inherit; } } @@ -509,7 +512,7 @@ button.wp-block-navigation-item__content { // Space unfolded items using gap and padding for submenus. .wp-block-navigation__submenu-container, .wp-block-navigation__container { - gap: var(--wp--style--block-gap, 2em); + gap: inherit; } // Apply top padding to nested submenus. From b4bfdf3aac50d8968aa3d486101cde28d5ad80c5 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 13 Jan 2022 13:42:58 +0800 Subject: [PATCH 090/149] Fix flaky classic block conversion undo test (#37933) --- packages/e2e-tests/specs/editor/blocks/classic.test.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js index cd5dc9cf2623cc..b12add309c114c 100644 --- a/packages/e2e-tests/specs/editor/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -45,8 +45,10 @@ describe( 'Classic', () => { await page.keyboard.type( 'test' ); // Click the image button. - await page.waitForSelector( 'div[aria-label^="Add Media"]' ); - await page.click( 'div[aria-label^="Add Media"]' ); + const addMediaButton = await page.waitForSelector( + 'div[aria-label^="Add Media"]' + ); + await addMediaButton.click(); await page.click( '.media-menu-item#menu-item-gallery' ); @@ -92,6 +94,7 @@ describe( 'Classic', () => { // Check that you can undo back to a Classic block gallery in one step. await pressKeyWithModifier( 'primary', 'z' ); + await page.waitForSelector( 'div[aria-label="Block: Classic"]' ); expect( await getEditedPostContent() ).toMatch( /\[gallery ids=\"\d+\"\]/ ); From 07a8e747ed37d7c4a56f3a555ba4b1215dfa243e Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 13 Jan 2022 09:58:19 +0000 Subject: [PATCH 091/149] Late escape comments link block (#37875) * Initial pass * Rename variable and avoid escaping pre-built HTML --- .../block-library/src/post-comments-link/index.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/post-comments-link/index.php b/packages/block-library/src/post-comments-link/index.php index 6f0aa103f47626..2db2536bb0edb9 100644 --- a/packages/block-library/src/post-comments-link/index.php +++ b/packages/block-library/src/post-comments-link/index.php @@ -27,28 +27,28 @@ function render_block_core_post_comments_link( $attributes, $content, $block ) { $comments_number = (int) get_comments_number( $block->context['postId'] ); $comments_link = get_comments_link( $block->context['postId'] ); $post_title = get_the_title( $block->context['postId'] ); - $comment_text = ''; + $comment_html = ''; if ( 0 === $comments_number ) { - $comment_text = sprintf( + $comment_html = sprintf( /* translators: %s post title */ __( 'No comments on %s' ), - $post_title + esc_html( $post_title ) ); } else { - $comment_text = sprintf( + $comment_html = sprintf( /* translators: 1: Number of comments, 2: post title */ _n( '%1$s comment on %2$s', '%1$s comments on %2$s', $comments_number ), - number_format_i18n( $comments_number ), - $post_title + esc_html( number_format_i18n( $comments_number ) ), + esc_html( $post_title ) ); } - return ""; + return ''; } /** From 8be802d28511792e6d03a6fd41e4b57e9732acc5 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 13 Jan 2022 09:59:36 +0000 Subject: [PATCH 092/149] Late escape post author blocks (#37874) * Post author initial pass * Author name initial pass * Remove uneeded escaping on `get_block_wrapper_attributes` --- packages/block-library/src/post-author-name/index.php | 2 +- packages/block-library/src/post-author/index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/post-author-name/index.php b/packages/block-library/src/post-author-name/index.php index ded8a48b85a793..5efc5718727a6a 100644 --- a/packages/block-library/src/post-author-name/index.php +++ b/packages/block-library/src/post-author-name/index.php @@ -27,7 +27,7 @@ function render_block_core_post_author_name( $attributes, $content, $block ) { $align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}"; if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) { - $author_name = sprintf( '%3$s', get_author_posts_url( $author_id ), $attributes['linkTarget'], $author_name ); + $author_name = sprintf( '%3$s', get_author_posts_url( $author_id ), esc_attr( $attributes['linkTarget'] ), $author_name ); } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) ); diff --git a/packages/block-library/src/post-author/index.php b/packages/block-library/src/post-author/index.php index e31be65f709942..dd251c2fd1c41e 100644 --- a/packages/block-library/src/post-author/index.php +++ b/packages/block-library/src/post-author/index.php @@ -40,7 +40,7 @@ function render_block_core_post_author( $attributes, $content, $block ) { return sprintf( '
          ', $wrapper_attributes ) . ( ! empty( $attributes['showAvatar'] ) ? '' : '' ) . '' . From 5a1b1f13dba73baaf1f15758d89b8e00fb114717 Mon Sep 17 00:00:00 2001 From: Rich Tabor Date: Thu, 13 Jan 2022 05:13:44 -0500 Subject: [PATCH 093/149] Add transforms (#37920) --- packages/block-library/src/site-logo/index.js | 2 ++ .../block-library/src/site-logo/transforms.js | 21 +++++++++++++++++++ .../block-library/src/site-title/index.js | 2 ++ .../src/site-title/transforms.js | 21 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 packages/block-library/src/site-logo/transforms.js create mode 100644 packages/block-library/src/site-title/transforms.js diff --git a/packages/block-library/src/site-logo/index.js b/packages/block-library/src/site-logo/index.js index 5ff08c804799df..d5e652d9580576 100644 --- a/packages/block-library/src/site-logo/index.js +++ b/packages/block-library/src/site-logo/index.js @@ -8,6 +8,7 @@ import { siteLogo as icon } from '@wordpress/icons'; */ import metadata from './block.json'; import edit from './edit'; +import transforms from './transforms'; const { name } = metadata; export { metadata, name }; @@ -15,4 +16,5 @@ export { metadata, name }; export const settings = { icon, edit, + transforms, }; diff --git a/packages/block-library/src/site-logo/transforms.js b/packages/block-library/src/site-logo/transforms.js new file mode 100644 index 00000000000000..6c77c82d5df5fb --- /dev/null +++ b/packages/block-library/src/site-logo/transforms.js @@ -0,0 +1,21 @@ +/** + * WordPress dependencies + */ +import { createBlock } from '@wordpress/blocks'; + +const transforms = { + to: [ + { + type: 'block', + blocks: [ 'core/site-title' ], + transform: ( { isLink, linkTarget } ) => { + return createBlock( 'core/site-title', { + isLink, + linkTarget, + } ); + }, + }, + ], +}; + +export default transforms; diff --git a/packages/block-library/src/site-title/index.js b/packages/block-library/src/site-title/index.js index d2b155ebcc8f3d..2c38d37390a76a 100644 --- a/packages/block-library/src/site-title/index.js +++ b/packages/block-library/src/site-title/index.js @@ -9,6 +9,7 @@ import { mapMarker as icon } from '@wordpress/icons'; import metadata from './block.json'; import edit from './edit'; import deprecated from './deprecated'; +import transforms from './transforms'; const { name } = metadata; export { metadata, name }; @@ -16,5 +17,6 @@ export { metadata, name }; export const settings = { icon, edit, + transforms, deprecated, }; diff --git a/packages/block-library/src/site-title/transforms.js b/packages/block-library/src/site-title/transforms.js new file mode 100644 index 00000000000000..a3c1221aeb4b6b --- /dev/null +++ b/packages/block-library/src/site-title/transforms.js @@ -0,0 +1,21 @@ +/** + * WordPress dependencies + */ +import { createBlock } from '@wordpress/blocks'; + +const transforms = { + to: [ + { + type: 'block', + blocks: [ 'core/site-logo' ], + transform: ( { isLink, linkTarget } ) => { + return createBlock( 'core/site-logo', { + isLink, + linkTarget, + } ); + }, + }, + ], +}; + +export default transforms; From 0aa5e545fc3fa70bf45aa39d2ec83f67d0aee3cc Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 13 Jan 2022 12:06:09 +0100 Subject: [PATCH 094/149] `SelectControl`: mark the `children` prop as optional (#37872) * `SelectControl`: mark the `children` prop as optional * Update prop documentation * Rename Storybook example * Changelog --- packages/components/CHANGELOG.md | 1 + packages/components/src/select-control/README.md | 4 ++-- packages/components/src/select-control/index.tsx | 6 ++++-- packages/components/src/select-control/stories/index.js | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index c03e959a54be86..2496d5c4cd01b2 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -10,6 +10,7 @@ - Add missing styles to the `BaseControl.VisualLabel` component. ([#37747](https://github.com/WordPress/gutenberg/pull/37747)) - Prevent keyDown events from propagating up in `CustomSelectControl` ([#30557](https://github.com/WordPress/gutenberg/pull/30557)) +- Mark `children` prop as optional in `SelectControl` ([#37872](https://github.com/WordPress/gutenberg/pull/37872)) ## 19.2.0 (2022-01-04) diff --git a/packages/components/src/select-control/README.md b/packages/components/src/select-control/README.md index 17d99165383d82..9d059fc8cf5470 100644 --- a/packages/components/src/select-control/README.md +++ b/packages/components/src/select-control/README.md @@ -201,9 +201,9 @@ An array of objects containing the following properties: #### children -An alternative to the `options` prop. +An alternative to the `options` prop. Use the `children` prop to have more control on the style of the items being rendered, like `optgroup`s or `options` and possibly avoid re-rendering due to the reference update on the `options` prop. -- Type: `Element` +- Type: `ReactNode` - Required: No #### onChange diff --git a/packages/components/src/select-control/index.tsx b/packages/components/src/select-control/index.tsx index 7ee32b6f55cb3a..ec2afed60d7123 100644 --- a/packages/components/src/select-control/index.tsx +++ b/packages/components/src/select-control/index.tsx @@ -3,7 +3,8 @@ */ import { isEmpty, noop } from 'lodash'; import classNames from 'classnames'; -import type { ChangeEvent, FocusEvent, Ref } from 'react'; +// eslint-disable-next-line no-restricted-imports +import type { ChangeEvent, FocusEvent, ReactNode, Ref } from 'react'; /** * WordPress dependencies @@ -30,7 +31,7 @@ function useUniqueId( idProp?: string ) { } export interface SelectControlProps - extends Omit< InputBaseProps, 'isFocused' > { + extends Omit< InputBaseProps, 'children' | 'isFocused' > { help?: string; hideLabelFromVision?: boolean; multiple?: boolean; @@ -49,6 +50,7 @@ export interface SelectControlProps size?: Size; value?: string | string[]; labelPosition?: LabelPosition; + children?: ReactNode; } function SelectControl( diff --git a/packages/components/src/select-control/stories/index.js b/packages/components/src/select-control/stories/index.js index 4d616b2926184a..5b21c55070feaf 100644 --- a/packages/components/src/select-control/stories/index.js +++ b/packages/components/src/select-control/stories/index.js @@ -69,7 +69,7 @@ export const _default = () => { return ; }; -export const withNativeChildren = () => { +export const withCustomChildren = () => { return ( From 22111f5bf2ed9cbb6db558ea7c03888c4f593b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20K=C3=A4gy?= Date: Thu, 13 Jan 2022 12:26:43 +0100 Subject: [PATCH 095/149] Add documentation for useBlockEditContext hook (#36299) * Add documentation for useBlockEditContext hook * fix spelling mistakes * Revert 'Add documentation for useBlockEditContext hook' * Move documentation inline to export of useBlockEditContext --- packages/block-editor/README.md | 9 ++++++++- packages/block-editor/src/components/block-edit/index.js | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 94a227890243b6..55eaf01f744cda 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -662,7 +662,14 @@ _Returns_ ### useBlockEditContext -Undocumented declaration. +The `useBlockEditContext` hook provides information about the block this hook is being used in. +It returns an object with the `name`, `isSelected` state, and the `clientId` of the block. +It is useful if you want to create custom hooks that need access to the current blocks clientId +but don't want to rely on the data getting passed in as a parameter. + +_Returns_ + +- `Object`: Block edit context ### useBlockProps diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 019ea12789c2b3..9b2875b3018a30 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -9,6 +9,14 @@ import { useMemo } from '@wordpress/element'; import Edit from './edit'; import { BlockEditContextProvider, useBlockEditContext } from './context'; +/** + * The `useBlockEditContext` hook provides information about the block this hook is being used in. + * It returns an object with the `name`, `isSelected` state, and the `clientId` of the block. + * It is useful if you want to create custom hooks that need access to the current blocks clientId + * but don't want to rely on the data getting passed in as a parameter. + * + * @return {Object} Block edit context + */ export { useBlockEditContext }; export default function BlockEdit( props ) { From 5e4f87b1f482c1f14665a28e906fccc81281aab0 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Thu, 13 Jan 2022 14:07:52 +0200 Subject: [PATCH 096/149] [Block Library - Post Featured Image]: Show all the controls when inside a Query Loop (#37945) --- .../src/post-featured-image/edit.js | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js index 6d38eb17f79b15..ed84d7b95a1804 100644 --- a/packages/block-library/src/post-featured-image/edit.js +++ b/packages/block-library/src/post-featured-image/edit.js @@ -92,9 +92,36 @@ function PostFeaturedImageDisplay( { createErrorNotice( message[ 2 ], { type: 'snackbar' } ); }; + const controls = ( + <> + + + + setAttributes( { isLink: ! isLink } ) } + checked={ isLink } + /> + + + + ); let image; if ( ! featuredImage && isDescendentOfQueryLoop ) { - return
          { placeholderChip }
          ; + return ( + <> + { controls } +
          { placeholderChip }
          + + ); } const label = __( 'Add a featured image' ); @@ -138,24 +165,7 @@ function PostFeaturedImageDisplay( { return ( <> - - - - setAttributes( { isLink: ! isLink } ) } - checked={ isLink } - /> - - + { controls } { !! media && ! isDescendentOfQueryLoop && ( Date: Thu, 13 Jan 2022 13:25:52 +0000 Subject: [PATCH 097/149] Remove warning for enqueued styles in Editor (#37937) --- .../src/components/iframe/index.js | 10 +++------- .../plugins/iframed-inline-styles.test.js | 6 ------ ...iframed-multiple-block-stylesheets.test.js | 4 ---- .../specs/widgets/customizing-widgets.test.js | 20 ------------------- .../specs/widgets/editing-widgets.test.js | 12 ----------- 5 files changed, 3 insertions(+), 49 deletions(-) diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js index 20d2f99fe72dbd..b4e1e44f6568bf 100644 --- a/packages/block-editor/src/components/iframe/index.js +++ b/packages/block-editor/src/components/iframe/index.js @@ -75,13 +75,9 @@ function styleSheetsCompat( doc ) { ); if ( isMatch && ! doc.getElementById( ownerNode.id ) ) { - // eslint-disable-next-line no-console - console.warn( - `Stylesheet ${ ownerNode.id } was not properly added. -For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). -For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles).`, - ownerNode.outerHTML - ); + // Display warning once we have a way to add style dependencies to the editor. + // See: https://github.com/WordPress/gutenberg/pull/37466. + doc.head.appendChild( ownerNode.cloneNode( true ) ); // Add inline styles belonging to the stylesheet. diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js index a995a80335da5a..4e4b0123235be8 100644 --- a/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js +++ b/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js @@ -57,11 +57,5 @@ describe( 'iframed inline styles', () => { expect( await getComputedStyle( canvas(), 'border-width' ) ).toBe( '2px' ); - - expect( console ).toHaveWarned( - `Stylesheet iframed-inline-styles-compat-style-css was not properly added. -For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). -For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles). ` - ); } ); } ); diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js index 900fec05be34d4..cc7aa8826b8f4f 100644 --- a/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js +++ b/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js @@ -63,9 +63,5 @@ describe( 'iframed multiple block stylesheets', () => { expect( await getComputedStyle( canvas(), 'background-color' ) ).toBe( 'rgb(0, 0, 0)' ); - - // Skip warnings related to block-styles enqueing and the use of add_editor_style. - // The issue is tracked on https://github.com/WordPress/gutenberg/issues/33212. - expect( console ).toHaveWarned(); } ); } ); diff --git a/packages/e2e-tests/specs/widgets/customizing-widgets.test.js b/packages/e2e-tests/specs/widgets/customizing-widgets.test.js index dec762a39da59c..4c6449676701bc 100644 --- a/packages/e2e-tests/specs/widgets/customizing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/customizing-widgets.test.js @@ -19,10 +19,6 @@ import { // eslint-disable-next-line no-restricted-imports import { find, findAll } from 'puppeteer-testing-library'; -const twentyTwentyError = `Stylesheet twentytwenty-block-editor-styles-css was not properly added. -For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). -For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles).`; - describe( 'Widgets Customizer', () => { beforeEach( async () => { await deleteAllWidgets(); @@ -163,8 +159,6 @@ describe( 'Widgets Customizer', () => { name: 'My Search', selector: '.widget-content *', } ).toBeFound( findOptions ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should open the inspector panel', async () => { @@ -250,8 +244,6 @@ describe( 'Widgets Customizer', () => { } ).toBeFound(); await expect( inspectorHeading ).not.toBeVisible(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should handle the inserter outer section', async () => { @@ -359,8 +351,6 @@ describe( 'Widgets Customizer', () => { name: 'Add a block', level: 2, } ).not.toBeFound(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should move focus to the block', async () => { @@ -456,8 +446,6 @@ describe( 'Widgets Customizer', () => { text: 'First Heading', } ); await expect( headingBlock ).toHaveFocus(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should clear block selection', async () => { @@ -520,8 +508,6 @@ describe( 'Widgets Customizer', () => { role: 'toolbar', name: 'Block tools', } ).not.toBeFound(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should handle legacy widgets', async () => { @@ -700,8 +686,6 @@ describe( 'Widgets Customizer', () => { selector: '*[aria-live="polite"][aria-relevant="additions text"]', } ).toBeFound(); await expect( paragraphBlock ).toBeVisible(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should move (inner) blocks to another sidebar', async () => { @@ -761,8 +745,6 @@ describe( 'Widgets Customizer', () => { await expect( movedParagraphBlockQuery ).toBeFound(); const movedParagraphBlock = await find( movedParagraphBlockQuery ); await expect( movedParagraphBlock ).toHaveFocus(); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'should not render Block Settings sections', async () => { @@ -855,8 +837,6 @@ describe( 'Widgets Customizer', () => { name: 'Customizing ▸ Widgets ▸ Footer #1 Block Settings', level: 3, } ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); } ); diff --git a/packages/e2e-tests/specs/widgets/editing-widgets.test.js b/packages/e2e-tests/specs/widgets/editing-widgets.test.js index 14330a4725de54..6174302419443e 100644 --- a/packages/e2e-tests/specs/widgets/editing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/editing-widgets.test.js @@ -25,10 +25,6 @@ import { import { find, findAll } from 'puppeteer-testing-library'; import { groupBy, mapValues } from 'lodash'; -const twentyTwentyError = `Stylesheet twentytwenty-block-editor-styles-css was not properly added. -For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). -For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles).`; - describe( 'Widgets screen', () => { beforeEach( async () => { await visitWidgetsScreen(); @@ -232,8 +228,6 @@ describe( 'Widgets screen', () => {
          ", } ` ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it.skip( 'Should insert content using the inline inserter', async () => { @@ -601,8 +595,6 @@ describe( 'Widgets screen', () => { initialSerializedWidgetAreas[ 'sidebar-1' ], ].join( '\n' ) ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it.skip( 'Should display legacy widgets', async () => { @@ -777,8 +769,6 @@ describe( 'Widgets screen', () => {
      ", } ` ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'Allows widget deletion to be undone', async () => { @@ -838,8 +828,6 @@ describe( 'Widgets screen', () => {
      ", } ` ); - - expect( console ).toHaveWarned( twentyTwentyError ); } ); it( 'can toggle sidebar list view', async () => { From 2916ef95eb9caac949529ed374cc30ef9767d92c Mon Sep 17 00:00:00 2001 From: Anton Vlasenko <43744263+anton-vlasenko@users.noreply.github.com> Date: Thu, 13 Jan 2022 15:00:23 +0100 Subject: [PATCH 098/149] Docs: Improve Gutenberg release documentation (#37898) * Updated the documentation so it's eaiser to understand whether a person needs to sync trunk or not. * Improve formatting. * Improve wording. * Improve grammar Co-authored-by: Dave Smith Co-authored-by: Dave Smith --- docs/contributors/code/release.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/contributors/code/release.md b/docs/contributors/code/release.md index e3f5fab69a74c4..fef57077473b66 100644 --- a/docs/contributors/code/release.md +++ b/docs/contributors/code/release.md @@ -160,7 +160,11 @@ There is also an option to perform [Standalone Bugfix Package Releases](#standal ### Synchronizing WordPress Trunk -For each Gutenberg plugin release, WordPress trunk should be synchronized. Note that the WordPress `trunk` branch can be closed or in "feature-freeze" mode. Usually, this happens between the first `beta` and the first `RC` of the WordPress release cycle. During this period, the Gutenberg plugin releases should not be synchronized with WordPress Core. +For each Gutenberg plugin release, WordPress trunk should be synchronized. + +Note that the WordPress `trunk` branch can be closed or in "feature-freeze" mode. Usually, feature freeze in WordPress Core happens about 2 weeks before Beta 1 and remains in effect until RC1 when the `trunk` gets branched. During this period, the Gutenberg plugin releases should not be synchronized with WordPress Core. + +A different person usually synchronizes the WordPress `trunk` branch and publishes the npm packages. Therefore, you typically shouldn't need to worry about handling this for the normal plugin release process. However, if you are still unsure, ask in [the #core-editor Slack channel](https://wordpress.slack.com/archives/C02QB2JS7). The process has three steps: 1) update the `wp/trunk` branch within the Gutenberg repo 2) publish the new package versions to npm 3) update the WordPress `trunk` branch. From 0dfecd2058b96f93b73082d051bed1a6506965f3 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 13 Jan 2022 14:06:03 +0000 Subject: [PATCH 099/149] Late escape comment blocks (#37860) * Escape and late escape * Escape classes in author block * Escape classes in comment content * Escape output in comment date * Escape edit link * Escape reply link * Escape comment template * Use correct escaping function * Remove overzealous escaping * Remove incorrect escaping * Remove unecessary escaping * Remove escaping handled elsewhere * Remove escaping handed by core functions * Remove unnecessary escaping * Remove escaping of HTML string * Remove unnecessary escaping --- packages/block-library/src/comment-date/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/comment-date/index.php b/packages/block-library/src/comment-date/index.php index 9dcdef59c7f412..b7a240e812dec2 100644 --- a/packages/block-library/src/comment-date/index.php +++ b/packages/block-library/src/comment-date/index.php @@ -31,13 +31,13 @@ function render_block_core_comment_date( $attributes, $content, $block ) { $link = get_comment_link( $comment ); if ( ! empty( $attributes['isLink'] ) ) { - $formatted_date = sprintf( '%2s', $link, $formatted_date ); + $formatted_date = sprintf( '%2s', esc_url( $link ), esc_html( $formatted_date ) ); } return sprintf( '
      ', $wrapper_attributes, - get_comment_date( 'c', $comment ), + esc_attr( get_comment_date( 'c', $comment ) ), $formatted_date ); } From f0982d1586ccc53ffc5df0b0e7f1a35dc9b40043 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 13 Jan 2022 14:06:44 +0000 Subject: [PATCH 100/149] Late escape Post blocks (#37876) * Post date initial pass * Post excerpt initial pass * Feature image block first pass * Post Navigation link first pass * Post Template first pass * Post terms first pass * First pass Post title * Avoid double escaping * Remove redunant escaping `get_block_wrapper_attributes` will escape for us. This is as per feedback on other PRs involving late escaping. --- packages/block-library/src/post-date/index.php | 4 ++-- packages/block-library/src/post-excerpt/index.php | 2 +- packages/block-library/src/post-featured-image/index.php | 2 +- packages/block-library/src/post-navigation-link/index.php | 6 +++--- packages/block-library/src/post-template/index.php | 4 ++-- packages/block-library/src/post-terms/index.php | 2 +- packages/block-library/src/post-title/index.php | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/post-date/index.php b/packages/block-library/src/post-date/index.php index 051fc04f4d9131..b49f3d8d261a8f 100644 --- a/packages/block-library/src/post-date/index.php +++ b/packages/block-library/src/post-date/index.php @@ -29,8 +29,8 @@ function render_block_core_post_date( $attributes, $content, $block ) { return sprintf( '
      ', $wrapper_attributes, - get_the_date( 'c', $post_ID ), - $formatted_date + esc_attr( get_the_date( 'c', $post_ID ) ), + esc_html( $formatted_date ) ); } diff --git a/packages/block-library/src/post-excerpt/index.php b/packages/block-library/src/post-excerpt/index.php index d650cc3cf073b5..27d160c5aa5308 100644 --- a/packages/block-library/src/post-excerpt/index.php +++ b/packages/block-library/src/post-excerpt/index.php @@ -24,7 +24,7 @@ function render_block_core_post_excerpt( $attributes, $content, $block ) { return ''; } - $more_text = ! empty( $attributes['moreText'] ) ? '' . $attributes['moreText'] . '' : ''; + $more_text = ! empty( $attributes['moreText'] ) ? '' . esc_html( $attributes['moreText'] ) . '' : ''; $filter_excerpt_more = function( $more ) use ( $more_text ) { return empty( $more_text ) ? $more : ''; }; diff --git a/packages/block-library/src/post-featured-image/index.php b/packages/block-library/src/post-featured-image/index.php index 21e6aca4450621..2f06854da204f3 100644 --- a/packages/block-library/src/post-featured-image/index.php +++ b/packages/block-library/src/post-featured-image/index.php @@ -43,7 +43,7 @@ function render_block_core_post_featured_image( $attributes, $content, $block ) if ( ! empty( $attributes['scale'] ) ) { $image_styles .= "object-fit:{$attributes['scale']};"; } - $featured_image = str_replace( 'src=', "style='$image_styles' src=", $featured_image ); + $featured_image = str_replace( 'src=', 'style="' . esc_attr( $image_styles ) . '" src=', $featured_image ); } return "
      $featured_image
      "; diff --git a/packages/block-library/src/post-navigation-link/index.php b/packages/block-library/src/post-navigation-link/index.php index 9fedf38d6fa1cb..1f3f2a4bb7dc64 100644 --- a/packages/block-library/src/post-navigation-link/index.php +++ b/packages/block-library/src/post-navigation-link/index.php @@ -49,13 +49,13 @@ function render_block_core_post_navigation_link( $attributes, $content ) { */ if ( ! $attributes['linkLabel'] ) { if ( $label ) { - $format = '' . $label . ' %link'; + $format = '' . esc_html( $label ) . ' %link'; } $link = '%title'; } elseif ( isset( $attributes['linkLabel'] ) && $attributes['linkLabel'] ) { // If the label link option is enabled and there is a custom label, display it before the title. if ( $label ) { - $link = '' . $label . ' %title'; + $link = '' . esc_html( $label ) . ' %title'; } else { /* * If the label link option is enabled and there is no custom label, @@ -64,7 +64,7 @@ function render_block_core_post_navigation_link( $attributes, $content ) { $label = 'next' === $navigation_type ? _x( 'Next:', 'label before the title of the next post' ) : _x( 'Previous:', 'label before the title of the previous post' ); $link = sprintf( '%1$s %2$s', - $label, + esc_html( $label ), '%title' ); } diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index 45bf3c4c64602e..725c805148d829 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -61,8 +61,8 @@ function render_block_core_post_template( $attributes, $content, $block ) { ) ) )->render( array( 'dynamic' => false ) ); - $post_classes = esc_attr( implode( ' ', get_post_class( 'wp-block-post' ) ) ); - $content .= '
    • ' . $block_content . '
    • '; + $post_classes = implode( ' ', get_post_class( 'wp-block-post' ) ); + $content .= '
    • ' . $block_content . '
    • '; } wp_reset_postdata(); diff --git a/packages/block-library/src/post-terms/index.php b/packages/block-library/src/post-terms/index.php index 2573c4f0fba4bc..d1902b93a82f98 100644 --- a/packages/block-library/src/post-terms/index.php +++ b/packages/block-library/src/post-terms/index.php @@ -40,7 +40,7 @@ function render_block_core_post_terms( $attributes, $content, $block ) { $block->context['postId'], $attributes['term'], "
      ", - '' . $separator . '', + '' . esc_html( $separator ) . '', '
      ' ); } diff --git a/packages/block-library/src/post-title/index.php b/packages/block-library/src/post-title/index.php index 56302864265165..00166f964f01ef 100644 --- a/packages/block-library/src/post-title/index.php +++ b/packages/block-library/src/post-title/index.php @@ -34,7 +34,7 @@ function render_block_core_post_title( $attributes, $content, $block ) { } if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) { - $title = sprintf( '%4$s', get_the_permalink( $post_ID ), $attributes['linkTarget'], $attributes['rel'], $title ); + $title = sprintf( '%4$s', get_the_permalink( $post_ID ), esc_attr( $attributes['linkTarget'] ), esc_attr( $attributes['rel'] ), esc_html( $title ) ); } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) ); From cef5825431528dfef63dba968019eb3ddd199e22 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 13 Jan 2022 22:33:22 +0800 Subject: [PATCH 101/149] Improve flaky draft creation navigation block e2e test (#37931) * Be less specific about the kind of error * Use per_page=-1 to get all items for deletion * Move expect(console) call to end of test * Make sure drafts are deleted --- .../specs/editor/blocks/navigation.test.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 49269f6e547853..f54791bdb0ad89 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -22,6 +22,7 @@ import { deleteUser, switchUserToAdmin, } from '@wordpress/e2e-test-utils'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -30,6 +31,7 @@ import menuItemsFixture from '../fixtures/menu-items-request-fixture.json'; const POSTS_ENDPOINT = '/wp/v2/posts'; const PAGES_ENDPOINT = '/wp/v2/pages'; +const DRAFT_PAGES_ENDPOINT = [ PAGES_ENDPOINT, { status: 'draft' } ]; const NAVIGATION_MENUS_ENDPOINT = '/wp/v2/navigation'; async function mockSearchResponse( items ) { @@ -126,8 +128,17 @@ const SELECT_MENU_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Select * @param {*} endpoints The endpoints of the resources to delete. */ async function deleteAll( endpoints ) { - for ( const path of endpoints ) { - const items = await rest( { path } ); + for ( const endpoint of endpoints ) { + const defaultArgs = { per_page: -1 }; + const isArrayEndpoint = Array.isArray( endpoint ); + const path = isArrayEndpoint ? endpoint[ 0 ] : endpoint; + const args = isArrayEndpoint + ? { ...defaultArgs, ...endpoint[ 1 ] } + : defaultArgs; + + const items = await rest( { + path: addQueryArgs( path, args ), + } ); for ( const item of items ) { await rest( { @@ -204,6 +215,7 @@ describe( 'Navigation', () => { await deleteAll( [ POSTS_ENDPOINT, PAGES_ENDPOINT, + DRAFT_PAGES_ENDPOINT, NAVIGATION_MENUS_ENDPOINT, ] ); await deleteAllClassicMenus(); @@ -217,6 +229,7 @@ describe( 'Navigation', () => { await deleteAll( [ POSTS_ENDPOINT, PAGES_ENDPOINT, + DRAFT_PAGES_ENDPOINT, NAVIGATION_MENUS_ENDPOINT, ] ); await deleteAllClassicMenus(); @@ -468,9 +481,6 @@ describe( 'Navigation', () => { ); const createPagePromise = createPageButton.click(); await Promise.all( [ responsePromise, createPagePromise ] ); - expect( console ).toHaveErroredWith( - 'Failed to load resource: the server responded with a status of 404 (Not Found)' - ); // Creating a draft is async, so wait for a sign of completion. In this // case the link that shows in the URL popover once a link is added. @@ -482,6 +492,9 @@ describe( 'Navigation', () => { // Expect a Navigation Block with a link for "A really long page name that will not exist". expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); + expect( console ).toHaveErroredWith( + 'Failed to load resource: the server responded with a status of 404 (Not Found)' + ); } ); it( 'renders buttons for the submenu opener elements when the block is set to open on click instead of hover', async () => { From 3018d1143767fd98571cc42d9cddee582a42f637 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 13 Jan 2022 16:42:22 +0000 Subject: [PATCH 102/149] Add: Copy all content to edit site (#37781) --- .../more-menu/copy-content-menu-item.js | 53 +++++++++++++++++++ .../src/components/header/more-menu/index.js | 2 + 2 files changed, 55 insertions(+) create mode 100644 packages/edit-site/src/components/header/more-menu/copy-content-menu-item.js diff --git a/packages/edit-site/src/components/header/more-menu/copy-content-menu-item.js b/packages/edit-site/src/components/header/more-menu/copy-content-menu-item.js new file mode 100644 index 00000000000000..c78bd78f4f3389 --- /dev/null +++ b/packages/edit-site/src/components/header/more-menu/copy-content-menu-item.js @@ -0,0 +1,53 @@ +/** + * WordPress dependencies + */ +import { MenuItem } from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { useCopyToClipboard } from '@wordpress/compose'; +import { store as noticesStore } from '@wordpress/notices'; +import { store as coreStore } from '@wordpress/core-data'; +import { __unstableSerializeAndClean } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../../store'; + +export default function CopyContentMenuItem() { + const { createNotice } = useDispatch( noticesStore ); + const getText = useSelect( ( select ) => { + return () => { + const { getEditedPostId, getEditedPostType } = select( + editSiteStore + ); + const { getEditedEntityRecord } = select( coreStore ); + const record = getEditedEntityRecord( + 'postType', + getEditedPostType(), + getEditedPostId() + ); + if ( record ) { + if ( typeof record.content === 'function' ) { + return record.content( record ); + } else if ( record.blocks ) { + return __unstableSerializeAndClean( record.blocks ); + } else if ( record.content ) { + return record.content; + } + } + return ''; + }; + }, [] ); + + function onSuccess() { + createNotice( 'info', __( 'All content copied.' ), { + isDismissible: true, + type: 'snackbar', + } ); + } + + const ref = useCopyToClipboard( getText, onSuccess ); + + return { __( 'Copy all content' ) }; +} diff --git a/packages/edit-site/src/components/header/more-menu/index.js b/packages/edit-site/src/components/header/more-menu/index.js index afa0f702823b11..2b82b318335766 100644 --- a/packages/edit-site/src/components/header/more-menu/index.js +++ b/packages/edit-site/src/components/header/more-menu/index.js @@ -22,6 +22,7 @@ import FeatureToggle from '../feature-toggle'; import ToolsMoreMenuGroup from '../tools-more-menu-group'; import SiteExport from './site-export'; import WelcomeGuideMenuItem from './welcome-guide-menu-item'; +import CopyContentMenuItem from './copy-content-menu-item'; const POPOVER_PROPS = { className: 'edit-site-more-menu__content', @@ -91,6 +92,7 @@ export default function MoreMenu() { { __( 'Keyboard shortcuts' ) } + Date: Thu, 13 Jan 2022 20:23:37 +0100 Subject: [PATCH 103/149] Bump tmpl from 1.0.4 to 1.0.5 (#37916) * Bump tmpl from 1.0.4 to 1.0.5 Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/daaku/nodejs-tmpl/releases) - [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) --- updated-dependencies: - dependency-name: tmpl dependency-type: indirect ... Signed-off-by: dependabot[bot] * Add back @wordpress/a11y and @wordpress/i18n Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bernie Reiter --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6241b6f45b0cf..951c0cec31e1be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57873,9 +57873,9 @@ } }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, "to-arraybuffer": { "version": "1.0.1", From 90a583a649aba94c853f2752713e001229aacdab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jan 2022 23:09:00 +0100 Subject: [PATCH 104/149] Bump follow-redirects from 1.14.1 to 1.14.7 (#37957) * Bump follow-redirects from 1.14.1 to 1.14.7 Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.1 to 1.14.7. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.1...v1.14.7) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] * Add back @wordpress/a11y and @wordpress/i18n dependencies Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bernie Reiter --- package-lock.json | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 951c0cec31e1be..5a352243defe5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21813,12 +21813,6 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "dev": true }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", - "dev": true - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -25708,14 +25702,6 @@ "dev": true, "requires": { "follow-redirects": "^1.14.0" - }, - "dependencies": { - "follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", - "dev": true - } } }, "axobject-query": { @@ -34478,9 +34464,9 @@ } }, "follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true }, "for-in": { From b4139c22218c75ce0eba7ae40424e8b832c42704 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Fri, 14 Jan 2022 09:50:27 +1100 Subject: [PATCH 105/149] Label components: improve consistency by setting to 8px margin-bottom (#37844) --- .../src/components/border-radius-control/style.scss | 2 +- packages/components/CHANGELOG.md | 1 + .../src/box-control/styles/box-control-styles.js | 2 +- .../src/custom-gradient-picker/style.scss | 1 - packages/components/src/form-token-field/style.scss | 2 +- .../input-control/styles/input-control-styles.tsx | 13 +++++++------ packages/components/src/tools-panel/styles.ts | 2 -- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/components/border-radius-control/style.scss b/packages/block-editor/src/components/border-radius-control/style.scss index 4cfeaaeb6fc739..becab0d9de11e5 100644 --- a/packages/block-editor/src/components/border-radius-control/style.scss +++ b/packages/block-editor/src/components/border-radius-control/style.scss @@ -2,7 +2,7 @@ margin-bottom: $grid-unit-15; legend { - padding-bottom: $grid-unit-05; + margin-bottom: $grid-unit-10; } .components-border-radius-control__wrapper { diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 2496d5c4cd01b2..d3eeb37c88a221 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bug Fix +- Update label spacing for the `BoxControl`, `CustomGradientPicker`, `FormTokenField`, `InputControl`, and `ToolsPanel` components to use a bottom margin of `8px` for consistency. ([#37844](https://github.com/WordPress/gutenberg/pull/37844)) - Add missing styles to the `BaseControl.VisualLabel` component. ([#37747](https://github.com/WordPress/gutenberg/pull/37747)) - Prevent keyDown events from propagating up in `CustomSelectControl` ([#30557](https://github.com/WordPress/gutenberg/pull/30557)) - Mark `children` prop as optional in `SelectControl` ([#37872](https://github.com/WordPress/gutenberg/pull/37872)) diff --git a/packages/components/src/box-control/styles/box-control-styles.js b/packages/components/src/box-control/styles/box-control-styles.js index ffec57a3ba82c7..14238f0a5e6647 100644 --- a/packages/components/src/box-control/styles/box-control-styles.js +++ b/packages/components/src/box-control/styles/box-control-styles.js @@ -19,7 +19,7 @@ export const Root = styled.div` export const Header = styled( Flex )` color: ${ COLORS.ui.label }; - padding-bottom: 8px; + margin-bottom: 8px; `; export const HeaderControlWrapper = styled( Flex )` diff --git a/packages/components/src/custom-gradient-picker/style.scss b/packages/components/src/custom-gradient-picker/style.scss index 4b4daff76ce309..4d0a0ade3567b1 100644 --- a/packages/components/src/custom-gradient-picker/style.scss +++ b/packages/components/src/custom-gradient-picker/style.scss @@ -113,7 +113,6 @@ $components-custom-gradient-picker__padding: $grid-unit-20; // 48px container, 1 .components-custom-gradient-picker { .components-input-control__label { line-height: 1; - padding-bottom: $grid-unit-10 !important; } label { text-transform: uppercase; diff --git a/packages/components/src/form-token-field/style.scss b/packages/components/src/form-token-field/style.scss index 8cd31d6420d7e9..278cf7daba79da 100644 --- a/packages/components/src/form-token-field/style.scss +++ b/packages/components/src/form-token-field/style.scss @@ -53,7 +53,7 @@ .components-form-token-field__label { display: inline-block; - margin-bottom: $grid-unit-05; + margin-bottom: $grid-unit-10; } .components-form-token-field__help { diff --git a/packages/components/src/input-control/styles/input-control-styles.tsx b/packages/components/src/input-control/styles/input-control-styles.tsx index 6436ebb8192621..32879f910535b6 100644 --- a/packages/components/src/input-control/styles/input-control-styles.tsx +++ b/packages/components/src/input-control/styles/input-control-styles.tsx @@ -227,18 +227,18 @@ export const Input = styled.input< InputProps >` } `; -const labelPadding = ( { +const labelMargin = ( { labelPosition, }: { labelPosition?: LabelPosition; } ) => { - let paddingBottom = 4; + let marginBottom = 8; if ( labelPosition === 'edge' || labelPosition === 'side' ) { - paddingBottom = 0; + marginBottom = 0; } - return css( { paddingTop: 0, paddingBottom } ); + return css( { marginTop: 0, marginRight: 0, marginBottom, marginLeft: 0 } ); }; const BaseLabel = styled( Text )< { labelPosition?: LabelPosition } >` @@ -246,11 +246,12 @@ const BaseLabel = styled( Text )< { labelPosition?: LabelPosition } >` box-sizing: border-box; color: currentColor; display: block; - margin: 0; + padding-top: 0; + padding-bottom: 0; max-width: 100%; z-index: 1; - ${ labelPadding } + ${ labelMargin } overflow: hidden; text-overflow: ellipsis; white-space: nowrap; diff --git a/packages/components/src/tools-panel/styles.ts b/packages/components/src/tools-panel/styles.ts index 0819ca0c53116f..3c55af733279bf 100644 --- a/packages/components/src/tools-panel/styles.ts +++ b/packages/components/src/tools-panel/styles.ts @@ -130,8 +130,6 @@ export const ToolsPanelItem = css` */ && ${ LabelWrapper } { label { - margin-bottom: ${ space( 2 ) }; - padding-bottom: 0; line-height: 1.4em; } } From 500e176d40fee9056a4912fef08fab5c0b947f07 Mon Sep 17 00:00:00 2001 From: Jorge Contreras Date: Thu, 13 Jan 2022 22:29:12 -0500 Subject: [PATCH 106/149] Fix draft previews (#37952) * Fix for #33616: Draft posts not previewable - Fixes issue with draft post not previwable if the draft was previously published. - During preview link creation, check if current post is in draft status. * test: Add E2E test for issue #33616 - Add end to end test for issue #33616: Draft post not previewable if the draft was previously published. * test: Update End to End test - Include a link to the issue that the test validates. - Use aria-label instead of css class as a selector for Title field. - Update test title to be more descriptive about the case under test. * docs: Add brief comment to provide context * docs: Remove link to PR * docs: Add link to PR --- .../specs/editor/various/preview.test.js | 67 ++++++++++++++++++- packages/editor/src/store/selectors.js | 7 +- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/preview.test.js b/packages/e2e-tests/specs/editor/various/preview.test.js index 6e830631a4150f..771cdab4995539 100644 --- a/packages/e2e-tests/specs/editor/various/preview.test.js +++ b/packages/e2e-tests/specs/editor/various/preview.test.js @@ -204,7 +204,7 @@ describe( 'Preview', () => { it( 'should not revert title during a preview right after a save draft', async () => { const editorPage = page; - // Type aaaaa in the title filed. + // Type aaaaa in the title field. await editorPage.type( '.editor-post-title__input', 'aaaaa' ); await editorPage.keyboard.press( 'Tab' ); @@ -248,6 +248,71 @@ describe( 'Preview', () => { await previewPage.close(); } ); + + // Verify correct preview. See: https://github.com/WordPress/gutenberg/issues/33616 + it( 'should display the correct preview when switching between published and draft statuses', async () => { + const editorPage = page; + + // Type Lorem in the title field. + await editorPage.type( '[aria-label="Add title"]', 'Lorem' ); + + // Open the preview page. + const previewPage = await openPreviewPage( editorPage ); + await previewPage.waitForSelector( '.entry-title' ); + + // Title in preview should match input. + let previewTitle = await previewPage.$eval( + '.entry-title', + ( node ) => node.textContent + ); + expect( previewTitle ).toBe( 'Lorem' ); + + // Return to editor and publish post. + await editorPage.bringToFront(); + await publishPost(); + + // Close the panel. + await page.waitForSelector( '.editor-post-publish-panel' ); + await page.click( '.editor-post-publish-panel__header button' ); + + // Change the title and preview again. + await editorPage.type( '[aria-label="Add title"]', ' Ipsum' ); + await editorPage.keyboard.press( 'Tab' ); + await waitForPreviewDropdownOpen( editorPage ); + await waitForPreviewNavigation( previewPage ); + + // Title in preview should match updated input. + previewTitle = await previewPage.$eval( + '.entry-title', + ( node ) => node.textContent + ); + + expect( previewTitle ).toBe( 'Lorem Ipsum' ); + + // Return to editor and switch to Draft. + await editorPage.bringToFront(); + await editorPage.waitForSelector( '.editor-post-switch-to-draft' ); + await editorPage.click( '.editor-post-switch-to-draft' ); + await page.keyboard.press( 'Enter' ); + + // Change the title. + await editorPage.type( '[aria-label="Add title"]', 'Draft ' ); + await editorPage.keyboard.press( 'Tab' ); + + // Open the preview page. + await waitForPreviewDropdownOpen( editorPage ); + await waitForPreviewNavigation( previewPage ); + + // Title in preview should match updated input. + previewTitle = await previewPage.$eval( + '.entry-title', + ( node ) => node.textContent + ); + + expect( previewTitle ).toBe( 'Draft Lorem Ipsum' ); + + await previewPage.close(); + } ); } ); describe( 'Preview with Custom Fields enabled', () => { diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index dc115a7cd008e5..cde861d255b3bb 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -839,7 +839,12 @@ export function getEditedPostPreviewLink( state ) { } let previewLink = getAutosaveAttribute( state, 'preview_link' ); - if ( ! previewLink ) { + // Fix for issue: https://github.com/WordPress/gutenberg/issues/33616 + // If the post is draft, ignore the preview link from the autosave record, + // because the preview could be a stale autosave if the post was switched from + // published to draft. + // See: https://github.com/WordPress/gutenberg/pull/37952 + if ( ! previewLink || 'draft' === getCurrentPost( state ).status ) { previewLink = getEditedPostAttribute( state, 'link' ); if ( previewLink ) { previewLink = addQueryArgs( previewLink, { preview: true } ); From 1cf3f882f86e6d8c523bf679730bcba8b7559b29 Mon Sep 17 00:00:00 2001 From: Alex Lende Date: Fri, 14 Jan 2022 01:45:36 -0700 Subject: [PATCH 107/149] Add theme.json v1 reference and v1 to v2 migration docs (#37886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André <583546+oandregal@users.noreply.github.com> --- bin/api-docs/gen-theme-reference.js | 4 +- docs/manifest.json | 20 ++- docs/reference-guides/README.md | 6 + .../theme-json-reference/README.md | 10 ++ .../theme-json-living.md} | 6 +- .../theme-json-migrations.md | 63 ++++++++++ .../theme-json-reference/theme-json-v1.md | 117 ++++++++++++++++++ docs/toc.json | 14 ++- 8 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 docs/reference-guides/theme-json-reference/README.md rename docs/reference-guides/{theme-json-reference.md => theme-json-reference/theme-json-living.md} (88%) create mode 100644 docs/reference-guides/theme-json-reference/theme-json-migrations.md create mode 100644 docs/reference-guides/theme-json-reference/theme-json-v1.md diff --git a/bin/api-docs/gen-theme-reference.js b/bin/api-docs/gen-theme-reference.js index 09c1d36802036f..e07566863420c3 100644 --- a/bin/api-docs/gen-theme-reference.js +++ b/bin/api-docs/gen-theme-reference.js @@ -34,7 +34,7 @@ const THEME_JSON_SCHEMA_FILE = path.resolve( */ const THEME_JSON_REF_DOC = path.resolve( ROOT_DIR, - 'docs/reference-guides/theme-json-reference.md' + 'docs/reference-guides/theme-json-reference/theme-json-living.md' ); /** @@ -126,7 +126,7 @@ const getStylePropertiesMarkup = ( struct ) => { * * @param {string} title * @param {Object} data - * @param {string} type settings|style + * @param {string} type settings|style * @return {string} markup */ const getSectionMarkup = ( title, data, type ) => { diff --git a/docs/manifest.json b/docs/manifest.json index 8a39dea5fcdb46..b12a022e4456eb 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -560,9 +560,27 @@ { "title": "Theme.json Reference", "slug": "theme-json-reference", - "markdown_source": "../docs/reference-guides/theme-json-reference.md", + "markdown_source": "../docs/reference-guides/theme-json-reference/README.md", "parent": "reference-guides" }, + { + "title": "Version 2 (living reference)", + "slug": "theme-json-living", + "markdown_source": "../docs/reference-guides/theme-json-reference/theme-json-living.md", + "parent": "theme-json-reference" + }, + { + "title": "Version 1 Reference", + "slug": "theme-json-v1", + "markdown_source": "../docs/reference-guides/theme-json-reference/theme-json-v1.md", + "parent": "theme-json-reference" + }, + { + "title": "Migrating to Newer Versions", + "slug": "theme-json-migrations", + "markdown_source": "../docs/reference-guides/theme-json-reference/theme-json-migrations.md", + "parent": "theme-json-reference" + }, { "title": "Component Reference", "slug": "components", diff --git a/docs/reference-guides/README.md b/docs/reference-guides/README.md index 787e6144098fa8..a13978610518cf 100644 --- a/docs/reference-guides/README.md +++ b/docs/reference-guides/README.md @@ -35,6 +35,12 @@ - [PluginSidebar](/docs/reference-guides/slotfills/plugin-sidebar.md) - [PluginSidebarMoreMenuItem](/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md) +## [Theme.json Reference](/docs/reference-guides/theme-json-reference/README.md) + +- [Version 2 (living reference)](/docs/reference-guides/theme-json-reference/theme-json-living.md) +- [Version 1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) +- [Migrating to Newer Versions](/docs/reference-guides/theme-json-reference/theme-json-migrations.md) + ## [RichText Reference](/docs/reference-guides/richtext.md) ## [Component Reference](/packages/components/README.md) diff --git a/docs/reference-guides/theme-json-reference/README.md b/docs/reference-guides/theme-json-reference/README.md new file mode 100644 index 00000000000000..819e7d561cda00 --- /dev/null +++ b/docs/reference-guides/theme-json-reference/README.md @@ -0,0 +1,10 @@ +# Theme.json Reference + +This reference guide lists the settings and style properties defined in the theme.json schema. See the [theme.json how to guide](/docs/how-to-guides/themes/theme-json.md) for examples and guide on how to use the theme.json file in your theme. + +- [Version 2 (living reference)](/docs/reference-guides/theme-json-reference/theme-json-living.md) + +## Older Versions + +- [Migrating to Newer Theme.json Versions](/docs/reference-guides/theme-json-reference/theme-json-migrations.md) +- [Version 1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) diff --git a/docs/reference-guides/theme-json-reference.md b/docs/reference-guides/theme-json-reference/theme-json-living.md similarity index 88% rename from docs/reference-guides/theme-json-reference.md rename to docs/reference-guides/theme-json-reference/theme-json-living.md index b7e84eacb134fc..23d53a21ed6406 100644 --- a/docs/reference-guides/theme-json-reference.md +++ b/docs/reference-guides/theme-json-reference/theme-json-living.md @@ -1,4 +1,8 @@ -# Theme.json Reference +# Version 2 (living reference) + +> This is the living specification for the **version 2** of theme.json. This version works with the upcoming WordPress 5.9 and the latest Gutenberg plugin. +> +> There're related documents you may be interested in: the [theme.json v1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) specification and the [reference to migrate from theme.json v1 to v2](/docs/reference-guides/theme-json-reference/theme-json-migrations.md). This reference guide lists the settings and style properties defined in the theme.json schema. See the [theme.json how to guide](/docs/how-to-guides/themes/theme-json.md) for examples and guide on how to use the theme.json file in your theme. diff --git a/docs/reference-guides/theme-json-reference/theme-json-migrations.md b/docs/reference-guides/theme-json-reference/theme-json-migrations.md new file mode 100644 index 00000000000000..cac253f64ffbe9 --- /dev/null +++ b/docs/reference-guides/theme-json-reference/theme-json-migrations.md @@ -0,0 +1,63 @@ +# Migrating to Newer Versions + +This guide documents the changes between different `theme.json` versions and how to upgrade. Using older versions will continue to be supported. Upgrading is recommended because new development will continue in the newer versions. + +## Migrating from v1 to v2 + +Upgrading to v2 enables some new features and adjusts the naming of some old features to be more consistent with one another. + +How to migrate from v1 to v2: + +1. Update `version` to `2`. +2. Rename the properties that were updated (see below) if you're using them. + +Refer to the [dev note for the release](https://make.wordpress.org/core/2022/01/08/updates-for-settings-styles-and-theme-json/) and the [reference documents](/docs/reference-guides/theme-json-reference/README.md) for the respective v1 and v2 versions. + +### Renamed properties + +| v1 | v2 | +| ------------------------------------------ | ------------------------------------ | +| `settings.border.customRadius` | `settings.border.radius` | +| `settings.spacing.customMargin` | `settings.spacing.margin` | +| `settings.spacing.customPadding` | `settings.spacing.padding` | +| `settings.typography.customLineHeight` | `settings.typography.lineHeight` | + +### New properties + +New top-level properties: `customTemplates`, `templateParts`. + +Additions to settings: + +- `settings.appearanceTools` +- `settings.border.color` +- `settings.border.style` +- `settings.border.width` +- `settings.color.background` +- `settings.color.defaultGradients` +- `settings.color.defaultPalette` +- `settings.color.text` +- `settings.spacing.blockGap` +- `settings.typography.fontFamilies` +- `settings.typography.fontStyle` +- `settings.typography.fontWeight` +- `settings.typography.letterSpacing` +- `settings.typography.textDecoration` +- `settings.typography.textTransform` + +Additions to styles: + +- `styles.border.color` +- `styles.border.style` +- `styles.border.width` +- `styles.filter.duotone` +- `styles.spacing.blockGap` +- `styles.typography.fontFamily` +- `styles.typography.fontStyle` +- `styles.typography.fontWeight` +- `styles.typography.letterSpacing` +- `styles.typography.textDecoration` +- `styles.typography.textTransform` + +### Changes to property values + +The default font sizes provided by core (`settings.typography.fontSizes`) have been updated. The Normal and Huge sizes (with `normal` and `huge` slugs) have been removed from the list, and Extra Large (`x-large` slug) has been added. When the UI controls show the default values provided by core, Normal and Huge will no longer be present. However, their CSS classes and CSS Custom Properties are still enqueued to make sure existing content that uses them still works as expected. diff --git a/docs/reference-guides/theme-json-reference/theme-json-v1.md b/docs/reference-guides/theme-json-reference/theme-json-v1.md new file mode 100644 index 00000000000000..d0ed8a70a31102 --- /dev/null +++ b/docs/reference-guides/theme-json-reference/theme-json-v1.md @@ -0,0 +1,117 @@ +# Version 1 Reference + +Theme.json version 2 has been released, see the [theme.json migration guide](/docs/reference-guides/theme-json-reference/theme-json-migrations.md#migrating-from-v1-to-v2) for updating to the latest version. + +## Settings + +### border + +Settings related to borders. + +| Property | Type | Default | Props | +| ------------ | ------- | ------- | ----- | +| customRadius | boolean | false | | + +--- + +### color + +Settings related to colors. + +| Property | Type | Default | Props | +| -------------- | ------- | ------- | -------------------- | +| custom | boolean | true | | +| customDuotone | boolean | true | | +| customGradient | boolean | true | | +| duotone | array | | colors, name, slug | +| gradients | array | | gradient, name, slug | +| link | boolean | false | | +| palette | array | | color, name, slug | + +--- + +### layout + +Settings related to layout. + +| Property | Type | Default | Props | +| ----------- | ------ | ------- | ----- | +| contentSize | string | | | +| wideSize | string | | | + +--- + +### spacing + +Settings related to spacing. + +| Property | Type | Default | Props | +| ------------- | ------- | ----------------- | ----- | +| customMargin | boolean | false | | +| customPadding | boolean | false | | +| units | array | px,em,rem,vh,vw,% | | + +--- + +### typography + +Settings related to typography. + +| Property | Type | Default | Props | +| ---------------- | ------- | ------- | ---------------- | +| customFontSize | boolean | true | | +| customLineHeight | boolean | false | | +| dropCap | boolean | true | | +| fontSizes | array | | name, size, slug | + +--- + +### custom + +Generate custom CSS custom properties of the form `--wp--custom--{key}--{nested-key}: {value};`. `camelCased` keys are transformed to `kebab-case` as to follow the CSS property naming schema. Keys at different depth levels are separated by `--`, so keys should not include `--` in the name. + +--- + +## Styles + +### border + +Border styles. + +| Property | Type | Props | +| -------- | ------ | ----- | +| radius | string | | + +--- + +### color + +Color styles. + +| Property | Type | Props | +| ---------- | ------ | ----- | +| background | string | | +| gradient | string | | +| text | string | | + +--- + +### spacing + +Spacing styles. + +| Property | Type | Props | +| -------- | ------ | ------------------------ | +| margin | object | bottom, left, right, top | +| padding | object | bottom, left, right, top | + +--- + +### typography + +Typography styles. + +| Property | Type | Props | +| ---------- | ------ | ----- | +| fontSize | string | | +| lineHeight | string | | diff --git a/docs/toc.json b/docs/toc.json index 40f53c88ae5c43..60b96af1c4e86a 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -221,7 +221,19 @@ ] }, { "docs/reference-guides/richtext.md": [] }, - { "docs/reference-guides/theme-json-reference.md": [] }, + { + "docs/reference-guides/theme-json-reference/README.md": [ + { + "docs/reference-guides/theme-json-reference/theme-json-living.md": [] + }, + { + "docs/reference-guides/theme-json-reference/theme-json-v1.md": [] + }, + { + "docs/reference-guides/theme-json-reference/theme-json-migrations.md": [] + } + ] + }, { "packages/components/README.md": "{{components}}" }, { "docs/reference-guides/packages.md": "{{packages}}" }, { From 97d4bd9a577e55bc59ce6e77fcb738263b58a36b Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 14 Jan 2022 16:49:25 +0800 Subject: [PATCH 108/149] Fix empty gray circle when site has no logo on template list page (#37474) * Refactor and show icon in place of missing site logo Fix handling of unresolved site Use globe icon Enforce single child for tooltip by using ternary * Fix handling of missing avatar --- .../edit-site/src/components/list/added-by.js | 124 ++++++++---------- 1 file changed, 57 insertions(+), 67 deletions(-) diff --git a/packages/edit-site/src/components/list/added-by.js b/packages/edit-site/src/components/list/added-by.js index 8612499b115b86..d0bfb1efd74785 100644 --- a/packages/edit-site/src/components/list/added-by.js +++ b/packages/edit-site/src/components/list/added-by.js @@ -18,6 +18,7 @@ import { commentAuthorAvatar as authorIcon, layout as themeIcon, plugins as pluginIcon, + globe as globeIcon, } from '@wordpress/icons'; import { __ } from '@wordpress/i18n'; @@ -35,6 +36,45 @@ function CustomizedTooltip( { isCustomized, children } ) { ); } +function BaseAddedBy( { text, icon, imageUrl, isCustomized } ) { + const [ isImageLoaded, setIsImageLoaded ] = useState( false ); + + return ( + + + { imageUrl ? ( +
      + setIsImageLoaded( true ) } + alt="" + src={ imageUrl } + /> +
      + ) : ( +
      + +
      + ) } +
      + { text } +
      + ); +} + function AddedByTheme( { slug, isCustomized } ) { const theme = useSelect( ( select ) => select( coreStore ).getTheme( slug ), @@ -42,18 +82,11 @@ function AddedByTheme( { slug, isCustomized } ) { ); return ( - - -
      - -
      -
      - { theme?.name?.rendered || slug } -
      + ); } @@ -64,18 +97,11 @@ function AddedByPlugin( { slug, isCustomized } ) { ); return ( - - -
      - -
      -
      - { plugin?.name || slug } -
      + ); } @@ -83,35 +109,13 @@ function AddedByAuthor( { id } ) { const user = useSelect( ( select ) => select( coreStore ).getUser( id ), [ id, ] ); - const [ isImageLoaded, setIsImageLoaded ] = useState( false ); - - const avatarURL = user?.avatar_urls?.[ 48 ]; - const hasAvatar = !! avatarURL; return ( - -
      - { hasAvatar ? ( - setIsImageLoaded( true ) } - alt="" - src={ avatarURL } - /> - ) : ( - - ) } -
      - { user?.nickname } -
      + ); } @@ -121,29 +125,15 @@ function AddedBySite() { const siteData = getEntityRecord( 'root', '__unstableBase' ); return { - name: siteData.name, + name: siteData?.name, logoURL: siteData?.site_logo ? getMedia( siteData.site_logo )?.source_url : undefined, }; }, [] ); - const [ isImageLoaded, setIsImageLoaded ] = useState( false ); return ( - -
      - setIsImageLoaded( true ) } - alt="" - src={ logoURL } - /> -
      - { name } -
      + ); } From f6817776426bfcfbcf88be736a506bf42237fe18 Mon Sep 17 00:00:00 2001 From: annezazu Date: Fri, 14 Jan 2022 03:26:04 -0700 Subject: [PATCH 109/149] Docs: Update versions for 5.8.2 and 5.8.3 (#37924) Accidentally got a bit behind on keeping this up to date for the 5.8.* point releases. This catches us up :) --- docs/contributors/versions-in-wordpress.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/contributors/versions-in-wordpress.md b/docs/contributors/versions-in-wordpress.md index 170f6ad76b26f8..88aa56f0021584 100644 --- a/docs/contributors/versions-in-wordpress.md +++ b/docs/contributors/versions-in-wordpress.md @@ -7,6 +7,8 @@ If anything looks incorrect here, please bring it up in #core-editor in [WordPre | Gutenberg Versions | WordPress Version | | ------------------ | ----------------- | | 10.8-11.9 | 5.9 | +| 10.0-10.7 | 5.8.3 | +| 10.0-10.7 | 5.8.2 | | 10.0-10.7 | 5.8.1 | | 10.0-10.7 | 5.8 | | 9.3-9.9 | 5.7.1 | From 3a4fe3461b4595e2f22dc29e954e19b3fd44ed4d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 14 Jan 2022 10:35:09 +0000 Subject: [PATCH 110/149] Late escape Latest Posts block (#37866) * Initial pass * Move escaping of post content to be as late as possible * Remove unwanted esc_html * Revert escaping of translated content * Revert escaping of input to get_block_wrapper_attributes --- .../block-library/src/latest-posts/index.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/latest-posts/index.php b/packages/block-library/src/latest-posts/index.php index 119fcdc5f2f495..1dc16f90d92081 100644 --- a/packages/block-library/src/latest-posts/index.php +++ b/packages/block-library/src/latest-posts/index.php @@ -86,28 +86,28 @@ function render_block_core_latest_posts( $attributes ) { $post, $attributes['featuredImageSizeSlug'], array( - 'style' => $image_style, + 'style' => esc_attr( $image_style ), ) ); if ( $attributes['addLinkToFeaturedImage'] ) { $featured_image = sprintf( '%3$s', - $post_link, - $title, + esc_url( $post_link ), + esc_attr( $title ), $featured_image ); } $list_items_markup .= sprintf( '
      %2$s
      ', - $image_classes, + esc_attr( $image_classes ), $featured_image ); } $list_items_markup .= sprintf( '%2$s', - $post_link, - $title + esc_url( $post_link ), + esc_html( $title ) ); if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) { @@ -143,14 +143,14 @@ function render_block_core_latest_posts( $attributes ) { $list_items_markup .= sprintf( '
      %1$s
      ', - $trimmed_excerpt + esc_html( $trimmed_excerpt ) ); } if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) { - $post_content = wp_kses_post( html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ) ); + $post_content = html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ); if ( post_password_required( $post ) ) { $post_content = __( 'This content is password protected.' ); @@ -158,7 +158,7 @@ function render_block_core_latest_posts( $attributes ) { $list_items_markup .= sprintf( '
      %1$s
      ', - $post_content + wp_kses_post( $post_content ) ); } From e781ffeaeea90f59de4fd41655ddf5e9169d3cf3 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 14 Jan 2022 13:06:03 +0200 Subject: [PATCH 111/149] [Block Library - Query Loop]: Reorganise inspector controls + `order` selection bug (#37949) * [Block Library - Query Loop]: Reorganise inspector controls * fix typo --- .../block-library/src/query/edit/index.js | 4 +- .../index.js} | 14 +++---- .../edit/inspector-controls/order-control.js | 41 +++++++++++++++++++ 3 files changed, 48 insertions(+), 11 deletions(-) rename packages/block-library/src/query/edit/{query-inspector-controls.js => inspector-controls/index.js} (96%) create mode 100644 packages/block-library/src/query/edit/inspector-controls/order-control.js diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index bf8e95d06e21a8..f31945a08f1d37 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -21,7 +21,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import QueryToolbar from './query-toolbar'; -import QueryInspectorControls from './query-inspector-controls'; +import QueryInspectorControls from './inspector-controls'; import QueryPlaceholder from './query-placeholder'; import { DEFAULTS_POSTS_PER_PAGE } from '../constants'; import { getFirstQueryClientIdFromBlocks } from '../utils'; @@ -65,7 +65,7 @@ export function QueryContent( { attributes, setAttributes } ) { // Changes in query property (which is an object) need to be in the same callback, // because updates are batched after the render and changes in different query properties - // would cause to overide previous wanted changes. + // would cause to override previous wanted changes. useEffect( () => { const newQuery = {}; if ( ! query.perPage && postsPerPage ) { diff --git a/packages/block-library/src/query/edit/query-inspector-controls.js b/packages/block-library/src/query/edit/inspector-controls/index.js similarity index 96% rename from packages/block-library/src/query/edit/query-inspector-controls.js rename to packages/block-library/src/query/edit/inspector-controls/index.js index 5297b06ba4185b..0b9c4bd4974176 100644 --- a/packages/block-library/src/query/edit/query-inspector-controls.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -25,8 +25,9 @@ import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ -import { getTermsInfo, usePostTypes } from '../utils'; -import { MAX_FETCHED_TERMS } from '../constants'; +import OrderControl from './order-control'; +import { getTermsInfo, usePostTypes } from '../../utils'; +import { MAX_FETCHED_TERMS } from '../../constants'; const stickyOptions = [ { label: __( 'Include' ), value: '' }, @@ -217,14 +218,9 @@ export default function QueryInspectorControls( { ) } { ! inherit && ( - - setQuery( { order: value } ) - } - onOrderByChange={ ( value ) => - setQuery( { orderBy: value } ) - } + onChange={ setQuery } /> ) } { showSticky && ( diff --git a/packages/block-library/src/query/edit/inspector-controls/order-control.js b/packages/block-library/src/query/edit/inspector-controls/order-control.js new file mode 100644 index 00000000000000..143e4c5f8dd8b0 --- /dev/null +++ b/packages/block-library/src/query/edit/inspector-controls/order-control.js @@ -0,0 +1,41 @@ +/** + * WordPress dependencies + */ +import { SelectControl } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +const orderOptions = [ + { + label: __( 'Newest to oldest' ), + value: 'date/desc', + }, + { + label: __( 'Oldest to newest' ), + value: 'date/asc', + }, + { + /* translators: label for ordering posts by title in ascending order */ + label: __( 'A → Z' ), + value: 'title/asc', + }, + { + /* translators: label for ordering posts by title in descending order */ + label: __( 'Z → A' ), + value: 'title/desc', + }, +]; +function OrderControl( { order, orderBy, onChange } ) { + return ( + { + const [ newOrderBy, newOrder ] = value.split( '/' ); + onChange( { order: newOrder, orderBy: newOrderBy } ); + } } + /> + ); +} + +export default OrderControl; From bbaaae817af6ed600572b3ff7238db63555cc508 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 14 Jan 2022 11:14:56 +0000 Subject: [PATCH 112/149] Late escape latest comments block (#37865) * Initial pass * Escape comment excerpt * Escape comment post title * Escape author name * Revert escaping of translations * Move Post title escaping at point of output Previously we were esaping within the function generating the title. Now we escape the result of calling the function. * Revert escaping of hardcoded inlined string The key here is that they are inlined and not variables * Revert escape of comment excerpt This is not escaped when used in Core so is ok * Revert escaping get_block_wrapper_attributes --- packages/block-library/src/latest-comments/index.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/latest-comments/index.php b/packages/block-library/src/latest-comments/index.php index 3e649bbf5f7492..1b340f39fe70f0 100644 --- a/packages/block-library/src/latest-comments/index.php +++ b/packages/block-library/src/latest-comments/index.php @@ -30,7 +30,7 @@ function wp_latest_comments_draft_or_post_title( $post = 0 ) { if ( empty( $title ) ) { $title = __( '(no title)' ); } - return esc_html( $title ); + return $title; } /** @@ -86,14 +86,14 @@ function render_block_core_latest_comments( $attributes = array() ) { $author_markup = ''; if ( $author_url ) { - $author_markup .= '' . get_comment_author( $comment ) . ''; + $author_markup .= '' . esc_html( get_comment_author( $comment ) ) . ''; } else { - $author_markup .= '' . get_comment_author( $comment ) . ''; + $author_markup .= '' . esc_html( get_comment_author( $comment ) ) . ''; } // `_draft_or_post_title` calls `esc_html()` so we don't need to wrap that call in // `esc_html`. - $post_title = '' . wp_latest_comments_draft_or_post_title( $comment->comment_post_ID ) . ''; + $post_title = '' . esc_html( wp_latest_comments_draft_or_post_title( $comment->comment_post_ID ) ) . ''; $list_items_markup .= sprintf( /* translators: 1: author name (inside or tag, based on if they have a URL), 2: post title related to this comment */ @@ -106,7 +106,7 @@ function render_block_core_latest_comments( $attributes = array() ) { $list_items_markup .= sprintf( '', esc_attr( get_comment_date( 'c', $comment ) ), - date_i18n( get_option( 'date_format' ), get_comment_date( 'U', $comment ) ) + esc_html( date_i18n( get_option( 'date_format' ), get_comment_date( 'U', $comment ) ) ) ); } $list_items_markup .= ''; From 0d5843db94297b8cc2683b8f866d90a2e97f97f2 Mon Sep 17 00:00:00 2001 From: Siobhan Bamber Date: Fri, 14 Jan 2022 13:38:43 +0000 Subject: [PATCH 113/149] [RNMobile] Hide help button from UBE (#37221) As described in https://github.com/wordpress-mobile/gutenberg-mobile/issues/4339, a help button is currently displaying in the bottom right-hand corner of the unsupported block editor (UBE) in both the Android and iOS apps. The button can be seen while logged into WordPress.com. When tapped on, the button isn't working as expected on iOS and prompts users to navigate away from the editor on Android, creating the potential for edits to be lost. With this PR, the button is hidden from view in order to avoid confusion and potential loss of edits. A high-level overview of the code changes can be found in the `Types of changes` section below. --- .../GutenbergWebViewActivity.java | 8 ++++++++ .../FallbackJavascriptInjection.swift | 8 -------- .../GutenbergWebSingleBlockViewController.swift | 8 ++++++++ .../react-native-bridge/ios/SourceFile.swift | 17 ++++++++++++++++- packages/react-native-editor/CHANGELOG.md | 2 ++ 5 files changed, 34 insertions(+), 9 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 ccc3682a2c661e..2b3302b75e2575 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 @@ -333,10 +333,18 @@ private void injectCssScript() { String injectWPBarsCssScript = getFileContentFromAssets("gutenberg-web-single-block/wp-bar-override.css"); injectWPBarsCssScript = removeWhiteSpace(removeNewLines(injectWPBarsCssScript)); evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectWPBarsCssScript)); + + String injectExternalCssScript = getOnGutenbergReadyExternalStyles(); + injectExternalCssScript = removeWhiteSpace(removeNewLines(injectExternalCssScript)); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectExternalCssScript)); } }); } + protected String getOnGutenbergReadyExternalStyles() { + return new String(); + } + private void injectOnGutenbergReadyExternalSources() { List list = getOnGutenbergReadyExternalSources(); for (String file : list) { diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift index 177eaf80eb1abd..13ae9dd1f05735 100644 --- a/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift @@ -60,14 +60,6 @@ public struct FallbackJavascriptInjection { } } -public extension SourceFile { - func jsScript(with argument: String? = nil) throws -> WKUserScript { - let content = try getContent() - let formatted = String(format: content, argument ?? []) - return formatted.toJsScript() - } -} - internal extension String { func toJsScript() -> WKUserScript { WKUserScript(source: self, injectionTime: .atDocumentEnd, forMainFrameOnly: false) diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift index c077b3aaf1204b..9159b847d52cbd 100644 --- a/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift @@ -58,6 +58,12 @@ open class GutenbergWebSingleBlockViewController: UIViewController { return [] } + /// Requests a set of CSS styles to be added to the web view when the editor has started loading. + /// - Returns: Array of all the styles to be added + open func onGutenbergLoadStyles() -> [WKUserScript] { + return [] + } + /// Requests a set of JS Scripts to be added to the web view when Gutenberg has been initialized. /// - Returns: Array of all the scripts to be added open func onGutenbergReadyScripts() -> [WKUserScript] { @@ -152,6 +158,7 @@ extension GutenbergWebSingleBlockViewController: WKNavigationDelegate { evaluateJavascript(jsInjection.injectWPBarsCssScript) evaluateJavascript(jsInjection.injectLocalStorageScript) onPageLoadScripts().forEach(evaluateJavascript) + onGutenbergLoadStyles().forEach(evaluateJavascript) } public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { @@ -160,6 +167,7 @@ extension GutenbergWebSingleBlockViewController: WKNavigationDelegate { evaluateJavascript(jsInjection.preventAutosavesScript) evaluateJavascript(jsInjection.injectEditorCssScript) evaluateJavascript(jsInjection.gutenbergObserverScript) + onGutenbergLoadStyles().forEach(evaluateJavascript) } } diff --git a/packages/react-native-bridge/ios/SourceFile.swift b/packages/react-native-bridge/ios/SourceFile.swift index ee0e0b54fe4a67..2f75e22278c0f1 100644 --- a/packages/react-native-bridge/ios/SourceFile.swift +++ b/packages/react-native-bridge/ios/SourceFile.swift @@ -20,7 +20,7 @@ public struct SourceFile { self.bundle = bundle } - func getContent() throws -> String { + public func getContent() throws -> String { guard let path = bundle.path(forResource: name, ofType: type.rawValue) else { throw SourceFileError.sourceFileNotFound("\(name).\(type)") } @@ -28,6 +28,21 @@ public struct SourceFile { } } +extension SourceFile { + public func jsScript(with argument: String? = nil) throws -> WKUserScript { + let content = try getContent() + let formatted = String(format: content, argument ?? []) + + switch self.type { + case .css: + let injectCssScriptTemplate = "window.injectCss(`%@`)" + return String(format: injectCssScriptTemplate, formatted).toJsScript() + case .js, .json: + return formatted.toJsScript() + } + } +} + extension SourceFile { static let editorStyle = SourceFile(name: "editor-style-overrides", type: .css) static let wpBarsStyle = SourceFile(name: "wp-bar-override", type: .css) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index bd1c20821200e2..4ee7e30cdebcd4 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,7 +11,9 @@ For each user feature we should also add a importance categorization label to i ## Unreleased +- [*] Hide help button from Unsupported Block Editor. [#37221] - [*] Add contrast checker to text-based blocks [#34902] + ## 1.69.0 - [*] Give multi-line block names central alignment in inserter [#37185] - [**] Fix empty line apperaing when splitting heading blocks on Android 12 [#37279] From 4b80bb34e6d330f53f937bc68f76a41b2967b9e8 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 14 Jan 2022 13:43:03 +0000 Subject: [PATCH 114/149] Show menus selection in placeholder only if available (#37980) * Don't show either Menu section if there are no menus * Fix conditional bug in JSX * Extract to clearer vars * Improve dropdown display conditional * Invert prop dependency --- .../src/navigation/edit/placeholder/index.js | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/navigation/edit/placeholder/index.js b/packages/block-library/src/navigation/edit/placeholder/index.js index bf2453488b8b6b..7e6fe10220328d 100644 --- a/packages/block-library/src/navigation/edit/placeholder/index.js +++ b/packages/block-library/src/navigation/edit/placeholder/index.js @@ -25,7 +25,7 @@ import useNavigationMenu from '../../use-navigation-menu'; import useCreateNavigationMenu from '../use-create-navigation-menu'; const ExistingMenusDropdown = ( { - canSwitchNavigationMenu, + showNavigationMenus, navigationMenus, setSelectedMenu, onFinish, @@ -38,6 +38,10 @@ const ExistingMenusDropdown = ( { iconPosition: 'right', className: 'wp-block-navigation-placeholder__actions__dropdown', }; + + const hasNavigationMenus = !! navigationMenus?.length; + const hasClassicMenus = !! menus?.length; + return ( { ( { onClose } ) => ( <> - - { canSwitchNavigationMenu && - navigationMenus?.map( ( menu ) => { + { showNavigationMenus && hasNavigationMenus && ( + + { navigationMenus.map( ( menu ) => { return ( { @@ -65,10 +69,11 @@ const ExistingMenusDropdown = ( { ); } ) } - - { showClassicMenus && ( + + ) } + { showClassicMenus && hasClassicMenus && ( - { menus?.map( ( menu ) => { + { menus.map( ( menu ) => { return ( { @@ -170,6 +175,12 @@ export default function NavigationPlaceholder( { const { navigationMenus } = useNavigationMenu(); + const hasNavigationMenus = !! navigationMenus?.length; + + const showSelectMenus = + ( canSwitchNavigationMenu || canUserCreateNavigation ) && + ( hasNavigationMenus || hasMenus ); + return ( <> { ( ! hasResolvedNavigationMenus || isStillLoading ) && ( @@ -187,10 +198,10 @@ export default function NavigationPlaceholder( {
      - { hasMenus || navigationMenus?.length ? ( + { showSelectMenus ? ( <> Date: Fri, 14 Jan 2022 15:06:58 +0100 Subject: [PATCH 115/149] [Mobile] - RichText - Use parsed font size values when comparing new changes (#37951) * Mobile - RichText - Use parsed font size values when comparing new changes to avoid not matching values that generate a render loop * Mobile - E2E - Move typography test to full tests instead of canary * Mobile - RichText - Avoid using the fontSize value from the props if there's a font size set from the styles * Mobile - E2E - Remove test and move some test cases into the current integration tests * Mobile - RichTest - Update tests --- .../rich-text/src/component/index.native.js | 42 ++++++++-- .../test/__snapshots__/index.native.js.snap | 65 +++++++++++++++ packages/rich-text/src/test/index.native.js | 83 +++++++++++++++---- 3 files changed, 166 insertions(+), 24 deletions(-) create mode 100644 packages/rich-text/src/test/__snapshots__/index.native.js.snap diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 8eba7874e1f36a..7d6a2d490e6b5c 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -836,8 +836,14 @@ export class RichText extends Component { this._editor.blur(); } - const currentFontSizeStyle = parseFloat( style?.fontSize ); - const prevFontSizeStyle = parseFloat( prevProps?.style?.fontSize ); + // For font size values changes from the font size picker + // we compare previous values to refresh the selected font size, + // this is also used when the tag name changes + // e.g Heading block and a level change like h1->h2. + const currentFontSizeStyle = this.getParsedFontSize( style?.fontSize ); + const prevFontSizeStyle = this.getParsedFontSize( + prevProps?.style?.fontSize + ); const isDifferentTag = prevProps.tagName !== tagName; if ( ( currentFontSize && @@ -891,6 +897,20 @@ export class RichText extends Component { }; } + getParsedFontSize( fontSize ) { + const { height, width } = Dimensions.get( 'window' ); + const cssUnitOptions = { height, width, fontSize: DEFAULT_FONT_SIZE }; + + if ( ! fontSize ) { + return fontSize; + } + + const selectedPxValue = + getPxFromCssUnit( fontSize, cssUnitOptions ) ?? DEFAULT_FONT_SIZE; + + return parseFloat( selectedPxValue ); + } + getFontSize( props ) { const { baseGlobalStyles, tagName, fontSize, style } = props; const tagNameFontSize = @@ -898,30 +918,34 @@ export class RichText extends Component { let newFontSize = DEFAULT_FONT_SIZE; + // For block-based themes, get the default editor font size. if ( baseGlobalStyles?.typography?.fontSize ) { newFontSize = baseGlobalStyles?.typography?.fontSize; } + // For block-based themes, get the default element font size + // e.g h1, h2. if ( tagNameFontSize ) { newFontSize = tagNameFontSize; } + // For font size values provided from the styles, + // usually from values set from the font size picker. if ( style?.fontSize ) { newFontSize = style.fontSize; } - if ( fontSize && ! tagNameFontSize ) { + // Fall-back to a font size provided from its props (if there's any) + // and there are no other default values to use. + if ( fontSize && ! tagNameFontSize && ! style?.fontSize ) { newFontSize = fontSize; } - const { height, width } = Dimensions.get( 'window' ); - const cssUnitOptions = { height, width, fontSize: DEFAULT_FONT_SIZE }; + // We need to always convert to px units because the selected value // could be coming from the web where it could be stored as a different unit. - const selectedPxValue = - getPxFromCssUnit( newFontSize, cssUnitOptions ) ?? - DEFAULT_FONT_SIZE; + const selectedPxValue = this.getParsedFontSize( newFontSize ); - return parseFloat( selectedPxValue ); + return selectedPxValue; } getLineHeight() { diff --git a/packages/rich-text/src/test/__snapshots__/index.native.js.snap b/packages/rich-text/src/test/__snapshots__/index.native.js.snap new file mode 100644 index 00000000000000..49c9a7dad92da9 --- /dev/null +++ b/packages/rich-text/src/test/__snapshots__/index.native.js.snap @@ -0,0 +1,65 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` Font Size renders component with style and font size 1`] = ` +" +

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet ut nibh vitae ornare. Sed auctor nec augue at blandit.

      +" +`; + +exports[` Font Size should update the font size when style prop with font size property is provided 1`] = ` + + + +`; + +exports[` Font Size should update the font size with decimals when style prop with font size property is provided 1`] = ` + + + +`; diff --git a/packages/rich-text/src/test/index.native.js b/packages/rich-text/src/test/index.native.js index b48d8828326494..f91e2e18b4bc01 100644 --- a/packages/rich-text/src/test/index.native.js +++ b/packages/rich-text/src/test/index.native.js @@ -1,16 +1,26 @@ -jest.mock( '@wordpress/data/src/components/use-select' ); /** * External dependencies */ import { Dimensions } from 'react-native'; -import { render } from 'test/helpers'; +import { getEditorHtml, render, initializeEditor } from 'test/helpers'; + /** * WordPress dependencies */ -import { useSelect } from '@wordpress/data'; +import { select } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { coreBlocks, registerBlock } from '@wordpress/block-library'; +import { + getBlockTypes, + setDefaultBlockName, + unregisterBlockType, +} from '@wordpress/blocks'; +import '@wordpress/jest-console'; + /** * Internal dependencies */ +import { store as richTextStore } from '../store'; import RichText from '../component/index.native'; /** @@ -25,16 +35,12 @@ const mockGlobalSettings = ( const DEFAULT_GLOBAL_STYLES = { __experimentalGlobalStylesBaseStyles: { typography: { fontSize } }, }; - const selectMock = { - getFormatTypes: jest.fn().mockReturnValue( [] ), - getBlockParents: jest.fn(), - getBlock: jest.fn(), - getSettings: jest.fn().mockReturnValue( DEFAULT_GLOBAL_STYLES ), - }; - - useSelect.mockImplementation( ( callback ) => { - return callback( () => selectMock ); - } ); + jest.spyOn( select( blockEditorStore ), 'getSettings' ).mockReturnValue( + DEFAULT_GLOBAL_STYLES + ); + jest.spyOn( select( richTextStore ), 'getFormatTypes' ).mockReturnValue( + [] + ); }; describe( '', () => { @@ -51,6 +57,13 @@ describe( '', () => { [ '1.42vh', 19 ], ]; + beforeAll( () => { + // Register Paragraph block + const paragraph = coreBlocks[ 'core/paragraph' ]; + registerBlock( paragraph ); + setDefaultBlockName( paragraph.name ); + } ); + beforeEach( () => { mockGlobalSettings( {} ); } ); @@ -59,6 +72,13 @@ describe( '', () => { Dimensions.set( { window } ); } ); + afterAll( () => { + // Clean up registered blocks + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); + } ); + describe( 'Font Size', () => { it( 'should display rich text at the DEFAULT font size.', () => { // Arrange @@ -133,10 +153,10 @@ describe( '', () => { } ); - it( `should display rich text at the font size computed from the LOCAL \`fontSize\` CSS with HIGHEST PRIORITY + it( `should display rich text at the font size computed from the LOCAL \`style.fontSize\` CSS with HIGHEST PRIORITY when CSS is provided ambiguously from ALL possible sources.`, () => { // Arrange - const expectedFontSize = 2; + const expectedFontSize = 1; mockGlobalSettings( { fontSize: '0' } ); // Act const { getByA11yLabel } = render( @@ -193,5 +213,38 @@ describe( '', () => { const actualFontSize = getByA11yLabel( 'editor' ).props.fontSize; expect( actualFontSize ).toBe( expectedFontSize ); } ); + + it( 'should update the font size when style prop with font size property is provided', () => { + // Arrange + const fontSize = '10'; + const style = { fontSize: '12' }; + // Act + const screen = render( ); + screen.update( ); + // Assert + expect( screen.toJSON() ).toMatchSnapshot(); + } ); + + it( 'renders component with style and font size', async () => { + // Arrange + const initialHtml = ` +

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet ut nibh vitae ornare. Sed auctor nec augue at blandit.

      + `; + // Act + await initializeEditor( { initialHtml } ); + // Assert + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'should update the font size with decimals when style prop with font size property is provided', () => { + // Arrange + const fontSize = '10'; + const style = { fontSize: '12.56px' }; + // Act + const screen = render( ); + screen.update( ); + // Assert + expect( screen.toJSON() ).toMatchSnapshot(); + } ); } ); } ); From 30e57e15008b6851dde44cd4a0031cb40a594d16 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 14 Jan 2022 14:35:09 +0000 Subject: [PATCH 116/149] Late escape Navigation blocks (#37870) * Initial pass Navigation block * Navigation link block first pass * Nav submenu block first pass * Remove redundant escaping * Fix PHP error * Remove redundant escaping * Don't escape SVGs * Don't escape SVGs...again * Remove redundant escaping * Revert code format changes * Code format revert * Revert code formatting * Don't esape SVG * Remove escape label * Remove redundant escaping * Don't escape translations * Revert early escaping * Filter inline style attribute using safecss_filter_attr --- packages/block-library/src/navigation-submenu/index.php | 8 ++++---- packages/block-library/src/navigation/index.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/index.php b/packages/block-library/src/navigation-submenu/index.php index a0eac8146f9e6d..6da79414c4beb3 100644 --- a/packages/block-library/src/navigation-submenu/index.php +++ b/packages/block-library/src/navigation-submenu/index.php @@ -199,9 +199,9 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) { // If Submenus open on hover, we render an anchor tag with attributes. // If submenu icons are set to show, we also render a submenu button, so the submenu can be opened on click. if ( ! $open_on_click ) { - $item_url = isset( $attributes['url'] ) ? esc_url( $attributes['url'] ) : ''; + $item_url = isset( $attributes['url'] ) ? $attributes['url'] : ''; // Start appending HTML attributes to anchor tag. - $html .= '
    • ' . $icon . '
    • '; + return '
    • ' . $icon . '
    • '; } /** From e1042c1b1d51c7494981a1c3f80d74e2f8d2e85c Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 14 Jan 2022 15:54:07 +0000 Subject: [PATCH 118/149] Post Lock: Adjust avatar design and update message (#37979) --- .../src/components/post-locked-modal/index.js | 55 +++++++++++-------- .../components/post-locked-modal/style.scss | 10 +++- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/packages/editor/src/components/post-locked-modal/index.js b/packages/editor/src/components/post-locked-modal/index.js index 3576dc91dc5dd0..8b516c5f8d5b01 100644 --- a/packages/editor/src/components/post-locked-modal/index.js +++ b/packages/editor/src/components/post-locked-modal/index.js @@ -185,6 +185,8 @@ export default function PostLockedModal() { src={ userAvatar } alt={ __( 'Avatar' ) } className="editor-post-locked-modal__avatar" + width={ 64 } + height={ 64 } /> ) }
      @@ -214,29 +216,36 @@ export default function PostLockedModal() {

      ) } { ! isTakeover && ( -

      - { createInterpolateElement( - userDisplayName - ? sprintf( - /* translators: %s: user's display name */ - __( - '%s is currently working on this post (), which means you cannot make changes, unless you take over.' - ), - userDisplayName - ) - : __( - 'Another user is currently working on this post (), which means you cannot make changes, unless you take over.' - ), - { - strong: , - PreviewLink: ( - - { __( 'preview' ) } - - ), - } - ) } -

      + <> +

      + { createInterpolateElement( + userDisplayName + ? sprintf( + /* translators: %s: user's display name */ + __( + '%s is currently working on this post (), which means you cannot make changes, unless you take over.' + ), + userDisplayName + ) + : __( + 'Another user is currently working on this post (), which means you cannot make changes, unless you take over.' + ), + { + strong: , + PreviewLink: ( + + { __( 'preview' ) } + + ), + } + ) } +

      +

      + { __( + 'If you take over, the other user will lose editing control to the post, but their changes will be saved.' + ) } +

      + ) } Date: Fri, 14 Jan 2022 17:04:53 +0100 Subject: [PATCH 119/149] [RNMobile] Buttons block: Fix content justification attribute (#37887) * Enable layout hooks supported by native The only hook currently supported by the native version is "core/layout/addAttribute", which extends block attributes to include "layout". * Fix content justification in buttons block * Use default block layout when no layout attribute * Use snapshot testing in border radius test case Additionally, the test case has been nested in a describe block. * Create buttons block snapshots * Add justify content test cases to buttons block * Update react-native-editor changelog --- .../block-editor/src/hooks/index.native.js | 1 + .../block-editor/src/hooks/layout.native.js | 23 ++++ .../block-library/src/buttons/edit.native.js | 22 +++- .../test/__snapshots__/edit.native.js.snap | 27 ++++ .../src/buttons/test/edit.native.js | 120 +++++++++++------- packages/react-native-editor/CHANGELOG.md | 1 + 6 files changed, 144 insertions(+), 50 deletions(-) create mode 100644 packages/block-editor/src/hooks/layout.native.js create mode 100644 packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap diff --git a/packages/block-editor/src/hooks/index.native.js b/packages/block-editor/src/hooks/index.native.js index 06ea26e2e157c4..57e98ef91f915d 100644 --- a/packages/block-editor/src/hooks/index.native.js +++ b/packages/block-editor/src/hooks/index.native.js @@ -9,6 +9,7 @@ import './generated-class-name'; import './style'; import './color'; import './font-size'; +import './layout'; export { getBorderClassesAndStyles, useBorderProps } from './use-border-props'; export { getColorClassesAndStyles, useColorProps } from './use-color-props'; diff --git a/packages/block-editor/src/hooks/layout.native.js b/packages/block-editor/src/hooks/layout.native.js new file mode 100644 index 00000000000000..2e9a873bdd1ecf --- /dev/null +++ b/packages/block-editor/src/hooks/layout.native.js @@ -0,0 +1,23 @@ +/** + * WordPress dependencies + */ +import { removeFilter } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import './layout.js'; + +// This filter is removed because layout styles shouldn't be added +// until layout types are supported in the native version. +removeFilter( + 'editor.BlockListBlock', + 'core/editor/layout/with-layout-styles' +); + +// This filter is removed because the layout controls shouldn't be +// enabled until layout types are supported in the native version. +removeFilter( + 'editor.BlockEdit', + 'core/editor/layout/with-inspector-controls' +); diff --git a/packages/block-library/src/buttons/edit.native.js b/packages/block-library/src/buttons/edit.native.js index 9bee300cba01dd..fe6186f1278b8f 100644 --- a/packages/block-library/src/buttons/edit.native.js +++ b/packages/block-library/src/buttons/edit.native.js @@ -13,7 +13,7 @@ import { JustifyContentControl, store as blockEditorStore, } from '@wordpress/block-editor'; -import { createBlock } from '@wordpress/blocks'; +import { createBlock, getBlockSupport } from '@wordpress/blocks'; import { useResizeObserver } from '@wordpress/compose'; import { useDispatch, useSelect } from '@wordpress/data'; import { useState, useEffect, useRef, useCallback } from '@wordpress/element'; @@ -30,16 +30,23 @@ const ALLOWED_BLOCKS = [ buttonBlockName ]; const layoutProp = { type: 'default', alignments: [] }; export default function ButtonsEdit( { - attributes: { contentJustification, align }, + attributes: { layout, align }, clientId, isSelected, setAttributes, blockWidth, + name, } ) { const [ resizeObserver, sizes ] = useResizeObserver(); const [ maxWidth, setMaxWidth ] = useState( 0 ); const { marginLeft: spacing } = styles.spacing; + // Extract attributes from block layout + const layoutBlockSupport = getBlockSupport( name, '__experimentalLayout' ); + const defaultBlockLayout = layoutBlockSupport?.default; + const usedLayout = layout || defaultBlockLayout || {}; + const { justifyContent } = usedLayout; + const { isInnerButtonSelected, shouldDelete } = useSelect( ( select ) => { const { @@ -126,9 +133,14 @@ export default function ButtonsEdit( { - setAttributes( { contentJustification: value } ) + setAttributes( { + layout: { + ...usedLayout, + justifyContent: value, + }, + } ) } popoverProps={ { position: 'bottom right', @@ -154,7 +166,7 @@ export default function ButtonsEdit( { shouldRenderFooterAppender && renderFooterAppender.current } orientation="horizontal" - horizontalAlignment={ contentJustification } + horizontalAlignment={ justifyContent } onDeleteBlock={ shouldDelete ? remove : undefined } onAddBlock={ onAddNextButton } parentWidth={ maxWidth } // This value controls the width of that the buttons are able to expand to. diff --git a/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap new file mode 100644 index 00000000000000..77c8ca306d822d --- /dev/null +++ b/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Buttons block justify content sets Justify items center option 1`] = ` +" +
      +" +`; + +exports[`Buttons block justify content sets Justify items left option 1`] = ` +" +
      +" +`; + +exports[`Buttons block justify content sets Justify items right option 1`] = ` +" +
      +" +`; + +exports[`Buttons block when a button is shown adjusts the border radius 1`] = ` +" +
      + +
      +" +`; diff --git a/packages/block-library/src/buttons/test/edit.native.js b/packages/block-library/src/buttons/test/edit.native.js index cfee24e237fcfd..a9ea061a9f6e7b 100644 --- a/packages/block-library/src/buttons/test/edit.native.js +++ b/packages/block-library/src/buttons/test/edit.native.js @@ -27,59 +27,89 @@ afterAll( () => { } ); } ); -describe( 'when a button is shown', () => { - it( 'adjusts the border radius', async () => { - const initialHtml = ` -
      - -
      - `; - const { getByA11yLabel } = await initializeEditor( { - initialHtml, - } ); +describe( 'Buttons block', () => { + describe( 'when a button is shown', () => { + it( 'adjusts the border radius', async () => { + const initialHtml = ` +
      + +
      + `; + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); - const buttonsBlock = await waitFor( () => - getByA11yLabel( /Buttons Block\. Row 1/ ) - ); - fireEvent.press( buttonsBlock ); + const buttonsBlock = await waitFor( () => + getByA11yLabel( /Buttons Block\. Row 1/ ) + ); + fireEvent.press( buttonsBlock ); - // onLayout event has to be explicitly dispatched in BlockList component, - // otherwise the inner blocks are not rendered. - const innerBlockListWrapper = await waitFor( () => - within( buttonsBlock ).getByTestId( 'block-list-wrapper' ) - ); - fireEvent( innerBlockListWrapper, 'layout', { - nativeEvent: { - layout: { - width: 100, + // onLayout event has to be explicitly dispatched in BlockList component, + // otherwise the inner blocks are not rendered. + const innerBlockListWrapper = await waitFor( () => + within( buttonsBlock ).getByTestId( 'block-list-wrapper' ) + ); + fireEvent( innerBlockListWrapper, 'layout', { + nativeEvent: { + layout: { + width: 100, + }, }, - }, + } ); + + const buttonInnerBlock = await waitFor( () => + within( buttonsBlock ).getByA11yLabel( /Button Block\. Row 1/ ) + ); + fireEvent.press( buttonInnerBlock ); + + const settingsButton = await waitFor( () => + getByA11yLabel( 'Open Settings' ) + ); + fireEvent.press( settingsButton ); + + const radiusStepper = await waitFor( () => + getByA11yLabel( /Border Radius/ ) + ); + + const incrementButton = await waitFor( () => + within( radiusStepper ).getByTestId( 'Increment' ) + ); + fireEvent( incrementButton, 'onPressIn' ); + + expect( getEditorHtml() ).toMatchSnapshot(); } ); + } ); - const buttonInnerBlock = await waitFor( () => - within( buttonsBlock ).getByA11yLabel( /Button Block\. Row 1/ ) - ); - fireEvent.press( buttonInnerBlock ); + describe( 'justify content', () => { + [ + 'Justify items left', + 'Justify items center', + 'Justify items right', + ].forEach( ( justificationOption ) => + it( `sets ${ justificationOption } option`, async () => { + const initialHtml = ` +
      + `; + const { getByA11yLabel, getByText } = await initializeEditor( { + initialHtml, + } ); - const settingsButton = await waitFor( () => - getByA11yLabel( 'Open Settings' ) - ); - fireEvent.press( settingsButton ); + const block = await waitFor( () => + getByA11yLabel( /Buttons Block\. Row 1/ ) + ); + fireEvent.press( block ); - const radiusStepper = await waitFor( () => - getByA11yLabel( /Border Radius/ ) - ); + fireEvent.press( + getByA11yLabel( 'Change items justification' ) + ); + + // Select alignment option + fireEvent.press( + await waitFor( () => getByText( justificationOption ) ) + ); - const incrementButton = await waitFor( () => - within( radiusStepper ).getByTestId( 'Increment' ) + expect( getEditorHtml() ).toMatchSnapshot(); + } ) ); - fireEvent( incrementButton, 'onPressIn' ); - - const expectedHtml = ` -
      - -
      -`; - expect( getEditorHtml() ).toBe( expectedHtml ); } ); } ); diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 4ee7e30cdebcd4..6d58d132f043ed 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -10,6 +10,7 @@ For each user feature we should also add a importance categorization label to i --> ## Unreleased +- [**] Fix content justification attribute in Buttons block [#37887] - [*] Hide help button from Unsupported Block Editor. [#37221] - [*] Add contrast checker to text-based blocks [#34902] From b1a165034ec66e37a1f010de67a842963ec01e16 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Fri, 14 Jan 2022 12:07:34 -0500 Subject: [PATCH 120/149] [RNmobile] Trim feature image copy (#37956) * Trim feature image copy * Add translation fix to changelog * revert changelog auto formatting * Clean up formatting on changelog --- .../block-library/src/image/edit.native.js | 4 +-- packages/react-native-editor/CHANGELOG.md | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 421a8a00a83912..cc5cbd82d77196 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -524,7 +524,7 @@ export class ImageEdit extends Component { const removeFeaturedButton = () => ( (