fix: could not insert link on the Web

This commit is contained in:
Lucas.Xu 2022-09-28 23:01:22 +08:00
parent ab0131c19c
commit 99cb2430f7
5 changed files with 124 additions and 32 deletions

View File

@ -3,29 +3,25 @@ import 'package:appflowy_editor/src/document/attributes.dart';
import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/document/path.dart';
import 'package:appflowy_editor/src/document/selection.dart';
import 'package:appflowy_editor/src/editor_state.dart';
Future<void> formatBuiltInTextAttributes(
EditorState editorState,
String key,
Attributes attributes, {
Selection? selection,
Path? path,
TextNode? textNode,
}) async {
final result = getTextNodeToBeFormatted(
editorState,
path: path,
textNode: textNode,
);
if (BuiltInAttributeKey.globalStyleKeys.contains(key)) {
assert(!(path != null && textNode != null));
assert(!(path == null && textNode == null));
TextNode formattedTextNode;
if (textNode != null) {
formattedTextNode = textNode;
} else if (path != null) {
formattedTextNode = editorState.document.nodeAtPath(path) as TextNode;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
// remove all the existing style
final newAttributes = formattedTextNode.attributes
final newAttributes = result.attributes
..removeWhere((key, value) {
if (BuiltInAttributeKey.globalStyleKeys.contains(key)) {
return true;
@ -41,6 +37,13 @@ Future<void> formatBuiltInTextAttributes(
newAttributes,
textNode: textNode,
);
} else if (BuiltInAttributeKey.partialStyleKeys.contains(key)) {
return updateTextNodeDeltaAttributes(
editorState,
selection,
attributes,
textNode: textNode,
);
}
}
@ -60,3 +63,20 @@ Future<void> formatTextToCheckbox(
textNode: textNode,
);
}
Future<void> formatLinkInText(
EditorState editorState,
String? link, {
Path? path,
TextNode? textNode,
}) async {
return formatBuiltInTextAttributes(
editorState,
BuiltInAttributeKey.href,
{
BuiltInAttributeKey.href: link,
},
path: path,
textNode: textNode,
);
}

View File

@ -1,6 +1,9 @@
import 'dart:async';
import 'package:appflowy_editor/src/document/attributes.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/document/path.dart';
import 'package:appflowy_editor/src/document/selection.dart';
import 'package:appflowy_editor/src/editor_state.dart';
import 'package:appflowy_editor/src/operation/transaction_builder.dart';
import 'package:flutter/widgets.dart';
@ -11,24 +14,90 @@ Future<void> updateTextNodeAttributes(
Path? path,
TextNode? textNode,
}) async {
assert(!(path != null && textNode != null));
assert(!(path == null && textNode == null));
final result = getTextNodeToBeFormatted(
editorState,
path: path,
textNode: textNode,
);
TextNode formattedTextNode;
if (textNode != null) {
formattedTextNode = textNode;
} else if (path != null) {
formattedTextNode = editorState.document.nodeAtPath(path) as TextNode;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
final completer = Completer<void>();
TransactionBuilder(editorState)
..updateNode(formattedTextNode, attributes)
..updateNode(result, attributes)
..commit();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
print('AAAAAAAAAAAAAA');
return;
completer.complete();
});
return completer.future;
}
Future<void> updateTextNodeDeltaAttributes(
EditorState editorState,
Selection? selection,
Attributes attributes, {
Path? path,
TextNode? textNode,
}) {
final result = getTextNodeToBeFormatted(
editorState,
path: path,
textNode: textNode,
);
final newSelection = _getSelection(editorState, selection: selection);
final completer = Completer<void>();
TransactionBuilder(editorState)
..formatText(
result,
newSelection.startIndex,
newSelection.length,
attributes,
)
..commit();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
completer.complete();
});
return completer.future;
}
// get formatted [TextNode]
TextNode getTextNodeToBeFormatted(
EditorState editorState, {
Path? path,
TextNode? textNode,
}) {
assert(!(path != null && textNode != null));
assert(!(path == null && textNode == null));
TextNode result;
if (textNode != null) {
result = textNode;
} else if (path != null) {
result = editorState.document.nodeAtPath(path) as TextNode;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
return result;
}
Selection _getSelection(
EditorState editorState, {
Selection? selection,
}) {
final currentSelection =
editorState.service.selectionService.currentSelection.value;
Selection result;
if (selection != null) {
result = selection;
} else if (currentSelection != null) {
result = currentSelection;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
return result;
}

View File

@ -53,6 +53,10 @@ class Selection {
Selection get reversed => copyWith(start: end, end: start);
int get startIndex => normalize.start.offset;
int get endIndex => normalize.end.offset;
int get length => endIndex - startIndex;
Selection collapse({bool atStart = false}) {
if (atStart) {
return Selection(start: start, end: start);

View File

@ -74,8 +74,8 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
padding: iconPadding,
name: check ? 'check' : 'uncheck',
),
onTap: () {
formatTextToCheckbox(
onTap: () async {
await formatTextToCheckbox(
widget.editorState,
!check,
textNode: widget.textNode,

View File

@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/commands/format_built_in_text.dart';
import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart';
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
import 'package:appflowy_editor/src/render/link_menu/link_menu.dart';
@ -345,11 +346,8 @@ void showLinkMenu(
onOpenLink: () async {
await safeLaunchUrl(linkText);
},
onSubmitted: (text) {
TransactionBuilder(editorState)
..formatText(
textNode, index, length, {BuiltInAttributeKey.href: text})
..commit();
onSubmitted: (text) async {
await formatLinkInText(editorState, text, textNode: textNode);
_dismissLinkMenu();
},
onCopyLink: () {
@ -377,6 +375,7 @@ void showLinkMenu(
Overlay.of(context)?.insert(_linkMenuOverlay!);
editorState.service.scrollService?.disable();
editorState.service.keyboardService?.disable();
editorState.service.selectionService.currentSelection
.addListener(_dismissLinkMenu);
}