Skip to content

Commit

Permalink
RichText: remove Editable & allow React to diff editable element (#17779
Browse files Browse the repository at this point in the history
)

* RichText: allow React to diff editable element

* Fix prop

* suppressContentEditableWarning

* fix unit tests, simplify

* Remove accidentally added file

* Update docs

* Revert React tree

* Address feedback

* Update packages/rich-text/src/component/index.js

Co-Authored-By: Andrew Duthie <andrew@andrewduthie.com>
  • Loading branch information
ellatrix and aduth committed Nov 12, 2019
1 parent 2102309 commit d9de027
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 282 deletions.
27 changes: 0 additions & 27 deletions packages/rich-text/src/component/aria.js

This file was deleted.

109 changes: 0 additions & 109 deletions packages/rich-text/src/component/editable.js

This file was deleted.

79 changes: 49 additions & 30 deletions packages/rich-text/src/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
find,
isNil,
pickBy,
startsWith,
} from 'lodash';

/**
Expand All @@ -22,10 +23,8 @@ import deprecated from '@wordpress/deprecated';
* Internal dependencies
*/
import FormatEdit from './format-edit';
import Editable from './editable';
import { pickAriaProps } from './aria';
import { create } from '../create';
import { apply, toDom } from '../to-dom';
import { apply } from '../to-dom';
import { toHTMLString } from '../to-html-string';
import { remove } from '../remove';
import { removeFormat } from '../remove-format';
Expand Down Expand Up @@ -58,6 +57,35 @@ const INSERTION_INPUT_TYPES_TO_IGNORE = new Set( [
'insertLink',
] );

/**
* In HTML, leading and trailing spaces are not visible, and multiple spaces
* elsewhere are visually reduced to one space. This rule prevents spaces from
* collapsing so all space is visible in the editor and can be removed. It also
* prevents some browsers from inserting non-breaking spaces at the end of a
* line to prevent the space from visually disappearing. Sometimes these non
* breaking spaces can linger in the editor causing unwanted non breaking spaces
* in between words. If also prevent Firefox from inserting a trailing `br` node
* to visualise any trailing space, causing the element to be saved.
*
* > Authors are encouraged to set the 'white-space' property on editing hosts
* > and on markup that was originally created through these editing mechanisms
* > to the value 'pre-wrap'. Default HTML whitespace handling is not well
* > suited to WYSIWYG editing, and line wrapping will not work correctly in
* > some corner cases if 'white-space' is left at its default value.
*
* https://html.spec.whatwg.org/multipage/interaction.html#best-practices-for-in-page-editors
*
* @type {string}
*/
const whiteSpace = 'pre-wrap';

/**
* Default style object for the editable element.
*
* @type {Object<string,string>}
*/
const defaultStyle = { whiteSpace };

/**
* Global stylesheet.
*/
Expand Down Expand Up @@ -130,7 +158,6 @@ class RichText extends Component {
this.createRecord = this.createRecord.bind( this );
this.applyRecord = this.applyRecord.bind( this );
this.valueToFormat = this.valueToFormat.bind( this );
this.valueToEditableHTML = this.valueToEditableHTML.bind( this );
this.onPointerDown = this.onPointerDown.bind( this );
this.formatToValue = this.formatToValue.bind( this );
this.Editable = this.Editable.bind( this );
Expand Down Expand Up @@ -170,6 +197,8 @@ class RichText extends Component {
console.warn( 'RichText cannot be used with an inline container. Please use a different tagName.' );
}
}

this.applyRecord( this.record, { domOnly: true } );
}

createRecord() {
Expand Down Expand Up @@ -861,9 +890,11 @@ class RichText extends Component {
__unstableIsSelected: isSelected,
} = this.props;

// Check if tag name changed.
let shouldReapply = tagName !== prevProps.tagName;

// Check if the content changed.
let shouldReapply = (
tagName === prevProps.tagName &&
shouldReapply = shouldReapply || (
value !== prevProps.value &&
value !== this.value
);
Expand Down Expand Up @@ -932,17 +963,6 @@ class RichText extends Component {
return value;
}

valueToEditableHTML( value ) {
const { __unstableMultilineTag: multilineTag } = this.props;

return toDom( {
value,
multilineTag,
prepareEditableTree: createPrepareEditableTree( this.props, 'format_prepare_functions' ),
placeholder: this.props.placeholder,
} ).body.innerHTML;
}

/**
* Removes editor only formats from the value.
*
Expand Down Expand Up @@ -983,29 +1003,26 @@ class RichText extends Component {

Editable( props ) {
const {
tagName: Tagname = 'div',
tagName: TagName = 'div',
style,
className,
placeholder,
forwardedRef,
} = this.props;
// Generating a key that includes `tagName` ensures that if the tag
// changes, we replace the relevant element. This is needed because we
// prevent Editable component updates.
const key = Tagname;
const ariaProps = pickBy( this.props, ( value, key ) =>
startsWith( key, 'aria-' ) );

return (
<Editable
<TagName
// Overridable props.
role="textbox"
aria-multiline
aria-label={ placeholder }
{ ...props }
{ ...ariaProps }
ref={ forwardedRef }
tagName={ Tagname }
style={ style }
record={ this.record }
valueToEditableHTML={ this.valueToEditableHTML }
aria-label={ placeholder }
{ ...pickAriaProps( this.props ) }
style={ style ? { ...style, whiteSpace } : defaultStyle }
className={ classnames( 'rich-text', className ) }
key={ key }
onPaste={ this.onPaste }
onInput={ this.onInput }
onCompositionEnd={ this.onCompositionEnd }
Expand All @@ -1024,6 +1041,8 @@ class RichText extends Component {
onKeyUp={ this.onSelectionChange }
onMouseUp={ this.onSelectionChange }
onTouchEnd={ this.onSelectionChange }
contentEditable
suppressContentEditableWarning
/>
);
}
Expand Down
Loading

0 comments on commit d9de027

Please sign in to comment.