mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: paste html rich text inside text
This commit is contained in:
parent
aba84a3ccd
commit
e73465170a
@ -15,12 +15,13 @@ class HTMLConverter {
|
||||
final result = <Node>[];
|
||||
final delta = Delta();
|
||||
|
||||
for (final child in _document.body?.nodes.toList() ?? <html.Node>[]) {
|
||||
final childNodes = _document.body?.nodes.toList() ?? <html.Node>[];
|
||||
for (final child in childNodes) {
|
||||
if (child is html.Element) {
|
||||
if (child.localName == "span") {
|
||||
delta.insert(child.text);
|
||||
} else if (child.localName == "strong") {
|
||||
delta.insert(child.text, {"bold": true});
|
||||
if (child.localName == "a" ||
|
||||
child.localName == "span" ||
|
||||
child.localName == "strong") {
|
||||
_handleRichTextElement(delta, child);
|
||||
} else {
|
||||
_handleElement(result, child);
|
||||
}
|
||||
@ -59,6 +60,25 @@ class HTMLConverter {
|
||||
}
|
||||
|
||||
_handleParagraph(List<Node> nodes, html.Element element) {
|
||||
_handleRichText(nodes, element);
|
||||
}
|
||||
|
||||
_handleRichTextElement(Delta delta, html.Element element) {
|
||||
if (element.localName == "span") {
|
||||
delta.insert(element.text);
|
||||
} else if (element.localName == "a") {
|
||||
final hyperLink = element.attributes["href"];
|
||||
Map<String, dynamic>? attributes;
|
||||
if (hyperLink != null) {
|
||||
attributes = {"href": hyperLink};
|
||||
}
|
||||
delta.insert(element.text, attributes);
|
||||
} else if (element.localName == "strong") {
|
||||
delta.insert(element.text, {"bold": true});
|
||||
}
|
||||
}
|
||||
|
||||
_handleRichText(List<Node> nodes, html.Element element) {
|
||||
final image = element.querySelector("img");
|
||||
if (image != null) {
|
||||
_handleImage(nodes, image);
|
||||
@ -69,13 +89,10 @@ class HTMLConverter {
|
||||
|
||||
for (final child in element.nodes.toList()) {
|
||||
if (child is html.Element) {
|
||||
if (child.localName == "a") {
|
||||
final hyperLink = child.attributes["href"];
|
||||
Map<String, dynamic>? attributes;
|
||||
if (hyperLink != null) {
|
||||
attributes = {"href": hyperLink};
|
||||
}
|
||||
delta.insert(child.text, attributes);
|
||||
if (child.localName == "a" ||
|
||||
child.localName == "span" ||
|
||||
child.localName == "strong") {
|
||||
_handleRichTextElement(delta, element);
|
||||
} else {
|
||||
delta.insert(child.text);
|
||||
}
|
||||
@ -122,11 +139,11 @@ class HTMLConverter {
|
||||
}
|
||||
|
||||
_handleListElement(List<Node> nodes, html.Element element) {
|
||||
final delta = Delta();
|
||||
delta.insert(element.text);
|
||||
if (delta.operations.isNotEmpty) {
|
||||
nodes.add(TextNode(
|
||||
type: "text", attributes: {"subtype": "bullet-list"}, delta: delta));
|
||||
final childNodes = element.nodes.toList();
|
||||
for (final child in childNodes) {
|
||||
if (child is html.Element) {
|
||||
_handleRichText(nodes, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ _handleCopy() async {
|
||||
}
|
||||
|
||||
_pasteHTML(EditorState editorState, String html) {
|
||||
final converter = HTMLConverter(html);
|
||||
final nodes = converter.toNodes();
|
||||
final selection = editorState.cursorSelection;
|
||||
if (selection == null) {
|
||||
return;
|
||||
@ -21,9 +19,31 @@ _pasteHTML(EditorState editorState, String html) {
|
||||
if (path.isEmpty) {
|
||||
return;
|
||||
}
|
||||
path[path.length - 1]++;
|
||||
|
||||
final converter = HTMLConverter(html);
|
||||
final nodes = converter.toNodes();
|
||||
|
||||
if (nodes.isEmpty) {
|
||||
return;
|
||||
} else if (nodes.length == 1) {
|
||||
final firstNode = nodes[0];
|
||||
final nodeAtPath = editorState.document.nodeAtPath(path)!;
|
||||
final tb = TransactionBuilder(editorState);
|
||||
final startOffset = selection.start.offset;
|
||||
if (nodeAtPath.type == "text" && firstNode.type == "text") {
|
||||
final textNodeAtPath = nodeAtPath as TextNode;
|
||||
final firstTextNode = firstNode as TextNode;
|
||||
tb.textEdit(textNodeAtPath,
|
||||
() => Delta().retain(startOffset).concat(firstTextNode.delta));
|
||||
tb.setAfterSelection(Selection.collapsed(Position(
|
||||
path: path, offset: startOffset + firstTextNode.delta.length)));
|
||||
}
|
||||
tb.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
final tb = TransactionBuilder(editorState);
|
||||
path[path.length - 1]++;
|
||||
tb.insertNodes(path, nodes);
|
||||
tb.commit();
|
||||
}
|
||||
@ -98,6 +118,7 @@ _handlePastePlainText(EditorState editorState, String plainText) {
|
||||
tb.insertNodes(path, nodes);
|
||||
tb.commit();
|
||||
|
||||
// fixme: don't set the cursor manually
|
||||
editorState.updateCursorSelection(Selection.collapsed(
|
||||
Position(path: nodes.last.path, offset: lines.last.length)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user