From e2a68c957667d2fd6932f4947135dbee5388fcbb Mon Sep 17 00:00:00 2001 From: Peng Zhou Date: Thu, 25 Jan 2024 14:57:49 +0800 Subject: [PATCH 1/5] add support for breakline --- lib/src/plugins/html/encoder/parser/text_node_parser.dart | 6 +++++- lib/src/plugins/html/html_document_decoder.dart | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/plugins/html/encoder/parser/text_node_parser.dart b/lib/src/plugins/html/encoder/parser/text_node_parser.dart index 88f2d1198..7845d8e5e 100644 --- a/lib/src/plugins/html/encoder/parser/text_node_parser.dart +++ b/lib/src/plugins/html/encoder/parser/text_node_parser.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:html/dom.dart' as dom; @@ -30,7 +32,9 @@ class HTMLTextNodeParser extends HTMLNodeParser { encodeParsers: encodeParsers, ), ); - + if (domNodes.isEmpty) { + return [dom.Element.tag(HTMLTags.br)]; + } final element = wrapChildrenNodesWithTagName(HTMLTags.paragraph, childNodes: domNodes); return [element]; diff --git a/lib/src/plugins/html/html_document_decoder.dart b/lib/src/plugins/html/html_document_decoder.dart index 9a8852e5a..9820fd63a 100644 --- a/lib/src/plugins/html/html_document_decoder.dart +++ b/lib/src/plugins/html/html_document_decoder.dart @@ -473,6 +473,7 @@ class HTMLTags { static const h1 = 'h1'; static const h2 = 'h2'; static const h3 = 'h3'; + static const br = 'br'; static const orderedList = 'ol'; static const unorderedList = 'ul'; static const list = 'li'; From f93b91d2c0f7552e7750eba56a7e497fd37fead8 Mon Sep 17 00:00:00 2001 From: Peng Zhou Date: Fri, 26 Jan 2024 01:27:46 +0800 Subject: [PATCH 2/5] add test for br tag parse --- .../html/encoder/parser/text_node_parser.dart | 2 -- .../encoder/parser/text_node_parser_test.dart | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/src/plugins/html/encoder/parser/text_node_parser.dart b/lib/src/plugins/html/encoder/parser/text_node_parser.dart index 7845d8e5e..7568b2ddf 100644 --- a/lib/src/plugins/html/encoder/parser/text_node_parser.dart +++ b/lib/src/plugins/html/encoder/parser/text_node_parser.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:html/dom.dart' as dom; diff --git a/test/plugins/html/encoder/parser/text_node_parser_test.dart b/test/plugins/html/encoder/parser/text_node_parser_test.dart index 5a9f2be7b..d53dab8c4 100644 --- a/test/plugins/html/encoder/parser/text_node_parser_test.dart +++ b/test/plugins/html/encoder/parser/text_node_parser_test.dart @@ -12,7 +12,7 @@ void main() async { const HTMLImageNodeParser(), const HtmlTableNodeParser(), ]; - group('html_text_node_parser.dart', () { + group('text_node_parser.dart', () { const text = 'Welcome to AppFlowy'; test('heading style', () { @@ -44,6 +44,19 @@ void main() async { ); }); + test('empty line', () { + final node = paragraphNode( + attributes: { + 'delta': [], + }, + ); + expect( + const HTMLTextNodeParser() + .transformNodeToHTMLString(node, encodeParsers: parser), + '
', + ); + }); + test('numbered list style', () { final node = numberedListNode( attributes: { From d7d573d4f183285b85f40ccb7d920ff8220bd610 Mon Sep 17 00:00:00 2001 From: Peng Zhou Date: Fri, 26 Jan 2024 11:57:11 +0800 Subject: [PATCH 3/5] fix test failure case. --- test/plugins/html/encoder/document_html_encoder_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/plugins/html/encoder/document_html_encoder_test.dart b/test/plugins/html/encoder/document_html_encoder_test.dart index 9450e9581..a17ad9adc 100644 --- a/test/plugins/html/encoder/document_html_encoder_test.dart +++ b/test/plugins/html/encoder/document_html_encoder_test.dart @@ -34,7 +34,7 @@ void main() async { } const example = - '''

AppFlowyEditor

👋 Welcome to AppFlowy Editor

AppFlowy Editor is a highly customizable rich-text editor

Here is an example your you can give a try

Span element

Span element two

Span element three

This is an anchor tag!

Features!

  • [x] Customizable
  • [x] Test-covered
  • [ ] more to come!
  • First item
  • Second item
  • List element
This is a quote!

Code block

Italic one

Italic two

Bold tag

You can also use AppFlowy Editor as a component to build your own app.

Awesome features

If you have questions or feedback, please submit an issue on Github or join the community along with 1000+ builders!

'''; + '''

AppFlowyEditor

👋 Welcome to AppFlowy Editor

AppFlowy Editor is a highly customizable rich-text editor

Here is an example your you can give a try

Span element

Span element two

Span element three

This is an anchor tag!

Features!

  • [x] Customizable
  • [x] Test-covered
  • [ ] more to come!
  • First item
  • Second item
  • List element
This is a quote!

Code block

Italic one

Italic two

Bold tag

You can also use AppFlowy Editor as a component to build your own app.

Awesome features

If you have questions or feedback, please submit an issue on Github or join the community along with 1000+ builders!



'''; const delta = { 'document': { @@ -307,7 +307,7 @@ const delta = { }, }; const nestedHTML = - '''

Welcome to the playground

In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting. The playground is a demo environment built with @lexical/react. Try typing in some text with different formats.

Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!

If you'd like to find out more about Lexical, you can:

  • Playground code can be found here.
  • Playground code can be found here.

Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance 🙂.

'''; + '''

Welcome to the playground

In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting. The playground is a demo environment built with @lexical/react. Try typing in some text with different formats.

Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!


If you'd like to find out more about Lexical, you can:

  • Playground code can be found here.
  • Playground code can be found here.

Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance 🙂.


'''; const nestedDelta = { 'document': { 'type': 'page', From f7563e73f4c6d079dacbcbd6940754b161c3d4bf Mon Sep 17 00:00:00 2001 From: Peng Zhou Date: Mon, 29 Jan 2024 13:38:55 +0800 Subject: [PATCH 4/5] feat: add html support --- .../encoder/parser/divider_node_parser.dart | 27 +++++++++++++++++++ lib/src/plugins/html/html_document.dart | 2 ++ .../encoder/document_html_encoder_test.dart | 5 +++- .../encoder/parser/text_node_parser_test.dart | 11 ++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 lib/src/plugins/html/encoder/parser/divider_node_parser.dart diff --git a/lib/src/plugins/html/encoder/parser/divider_node_parser.dart b/lib/src/plugins/html/encoder/parser/divider_node_parser.dart new file mode 100644 index 000000000..3f2bf1225 --- /dev/null +++ b/lib/src/plugins/html/encoder/parser/divider_node_parser.dart @@ -0,0 +1,27 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:html/dom.dart' as dom; + +class HTMLDividerNodeParser extends HTMLNodeParser { + const HTMLDividerNodeParser(); + + @override + String get id => DividerBlockKeys.type; + + @override + String transformNodeToHTMLString( + Node node, { + required List encodeParsers, + }) { + return toHTMLString( + transformNodeToDomNodes(node, encodeParsers: encodeParsers), + ); + } + + @override + List transformNodeToDomNodes( + Node node, { + required List encodeParsers, + }) { + return [dom.Element.tag(HTMLTags.divider)]; + } +} diff --git a/lib/src/plugins/html/html_document.dart b/lib/src/plugins/html/html_document.dart index c2fa3fd4a..e4d7f05c6 100644 --- a/lib/src/plugins/html/html_document.dart +++ b/lib/src/plugins/html/html_document.dart @@ -3,6 +3,7 @@ library delta_markdown; import 'dart:convert'; import 'package:appflowy_editor/src/core/document/document.dart'; +import 'package:appflowy_editor/src/plugins/html/encoder/parser/divider_node_parser.dart'; import 'package:appflowy_editor/src/plugins/html/html_document_decoder.dart'; import 'package:appflowy_editor/src/plugins/html/html_document_encoder.dart'; @@ -29,6 +30,7 @@ String documentToHTML( const HTMLHeadingNodeParser(), const HTMLImageNodeParser(), const HtmlTableNodeParser(), + const HTMLDividerNodeParser(), ], ).encode(document); } diff --git a/test/plugins/html/encoder/document_html_encoder_test.dart b/test/plugins/html/encoder/document_html_encoder_test.dart index a17ad9adc..5b17cd614 100644 --- a/test/plugins/html/encoder/document_html_encoder_test.dart +++ b/test/plugins/html/encoder/document_html_encoder_test.dart @@ -1,4 +1,5 @@ import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor/src/plugins/html/encoder/parser/divider_node_parser.dart'; import 'package:flutter_test/flutter_test.dart'; void main() async { @@ -11,6 +12,7 @@ void main() async { const HTMLHeadingNodeParser(), const HTMLImageNodeParser(), const HtmlTableNodeParser(), + const HTMLDividerNodeParser(), ]; group('document_html_encoder_test.dart', () { setUpAll(() { @@ -34,7 +36,7 @@ void main() async { } const example = - '''

AppFlowyEditor

👋 Welcome to AppFlowy Editor

AppFlowy Editor is a highly customizable rich-text editor

Here is an example your you can give a try

Span element

Span element two

Span element three

This is an anchor tag!

Features!

  • [x] Customizable
  • [x] Test-covered
  • [ ] more to come!
  • First item
  • Second item
  • List element
This is a quote!

Code block

Italic one

Italic two

Bold tag

You can also use AppFlowy Editor as a component to build your own app.

Awesome features

If you have questions or feedback, please submit an issue on Github or join the community along with 1000+ builders!



'''; + '''

AppFlowyEditor

👋 Welcome to AppFlowy Editor

AppFlowy Editor is a highly customizable rich-text editor

Here is an example your you can give a try

Span element

Span element two

Span element three

This is an anchor tag!

Features!

  • [x] Customizable
  • [x] Test-covered
  • [ ] more to come!
  • First item
  • Second item
  • List element
This is a quote!

Code block

Italic one

Italic two

Bold tag

You can also use AppFlowy Editor as a component to build your own app.


Awesome features

If you have questions or feedback, please submit an issue on Github or join the community along with 1000+ builders!



'''; const delta = { 'document': { @@ -275,6 +277,7 @@ const delta = { ], }, }, + {'type': 'divider'}, { 'type': 'heading', 'data': { diff --git a/test/plugins/html/encoder/parser/text_node_parser_test.dart b/test/plugins/html/encoder/parser/text_node_parser_test.dart index d53dab8c4..24b7522a5 100644 --- a/test/plugins/html/encoder/parser/text_node_parser_test.dart +++ b/test/plugins/html/encoder/parser/text_node_parser_test.dart @@ -1,4 +1,5 @@ import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor/src/plugins/html/encoder/parser/divider_node_parser.dart'; import 'package:flutter_test/flutter_test.dart'; void main() async { @@ -11,6 +12,7 @@ void main() async { const HTMLHeadingNodeParser(), const HTMLImageNodeParser(), const HtmlTableNodeParser(), + const HTMLDividerNodeParser(), ]; group('text_node_parser.dart', () { const text = 'Welcome to AppFlowy'; @@ -108,6 +110,15 @@ void main() async { ); }); + test('divider', () { + final node = dividerNode(); + expect( + const HTMLDividerNodeParser() + .transformNodeToHTMLString(node, encodeParsers: parser), + '
', + ); + }); + test('fallback', () { final node = paragraphNode( attributes: { From 7f7335a413fc3cec09a169379ddc214256e5f3d6 Mon Sep 17 00:00:00 2001 From: Peng Zhou Date: Wed, 31 Jan 2024 15:51:39 +0800 Subject: [PATCH 5/5] fix: todo list(checkbox) not work as expected --- .../html/encoder/parser/todo_list_node_parser.dart | 8 +++++--- .../html/encoder/parser/text_node_parser_test.dart | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/src/plugins/html/encoder/parser/todo_list_node_parser.dart b/lib/src/plugins/html/encoder/parser/todo_list_node_parser.dart index bae2dd9d9..5d31f6704 100644 --- a/lib/src/plugins/html/encoder/parser/todo_list_node_parser.dart +++ b/lib/src/plugins/html/encoder/parser/todo_list_node_parser.dart @@ -26,10 +26,12 @@ class HTMLTodoListNodeParser extends HTMLNodeParser { }) { final delta = node.delta ?? Delta(); final domNodes = deltaHTMLEncoder.convert(delta); + final elementNode = dom.Element.html(''); - elementNode.attributes['checked'] = - node.attributes[TodoListBlockKeys.checked].toString(); - domNodes.add(elementNode); + if (node.attributes[TodoListBlockKeys.checked] as bool? ?? false) { + elementNode.attributes['checked'] = ''; + } + domNodes.insert(0, elementNode); domNodes.addAll( processChildrenNodes(node.children, encodeParsers: encodeParsers), ); diff --git a/test/plugins/html/encoder/parser/text_node_parser_test.dart b/test/plugins/html/encoder/parser/text_node_parser_test.dart index 24b7522a5..1a4b494ca 100644 --- a/test/plugins/html/encoder/parser/text_node_parser_test.dart +++ b/test/plugins/html/encoder/parser/text_node_parser_test.dart @@ -88,12 +88,12 @@ void main() async { expect( const HTMLTodoListNodeParser() .transformNodeToHTMLString(checkedNode, encodeParsers: parser), - '
Welcome to AppFlowy
', + '
Welcome to AppFlowy
', ); expect( const HTMLTodoListNodeParser() .transformNodeToHTMLString(uncheckedNode, encodeParsers: parser), - '
Welcome to AppFlowy
', + '
Welcome to AppFlowy
', ); });