Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RichText 🧹 (clean up, move Autocomplete, remove DOM dependency) #16905

Merged
merged 8 commits into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all 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.

95 changes: 62 additions & 33 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 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
Original file line number Diff line number Diff line change
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
Loading