Skip to content

Commit fd0a32c

Browse files
committed
Elevate td and tr elements to be parsed as cell type but cleaner and more robust code
1 parent d876489 commit fd0a32c

File tree

5 files changed

+65
-30
lines changed

5 files changed

+65
-30
lines changed

example/lib/main.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ const htmlData = """
6161
</thead>
6262
<tbody>
6363
<tr>
64-
<td rowspan='2'>Rowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\n</td><td>Data</td><td>Data</td>
64+
<td rowspan='2'>Rowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan\nRowspan</td><td>Data</td><td>Data</td>
6565
</tr>
6666
<tr>
67-
<td colspan="2">Colpsan</td>
67+
<td colspan="2">Colpsan\nColpsan\nColpsan</td>
6868
</tr>
6969
</tbody>
7070
<tfoot>

lib/html_parser.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ class HtmlParser extends StatelessWidget {
134134
return parseReplacedElement(node);
135135
} else if (LAYOUT_ELEMENTS.contains(node.localName)) {
136136
return parseLayoutElement(node, children);
137-
} else if (TABLE_STYLE_ELEMENTS.contains(node.localName)) {
137+
} else if (TABLE_CELL_ELEMENTS.contains(node.localName)) {
138+
return parseTableCellElement(node, children);
139+
} else if (TABLE_DEFINITION_ELEMENTS.contains(node.localName)) {
138140
return parseTableDefinitionElement(node, children);
139141
} else if (customRenderTags.contains(node.localName)) {
140142
return parseStyledElement(node, children);

lib/src/html_elements.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ const STYLED_ELEMENTS = [
3030
"strong",
3131
"sub",
3232
"sup",
33-
"td",
34-
"th",
3533
"time",
3634
"tt",
3735
"u",
@@ -97,7 +95,9 @@ const LAYOUT_ELEMENTS = [
9795
"thead",
9896
];
9997

100-
const TABLE_STYLE_ELEMENTS = ["col", "colgroup"];
98+
const TABLE_CELL_ELEMENTS = ["th", "td"];
99+
100+
const TABLE_DEFINITION_ELEMENTS = ["col", "colgroup"];
101101

102102
/**
103103
Here is a list of elements with planned support:

lib/src/layout_element.dart

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,12 @@ class TableLayoutElement extends LayoutElement {
6464
final rowSizes =
6565
List.generate(rows.length, (_) => IntrinsicContentTrackSize());
6666

67-
// Calculate column bounds to handle rowspan skipping
68-
int columnMax = rows.map((row) {
69-
return row.children
70-
.where((tag) => tag.name == "th" || tag.name == "td")
71-
.fold(0, (int value, child) {
72-
final colspanText = child.attributes["colspan"];
73-
final colspan =
74-
colspanText == null ? 1 : int.tryParse(colspanText) ?? 1;
75-
return value + colspan;
76-
});
77-
}).fold(0, max);
67+
// Calculate column bounds
68+
int columnMax = rows
69+
.map((row) => row.children
70+
.whereType<TableCellElement>()
71+
.fold(0, (int value, child) => value + child.colspan))
72+
.fold(0, max);
7873

7974
final cells = <GridPlacement>[];
8075
final columnRowOffset = List.generate(columnMax + 1, (_) => 0);
@@ -86,13 +81,7 @@ class TableLayoutElement extends LayoutElement {
8681
columnRowOffset[columni] = columnRowOffset[columni] - 1;
8782
columni++;
8883
}
89-
if (child.name == "th" || child.name == "td") {
90-
final colspanText = child.attributes["colspan"];
91-
final rowspanText = child.attributes["rowspan"];
92-
final colspan =
93-
colspanText == null ? 1 : int.tryParse(colspanText) ?? 1;
94-
final rowspan =
95-
rowspanText == null ? 1 : int.tryParse(rowspanText) ?? 1;
84+
if (child is TableCellElement) {
9685
cells.add(GridPlacement(
9786
child: Container(
9887
width: double.infinity,
@@ -107,12 +96,12 @@ class TableLayoutElement extends LayoutElement {
10796
),
10897
),
10998
columnStart: columni,
110-
columnSpan: colspan,
99+
columnSpan: child.colspan,
111100
rowStart: rowi,
112-
rowSpan: rowspan,
101+
rowSpan: child.rowspan,
113102
));
114-
columnRowOffset[columni] = rowspan - 1;
115-
columni += colspan;
103+
columnRowOffset[columni] = child.rowspan - 1;
104+
columni += child.colspan;
116105
}
117106
}
118107
rowi++;
@@ -163,6 +152,52 @@ class TableRowLayoutElement extends LayoutElement {
163152
}
164153
}
165154

155+
class TableCellElement extends StyledElement {
156+
int colspan = 1;
157+
int rowspan = 1;
158+
159+
TableCellElement({
160+
String name,
161+
String elementId,
162+
List<String> elementClasses,
163+
@required List<StyledElement> children,
164+
Style style,
165+
dom.Element node,
166+
}) : super(
167+
name: name,
168+
elementId: elementId,
169+
elementClasses: elementClasses,
170+
children: children,
171+
style: style,
172+
node: node) {
173+
colspan = _parseSpan(this, "colspan");
174+
rowspan = _parseSpan(this, "rowspan");
175+
}
176+
177+
static int _parseSpan(StyledElement element, String attributeName) {
178+
final spanValue = element.attributes[attributeName];
179+
return spanValue == null ? 1 : int.tryParse(spanValue) ?? 1;
180+
}
181+
}
182+
183+
TableCellElement parseTableCellElement(dom.Element element,
184+
List<StyledElement> children,
185+
) {
186+
final cell = TableCellElement(
187+
name: element.localName,
188+
elementId: element.id,
189+
elementClasses: element.classes.toList(),
190+
children: children,
191+
node: element,
192+
);
193+
if (element.localName == "th") {
194+
cell.style = Style(
195+
fontWeight: FontWeight.bold,
196+
);
197+
}
198+
return cell;
199+
}
200+
166201
class TableStyleElement extends StyledElement {
167202
TableStyleElement({
168203
String name,

lib/src/styled_element.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,6 @@ StyledElement parseStyledElement(
349349
verticalAlign: VerticalAlign.SUPER,
350350
);
351351
break;
352-
case "th":
353-
continue bold;
354352
case "tt":
355353
continue monospace;
356354
underline:

0 commit comments

Comments
 (0)