From 316a4ecbd20570abd8fc16de019c1db19e0809ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 10:53:59 +0200 Subject: [PATCH 1/9] Add deprecation --- .../block-library/src/quote/v2/deprecated.js | 107 ++++++++++++++++++ packages/block-library/src/quote/v2/index.js | 2 + 2 files changed, 109 insertions(+) create mode 100644 packages/block-library/src/quote/v2/deprecated.js diff --git a/packages/block-library/src/quote/v2/deprecated.js b/packages/block-library/src/quote/v2/deprecated.js new file mode 100644 index 00000000000000..4a65080ed4d9f3 --- /dev/null +++ b/packages/block-library/src/quote/v2/deprecated.js @@ -0,0 +1,107 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { omit } from 'lodash'; + +/** + * WordPress dependencies + */ +import { createBlock, parseWithAttributeSchema } from '@wordpress/blocks'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import deprecationsForV1Block from '../deprecated'; + +const migrateToQuoteV2 = ( attributes ) => { + const { value } = attributes; + + return [ + { + ...omit( attributes, [ 'value' ] ), + }, + value + ? parseWithAttributeSchema( value, { + type: 'array', + source: 'query', + selector: 'p', + query: { + content: { + type: 'string', + source: 'text', + }, + }, + } ).map( ( { content } ) => + createBlock( 'core/paragraph', { content } ) + ) + : createBlock( 'core/paragraph' ), + ]; +}; + +const v3 = { + attributes: { + value: { + type: 'string', + source: 'html', + selector: 'blockquote', + multiline: 'p', + default: '', + __experimentalRole: 'content', + }, + citation: { + type: 'string', + source: 'html', + selector: 'cite', + default: '', + __experimentalRole: 'content', + }, + align: { + type: 'string', + }, + }, + supports: { + anchor: true, + __experimentalSlashInserter: true, + typography: { + fontSize: true, + lineHeight: true, + __experimentalFontStyle: true, + __experimentalFontWeight: true, + __experimentalLetterSpacing: true, + __experimentalTextTransform: true, + __experimentalDefaultControls: { + fontSize: true, + fontAppearance: true, + }, + }, + }, + save( { attributes } ) { + const { align, value, citation } = attributes; + + const className = classnames( { + [ `has-text-align-${ align }` ]: align, + } ); + + return ( +
++ ); + }, + migrate: migrateToQuoteV2, +}; + +/** + * New deprecations need to be placed first + * for them to have higher priority. + * + * Old deprecations may need to be updated as well. + * + * See block-deprecation.md + */ +export default [ v3, ...deprecationsForV1Block ]; diff --git a/packages/block-library/src/quote/v2/index.js b/packages/block-library/src/quote/v2/index.js index e30680b2493b05..887910a0f61e1c 100644 --- a/packages/block-library/src/quote/v2/index.js +++ b/packages/block-library/src/quote/v2/index.js @@ -11,6 +11,7 @@ import { addFilter } from '@wordpress/hooks'; import edit from './edit'; import save from './save'; import transforms from './transforms'; +import deprecated from './deprecated'; const settings = { icon, @@ -30,6 +31,7 @@ const settings = { transforms, edit, save, + deprecated, }; export default settings; From 6b891e56810c5d68f8ccf36f3a16da2f8924b61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 10:58:58 +0200 Subject: [PATCH 2/9] Do not deregister value dynamically By doing this, we are also deregistering it for the deprecations. --- packages/block-library/package.json | 3 +- packages/block-library/src/quote/v2/index.js | 32 -------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/packages/block-library/package.json b/packages/block-library/package.json index df844f5cf29392..8273630e6d72ea 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -29,8 +29,7 @@ "src/**/*.scss", "src/navigation-link/index.js", "src/template-part/index.js", - "src/query/index.js", - "src/quote/v2/index.js" + "src/query/index.js" ], "dependencies": { "@babel/runtime": "^7.16.0", diff --git a/packages/block-library/src/quote/v2/index.js b/packages/block-library/src/quote/v2/index.js index 887910a0f61e1c..7019fe59db6464 100644 --- a/packages/block-library/src/quote/v2/index.js +++ b/packages/block-library/src/quote/v2/index.js @@ -3,7 +3,6 @@ */ import { __ } from '@wordpress/i18n'; import { quote as icon } from '@wordpress/icons'; -import { addFilter } from '@wordpress/hooks'; /** * Internal dependencies @@ -35,34 +34,3 @@ const settings = { }; export default settings; - -/** - * This function updates the attributes for the quote v2. - * This should be moved to block.json when v2 becomes the default. - * - * @param {Array} blockSettings The settings of the block to be registered. - * @param {string} blockName The name of the block to be registered. - * @return {Array} New settings. - */ -function registerQuoteV2Attributes( blockSettings, blockName ) { - if ( ! window?.__experimentalEnableQuoteBlockV2 ) { - return blockSettings; - } - - if ( blockName !== 'core/quote' ) { - return blockSettings; - } - - // Deregister the old ones. - delete blockSettings.attributes.value; - - return blockSettings; -} - -// Importing this file includes side effects. -// This has been declared in block-library/package.json under sideEffects. -addFilter( - 'blocks.registerBlockType', - 'core/quote/v2-attributes', - registerQuoteV2Attributes -); From e3445b998f60e4ec4dbd2c9dd9577e460e59e9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 11:30:34 +0200 Subject: [PATCH 3/9] Migrate templates provided to the CPT --- .../block-library/src/quote/v2/deprecated.js | 2 +- packages/block-library/src/quote/v2/edit.js | 48 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/quote/v2/deprecated.js b/packages/block-library/src/quote/v2/deprecated.js index 4a65080ed4d9f3..ff577684e5634e 100644 --- a/packages/block-library/src/quote/v2/deprecated.js +++ b/packages/block-library/src/quote/v2/deprecated.js @@ -15,7 +15,7 @@ import { RichText, useBlockProps } from '@wordpress/block-editor'; */ import deprecationsForV1Block from '../deprecated'; -const migrateToQuoteV2 = ( attributes ) => { +export const migrateToQuoteV2 = ( attributes ) => { const { value } = attributes; return [ diff --git a/packages/block-library/src/quote/v2/edit.js b/packages/block-library/src/quote/v2/edit.js index 44be35f18de00b..dbca734830b7a5 100644 --- a/packages/block-library/src/quote/v2/edit.js +++ b/packages/block-library/src/quote/v2/edit.js @@ -9,24 +9,66 @@ import { store as blockEditorStore, } from '@wordpress/block-editor'; import { BlockQuotation } from '@wordpress/components'; -import { useSelect } from '@wordpress/data'; +import { useDispatch, useSelect, useRegistry } from '@wordpress/data'; import { createBlock } from '@wordpress/blocks'; -import { Platform } from '@wordpress/element'; +import { Platform, useEffect } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { migrateToQuoteV2 } from './deprecated'; const isWebPlatform = Platform.OS === 'web'; const TEMPLATE = [ [ 'core/paragraph', {} ] ]; +/** + * At the moment, deprecations don't handle create blocks from attributes + * (like when using CPT templates). For this reason, this hook is necessary + * to avoid breaking templates using the old quote block format. + * + * @param {Object} attributes Block attributes. + * @param {string} clientId Block client ID. + */ +const useMigrateOnLoad = ( attributes, clientId ) => { + const registry = useRegistry(); + const { updateBlockAttributes, replaceInnerBlocks } = useDispatch( + blockEditorStore + ); + useEffect( () => { + // As soon as the block is loaded, migrate it to the new version. + + if ( ! attributes.value ) { + // No need to migrate if it doesn't have the value attribute. + return; + } + + const [ newAttributes, newInnerBlocks ] = migrateToQuoteV2( + attributes + ); + + registry.batch( () => { + updateBlockAttributes( clientId, newAttributes ); + replaceInnerBlocks( clientId, newInnerBlocks ); + } ); + }, [ attributes.value ] ); +}; + export default function QuoteEdit( { - attributes: { citation }, + attributes, setAttributes, isSelected, insertBlocksAfter, clientId, } ) { + const { citation } = attributes; + + useMigrateOnLoad( attributes, clientId ); + const isAncestorOfSelectedBlock = useSelect( ( select ) => select( blockEditorStore ).hasSelectedInnerBlock( clientId ) ); const hasSelection = isSelected || isAncestorOfSelectedBlock; + const blockProps = useBlockProps(); const innerBlocksProps = useInnerBlocksProps( blockProps, { template: TEMPLATE, From 2bdddf11d77c5cf18a31183f003240c5a489d20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:15:04 +0200 Subject: [PATCH 4/9] Add minimal unit tests for migrateToQuotev2 --- .../src/quote/v2/test/migrate.js | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 packages/block-library/src/quote/v2/test/migrate.js diff --git a/packages/block-library/src/quote/v2/test/migrate.js b/packages/block-library/src/quote/v2/test/migrate.js new file mode 100644 index 00000000000000..112002e2d78ee6 --- /dev/null +++ b/packages/block-library/src/quote/v2/test/migrate.js @@ -0,0 +1,68 @@ +/** + * WordPress dependencies + */ +import { + registerBlockType, + serialize, + unregisterBlockType, +} from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { migrateToQuoteV2 } from '../deprecated'; +import * as paragraph from '../../../paragraph'; +import * as quote from '../../../quote'; +import * as quoteV2 from '../../../quote/v2'; + +describe( 'Migrate quote block', () => { + beforeAll( () => { + registerBlockType( + { name: paragraph.name, ...paragraph.metadata }, + paragraph.settings + ); + registerBlockType( + { name: quote.name, ...quote.metadata }, + quoteV2.settings + ); + } ); + + afterAll( () => { + unregisterBlockType( paragraph.name ); + unregisterBlockType( quote.name ); + } ); + + it( 'should migrate the value attribute to inner blocks', () => { + const [ attributes, innerBlocks ] = migrateToQuoteV2( { + value: '+ { ! RichText.isEmpty( citation ) && ( + + ) } +
First paragraph
Second paragraph
', + citation: 'Author', + } ); + expect( attributes ).toEqual( { + citation: 'Author', + } ); + expect( serialize( innerBlocks ) ).toEqual( + ` +First paragraph
+ + + +Second paragraph
+` + ); + } ); + + it( 'should create a paragraph if value is empty', () => { + const [ attributes, innerBlocks ] = migrateToQuoteV2( { + value: undefined, + citation: 'Author', + } ); + expect( attributes ).toEqual( { + citation: 'Author', + } ); + expect( serialize( innerBlocks ) ).toEqual( + ` + +` + ); + } ); +} ); From 19a51115d5bc2b6213861da92dd4eb7bcbbdb696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:14:47 +0200 Subject: [PATCH 5/9] Carry over the formats of the value att --- .../block-library/src/quote/v2/deprecated.js | 2 +- .../src/quote/v2/test/migrate.js | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/quote/v2/deprecated.js b/packages/block-library/src/quote/v2/deprecated.js index ff577684e5634e..a9950e4a225483 100644 --- a/packages/block-library/src/quote/v2/deprecated.js +++ b/packages/block-library/src/quote/v2/deprecated.js @@ -30,7 +30,7 @@ export const migrateToQuoteV2 = ( attributes ) => { query: { content: { type: 'string', - source: 'text', + source: 'html', }, }, } ).map( ( { content } ) => diff --git a/packages/block-library/src/quote/v2/test/migrate.js b/packages/block-library/src/quote/v2/test/migrate.js index 112002e2d78ee6..7f90d4cb11bc65 100644 --- a/packages/block-library/src/quote/v2/test/migrate.js +++ b/packages/block-library/src/quote/v2/test/migrate.js @@ -62,6 +62,30 @@ describe( 'Migrate quote block', () => { expect( serialize( innerBlocks ) ).toEqual( ` +` + ); + } ); + + it( 'should keep the formats of the value', () => { + const [ attributes, innerBlocks ] = migrateToQuoteV2( { + value: + 'Bold
and
italic
', + citation: 'Author', + } ); + expect( attributes ).toEqual( { + citation: 'Author', + } ); + expect( serialize( innerBlocks ) ).toEqual( + ` +Bold
+ + + +and
+ + + +italic
` ); } ); From f3cac0724c2cc8d398efed7fdcb31a97020d7c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:16:48 +0200 Subject: [PATCH 6/9] Pullquote to quote transform: carry over the formats of the value att --- packages/block-library/src/quote/v2/transforms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/quote/v2/transforms.js b/packages/block-library/src/quote/v2/transforms.js index 90d1b3273b8df1..0479beecf7d687 100644 --- a/packages/block-library/src/quote/v2/transforms.js +++ b/packages/block-library/src/quote/v2/transforms.js @@ -29,7 +29,7 @@ const transforms = { query: { content: { type: 'string', - source: 'text', + source: 'html', }, }, } ).map( ( { content } ) => From 025c85c73f67127cf147a63b8e266d969d47b249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:19:26 +0200 Subject: [PATCH 7/9] Update packages/block-library/src/quote/v2/edit.js Co-authored-by: Riad Benguella