Skip to content

Commit

Permalink
Quote v2: retain selection after transform (#39838)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored Mar 30, 2022
1 parent 55eab45 commit 7f80dd4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ function RichTextWrapper(
__unstableAllowPrefixTransformations,
formatTypes,
onReplace,
selectionChange,
} ),
useRemoveBrowserShortcuts(),
useShortcuts( keyboardShortcuts ),
Expand Down
43 changes: 40 additions & 3 deletions packages/block-editor/src/components/rich-text/use-input-rules.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/**
* External dependencies
*/
import { findKey } from 'lodash';

/**
* WordPress dependencies
*/
import { useRef } from '@wordpress/element';
import { useRefEffect } from '@wordpress/compose';
import { slice, toHTMLString } from '@wordpress/rich-text';
import { insert, toHTMLString } from '@wordpress/rich-text';
import { getBlockTransforms, findTransform } from '@wordpress/blocks';
import { useDispatch } from '@wordpress/data';

Expand All @@ -13,6 +18,37 @@ import { useDispatch } from '@wordpress/data';
import { store as blockEditorStore } from '../../store';
import { preventEventDiscovery } from './prevent-event-discovery';

// A robust way to retain selection position through various
// transforms is to insert a special character at the position and
// then recover it.
const START_OF_SELECTED_AREA = '\u0086';

function findSelection( blocks ) {
let i = blocks.length;

while ( i-- ) {
const attributeKey = findKey(
blocks[ i ].attributes,
( v ) =>
typeof v === 'string' &&
v.indexOf( START_OF_SELECTED_AREA ) !== -1
);

if ( attributeKey ) {
blocks[ i ].attributes[ attributeKey ] = blocks[ i ].attributes[
attributeKey
].replace( START_OF_SELECTED_AREA, '' );
return blocks[ i ].clientId;
}

const nestedSelection = findSelection( blocks[ i ].innerBlocks );

if ( nestedSelection ) {
return nestedSelection;
}
}
}

export function useInputRules( props ) {
const {
__unstableMarkLastChangeAsPersistent,
Expand All @@ -22,7 +58,7 @@ export function useInputRules( props ) {
propsRef.current = props;
return useRefEffect( ( element ) => {
function inputRule() {
const { value, onReplace } = propsRef.current;
const { value, onReplace, selectionChange } = propsRef.current;

if ( ! onReplace ) {
return;
Expand Down Expand Up @@ -52,10 +88,11 @@ export function useInputRules( props ) {
}

const content = toHTMLString( {
value: slice( value, start, text.length ),
value: insert( value, START_OF_SELECTED_AREA, 0, start ),
} );
const block = transformation.transform( content );

selectionChange( findSelection( [ block ] ) );
onReplace( [ block ] );
__unstableMarkAutomaticChange();
}
Expand Down

0 comments on commit 7f80dd4

Please sign in to comment.