From 346fd027de14b12446c3a5518c1e355b4b18cf08 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 5 Oct 2018 18:11:54 -0400 Subject: [PATCH 1/4] Blocks: Normalize RichText value from string (as HTML), children --- packages/blocks/src/api/factory.js | 47 ++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index b515cab33323a9..f046484db1293b 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -3,6 +3,10 @@ */ import uuid from 'uuid/v4'; import { + cond, + isString, + stubTrue, + identity, every, reduce, castArray, @@ -27,6 +31,24 @@ import deprecated from '@wordpress/deprecated'; * Internal dependencies */ import { getBlockType, getBlockTypes } from './registration'; +import children from './children'; + +function isInvalidRichTextValue( value ) { + return ! value || ! value.text; +} + +function isChildrenValue( value ) { + return Array.isArray( value ); +} + +const SCHEMA_SOURCE_NORMALIZE_VALUE = { + 'rich-text': cond( [ + [ isString, ( html ) => create( { html } ) ], + [ isChildrenValue, ( value ) => create( { html: children.toHTML( value ) } ) ], + [ isInvalidRichTextValue, () => create() ], + [ stubTrue, identity ], + ] ), +}; /** * Returns a block object given its type and attributes. @@ -44,21 +66,15 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { // Ensure attributes contains only values defined by block type, and merge // default values for missing attributes. const attributes = reduce( blockType.attributes, ( result, schema, key ) => { - const value = blockAttributes[ key ]; + let value = blockAttributes[ key ]; - if ( undefined !== value ) { - result[ key ] = value; - } else if ( schema.hasOwnProperty( 'default' ) ) { - result[ key ] = schema.default; + if ( value === undefined && schema.hasOwnProperty( 'default' ) ) { + value = schema.default; } - if ( schema.source === 'rich-text' ) { - // Ensure value passed is always a rich text value. - if ( typeof result[ key ] === 'string' ) { - result[ key ] = create( { text: result[ key ] } ); - } else if ( ! result[ key ] || ! result[ key ].text ) { - result[ key ] = create(); - } + if ( SCHEMA_SOURCE_NORMALIZE_VALUE.hasOwnProperty( schema.source ) ) { + const toNormalValue = SCHEMA_SOURCE_NORMALIZE_VALUE[ schema.source ]; + value = toNormalValue( value ); } if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { @@ -71,12 +87,13 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { // Ensure value passed is always an array, which we're expecting in // the RichText component to handle the deprecated value. if ( typeof result[ key ] === 'string' ) { - result[ key ] = [ result[ key ] ]; - } else if ( ! Array.isArray( result[ key ] ) ) { - result[ key ] = []; + value = [ value ]; + } else if ( ! Array.isArray( value ) ) { + value = []; } } + result[ key ] = value; return result; }, {} ); From e09bdac606e938820a07739e8648838a2e70435f Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 8 Oct 2018 17:34:02 +0100 Subject: [PATCH 2/4] Only support the children format for templates and avoiding baking the normalization in createBlock --- packages/blocks/src/api/factory.js | 28 ------------------- packages/blocks/src/api/templates.js | 42 ++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index f046484db1293b..6e45d0de2da666 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -3,10 +3,6 @@ */ import uuid from 'uuid/v4'; import { - cond, - isString, - stubTrue, - identity, every, reduce, castArray, @@ -24,31 +20,12 @@ import { * WordPress dependencies */ import { createHooks, applyFilters } from '@wordpress/hooks'; -import { create } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; /** * Internal dependencies */ import { getBlockType, getBlockTypes } from './registration'; -import children from './children'; - -function isInvalidRichTextValue( value ) { - return ! value || ! value.text; -} - -function isChildrenValue( value ) { - return Array.isArray( value ); -} - -const SCHEMA_SOURCE_NORMALIZE_VALUE = { - 'rich-text': cond( [ - [ isString, ( html ) => create( { html } ) ], - [ isChildrenValue, ( value ) => create( { html: children.toHTML( value ) } ) ], - [ isInvalidRichTextValue, () => create() ], - [ stubTrue, identity ], - ] ), -}; /** * Returns a block object given its type and attributes. @@ -72,11 +49,6 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { value = schema.default; } - if ( SCHEMA_SOURCE_NORMALIZE_VALUE.hasOwnProperty( schema.source ) ) { - const toNormalValue = SCHEMA_SOURCE_NORMALIZE_VALUE[ schema.source ]; - value = toNormalValue( value ); - } - if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { deprecated( `${ schema.source } source`, { alternative: 'rich-text source', diff --git a/packages/blocks/src/api/templates.js b/packages/blocks/src/api/templates.js index 9e37742d2ecc41..2e024cdbb97f47 100644 --- a/packages/blocks/src/api/templates.js +++ b/packages/blocks/src/api/templates.js @@ -1,12 +1,19 @@ /** * External dependencies */ -import { every, map } from 'lodash'; +import { get, every, map, mapValues } from 'lodash'; + +/** + * WordPress dependencies + */ +import { create } from '@wordpress/rich-text'; +import { renderToString } from '@wordpress/element'; /** * Internal dependencies */ import { createBlock } from './factory'; +import { getBlockType } from './registration'; /** * Checks whether a list of blocks matches a template by comparing the block names. @@ -56,9 +63,40 @@ export function synchronizeBlocksWithTemplate( blocks = [], template ) { return { ...block, innerBlocks }; } + // The template attributes format is a bit different than the block's attributes format + // Because we don't want to expose the `rich-text` type in templates format + // Instead, we use the "element" format which is less verbose. + const blockType = getBlockType( name ); + const isRichTextAttribute = ( attributeDefinition ) => get( attributeDefinition, [ 'source' ] ) === 'rich-text'; + const isQueryAttribute = ( attributeDefinition ) => get( attributeDefinition, [ 'source' ] ) === 'query'; + + const normalizeAttributes = ( schema, values ) => { + return mapValues( values, ( value, key ) => { + return normalizeAttribute( schema[ key ], value ); + } ); + }; + const normalizeAttribute = ( definition, value ) => { + if ( isRichTextAttribute( definition ) ) { + return create( { html: renderToString( value ) } ); + } + + if ( isQueryAttribute( definition ) && value ) { + return value.map( ( subValues ) => { + return normalizeAttributes( definition.query, subValues ); + } ); + } + + return value; + }; + + const normalizedAttributes = normalizeAttributes( + get( blockType, [ 'attributes' ], {} ), + attributes + ); + return createBlock( name, - attributes, + normalizedAttributes, synchronizeBlocksWithTemplate( [], innerBlocksTemplate ) ); } ); From f7c05926f59c794eb1c0de9f833efcd4a5f7064c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 9 Oct 2018 10:18:44 +0100 Subject: [PATCH 3/4] Fix unit tests --- packages/blocks/src/api/factory.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index 6e45d0de2da666..a52afa100658b7 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -20,6 +20,7 @@ import { * WordPress dependencies */ import { createHooks, applyFilters } from '@wordpress/hooks'; +import { create } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; /** @@ -49,6 +50,15 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { value = schema.default; } + if ( schema.source === 'rich-text' ) { + // Ensure value passed is always a rich text value. + if ( typeof value === 'string' ) { + value = create( { text: value } ); + } else if ( ! value || ! value.text ) { + value = create(); + } + } + if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { deprecated( `${ schema.source } source`, { alternative: 'rich-text source', @@ -57,15 +67,18 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) { } ); // Ensure value passed is always an array, which we're expecting in - // the RichText component to handle the deprecated value. - if ( typeof result[ key ] === 'string' ) { + // the RichText getColorObjectByAttributeValuescomponent to handle the deprecated value. + if ( typeof value === 'string' ) { value = [ value ]; } else if ( ! Array.isArray( value ) ) { value = []; } } - result[ key ] = value; + if ( value !== undefined ) { + result[ key ] = value; + } + return result; }, {} ); From f5daaecc861a86694f7aa7f91952e2d4be6d7c5a Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 9 Oct 2018 12:53:04 +0100 Subject: [PATCH 4/4] Fix e2e tests --- test/e2e/test-plugins/block-icons/index.js | 11 +++++------ test/e2e/test-plugins/inner-blocks-templates/index.js | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/test/e2e/test-plugins/block-icons/index.js b/test/e2e/test-plugins/block-icons/index.js index 1c351147fda3f9..7ac84f826fe2aa 100644 --- a/test/e2e/test-plugins/block-icons/index.js +++ b/test/e2e/test-plugins/block-icons/index.js @@ -1,6 +1,5 @@ ( function() { var registerBlockType = wp.blocks.registerBlockType; - var create = wp.richText.create; var el = wp.element.createElement; var InnerBlocks = wp.editor.InnerBlocks; var circle = el( 'circle', { cx: 10, cy: 10, r: 10, fill: 'red', stroke: 'blue', strokeWidth: '10' } ); @@ -19,7 +18,7 @@ allowedBlocks: [ 'core/paragraph', 'core/image' ], template: [ [ 'core/paragraph', { - content: create( { text: 'TestSimpleSvgIcon' } ), + content: 'TestSimpleSvgIcon', } ], ], } @@ -47,7 +46,7 @@ allowedBlocks: [ 'core/paragraph', 'core/image' ], template: [ [ 'core/paragraph', { - content: create( { text: 'TestDashIcon' } ), + content: 'TestDashIcon' } ], ], } @@ -77,7 +76,7 @@ allowedBlocks: [ 'core/paragraph', 'core/image' ], template: [ [ 'core/paragraph', { - content: create( { text: 'TestFunctionIcon' } ), + content: 'TestFunctionIcon', } ], ], } @@ -109,7 +108,7 @@ allowedBlocks: [ 'core/paragraph', 'core/image' ], template: [ [ 'core/paragraph', { - content: create( { text: 'TestIconColors' } ), + content: 'TestIconColors', } ], ], } @@ -140,7 +139,7 @@ allowedBlocks: [ 'core/paragraph', 'core/image' ], template: [ [ 'core/paragraph', { - content: create( { text: 'TestIconColors' } ), + content: 'TestIconColors', } ], ], } diff --git a/test/e2e/test-plugins/inner-blocks-templates/index.js b/test/e2e/test-plugins/inner-blocks-templates/index.js index d4ca5d70c521d1..5510e194d62a49 100644 --- a/test/e2e/test-plugins/inner-blocks-templates/index.js +++ b/test/e2e/test-plugins/inner-blocks-templates/index.js @@ -7,7 +7,7 @@ var TEMPLATE = [ [ 'core/paragraph', { fontSize: 'large', - content: create( { text: 'Content…' } ), + content: 'Content…', } ], ];