diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 0b03bcca6a490d..40f758f064e081 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -30,6 +30,7 @@ import { getTextContent, insert, __unstableInsertLineSeparator as insertLineSeparator, + __unstableRemoveLineSeparator as removeLineSeparator, __unstableIsEmptyLine as isEmptyLine, __unstableToDom as toDom, remove, @@ -639,7 +640,7 @@ export class RichText extends Component { if ( keyCode === DELETE || keyCode === BACKSPACE ) { const value = this.createRecord(); - const { replacements, text, start, end } = value; + const { start, end } = value; // Always handle full content deletion ourselves. if ( start === 0 && end !== 0 && end === value.text.length ) { @@ -649,58 +650,7 @@ export class RichText extends Component { } if ( this.multilineTag ) { - let newValue; - - if ( keyCode === BACKSPACE ) { - const index = start - 1; - - if ( text[ index ] === LINE_SEPARATOR ) { - const collapsed = isCollapsed( value ); - - // If the line separator that is about te be removed - // contains wrappers, remove the wrappers first. - if ( collapsed && replacements[ index ] && replacements[ index ].length ) { - const newReplacements = replacements.slice(); - - newReplacements[ index ] = replacements[ index ].slice( 0, -1 ); - newValue = { - ...value, - replacements: newReplacements, - }; - } else { - newValue = remove( - value, - // Only remove the line if the selection is - // collapsed, otherwise remove the selection. - collapsed ? start - 1 : start, - end - ); - } - } - } else if ( text[ end ] === LINE_SEPARATOR ) { - const collapsed = isCollapsed( value ); - - // If the line separator that is about te be removed - // contains wrappers, remove the wrappers first. - if ( collapsed && replacements[ end ] && replacements[ end ].length ) { - const newReplacements = replacements.slice(); - - newReplacements[ end ] = replacements[ end ].slice( 0, -1 ); - newValue = { - ...value, - replacements: newReplacements, - }; - } else { - newValue = remove( - value, - start, - // Only remove the line if the selection is - // collapsed, otherwise remove the selection. - collapsed ? end + 1 : end, - ); - } - } - + const newValue = removeLineSeparator( value, keyCode === BACKSPACE ); if ( newValue ) { this.onChange( newValue ); event.preventDefault(); diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index 5adcbd23054122..92143f16b10697 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -26,9 +26,9 @@ import { split, toHTMLString, insert, - __UNSTABLE_LINE_SEPARATOR as LINE_SEPARATOR, __unstableInsertLineSeparator as insertLineSeparator, __unstableIsEmptyLine as isEmptyLine, + __unstableRemoveLineSeparator as removeLineSeparator, isCollapsed, remove, } from '@wordpress/rich-text'; @@ -386,7 +386,7 @@ export class RichText extends Component { this.comesFromAztec = true; this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; const value = this.createRecord(); - const { replacements, text, start, end } = value; + const { start, end } = value; let newValue; // Always handle full content deletion ourselves. @@ -398,56 +398,7 @@ export class RichText extends Component { } if ( this.multilineTag ) { - if ( keyCode === BACKSPACE ) { - const index = start - 1; - - if ( text[ index ] === LINE_SEPARATOR ) { - const collapsed = isCollapsed( value ); - - // If the line separator that is about te be removed - // contains wrappers, remove the wrappers first. - if ( collapsed && replacements[ index ] && replacements[ index ].length ) { - const newReplacements = replacements.slice(); - - newReplacements[ index ] = replacements[ index ].slice( 0, -1 ); - newValue = { - ...value, - replacements: newReplacements, - }; - } else { - newValue = remove( - value, - // Only remove the line if the selection is - // collapsed, otherwise remove the selection. - collapsed ? start - 1 : start, - end - ); - } - } - } else if ( text[ end ] === LINE_SEPARATOR ) { - const collapsed = isCollapsed( value ); - - // If the line separator that is about te be removed - // contains wrappers, remove the wrappers first. - if ( collapsed && replacements[ end ] && replacements[ end ].length ) { - const newReplacements = replacements.slice(); - - newReplacements[ end ] = replacements[ end ].slice( 0, -1 ); - newValue = { - ...value, - replacements: newReplacements, - }; - } else { - newValue = remove( - value, - start, - // Only remove the line if the selection is - // collapsed, otherwise remove the selection. - collapsed ? end + 1 : end, - ); - } - } - + newValue = removeLineSeparator( value, keyCode === BACKSPACE ); if ( newValue ) { this.onFormatChange( newValue ); return; diff --git a/packages/rich-text/src/index.js b/packages/rich-text/src/index.js index 6dbfe46b6d93b4..8f57a21e4ddf34 100644 --- a/packages/rich-text/src/index.js +++ b/packages/rich-text/src/index.js @@ -20,6 +20,7 @@ export { remove } from './remove'; export { replace } from './replace'; export { insert } from './insert'; export { insertLineSeparator as __unstableInsertLineSeparator } from './insert-line-separator'; +export { removeLineSeparator as __unstableRemoveLineSeparator } from './remove-line-separator'; export { insertObject } from './insert-object'; export { slice } from './slice'; export { split } from './split'; diff --git a/packages/rich-text/src/remove-line-separator.js b/packages/rich-text/src/remove-line-separator.js new file mode 100644 index 00000000000000..f9e6dfb157952e --- /dev/null +++ b/packages/rich-text/src/remove-line-separator.js @@ -0,0 +1,56 @@ +/** + * Internal dependencies + */ + +import { LINE_SEPARATOR } from './special-characters'; +import { isCollapsed } from './is-collapsed'; +import { remove } from './remove'; + +/** + * Removes a line separator character, if existing, from a Rich Text value at the current + * indices. If no line separator exists on the indices it will return undefined. + * + * @param {Object} value Value to modify. + * @param {boolean} backward indicates if are removing from the start index or the end index. + * + * @return {Object|undefined} A new value with the line separator removed. Or undefined if no line separator is found on the position. + */ +export function removeLineSeparator( + value, + backward = true, +) { + const { replacements, text, start, end } = value; + const collapsed = isCollapsed( value ); + let index = start - 1; + let removeStart = collapsed ? start - 1 : start; + let removeEnd = end; + if ( ! backward ) { + index = end; + removeStart = start; + removeEnd = collapsed ? end + 1 : end; + } + + if ( text[ index ] !== LINE_SEPARATOR ) { + return; + } + + let newValue; + // If the line separator that is about te be removed + // contains wrappers, remove the wrappers first. + if ( collapsed && replacements[ index ] && replacements[ index ].length ) { + const newReplacements = replacements.slice(); + + newReplacements[ index ] = replacements[ index ].slice( 0, -1 ); + newValue = { + ...value, + replacements: newReplacements, + }; + } else { + newValue = remove( + value, + removeStart, + removeEnd + ); + } + return newValue; +}