@@ -443,6 +443,54 @@ void main() {
443443 );
444444 });
445445
446+ testWidgetsOnWebAndroid ("inserts new item upon new line insertion at end of existing item" , (tester) async {
447+ final context = await tester //
448+ .createDocument ()
449+ .fromMarkdown ('* Item 1' )
450+ .pump ();
451+
452+ final document = context.findEditContext ().document;
453+
454+ // Place the caret at the end of the list item.
455+ await tester.placeCaretInParagraph (document.first.id, 6 );
456+
457+ // Type at the end of the list item to generate a composing region,
458+ // simulating the Samsung keyboard.
459+ await tester.typeImeText ('2' );
460+ await tester.ime.sendDeltas (const [
461+ TextEditingDeltaNonTextUpdate (
462+ oldText: '. Item 12' ,
463+ selection: TextSelection .collapsed (offset: 9 ),
464+ composing: TextRange .collapsed (9 ),
465+ ),
466+ ], getter: imeClientGetter);
467+
468+ // On Android Web, pressing ENTER generates both a "\n" insertion and a newline input action.
469+ await tester.pressEnterWithIme (getter: imeClientGetter);
470+
471+ // Ensure that a new, empty list item was created.
472+ expect (document.nodeCount, 2 );
473+
474+ // Ensure the existing item remains the same.
475+ expect (document.first, isA <ListItemNode >());
476+ expect ((document.first as ListItemNode ).text.toPlainText (), "Item 12" );
477+
478+ // Ensure the new item has the correct list item type and indentation.
479+ expect (document.last, isA <ListItemNode >());
480+ expect ((document.last as ListItemNode ).text.toPlainText (), "" );
481+ expect ((document.last as ListItemNode ).type, ListItemType .unordered);
482+ expect ((document.last as ListItemNode ).indent, 0 );
483+ expect (
484+ SuperEditorInspector .findDocumentSelection (),
485+ DocumentSelection .collapsed (
486+ position: DocumentPosition (
487+ nodeId: document.last.id,
488+ nodePosition: const TextNodePosition (offset: 0 ),
489+ ),
490+ ),
491+ );
492+ });
493+
446494 testWidgetsOnMobile ("inserts new item upon new line input action at end of existing item" , (tester) async {
447495 final context = await tester //
448496 .createDocument ()
@@ -558,6 +606,40 @@ void main() {
558606 );
559607 });
560608
609+ testWidgetsOnWebAndroid ("splits list item into two upon new line insertion in middle of existing item" ,
610+ (tester) async {
611+ final context = await tester //
612+ .createDocument ()
613+ .fromMarkdown ('* List Item' )
614+ .pump ();
615+
616+ final document = context.findEditContext ().document;
617+
618+ // Place the caret at "List |Item"
619+ await tester.placeCaretInParagraph (document.first.id, 5 );
620+
621+ // On Android Web, pressing ENTER generates both a "\n" insertion and a newline input action.
622+ await tester.pressEnterWithIme (getter: imeClientGetter);
623+
624+ // Ensure that a new item was created with part of the previous item.
625+ expect (document.nodeCount, 2 );
626+ expect (document.first, isA <ListItemNode >());
627+ expect ((document.first as ListItemNode ).text.toPlainText (), "List " );
628+ expect (document.last, isA <ListItemNode >());
629+ expect ((document.last as ListItemNode ).text.toPlainText (), "Item" );
630+ expect ((document.last as ListItemNode ).type, ListItemType .unordered);
631+ expect ((document.last as ListItemNode ).indent, 0 );
632+ expect (
633+ SuperEditorInspector .findDocumentSelection (),
634+ DocumentSelection .collapsed (
635+ position: DocumentPosition (
636+ nodeId: document.last.id,
637+ nodePosition: const TextNodePosition (offset: 0 ),
638+ ),
639+ ),
640+ );
641+ });
642+
561643 testWidgetsOnMobile ("splits list item into two upon new line input action in middle of existing item" ,
562644 (tester) async {
563645 final context = await tester //
@@ -939,6 +1021,43 @@ A paragraph
9391021 );
9401022 });
9411023
1024+ testWidgetsOnWebAndroid ("inserts new item upon new line insertion at end of existing item" , (tester) async {
1025+ final context = await tester //
1026+ .createDocument ()
1027+ .fromMarkdown ('1. Item 1' )
1028+ .pump ();
1029+
1030+ final document = context.findEditContext ().document;
1031+
1032+ // Place the caret at the end of the list item.
1033+ await tester.placeCaretInParagraph (document.first.id, 6 );
1034+
1035+ // On Android Web, pressing ENTER generates both a "\n" insertion and a newline input action.
1036+ await tester.pressEnterWithIme (getter: imeClientGetter);
1037+
1038+ // Ensure that a new, empty list item was created.
1039+ expect (document.nodeCount, 2 );
1040+
1041+ // Ensure the existing item remains the same.
1042+ expect (document.first, isA <ListItemNode >());
1043+ expect ((document.first as ListItemNode ).text.toPlainText (), "Item 1" );
1044+
1045+ // Ensure the new item has the correct list item type and indentation.
1046+ expect (document.last, isA <ListItemNode >());
1047+ expect ((document.last as ListItemNode ).text.toPlainText (), "" );
1048+ expect ((document.last as ListItemNode ).type, ListItemType .ordered);
1049+ expect ((document.last as ListItemNode ).indent, 0 );
1050+ expect (
1051+ SuperEditorInspector .findDocumentSelection (),
1052+ DocumentSelection .collapsed (
1053+ position: DocumentPosition (
1054+ nodeId: document.last.id,
1055+ nodePosition: const TextNodePosition (offset: 0 ),
1056+ ),
1057+ ),
1058+ );
1059+ });
1060+
9421061 testWidgetsOnMobile ("inserts new item upon new line input action at end of existing item" , (tester) async {
9431062 final context = await tester //
9441063 .createDocument ()
@@ -1043,6 +1162,40 @@ A paragraph
10431162 );
10441163 });
10451164
1165+ testWidgetsOnWebAndroid ("splits list item into two upon new line insertion in middle of existing item" ,
1166+ (tester) async {
1167+ final context = await tester //
1168+ .createDocument ()
1169+ .fromMarkdown ('1. List Item' )
1170+ .pump ();
1171+
1172+ final document = context.findEditContext ().document;
1173+
1174+ // Place the caret at "List |Item"
1175+ await tester.placeCaretInParagraph (document.first.id, 5 );
1176+
1177+ // On Android Web, pressing ENTER generates both a "\n" insertion and a newline input action.
1178+ await tester.pressEnterWithIme (getter: imeClientGetter);
1179+
1180+ // Ensure that a new item was created with part of the previous item.
1181+ expect (document.nodeCount, 2 );
1182+ expect (document.first, isA <ListItemNode >());
1183+ expect ((document.first as ListItemNode ).text.toPlainText (), "List " );
1184+ expect (document.last, isA <ListItemNode >());
1185+ expect ((document.last as ListItemNode ).text.toPlainText (), "Item" );
1186+ expect ((document.last as ListItemNode ).type, ListItemType .ordered);
1187+ expect ((document.last as ListItemNode ).indent, 0 );
1188+ expect (
1189+ SuperEditorInspector .findDocumentSelection (),
1190+ DocumentSelection .collapsed (
1191+ position: DocumentPosition (
1192+ nodeId: document.last.id,
1193+ nodePosition: const TextNodePosition (offset: 0 ),
1194+ ),
1195+ ),
1196+ );
1197+ });
1198+
10461199 testWidgetsOnMobile ("splits list item into two upon new line input action in middle of existing item" ,
10471200 (tester) async {
10481201 final context = await tester //
0 commit comments