Skip to content

Commit c05a441

Browse files
committed
Update new parser with more tag support
1 parent a7dc12d commit c05a441

File tree

7 files changed

+235
-46
lines changed

7 files changed

+235
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## [0.10.0] - UNRELEASED
1+
## [1.0.0] - UNRELEASED
22
* Adds support for a new parser, which resolves several major issues.
33

44
## [0.9.7] - May 13, 2019:

lib/block_element.dart

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1+
import 'package:flutter/widgets.dart';
12
import 'package:flutter_html/html_elements.dart';
23
import 'package:html/dom.dart' as dom;
34

45
/// A [Block] contains information about a [BlockElement] (width, height, padding, margins)
56
class Block {
6-
final double marginLeft;
7-
final double marginTop;
8-
final double marginRight;
9-
final double marginBottom;
7+
final EdgeInsets margin;
108

119
final double width;
1210
final double height;
1311

14-
Block({
15-
this.marginLeft,
16-
this.marginTop,
17-
this.marginRight,
18-
this.marginBottom,
12+
const Block({
13+
this.margin,
1914
this.width,
2015
this.height,
2116
});
17+
18+
@override
19+
String toString() {
20+
return "(${margin != null? "Margin: $margin": ""} ${width != null? "Width: $width": ""}, ${height != null? "Height: $height": ""})";
21+
}
2222
}
2323

2424
/// A [BlockElement] is a [StyledElement] that wraps before and after the its [children].
@@ -33,18 +33,68 @@ class BlockElement extends StyledElement {
3333
Style style,
3434
this.block,
3535
}) : super(name: name, children: children, style: style);
36+
37+
@override
38+
String toString() {
39+
String selfData = "$name [Children: ${children?.length ?? 0}] <Block: $block Style: $style>";
40+
children?.forEach((child) {
41+
selfData += ("\n${child.toString()}").replaceAll(RegExp("^", multiLine: true), "-");
42+
});
43+
return selfData;
44+
}
45+
}
46+
47+
BlockElement parseBlockElement(dom.Element node, List<StyledElement> children) {
48+
BlockElement blockElement = BlockElement(
49+
name: node.localName,
50+
children: children,
51+
block: parseBlockElementBlock(node),
52+
);
53+
54+
// Add styles to new block element.
55+
switch(node.localName) {
56+
case "h1":
57+
blockElement.style = Style(textStyle: TextStyle(fontSize: 26.0, fontWeight: FontWeight.bold));
58+
break;
59+
case "h2":
60+
blockElement.style = Style(textStyle: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold));
61+
break;
62+
case "h3":
63+
blockElement.style = Style(textStyle: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold));
64+
break;
65+
case "h4":
66+
blockElement.style = Style(textStyle: TextStyle(fontSize: 20.0));
67+
break;
68+
case "h5":
69+
blockElement.style = Style(textStyle: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold));
70+
break;
71+
case "h6":
72+
blockElement.style = Style(textStyle: TextStyle(fontSize: 18.0));
73+
break;
74+
case "ol":
75+
blockElement.style = Style(indentChildren: true, listCharacter: (i) => "$i.");
76+
break;
77+
case "ul":
78+
blockElement.style = Style(indentChildren: true, listCharacter: (i) => ".");
79+
break;
80+
}
81+
82+
return blockElement;
3683
}
3784

3885
Block parseBlockElementBlock(dom.Element element) {
3986
switch (element.localName) {
4087
case "div":
41-
return Block(
42-
marginTop: 14,
43-
marginBottom: 14,
88+
return const Block(
89+
margin: const EdgeInsets.symmetric(vertical: 14.0),
4490
);
4591
break;
92+
case "p":
93+
return const Block(
94+
margin: const EdgeInsets.symmetric(vertical: 14.0),
95+
);
4696
default:
47-
return Block();
97+
return const Block();
4898
break;
4999
}
50100
}

lib/content_element.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:html/dom.dart' as dom;
88
abstract class ContentElement extends StyledElement {
99
ContentElement({
1010
String name,
11-
dynamic style,
11+
Style style,
1212
}) : super(name: name, children: null, style: style);
1313
}
1414

@@ -17,7 +17,7 @@ class TextContentElement extends ContentElement {
1717
final String text;
1818

1919
TextContentElement({
20-
dynamic style,
20+
Style style,
2121
this.text,
2222
}) : super(name: "text", style: style);
2323
}

lib/flutter_html.dart

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Html extends StatelessWidget {
1717
this.customTextStyle,
1818
this.blockSpacing = 14.0,
1919
this.useRichText = false,
20+
this.useFancyNewParser = false,
2021
this.onImageError,
2122
this.linkStyle = const TextStyle(
2223
decoration: TextDecoration.underline,
@@ -32,6 +33,7 @@ class Html extends StatelessWidget {
3233
final bool renderNewlines;
3334
final double blockSpacing;
3435
final bool useRichText;
36+
final bool useFancyNewParser;
3537
final ImageErrorListener onImageError;
3638
final TextStyle linkStyle;
3739

@@ -62,16 +64,20 @@ class Html extends StatelessWidget {
6264
onImageError: onImageError,
6365
linkStyle: linkStyle,
6466
)
65-
: HtmlOldParser(
66-
width: width,
67-
onLinkTap: onLinkTap,
68-
renderNewlines: renderNewlines,
69-
customRender: customRender,
70-
html: data,
71-
blockSpacing: blockSpacing,
72-
onImageError: onImageError,
73-
linkStyle: linkStyle,
74-
),
67+
: (useFancyNewParser)
68+
? HtmlParser(
69+
data,
70+
)
71+
: HtmlOldParser(
72+
width: width,
73+
onLinkTap: onLinkTap,
74+
renderNewlines: renderNewlines,
75+
customRender: customRender,
76+
html: data,
77+
blockSpacing: blockSpacing,
78+
onImageError: onImageError,
79+
linkStyle: linkStyle,
80+
),
7581
),
7682
);
7783
}

lib/html_elements.dart

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ export 'block_element.dart';
44
export 'content_element.dart';
55

66
const STYLED_ELEMENTS = [
7+
"abbr",
8+
"acronym",
9+
"address",
710
"b",
811
"i",
12+
"span",
13+
"u",
914
];
1015

1116
const INTERACTABLE_ELEMENTS = [
@@ -15,7 +20,19 @@ const INTERACTABLE_ELEMENTS = [
1520
const BLOCK_ELEMENTS = [
1621
"body",
1722
"div",
23+
"footer",
24+
"h1",
25+
"h2",
26+
"h3",
27+
"h4",
28+
"h5",
29+
"h6",
30+
"header",
1831
"html",
32+
"li",
33+
"ol",
34+
"p",
35+
"ul",
1936
];
2037

2138
const CONTENT_ELEMENTS = [
@@ -29,3 +46,91 @@ enum ElementType {
2946
BLOCK,
3047
INTERACTABLE,
3148
}
49+
50+
/**
51+
Here is a list of elements which are not currently supported (but have planned support):
52+
a - i [x]
53+
abbr - s [x]
54+
acronym - s [x]
55+
address - s [ ]
56+
audio - c [ ]
57+
article - b [ ]
58+
aside - b [ ]
59+
b - s [x]
60+
bdi - s [ ]
61+
bdo - s [ ]
62+
big - s [ ]
63+
blockquote- b [ ]
64+
body - b [x]
65+
br - b [ ]
66+
caption - b [ ]
67+
center - b [ ]
68+
cite - s [ ]
69+
code - s [ ]
70+
data - s [ ]
71+
dd - c [ ]
72+
del - s [ ]
73+
details - b [ ]
74+
dfn - s [ ]
75+
div - b [x]
76+
dl - [ ]
77+
dt - [ ]
78+
em - [ ]
79+
figcaption- [ ]
80+
figure - [ ]
81+
font - [ ]
82+
footer - b [x]
83+
h1 - b [x]
84+
h2 - b [x]
85+
h3 - b [x]
86+
h4 - b [x]
87+
h5 - b [x]
88+
h6 - b [x]
89+
header - b [x]
90+
hr - c?[ ]
91+
html - b [x]
92+
i - s [x]
93+
img - c [x]
94+
ins - s [ ]
95+
kbd - [ ]
96+
li - b [x]
97+
main - [ ]
98+
mark - [ ]
99+
nav - [ ]
100+
noscript - b [ ]
101+
ol - b [x]
102+
p - b [x]
103+
pre - s [ ]
104+
q - [ ]
105+
rp - [ ]
106+
rt - [ ]
107+
ruby - [ ]
108+
s - [ ]
109+
samp - [ ]
110+
section - [ ]
111+
small - s [ ]
112+
source - [ ]
113+
span - s [x]
114+
strike - s [ ]
115+
strong - s [ ]
116+
sub - s [ ]
117+
summary - b [ ]
118+
sup - s [ ]
119+
svg - c [ ]
120+
table - b [ ]
121+
tbody - b [ ]
122+
td - [ ]
123+
template - [ ]
124+
tfoot - b [ ]
125+
th - [ ]
126+
thead - b [ ]
127+
time - [ ]
128+
tr - b [ ]
129+
track - [ ]
130+
tt - [ ]
131+
u - s [x]
132+
ul - b [x]
133+
var - [ ]
134+
video - c [ ]
135+
wbr - [ ]
136+
*/

lib/html_parser.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,11 +1817,7 @@ class HtmlParser extends StatelessWidget {
18171817
} else if (INTERACTABLE_ELEMENTS.contains(node.localName)) {
18181818
return parseInteractableElement(node, children);
18191819
} else if (BLOCK_ELEMENTS.contains(node.localName)) {
1820-
return BlockElement(
1821-
name: node.localName,
1822-
children: children,
1823-
block: parseBlockElementBlock(node),
1824-
);
1820+
return parseBlockElement(node, children);
18251821
} else if (CONTENT_ELEMENTS.contains(node.localName)) {
18261822
return parseContentElement(node);
18271823
} else {
@@ -1835,15 +1831,20 @@ class HtmlParser extends StatelessWidget {
18351831
}
18361832

18371833
/// [cleanTree] optimizes the [StyledElement] tree so all [BlockElement]s are
1838-
/// on the first level, redundant levels are collapsed, and empty elements are
1839-
/// removed.
1834+
/// on the first level, redundant levels are collapsed, empty elements are
1835+
/// removed, and lists are converted to StyledElements.
18401836
static StyledElement cleanTree(StyledElement tree) {
18411837
return tree; //For now, just pass data through. TODO optimize tree
18421838
}
18431839

18441840
/// [parseTree] converts a tree of [StyledElement]s to a Flutter [Widget] tree.
18451841
static Widget parseTree(BuildContext context, StyledElement tree) {
1846-
//TODO
1842+
//TODO convert StyledElement tree to a Widget tree.
1843+
return Text(
1844+
tree.toString(),
1845+
softWrap: false,
1846+
style: TextStyle(fontFamily: 'Monospace'),
1847+
);
18471848
}
18481849
}
18491850

0 commit comments

Comments
 (0)