Skip to content

Commit

Permalink
[Mobile] Support prefix transforms in mobile (#62576)
Browse files Browse the repository at this point in the history
* RichText - Event Listeners: Export findSelection to be reused with the native functionality

* API - Factory - Add support for prefix type in native

* Native RichText - Add suppot for inputRules

* Native - Add prefix support tests

* Remove useRegistry

* Update Changelog

* Update Changelog

Co-authored-by: geriux <geriux@git.wordpress.org>
Co-authored-by: twstokes <twstokes@git.wordpress.org>
  • Loading branch information
3 people committed Jun 20, 2024
1 parent bb79514 commit 35db76a
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
START_OF_SELECTED_AREA,
} from '../../../utils/selection';

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

while ( i-- ) {
Expand Down
18 changes: 10 additions & 8 deletions packages/block-editor/src/components/rich-text/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
create,
split,
toHTMLString,
slice,
} from '@wordpress/rich-text';
import { isURL } from '@wordpress/url';

Expand All @@ -46,6 +45,8 @@ import EmbedHandlerPicker from './embed-handler-picker';
import { Content } from './content';
import RichText from './native';
import { withDeprecations } from './with-deprecations';
import { findSelection } from './event-listeners/input-rules';
import { START_OF_SELECTED_AREA } from '../../utils/selection';

const classes = 'block-editor-rich-text__editable';

Expand Down Expand Up @@ -502,7 +503,7 @@ export function RichTextWrapper(
);

const inputRule = useCallback(
( value, valueToFormat ) => {
( value ) => {
if ( ! onReplace ) {
return;
}
Expand All @@ -518,7 +519,7 @@ export function RichTextWrapper(
return;
}

const trimmedTextBefore = text.slice( 0, startPosition ).trim();
const trimmedTextBefore = text.slice( 0, start ).trim();
const prefixTransforms = getBlockTransforms( 'from' ).filter(
( { type } ) => type === 'prefix'
);
Expand All @@ -533,15 +534,16 @@ export function RichTextWrapper(
return;
}

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

const currentSelection = findSelection( [ block ] );
onReplace( [ block ] );
selectionChange( ...currentSelection );
__unstableMarkAutomaticChange();
},
[ onReplace, __unstableMarkAutomaticChange ]
[ onReplace, start, selectionChange, __unstableMarkAutomaticChange ]
);

const mergedRef = useMergeRefs( [ providedRef, fallbackRef ] );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,23 @@ export class RichText extends Component {
const contentWithoutRootTag = this.removeRootTagsProducedByAztec(
event.nativeEvent.text
);

const { __unstableInputRule } = this.props;
const currentValuePosition = {
end: this.isIOS ? this.selectionEnd : this.selectionEnd + 1,
start: this.isIOS ? this.selectionStart : this.selectionStart + 1,
};

if (
__unstableInputRule &&
__unstableInputRule( {
...currentValuePosition,
...this.formatToValue( contentWithoutRootTag ),
} )
) {
return;
}

// On iOS, onChange can be triggered after selection changes, even though there are no content changes.
if ( contentWithoutRootTag === this.value?.toString() ) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Paragraph block should be able to use a prefix to create a Heading block 1`] = `
"<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading"></h1>
<!-- /wp:heading -->"
`;

exports[`Paragraph block should be able to use a prefix to create a List block 1`] = `
"<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->"
`;

exports[`Paragraph block should be able to use a prefix to create a Quote block 1`] = `
"<!-- wp:quote -->
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph --></blockquote>
<!-- /wp:quote -->"
`;

exports[`Paragraph block should be able to use a prefix to create a numbered List block 1`] = `
"<!-- wp:list {"ordered":true} -->
<ol class="wp-block-list"><!-- wp:list-item -->
<li></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->"
`;

exports[`Paragraph block should prevent deleting the first Paragraph block when pressing backspace at the start 1`] = `
"<!-- wp:paragraph -->
<p>A quick brown fox jumps over the lazy dog.</p>
Expand Down
99 changes: 99 additions & 0 deletions packages/block-library/src/paragraph/test/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,105 @@ describe( 'Paragraph block', () => {
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'should be able to use a prefix to create a Heading block', async () => {
const screen = await initializeEditor();
await addBlock( screen, 'Paragraph' );
const text = '# ';

const paragraphBlock = getBlock( screen, 'Paragraph' );
fireEvent.press( paragraphBlock );
const paragraphTextInput =
within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
typeInRichText( paragraphTextInput, text, {
finalSelectionStart: 1,
finalSelectionEnd: 1,
} );

fireEvent( paragraphTextInput, 'onChange', {
nativeEvent: { text },
preventDefault() {},
} );

const headingBlock = getBlock( screen, 'Heading' );
expect( headingBlock ).toBeVisible();
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'should be able to use a prefix to create a Quote block', async () => {
const screen = await initializeEditor();
await addBlock( screen, 'Paragraph' );
const text = '> ';

const paragraphBlock = getBlock( screen, 'Paragraph' );
fireEvent.press( paragraphBlock );
const paragraphTextInput =
within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
typeInRichText( paragraphTextInput, text, {
finalSelectionStart: 1,
finalSelectionEnd: 1,
} );

fireEvent( paragraphTextInput, 'onChange', {
nativeEvent: { text },
preventDefault() {},
} );
const quoteBlock = getBlock( screen, 'Quote' );
await triggerBlockListLayout( quoteBlock );

expect( quoteBlock ).toBeVisible();
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'should be able to use a prefix to create a List block', async () => {
const screen = await initializeEditor();
await addBlock( screen, 'Paragraph' );
const text = '- ';

const paragraphBlock = getBlock( screen, 'Paragraph' );
fireEvent.press( paragraphBlock );
const paragraphTextInput =
within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
typeInRichText( paragraphTextInput, text, {
finalSelectionStart: 1,
finalSelectionEnd: 1,
} );

fireEvent( paragraphTextInput, 'onChange', {
nativeEvent: { text },
preventDefault() {},
} );
const listBlock = getBlock( screen, 'List' );
await triggerBlockListLayout( listBlock );

expect( listBlock ).toBeVisible();
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'should be able to use a prefix to create a numbered List block', async () => {
const screen = await initializeEditor();
await addBlock( screen, 'Paragraph' );
const text = '1. ';

const paragraphBlock = getBlock( screen, 'Paragraph' );
fireEvent.press( paragraphBlock );
const paragraphTextInput =
within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
typeInRichText( paragraphTextInput, text, {
finalSelectionStart: 2,
finalSelectionEnd: 2,
} );

fireEvent( paragraphTextInput, 'onChange', {
nativeEvent: { text },
preventDefault() {},
} );
const listBlock = getBlock( screen, 'List' );
await triggerBlockListLayout( listBlock );

expect( listBlock ).toBeVisible();
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'should bold text', async () => {
// Arrange
const screen = await initializeEditor();
Expand Down
4 changes: 4 additions & 0 deletions packages/blocks/src/api/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,10 @@ export function getBlockTransforms( direction, blockTypeOrName ) {
return true;
}

if ( t.type === 'prefix' ) {
return true;
}

if ( ! t.blocks || ! t.blocks.length ) {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For each user feature we should also add a importance categorization label to i
- [internal] Fix Inserter items list filtering [#62334]
- [*] Prevent hiding the keyboard when creating new list items [#62446]
- [*] Fix issue when pasting HTML content [#62588]
- [**] Add support prefix transforms [#62576]

## 1.120.1
- [*] RichText - Fix undefined onDelete callback [#62486]
Expand Down

1 comment on commit 35db76a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 35db76a.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/9594772182
📝 Reported issues:

Please sign in to comment.