diff --git a/blocks/api/factory.js b/blocks/api/factory.js index f3fb437c932e9a..e2ffc1468b5058 100644 --- a/blocks/api/factory.js +++ b/blocks/api/factory.js @@ -69,8 +69,8 @@ export function createBlock( name, blockAttributes = {} ) { * @param {Boolean} isMultiBlock Array of possible block transformations * @return {Function} Predicate that receives a block type. */ -const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( transform ) => ( - transform.type === 'block' && +const isTransformForBlockSource = ( sourceName, transformType, isMultiBlock = false ) => ( transform ) => ( + transform.type === transformType && transform.blocks.indexOf( sourceName ) !== -1 && ( ! isMultiBlock || transform.isMultiBlock ) ); @@ -83,10 +83,10 @@ const isTransformForBlockSource = ( sourceName, isMultiBlock = false ) => ( tran * @param {Boolean} isMultiBlock Array of possible block transformations * @return {Function} Predicate that receives a block type. */ -const createIsTypeTransformableFrom = ( sourceName, isMultiBlock = false ) => ( type ) => ( +const createIsTypeTransformableFrom = ( sourceName, transformType, isMultiBlock = false ) => ( type ) => ( !! find( get( type, 'transforms.from', [] ), - isTransformForBlockSource( sourceName, isMultiBlock ), + isTransformForBlockSource( sourceName, transformType, isMultiBlock ), ) ); @@ -111,7 +111,7 @@ export function getPossibleBlockTransformations( blocks ) { //compute the block that have a from transformation able to transfer blocks passed as argument. const blocksToBeTransformedFrom = filter( getBlockTypes(), - createIsTypeTransformableFrom( sourceBlockName, isMultiBlock ), + createIsTypeTransformableFrom( sourceBlockName, 'block', isMultiBlock ), ).map( type => type.name ); const blockType = getBlockType( sourceBlockName ); @@ -136,6 +136,22 @@ export function getPossibleBlockTransformations( blocks ) { }, [] ); } +/** + * Gets all possible shortcut transforms based on a block name. + * + * @param {String} name Block name. + * @return {Array} Array of transforms. + */ +export function getPossibleShortcutTransformations( name ) { + const transformsFrom = getBlockTypes() + .reduce( ( acc, blockType ) => [ ...acc, ...get( blockType, 'transforms.from', [] ) ], [] ) + .filter( isTransformForBlockSource( name, 'shortcut', false ) ); + const transformsTo = get( getBlockType( name ), 'transforms.to', [] ) + .filter( ( { type } ) => type === 'shortcut' ); + + return [ ...transformsFrom, ...transformsTo ]; +} + /** * Switch one or more blocks into one or more blocks of the new block type. * diff --git a/blocks/api/index.js b/blocks/api/index.js index 7f0653a133c5b3..b9904d52406720 100644 --- a/blocks/api/index.js +++ b/blocks/api/index.js @@ -1,4 +1,10 @@ -export { createBlock, getPossibleBlockTransformations, switchToBlockType, createReusableBlock } from './factory'; +export { + createBlock, + getPossibleBlockTransformations, + getPossibleShortcutTransformations, + switchToBlockType, + createReusableBlock, +} from './factory'; export { default as parse, getBlockAttributes } from './parser'; export { default as rawHandler } from './raw-handling'; export { diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index c68d85fefdbbb4..a5090164c54086 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -79,6 +79,19 @@ registerBlockType( 'core/heading', { } ); }, }, + ...'23456'.split( '' ).map( ( level ) => ( { + type: 'shortcut', + blocks: [ 'core/paragraph' ], + shortcut: level, + transform( blockAttributes ) { + return blockAttributes.map( ( { content } ) => { + return createBlock( 'core/heading', { + nodeName: `H${ level }`, + content, + } ); + } ); + }, + } ) ), ], to: [ { @@ -90,6 +103,24 @@ registerBlockType( 'core/heading', { } ); }, }, + ...'23456'.split( '' ).map( ( level ) => ( { + type: 'shortcut', + shortcut: level, + transform( blockAttributes ) { + return blockAttributes.map( ( { content, nodeName } ) => { + if ( nodeName === `H${ level }` ) { + return createBlock( 'core/paragraph', { + content, + } ); + } else { + return createBlock( 'core/heading', { + nodeName: `H${ level }`, + content, + } ); + } + } ); + }, + } ) ), ], }, diff --git a/blocks/library/list/index.js b/blocks/library/list/index.js index cec6b4aa69da5d..44cdce96d67a41 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -113,6 +113,19 @@ registerBlockType( 'core/list', { } ); }, }, + ...[ 'OL', 'UL' ].map( ( tag ) => ( { + type: 'shortcut', + blocks: [ 'core/paragraph' ], + shortcut: tag.charAt( 0 ).toLowerCase(), + transform( blockAttributes ) { + const items = blockAttributes.map( ( { content } ) => content ); + const hasItems = ! items.every( isEmpty ); + return createBlock( 'core/list', { + nodeName: tag, + values: hasItems ? items.map( ( content, index ) =>