Skip to content

Commit

Permalink
Add part of list shortcut
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Jan 12, 2018
1 parent 5bbfe3f commit f851af9
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
16 changes: 11 additions & 5 deletions blocks/api/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
);
Expand All @@ -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 ),
)
);

Expand All @@ -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 );
Expand All @@ -136,6 +136,12 @@ export function getPossibleBlockTransformations( blocks ) {
}, [] );
}

export function getPossibleShortcutTransformations( block ) {
return getBlockTypes()
.reduce( ( acc, blockType ) => [ ...acc, ...get( blockType, 'transforms.from', [] ) ], [] )
.filter( isTransformForBlockSource( block.name, 'shortcut', false ) );
}

/**
* Switch one or more blocks into one or more blocks of the new block type.
*
Expand Down
8 changes: 7 additions & 1 deletion blocks/api/index.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions blocks/library/list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) => <li key={ index }>{ content }</li> ) : [],
} );
},
} ) ),
{
type: 'block',
blocks: [ 'core/quote' ],
Expand Down
20 changes: 17 additions & 3 deletions editor/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { connect } from 'react-redux';
import classnames from 'classnames';
import { get, partial, reduce, size } from 'lodash';
import { get, partial, reduce, size, find } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -16,6 +16,7 @@ import {
getBlockType,
getSaveElement,
isReusableBlock,
getPossibleShortcutTransformations,
} from '@wordpress/blocks';
import { withFilters, withContext } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
Expand Down Expand Up @@ -65,7 +66,7 @@ import {
getBlockMode,
} from '../../store/selectors';

const { BACKSPACE, ESCAPE, DELETE, ENTER, UP, RIGHT, DOWN, LEFT } = keycodes;
const { BACKSPACE, ESCAPE, DELETE, ENTER, UP, RIGHT, DOWN, LEFT, isAccess } = keycodes;

/**
* Given a DOM node, finds the closest scrollable container node.
Expand All @@ -92,7 +93,7 @@ function getScrollContainer( node ) {
}

export class BlockListBlock extends Component {
constructor() {
constructor( { block } ) {
super( ...arguments );

this.setBlockListRef = this.setBlockListRef.bind( this );
Expand All @@ -113,6 +114,8 @@ export class BlockListBlock extends Component {
this.previousOffset = null;
this.hadTouchStart = false;

this.shortcutTransformations = getPossibleShortcutTransformations( block );

this.state = {
error: null,
};
Expand Down Expand Up @@ -298,6 +301,17 @@ export class BlockListBlock extends Component {

onKeyDown( event ) {
const { keyCode, target } = event;
const { block, onReplace } = this.props;

const transform = find( this.shortcutTransformations, ( { shortcut } ) => isAccess( event, shortcut ) );

if ( transform ) {
const newBlock = transform.transform( [ block.attributes ] );

onReplace( [ newBlock ] );

return;
}

switch ( keyCode ) {
case ENTER:
Expand Down
19 changes: 19 additions & 0 deletions utils/keycodes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Browser dependencies
*/
const { userAgent } = window.navigator;

const isMac = userAgent.indexOf( 'Mac' ) !== -1;

export const BACKSPACE = 8;
export const TAB = 9;
export const ENTER = 13;
Expand All @@ -10,3 +17,15 @@ export const DOWN = 40;
export const DELETE = 46;

export const F10 = 121;

export function isAccess( event, letter ) {
if ( isMac ) {
if ( ! event.ctrlKey || ! event.altKey ) {
return;
}
} else if ( ! event.shiftKey || ! event.altKey ) {
return;
}

return event.keyCode === letter.toUpperCase().charCodeAt(0);
}

0 comments on commit f851af9

Please sign in to comment.