feat: format the selected text to url if available (#3245)

This commit is contained in:
Lucas.Xu 2023-08-22 15:46:27 +08:00 committed by GitHub
parent 77637ff461
commit 724fc895e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 3 deletions

View File

@ -195,11 +195,43 @@ void main() {
// expect(node.attributes[ImageBlockKeys.url], isNotNull);
// });
});
testWidgets(
'format the selected text to href when pasting url if available',
(tester) async {
const text = 'appflowy';
const url = 'https://appflowy.io';
await tester.pasteContent(
plainText: url,
beforeTest: (editorState) async {
await tester.ime.insertText(text);
await tester.editor.updateSelection(
Selection.single(
path: [0],
startOffset: 0,
endOffset: text.length,
),
);
},
(editorState) {
final node = editorState.getNodeAtPath([0])!;
expect(node.type, ParagraphBlockKeys.type);
expect(node.delta!.toJson(), [
{
'insert': text,
'attributes': {'href': url}
}
]);
},
);
},
);
}
extension on WidgetTester {
Future<void> pasteContent(
void Function(EditorState editorState) test, {
Future<void> Function(EditorState editorState)? beforeTest,
String? plainText,
String? html,
(String, Uint8List?)? image,
@ -210,6 +242,8 @@ extension on WidgetTester {
// create a new document
await createNewPageWithName();
await beforeTest?.call(editor.getCurrentEditorState());
// mock the clipboard
getIt<ClipboardService>().setData(
ClipboardServiceData(
@ -227,7 +261,6 @@ extension on WidgetTester {
);
await pumpAndSettle();
final editorState = editor.getCurrentEditorState();
test(editorState);
test(editor.getCurrentEditorState());
}
}

View File

@ -53,7 +53,6 @@ CommandShortcutEventHandler _pasteCommandHandler = (editorState) {
await editorState.deleteSelectionIfNeeded();
await editorState.pasteImage(image.$1, image.$2!);
} else if (plainText != null && plainText.isNotEmpty) {
await editorState.deleteSelectionIfNeeded();
await editorState.pastePlainText(plainText);
}
}();

View File

@ -7,6 +7,12 @@ RegExp _hrefRegex = RegExp(
extension PasteFromPlainText on EditorState {
Future<void> pastePlainText(String plainText) async {
if (await pasteHtmlIfAvailable(plainText)) {
return;
}
await deleteSelectionIfNeeded();
final nodes = plainText
.split('\n')
.map(
@ -33,4 +39,26 @@ extension PasteFromPlainText on EditorState {
await pasteMultiLineNodes(nodes.toList());
}
}
Future<bool> pasteHtmlIfAvailable(String plainText) async {
final selection = this.selection;
if (selection == null ||
!selection.isSingle ||
selection.isCollapsed ||
!_hrefRegex.hasMatch(plainText)) {
return false;
}
final node = getNodeAtPath(selection.start.path);
if (node == null) {
return false;
}
final transaction = this.transaction;
transaction.formatText(node, selection.startIndex, selection.length, {
AppFlowyRichTextKeys.href: plainText,
});
await apply(transaction);
return true;
}
}