diff --git a/packages/block-library/src/heading/edit.native.js b/packages/block-library/src/heading/edit.native.js index ba07909d3a6df..d21613cabe098 100644 --- a/packages/block-library/src/heading/edit.native.js +++ b/packages/block-library/src/heading/edit.native.js @@ -16,7 +16,64 @@ import { Component } from '@wordpress/element'; import { RichText, BlockControls } from '@wordpress/editor'; import { createBlock } from '@wordpress/blocks'; +const name = 'core/heading'; + +/** + * Internal dependencies + */ +import styles from './style.scss'; + class HeadingEdit extends Component { + constructor( props ) { + super( props ); + + this.splitBlock = this.splitBlock.bind( this ); + } + + + /** + * Split handler for RichText value, namely when content is pasted or the + * user presses the Enter key. + * + * @param {?Array} before Optional before value, to be used as content + * in place of what exists currently for the + * block. If undefined, the block is deleted. + * @param {?Array} after Optional after value, to be appended in a new + * paragraph block to the set of blocks passed + * as spread. + * @param {...WPBlock} blocks Optional blocks inserted between the before + * and after value blocks. + */ + splitBlock( before, after, ...blocks ) { + const { + attributes, + insertBlocksAfter, + setAttributes, + onReplace, + } = this.props; + + if ( after !== null ) { + // Append "After" content as a new paragraph block to the end of + // any other blocks being inserted after the current paragraph. + const newBlock = createBlock( name, { content: after } ); + blocks.push( newBlock ); + } + + if ( blocks.length && insertBlocksAfter ) { + insertBlocksAfter( blocks ); + } + + const { content } = attributes; + if ( before === null ) { + onReplace( [] ); + } else if ( content !== before ) { + // Only update content if it has in-fact changed. In case that user + // has created a new paragraph at end of an existing one, the value + // of before will be strictly equal to the current content. + setAttributes( { content: before } ); + } + } + render() { const { attributes, @@ -49,17 +106,7 @@ class HeadingEdit extends Component { onCaretVerticalPositionChange={ this.props.onCaretVerticalPositionChange } onChange={ ( value ) => setAttributes( { content: value } ) } onMerge={ mergeBlocks } - onSplit={ - insertBlocksAfter ? - ( before, after, ...blocks ) => { - setAttributes( { content: before } ); - insertBlocksAfter( [ - ...blocks, - createBlock( 'core/paragraph', { content: after } ), - ] ); - } : - undefined - } + onSplit={ this.splitBlock } placeholder={ placeholder || __( 'Write heading…' ) } /> diff --git a/packages/editor/src/components/rich-text/index.native.js b/packages/editor/src/components/rich-text/index.native.js index a13f66e85e4bf..5c707388ee432 100644 --- a/packages/editor/src/components/rich-text/index.native.js +++ b/packages/editor/src/components/rich-text/index.native.js @@ -97,9 +97,16 @@ export class RichText extends Component { */ getRecord() { const { formatPlaceholder, start, end } = this.state; + + var value = this.props.value === undefined ? null : this.props.value; + // Since we get the text selection from Aztec we need to be in sync with the HTML `value` // Removing leading white spaces using `trim()` should make sure this is the case. - const { formats, text } = this.formatToValue( this.props.value === undefined ? undefined : this.props.value.trimLeft() ); + if (typeof value === 'string' || value instanceof String) { + value = value.trimLeft(); + } + + const { formats, text } = this.formatToValue( value ); return { formats, formatPlaceholder, text, start, end }; }