From f718d8ee43693bf9ee4c79a3732597cdde14eb4d Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 14 Dec 2017 18:08:53 +0100 Subject: [PATCH 1/5] Blocks: Move logic for generating class name to BlockEdit component --- blocks/block-edit/index.js | 21 ++++++++++++++++++--- blocks/library/block/index.js | 9 +-------- editor/components/block-list/block.js | 1 - 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/blocks/block-edit/index.js b/blocks/block-edit/index.js index 87d89199fa014f..ad84902cdf7395 100644 --- a/blocks/block-edit/index.js +++ b/blocks/block-edit/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -6,22 +11,32 @@ import { withFilters } from '@wordpress/components'; /** * Internal dependencies */ -import { getBlockType } from '../api'; +import { + getBlockType, + getBlockDefaultClassname, + hasBlockSupport, +} from '../api'; export function BlockEdit( props ) { - const { name, ...editProps } = props; + const { name, attributes } = props; const blockType = getBlockType( name ); if ( ! blockType ) { return null; } + // Generate a class name for the block's editable form + const generatedClassName = hasBlockSupport( blockType, 'className', true ) ? + getBlockDefaultClassname( name ) : + null; + const className = classnames( generatedClassName, attributes.className ); + // `edit` and `save` are functions or components describing the markup // with which a block is displayed. If `blockType` is valid, assign // them preferencially as the render value for the block. const Edit = blockType.edit || blockType.save; - return ; + return ; } export default withFilters( 'blocks.BlockEdit' )( BlockEdit ); diff --git a/blocks/library/block/index.js b/blocks/library/block/index.js index 6f8bb6be3ac277..6e684cd08e3b10 100644 --- a/blocks/library/block/index.js +++ b/blocks/library/block/index.js @@ -3,7 +3,6 @@ */ import { pickBy, noop } from 'lodash'; import { connect } from 'react-redux'; -import classnames from 'classnames'; /** * WordPress dependencies @@ -15,7 +14,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { getBlockType, registerBlockType, hasBlockSupport, getBlockDefaultClassname } from '../../api'; +import { getBlockType, registerBlockType } from '../../api'; import ReusableBlockEditPanel from './edit-panel'; class ReusableBlockEdit extends Component { @@ -89,11 +88,6 @@ class ReusableBlockEdit extends Component { const blockType = getBlockType( reusableBlock.type ); const BlockEdit = blockType.edit || blockType.save; - // Generate a class name for the block's editable form - const generatedClassName = hasBlockSupport( blockType, 'className', true ) ? - getBlockDefaultClassname( reusableBlock.type ) : - null; - const className = classnames( generatedClassName, reusableBlockAttributes.className ); return [ // We fake the block being read-only by wrapping it with an element that has pointer-events: none
@@ -102,7 +96,6 @@ class ReusableBlockEdit extends Component { focus={ isEditing ? focus : null } attributes={ reusableBlockAttributes } setAttributes={ isEditing ? this.setAttributes : noop } - className={ className } />
, focus && ( diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index 50fb5b47a2ae9f..f9d6b45e1752bf 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -424,7 +424,6 @@ export class BlockListBlock extends Component { onReplace={ isLocked ? undefined : onReplace } setFocus={ partial( onFocus, block.uid ) } mergeBlocks={ isLocked ? undefined : this.mergeBlocks } - className={ className } id={ block.uid } isSelectionEnabled={ this.props.isSelectionEnabled } toggleSelection={ this.props.toggleSelection } From 1342736459440087e6ae173e67d491558adb35cd Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 14 Dec 2017 18:25:12 +0100 Subject: [PATCH 2/5] Blocks: Add test for generated class name with BlockEdit --- blocks/block-edit/index.js | 2 +- blocks/block-edit/test/index.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/blocks/block-edit/index.js b/blocks/block-edit/index.js index ad84902cdf7395..a1cdea30ac04fc 100644 --- a/blocks/block-edit/index.js +++ b/blocks/block-edit/index.js @@ -18,7 +18,7 @@ import { } from '../api'; export function BlockEdit( props ) { - const { name, attributes } = props; + const { name, attributes = {} } = props; const blockType = getBlockType( name ); if ( ! blockType ) { diff --git a/blocks/block-edit/test/index.js b/blocks/block-edit/test/index.js index b02185797b43bc..47a853fa373079 100644 --- a/blocks/block-edit/test/index.js +++ b/blocks/block-edit/test/index.js @@ -53,4 +53,23 @@ describe( 'BlockEdit', () => { expect( wrapper.type() ).toBe( save ); } ); + + it( 'should combine the default class name with a custom one', () => { + const edit = ( { className } ) =>
; + const attributes = { + className: 'my-class', + }; + registerBlockType( 'core/test-block', { + edit, + save: noop, + category: 'common', + title: 'block title', + } ); + + const wrapper = shallow( + + ); + + expect( wrapper.prop( 'className' ) ).toBe( 'wp-block-test-block my-class' ); + } ); } ); From 6e6356a7384a2c77277847c6a107b71c97126841 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 15 Dec 2017 12:58:50 +0100 Subject: [PATCH 3/5] Editor: Move generatedClassName logic out of BlockListBlock --- blocks/api/index.js | 7 ++++- blocks/api/serializer.js | 39 ++++++++++++++++++++------- editor/components/block-list/block.js | 19 +++---------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/blocks/api/index.js b/blocks/api/index.js index c4fd64bcf4c76d..7f0653a133c5b3 100644 --- a/blocks/api/index.js +++ b/blocks/api/index.js @@ -1,7 +1,12 @@ export { createBlock, getPossibleBlockTransformations, switchToBlockType, createReusableBlock } from './factory'; export { default as parse, getBlockAttributes } from './parser'; export { default as rawHandler } from './raw-handling'; -export { default as serialize, getBlockDefaultClassname, getBlockContent } from './serializer'; +export { + default as serialize, + getBlockContent, + getBlockDefaultClassname, + getSaveElement, +} from './serializer'; export { isValidBlock } from './validation'; export { getCategories } from './categories'; export { diff --git a/blocks/api/serializer.js b/blocks/api/serializer.js index 91ebc6fc0c5f27..24b903997c3fc4 100644 --- a/blocks/api/serializer.js +++ b/blocks/api/serializer.js @@ -28,24 +28,25 @@ export function getBlockDefaultClassname( blockName ) { /** * Given a block type containg a save render implementation and attributes, returns the - * static markup to be saved. + * enhanced element to be saved or string when raw HTML expected. * * @param {Object} blockType Block type * @param {Object} attributes Block attributes - * @return {string} Save content + * @return {Object|string} Save content */ -export function getSaveContent( blockType, attributes ) { +export function getSaveElement( blockType, attributes ) { const { save } = blockType; - let saveContent; + + let saveElement; if ( save.prototype instanceof Component ) { - saveContent = createElement( save, { attributes } ); + saveElement = createElement( save, { attributes } ); } else { - saveContent = save( { attributes } ); + saveElement = save( { attributes } ); // Special-case function render implementation to allow raw HTML return - if ( 'string' === typeof saveContent ) { - return saveContent; + if ( 'string' === typeof saveElement ) { + return saveElement; } } @@ -59,10 +60,28 @@ export function getSaveContent( blockType, attributes ) { return cloneElement( element, props ); }; - const contentWithExtraProps = Children.map( saveContent, addExtraContainerProps ); + + return Children.map( saveElement, addExtraContainerProps ); +} + +/** + * Given a block type containg a save render implementation and attributes, returns the + * static markup to be saved. + * + * @param {Object} blockType Block type + * @param {Object} attributes Block attributes + * @return {string} Save content + */ +export function getSaveContent( blockType, attributes ) { + const saveElement = getSaveElement( blockType, attributes ); + + // Special-case function render implementation to allow raw HTML return + if ( 'string' === typeof saveElement ) { + return saveElement; + } // Otherwise, infer as element - return renderToString( contentWithExtraProps ); + return renderToString( saveElement ); } /** diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index f9d6b45e1752bf..e65785bbe1b71c 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -8,14 +8,13 @@ import { get, partial, reduce, size } from 'lodash'; /** * WordPress dependencies */ -import { Component, compose, createElement } from '@wordpress/element'; +import { Component, compose } from '@wordpress/element'; import { keycodes } from '@wordpress/utils'; import { - getBlockType, BlockEdit, - getBlockDefaultClassname, createBlock, - hasBlockSupport, + getBlockType, + getSaveElement, isReusableBlock, } from '@wordpress/blocks'; import { withFilters, withContext } from '@wordpress/components'; @@ -377,12 +376,6 @@ export class BlockListBlock extends Component { wrapperProps = blockType.getEditWrapperProps( block.attributes ); } - // Generate a class name for the block's editable form - const generatedClassName = hasBlockSupport( blockType, 'className', true ) ? - getBlockDefaultClassname( block.name ) : - null; - const className = classnames( generatedClassName, block.attributes.className ); - // Disable reason: Each block can be selected by clicking on it /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ return ( @@ -433,11 +426,7 @@ export class BlockListBlock extends Component { ) } { ! isValid && [ - createElement( blockType.save, { - key: 'invalid-preview', - attributes: block.attributes, - className, - } ), + getSaveElement( blockType, block.attributes ), Date: Mon, 18 Dec 2017 10:21:38 +0100 Subject: [PATCH 4/5] Blocks: Make sure Reusable Blocks get class name apllied properly --- blocks/block-edit/index.js | 2 +- blocks/library/block/index.js | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/blocks/block-edit/index.js b/blocks/block-edit/index.js index a1cdea30ac04fc..8d2c93d9f24d53 100644 --- a/blocks/block-edit/index.js +++ b/blocks/block-edit/index.js @@ -36,7 +36,7 @@ export function BlockEdit( props ) { // them preferencially as the render value for the block. const Edit = blockType.edit || blockType.save; - return ; + return ; } export default withFilters( 'blocks.BlockEdit' )( BlockEdit ); diff --git a/blocks/library/block/index.js b/blocks/library/block/index.js index 6e684cd08e3b10..0988ca56ab53b9 100644 --- a/blocks/library/block/index.js +++ b/blocks/library/block/index.js @@ -14,7 +14,8 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { getBlockType, registerBlockType } from '../../api'; +import BlockEdit from '../../block-edit'; +import { registerBlockType } from '../../api'; import ReusableBlockEditPanel from './edit-panel'; class ReusableBlockEdit extends Component { @@ -85,14 +86,13 @@ class ReusableBlockEdit extends Component { } const reusableBlockAttributes = { ...reusableBlock.attributes, ...attributes }; - const blockType = getBlockType( reusableBlock.type ); - const BlockEdit = blockType.edit || blockType.save; return [ // We fake the block being read-only by wrapping it with an element that has pointer-events: none
null, } ); From 3650811f405ae91d1563d83195b307e37067743d Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 18 Dec 2017 11:47:43 +0100 Subject: [PATCH 5/5] Editor: Wrap invalid block preview with key --- editor/components/block-list/block.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index e65785bbe1b71c..3a7818d4e2feff 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -426,7 +426,9 @@ export class BlockListBlock extends Component { ) } { ! isValid && [ - getSaveElement( blockType, block.attributes ), +
+ { getSaveElement( blockType, block.attributes ) } +
,