Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List block: Add migration from v1 to v2 #39799

Merged
merged 4 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/block-library/src/list/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { RichText, useBlockProps } from '@wordpress/block-editor';
*/
import migrateFontFamily from '../utils/migrate-font-family';

const v1 = {
const v0 = {
attributes: {
ordered: {
type: 'boolean',
Expand Down Expand Up @@ -76,4 +76,4 @@ const v1 = {
*
* See block-deprecation.md
*/
export default [ v1 ];
export default [ v0 ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's version 0? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a random name for the first deprecated version :P

132 changes: 132 additions & 0 deletions packages/block-library/src/list/test/migrate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* WordPress dependencies
*/
import { registerBlockType, serialize } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { migrateToListV2 } from '../v2/migrate';
import * as listItem from '../../list-item';
import * as list from '../../list';
import listV2 from '../../list/v2';

describe( 'Migrate list block', () => {
beforeAll( () => {
const prev = window.__experimentalEnableListBlockV2;

// force list and list item block registration.
registerBlockType(
{ name: listItem.name, ...listItem.metadata },
listItem.settings
);
registerBlockType( { name: list.name, ...list.metadata }, listV2 );

window.__experimentalEnableListBlockV2 = prev;
} );

it( 'should migrate the values attribute to inner blocks', () => {
const [ updatedAttributes, updatedInnerBlocks ] = migrateToListV2( {
values:
'<li>test</li><li>test</li><li>test<ol><li>test test</li><li>test est eesssss</li></ol></li>',
ordered: false,
} );

expect( updatedAttributes ).toEqual( {
ordered: false,
// Ideally the values attributes shouldn't be here
// but since we didn't enable v2 by default yet,
// we're keeping the old default value in block.json
values: '',
} );
expect( serialize( updatedInnerBlocks ) )
.toEqual( `<!-- wp:list-item -->
<li>test</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>test</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>test<!-- wp:list {\"ordered\":true} -->
<ol><!-- wp:list-item -->
<li>test test</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>test est eesssss</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list --></li>
<!-- /wp:list-item -->` );
} );

it( 'should handle empty space properly', () => {
const [ updatedAttributes, updatedInnerBlocks ] = migrateToListV2( {
values: `<li>Europe</li>
<li>
\tAfrica
<ol>
<li>Algeria</li>
</ol>
\t
</li>`,
ordered: false,
} );

expect( updatedAttributes ).toEqual( {
ordered: false,
// Ideally the values attributes shouldn't be here
// but since we didn't enable v2 by default yet,
// we're keeping the old default value in block.json
values: '',
} );
expect( serialize( updatedInnerBlocks ) )
.toEqual( `<!-- wp:list-item -->
<li>Europe</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Africa<!-- wp:list {\"ordered\":true} -->
<ol><!-- wp:list-item -->
<li>Algeria</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list --></li>
<!-- /wp:list-item -->` );
} );

it( 'should handle formats properly', () => {
const [ updatedAttributes, updatedInnerBlocks ] = migrateToListV2( {
values: `<li>Europe<ul><li>France<ul><li>Lyon <strong>Rhone</strong>s</li><li>Paris <em>Ile de france</em><ul><li><em>1er</em></li></ul></li></ul></li></ul></li></ul></li>`,
ordered: false,
} );

expect( updatedAttributes ).toEqual( {
ordered: false,
// Ideally the values attributes shouldn't be here
// but since we didn't enable v2 by default yet,
// we're keeping the old default value in block.json
values: '',
} );
expect( serialize( updatedInnerBlocks ) )
.toEqual( `<!-- wp:list-item -->
<li>Europe<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>France<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Lyon <strong>Rhone</strong>s</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Paris <em>Ile de france</em><!-- wp:list -->
<ul><!-- wp:list-item -->
<li><em>1er</em></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->` );
} );
} );
89 changes: 89 additions & 0 deletions packages/block-library/src/list/v2/deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* WordPress dependencies
*/
import { RichText, useBlockProps } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import initialDeprecations from '../deprecated';
import { migrateToListV2 } from './migrate';

const v1 = {
attributes: {
ordered: {
type: 'boolean',
default: false,
__experimentalRole: 'content',
},
values: {
type: 'string',
source: 'html',
selector: 'ol,ul',
multiline: 'li',
__unstableMultilineWrapperTags: [ 'ol', 'ul' ],
default: '',
__experimentalRole: 'content',
},
type: {
type: 'string',
},
start: {
type: 'number',
},
reversed: {
type: 'boolean',
},
placeholder: {
type: 'string',
},
},
supports: {
anchor: true,
className: false,
typography: {
fontSize: true,
__experimentalFontFamily: true,
lineHeight: true,
__experimentalFontStyle: true,
__experimentalFontWeight: true,
__experimentalLetterSpacing: true,
__experimentalTextTransform: true,
__experimentalDefaultControls: {
fontSize: true,
},
},
color: {
gradients: true,
link: true,
__experimentalDefaultControls: {
background: true,
text: true,
},
},
__unstablePasteTextInline: true,
__experimentalSelector: 'ol,ul',
__experimentalSlashInserter: true,
},
save( { attributes } ) {
const { ordered, values, type, reversed, start } = attributes;
const TagName = ordered ? 'ol' : 'ul';

return (
<TagName { ...useBlockProps.save( { type, reversed, start } ) }>
<RichText.Content value={ values } multiline="li" />
</TagName>
);
},
migrate: migrateToListV2,
};

/**
* 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 [ v1, ...initialDeprecations ];
43 changes: 41 additions & 2 deletions packages/block-library/src/list/v2/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
store as blockEditorStore,
} from '@wordpress/block-editor';
import { ToolbarButton } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
import { isRTL, __ } from '@wordpress/i18n';
import {
formatListBullets,
Expand All @@ -24,15 +24,53 @@ import {
formatOutdentRTL,
} from '@wordpress/icons';
import { createBlock } from '@wordpress/blocks';
import { useCallback } from '@wordpress/element';
import { useCallback, useEffect } from '@wordpress/element';
import deprecated from '@wordpress/deprecated';

/**
* Internal dependencies
*/
import OrderedListSettings from '../ordered-list-settings';
import { migrateToListV2 } from './migrate';

const TEMPLATE = [ [ 'core/list-item' ] ];

/**
* 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 list block format.
*
* @param {Object} attributes Block attributes.
* @param {string} clientId Block client ID.
*/
function 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.values ) {
return;
}

const [ newAttributes, newInnerBlocks ] = migrateToListV2( attributes );

deprecated( 'Value attribute on the list block', {
since: '6.0',
version: '6.5',
alternative: 'inner blocks',
} );

registry.batch( () => {
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
updateBlockAttributes( clientId, newAttributes );
replaceInnerBlocks( clientId, newInnerBlocks );
} );
}, [ attributes.values ] );
}

function useOutdentList( clientId ) {
const { canOutdent } = useSelect(
( innerSelect ) => {
Expand Down Expand Up @@ -97,6 +135,7 @@ function Edit( { attributes, setAttributes, clientId } ) {
allowedBlocks: [ 'core/list-item' ],
template: TEMPLATE,
} );
useMigrateOnLoad( attributes, clientId );
const { ordered, reversed, start } = attributes;
const TagName = ordered ? 'ol' : 'ul';

Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/list/v2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { list as icon } from '@wordpress/icons';
import edit from './edit';
import save from './save';
import transforms from './transforms';
import deprecated from './deprecated';

const settings = {
icon,
edit,
save,
transforms,
deprecated,
};

export default settings;
Loading