Skip to content

Commit 5d3137c

Browse files
committed
Add custom node rendering
- It is now possible to render any dom.Node with a custom renderer if necessary. - The fallback is the default rendering like before.
1 parent bd19c57 commit 5d3137c

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/flutter_html.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Html extends StatelessWidget {
1212
this.defaultTextStyle = const TextStyle(color: Colors.black),
1313
this.onLinkTap,
1414
this.renderNewlines = false,
15+
this.customRender,
1516
}) : super(key: key);
1617

1718
final String data;
@@ -21,6 +22,10 @@ class Html extends StatelessWidget {
2122
final Function onLinkTap;
2223
final bool renderNewlines;
2324

25+
/// Either return a custom widget for specific node types or return null to
26+
/// fallback to the default rendering.
27+
final CustomRender customRender;
28+
2429
@override
2530
Widget build(BuildContext context) {
2631
final double width = MediaQuery.of(context).size.width;
@@ -37,6 +42,7 @@ class Html extends StatelessWidget {
3742
width: width,
3843
onLinkTap: onLinkTap,
3944
renderNewlines: renderNewlines,
45+
customRender: customRender,
4046
).parse(data),
4147
),
4248
),

lib/html_parser.dart

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import 'package:flutter/material.dart';
22
import 'package:html/parser.dart' as parser;
33
import 'package:html/dom.dart' as dom;
44

5+
typedef CustomRender = Widget Function(dom.Node node, List<Widget> children);
6+
57
class HtmlParser {
68
HtmlParser({
79
@required this.width,
810
this.onLinkTap,
911
this.renderNewlines = false,
12+
this.customRender,
1013
});
1114

1215
final double width;
1316
final Function onLinkTap;
1417
final bool renderNewlines;
18+
final CustomRender customRender;
1519

1620
static const _supportedElements = [
1721
"a",
@@ -93,21 +97,39 @@ class HtmlParser {
9397
List<Widget> widgetList = new List<Widget>();
9498

9599
if (renderNewlines) {
96-
print("Before: $data");
100+
assert(() {
101+
print("Before: $data");
102+
return true;
103+
}());
97104
data = data.replaceAll("\n", "<br />");
98-
print("After: $data");
105+
assert(() {
106+
print("After: $data");
107+
}());
99108
}
100109
dom.Document document = parser.parse(data);
101110
widgetList.add(_parseNode(document.body));
102111
return widgetList;
103112
}
104113

105114
Widget _parseNode(dom.Node node) {
115+
if (customRender != null) {
116+
final Widget customWidget =
117+
customRender(node, _parseNodeList(node.nodes));
118+
if (customWidget != null) {
119+
return customWidget;
120+
}
121+
}
122+
106123
if (node is dom.Element) {
107-
print("Found ${node.localName}");
124+
assert(() {
125+
print("Found ${node.localName}");
126+
return true;
127+
}());
128+
108129
if (!_supportedElements.contains(node.localName)) {
109130
return Container();
110131
}
132+
111133
switch (node.localName) {
112134
case "a":
113135
return GestureDetector(

0 commit comments

Comments
 (0)