Skip to content

Commit

Permalink
chore: refactor the html_node_parser.dart
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasXu0 committed Jul 19, 2023
1 parent 83488dc commit 80cdeab
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 116 deletions.
4 changes: 3 additions & 1 deletion lib/src/plugins/html/encoder/delta_html_encoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import 'dart:convert';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

final deltaHTMLEncoder = DeltaHTMLEncoder();

/// A [Delta] encoder that encodes a [Delta] to html.
///
/// supported nested styles.
class DeltaHtmlEncoder extends Converter<Delta, List<dom.Node>> {
class DeltaHTMLEncoder extends Converter<Delta, List<dom.Node>> {
@override
List<dom.Node> convert(Delta input) {
return input
Expand Down
43 changes: 23 additions & 20 deletions lib/src/plugins/html/encoder/parser/bulleted_list_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlBulletedListNodeParser extends HtmlNodeParser {
class HtmlBulletedListNodeParser extends HTMLNodeParser {
const HtmlBulletedListNodeParser();

@override
String get id => BulletedListBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
assert(node.type == BulletedListBlockKeys.type);

return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final List<dom.Node> result = [];
final delta = node.delta;
if (delta == null) {
throw Exception('Delta is null');
}
final convertedNodes = DeltaHtmlEncoder().convert(delta);
const tagName = HTMLTags.list;
if (node.children.isNotEmpty) {
convertedNodes.addAll(
childrenNodes(node.children.toList(), encodeParsers: encodeParsers),
);
}
final element = insertText(tagName, childNodes: convertedNodes);

final stashListContainer = dom.Element.tag(
HTMLTags.unorderedList,
final domNodes = deltaHTMLEncoder.convert(delta);
domNodes.addAll(
childrenNodes(
node.children.toList(),
encodeParsers: encodeParsers,
),
);
stashListContainer.append(element);
result.add(stashListContainer);
return result;
final element = insertText(HTMLTags.list, childNodes: domNodes);

return [
dom.Element.tag(
HTMLTags.unorderedList,
)..append(element)
];
}
}
17 changes: 11 additions & 6 deletions lib/src/plugins/html/encoder/parser/heading_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlHeadingNodeParser extends HtmlNodeParser {
class HtmlHeadingNodeParser extends HTMLNodeParser {
const HtmlHeadingNodeParser();

@override
String get id => HeadingBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final delta = node.delta;
final attribute = node.attributes;
final List<dom.Node> result = [];
if (delta == null) {
assert(false, 'Delta is null');
}
final convertedNodes = DeltaHtmlEncoder().convert(delta!);
final convertedNodes = DeltaHTMLEncoder().convert(delta!);
if (node.children.isNotEmpty) {
convertedNodes.addAll(
childrenNodes(node.children.toList(), encodeParsers: encodeParsers),
Expand Down
78 changes: 42 additions & 36 deletions lib/src/plugins/html/encoder/parser/html_node_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,56 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:collection/collection.dart';
import 'package:html/dom.dart' as dom;

abstract class HtmlNodeParser {
const HtmlNodeParser();
abstract class HTMLNodeParser {
const HTMLNodeParser();

/// The id of the node parser.
///
/// Basically, it's the type of the node.
String get id;
String transform(Node node, {required List<HtmlNodeParser> encodeParsers});
List<dom.Node> htmlNodes(

/// Transform the [node] to html string.
String transformNodeToHTMLString(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
});

/// Convert the [node] to html nodes.
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HTMLNodeParser> encodeParsers,
});
}

dom.Element insertText(
String tagName, {
required List<dom.Node> childNodes,
}) {
final p = dom.Element.tag(tagName);
for (final node in childNodes) {
p.append(node);
dom.Element insertText(
String tagName, {
required List<dom.Node> childNodes,
}) {
final p = dom.Element.tag(tagName);
for (final node in childNodes) {
p.append(node);
}
return p;
}
return p;
}

//iterate over its childrens if exist
List<dom.Node> childrenNodes(
List<Node> nodes, {
required List<HtmlNodeParser> encodeParsers,
}) {
final result = <dom.Node>[];
for (final node in nodes) {
HtmlNodeParser? parser = encodeParsers.firstWhereOrNull(
(element) => element.id == node.type,
);
if (parser != null) {
result.addAll(parser.htmlNodes(node, encodeParsers: encodeParsers));
//iterate over its children if exist
List<dom.Node> childrenNodes(
List<Node> nodes, {
required List<HTMLNodeParser> encodeParsers,
}) {
final result = <dom.Node>[];
for (final node in nodes) {
final parser = encodeParsers.firstWhereOrNull(
(element) => element.id == node.type,
);
if (parser != null) {
result.addAll(
parser.transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}
}
return result;
}
return result;
}

String toHTMLString(List<dom.Node> nodes) {
final elements = nodes;
final copyString = elements.fold<String>(
'',
(previousValue, element) => previousValue + stringify(element),
);
return copyString.replaceAll("\n", "");
String toHTMLString(List<dom.Node> nodes) =>
nodes.map((e) => stringify(e)).join().replaceAll('\n', '');
}
15 changes: 10 additions & 5 deletions lib/src/plugins/html/encoder/parser/image_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlImageNodeParser extends HtmlNodeParser {
class HtmlImageNodeParser extends HTMLNodeParser {
const HtmlImageNodeParser();

@override
String get id => ImageBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final List<dom.Node> result = [];

Expand Down
17 changes: 11 additions & 6 deletions lib/src/plugins/html/encoder/parser/numbered_list_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlNumberedListNodeParser extends HtmlNodeParser {
class HtmlNumberedListNodeParser extends HTMLNodeParser {
const HtmlNumberedListNodeParser();

@override
String get id => NumberedListBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
assert(node.type == NumberedListBlockKeys.type);

return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final List<dom.Node> result = [];
final delta = node.delta;
if (delta == null) {
throw Exception('Delta is null');
}
final convertedNodes = DeltaHtmlEncoder().convert(delta);
final convertedNodes = DeltaHTMLEncoder().convert(delta);
const tagName = HTMLTags.list;
if (node.children.isNotEmpty) {
convertedNodes.addAll(
Expand Down
17 changes: 11 additions & 6 deletions lib/src/plugins/html/encoder/parser/quote_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlQuoteNodeParser extends HtmlNodeParser {
class HtmlQuoteNodeParser extends HTMLNodeParser {
const HtmlQuoteNodeParser();

@override
String get id => QuoteBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
assert(node.type == QuoteBlockKeys.type);

return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final List<dom.Node> result = [];
final delta = node.delta;
if (delta == null) {
throw Exception('Delta is null');
}
final convertedNodes = DeltaHtmlEncoder().convert(delta);
final convertedNodes = DeltaHTMLEncoder().convert(delta);
if (node.children.isNotEmpty) {
convertedNodes.addAll(
childrenNodes(node.children.toList(), encodeParsers: encodeParsers),
Expand Down
17 changes: 11 additions & 6 deletions lib/src/plugins/html/encoder/parser/text_node_parser.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:html/dom.dart' as dom;

class HtmlTextNodeParser extends HtmlNodeParser {
class HtmlTextNodeParser extends HTMLNodeParser {
const HtmlTextNodeParser();

@override
String get id => ParagraphBlockKeys.type;

@override
String transform(Node node, {required List<HtmlNodeParser> encodeParsers}) {
return toHTMLString(htmlNodes(node, encodeParsers: encodeParsers));
String transformNodeToHTMLString(
Node node, {
required List<HTMLNodeParser> encodeParsers,
}) {
return toHTMLString(
transformNodeToDomNodes(node, encodeParsers: encodeParsers),
);
}

@override
List<dom.Node> htmlNodes(
List<dom.Node> transformNodeToDomNodes(
Node node, {
required List<HtmlNodeParser> encodeParsers,
required List<HTMLNodeParser> encodeParsers,
}) {
final delta = node.delta;
final List<dom.Node> result = [];
if (delta == null) {
assert(false, 'Delta is null');
}
final convertedNodes = DeltaHtmlEncoder().convert(delta!);
final convertedNodes = DeltaHTMLEncoder().convert(delta!);
if (node.children.isNotEmpty) {
convertedNodes.addAll(
childrenNodes(node.children.toList(), encodeParsers: encodeParsers),
Expand Down
Loading

0 comments on commit 80cdeab

Please sign in to comment.