Navigation Menu

Skip to content

Commit

Permalink
RichText 🧹 (clean up, move Autocomplete, remove DOM dependency) (#16905)
Browse files Browse the repository at this point in the history
* RichText 🧹

* Clean up

* Clean up

* Simplify

* Move Autocomplete

* children => Editable wrapper component

* Bind Editable wrapper to class

* Minimise diff
  • Loading branch information
ellatrix committed Aug 14, 2019
1 parent 989c224 commit 24caaa3
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 257 deletions.
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.

95 changes: 62 additions & 33 deletions packages/block-editor/src/components/rich-text/index.js
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 Down Expand Up @@ -42,6 +42,21 @@ 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 @@ -102,7 +117,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 +170,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 +208,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 +217,7 @@ class RichTextWrapper extends Component {
if ( ! hasPastedBlocks || ! isEmpty( before ) ) {
blocks.push( onSplit( toHTMLString( {
value: before,
multilineTag: multiline,
multilineTag,
} ) ) );
}

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

Expand Down Expand Up @@ -313,6 +335,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 +344,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 +359,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,18 +368,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' && (
{ isSelected && multilineTag === 'li' && (
<ListEdit
onTagNameChange={ onTagNameChange }
tagName={ tagName }
Expand All @@ -378,10 +397,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 +483,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 +503,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
1 change: 0 additions & 1 deletion packages/rich-text/package.json
Expand Up @@ -24,7 +24,6 @@
"@babel/runtime": "^7.4.4",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"@wordpress/dom": "file:../dom",
"@wordpress/element": "file:../element",
"@wordpress/escape-html": "file:../escape-html",
"@wordpress/hooks": "file:../hooks",
Expand Down

0 comments on commit 24caaa3

Please sign in to comment.