Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 64 additions & 43 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { omit } from 'lodash';
*/
import { RawHTML, Component } from '@wordpress/element';
import { withDispatch, withSelect } from '@wordpress/data';
import { pasteHandler, children, getBlockTransforms, findTransform } from '@wordpress/blocks';
import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform } from '@wordpress/blocks';
import { withInstanceId, compose } from '@wordpress/compose';
import {
RichText,
Expand All @@ -36,12 +36,26 @@ import Autocomplete from '../autocomplete';
import BlockFormatControls from '../block-format-controls';
import FormatToolbar from './format-toolbar';
import { withBlockEditContext } from '../block-edit/context';
import { ListEdit } from './list-edit';
import { RemoveBrowserShortcuts } from './remove-browser-shortcuts';

const wrapperClasses = 'editor-rich-text block-editor-rich-text';
const classes = 'editor-rich-text__editable block-editor-rich-text__editable';

/**
* Get the multiline tag based on the multiline prop.
*
* @param {?(string|boolean)} multiline The multiline prop.
*
* @return {?string} The multiline tag.
*/
function getMultilineTag( multiline ) {
if ( multiline !== true && multiline !== 'p' && multiline !== 'li' ) {
return;
}

return multiline === true ? 'p' : multiline;
}

class RichTextWrapper extends Component {
constructor() {
super( ...arguments );
Expand Down Expand Up @@ -85,7 +99,7 @@ class RichTextWrapper extends Component {
}
}

onDelete( { value, isReverse } ) {
onDelete( { isReverse, value } ) {
const { onMerge, onRemove } = this.props;

if ( onMerge ) {
Expand All @@ -102,7 +116,13 @@ class RichTextWrapper extends Component {
}

onPaste( { value, onChange, html, plainText, image } ) {
const { onReplace, onSplit, tagName, canUserUseUnfilteredHTML } = this.props;
const {
onReplace,
onSplit,
tagName,
canUserUseUnfilteredHTML,
multiline,
} = this.props;

if ( image && ! html ) {
const file = image.getAsFile ? image.getAsFile() : image;
Expand Down Expand Up @@ -149,7 +169,7 @@ class RichTextWrapper extends Component {

// If the content should be multiline, we should process text
// separated by a line break as separate lines.
if ( this.multilineTag ) {
if ( multiline ) {
valueToInsert = replace( valueToInsert, /\n+/g, LINE_SEPARATOR );
}

Expand Down Expand Up @@ -187,6 +207,7 @@ class RichTextWrapper extends Component {
const blocks = [];
const [ before, after ] = split( record );
const hasPastedBlocks = pastedBlocks.length > 0;
const multilineTag = getMultilineTag( multiline );

// Create a block with the content before the caret if there's no pasted
// blocks, or if there are pasted blocks and the value is not empty.
Expand All @@ -195,7 +216,7 @@ class RichTextWrapper extends Component {
if ( ! hasPastedBlocks || ! isEmpty( before ) ) {
blocks.push( onSplit( toHTMLString( {
value: before,
multilineTag: multiline,
multilineTag,
} ) ) );
}

Expand All @@ -212,7 +233,7 @@ class RichTextWrapper extends Component {
if ( hasPastedBlocks || ! onSplitMiddle || ! isEmpty( after ) ) {
blocks.push( onSplit( toHTMLString( {
value: after,
multilineTag: multiline,
multilineTag,
} ) ) );
}

Expand Down Expand Up @@ -274,14 +295,14 @@ class RichTextWrapper extends Component {

render() {
const {
children,
tagName,
value: originalValue,
onChange: originalOnChange,
selectionStart,
selectionEnd,
onSelectionChange,
multiline,
onTagNameChange,
inlineToolbar,
wrapperClassName,
className,
Expand Down Expand Up @@ -313,6 +334,7 @@ class RichTextWrapper extends Component {
// From experimental filter. To do: pick props instead.
...experimentalProps
} = this.props;
const multilineTag = getMultilineTag( multiline );

const adjustedAllowedFormats = this.getAllowedFormats();
const hasFormats = ! adjustedAllowedFormats || adjustedAllowedFormats.length > 0;
Expand All @@ -321,13 +343,13 @@ class RichTextWrapper extends Component {

// Handle deprecated format.
if ( Array.isArray( originalValue ) ) {
adjustedValue = children.toHTML( originalValue );
adjustedOnChange = ( newValue ) => originalOnChange( children.fromDOM(
adjustedValue = childrenSource.toHTML( originalValue );
adjustedOnChange = ( newValue ) => originalOnChange( childrenSource.fromDOM(
__unstableCreateElement( document, newValue ).childNodes
) );
}

return (
const content = (
<RichText
{ ...experimentalProps }
value={ adjustedValue }
Expand All @@ -336,7 +358,6 @@ class RichTextWrapper extends Component {
selectionEnd={ selectionEnd }
onSelectionChange={ onSelectionChange }
tagName={ tagName }
wrapperClassName={ classnames( wrapperClasses, wrapperClassName ) }
className={ classnames( classes, className, { 'is-selected': originalIsSelected } ) }
placeholder={ placeholder }
allowedFormats={ adjustedAllowedFormats }
Expand All @@ -346,25 +367,15 @@ class RichTextWrapper extends Component {
onPaste={ this.onPaste }
__unstableIsSelected={ originalIsSelected }
__unstableInputRule={ this.inputRule }
__unstableAutocomplete={ Autocomplete }
__unstableAutocompleters={ autocompleters }
__unstableOnReplace={ onReplace }
__unstableMultiline={ multiline }
__unstableMultilineTag={ multilineTag }
__unstableIsCaretWithinFormattedText={ isCaretWithinFormattedText }
__unstableOnEnterFormattedText={ onEnterFormattedText }
__unstableOnExitFormattedText={ onExitFormattedText }
__unstableOnCreateUndoLevel={ onCreateUndoLevel }
>
{ ( { isSelected, value, onChange } ) =>
{ ( { isSelected, value, onChange, Editable } ) =>
<>
{ isSelected && multiline === 'li' && (
<ListEdit
onTagNameChange={ onTagNameChange }
tagName={ tagName }
value={ value }
onChange={ onChange }
/>
) }
{ isSelected && children && children( { value, onChange } ) }
{ isSelected && ! inlineToolbar && hasFormats && (
<BlockFormatControls>
<FormatToolbar />
Expand All @@ -378,10 +389,30 @@ class RichTextWrapper extends Component {
</IsolatedEventContainer>
) }
{ isSelected && <RemoveBrowserShortcuts /> }
<Autocomplete
onReplace={ onReplace }
completers={ autocompleters }
record={ value }
onChange={ onChange }
>
{ ( { listBoxId, activeId } ) =>
<Editable
aria-autocomplete={ listBoxId ? 'list' : undefined }
aria-owns={ listBoxId }
aria-activedescendant={ activeId }
/>
}
</Autocomplete>
</>
}
</RichText>
);

return (
<div className={ classnames( wrapperClasses, wrapperClassName ) }>
{ content }
</div>
);
}
}

Expand Down Expand Up @@ -444,23 +475,18 @@ const RichTextContainer = compose( [
] )( RichTextWrapper );

RichTextContainer.Content = ( { value, tagName: Tag, multiline, ...props } ) => {
let html = value;
let MultilineTag;

if ( multiline === true || multiline === 'p' || multiline === 'li' ) {
MultilineTag = multiline === true ? 'p' : multiline;
}

// Handle deprecated `children` and `node` sources.
if ( Array.isArray( value ) ) {
html = children.toHTML( value );
value = childrenSource.toHTML( value );
}

if ( ! html && MultilineTag ) {
html = `<${ MultilineTag }></${ MultilineTag }>`;
const MultilineTag = getMultilineTag( multiline );

if ( ! value && MultilineTag ) {
value = `<${ MultilineTag }></${ MultilineTag }>`;
}

const content = <RawHTML>{ html }</RawHTML>;
const content = <RawHTML>{ value }</RawHTML>;

if ( Tag ) {
return <Tag { ...omit( props, [ 'format' ] ) }>{ content }</Tag>;
Expand All @@ -469,13 +495,8 @@ RichTextContainer.Content = ( { value, tagName: Tag, multiline, ...props } ) =>
return content;
};

RichTextContainer.isEmpty = ( value = '' ) => {
// Handle deprecated `children` and `node` sources.
if ( Array.isArray( value ) ) {
return ! value || value.length === 0;
}

return value.length === 0;
RichTextContainer.isEmpty = ( value ) => {
return ! value || value.length === 0;
};

RichTextContainer.Content.defaultProps = {
Expand Down
104 changes: 0 additions & 104 deletions packages/block-editor/src/components/rich-text/list-edit.js

This file was deleted.

Loading