Skip to content

Commit 067d97a

Browse files
authored
Fix 100% width TD in recursive TABLEs (#952)
1 parent b341979 commit 067d97a

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed
2.35 KB
Loading

packages/core/lib/src/widgets/html_table.dart

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> {
206206
properties.add(IntProperty('columnStart', columnStart));
207207
properties.add(IntProperty('rowSpan', rowSpan, defaultValue: 1));
208208
properties.add(IntProperty('rowStart', rowStart));
209+
properties.add(DiagnosticsProperty('width', width, defaultValue: null));
209210
}
210211

211212
@override
@@ -542,7 +543,7 @@ class _TableRenderLayouter {
542543
) {
543544
final effectiveMinValues = List.filled(values.length, .0);
544545
for (var i = 0; i < values.length; i++) {
545-
if (calculatedMinValues[i] > 0 && calculatedMinValues[i] >= values[i]) {
546+
if (calculatedMinValues[i] > .0 && calculatedMinValues[i] >= values[i]) {
546547
// min value is smaller than in-calculation width
547548
// let's keep the current value as long as possible
548549
// we want the column to grow to its dry size naturally
@@ -551,20 +552,29 @@ class _TableRenderLayouter {
551552
}
552553

553554
final remaining = max(.0, available - effectiveMinValues.sum);
555+
var valuesCount = 0;
554556
var valuesSum = .0;
555557
for (var i = 0; i < values.length; i++) {
556-
if (effectiveMinValues[i] == 0) {
558+
if (effectiveMinValues[i] == .0) {
559+
valuesCount++;
557560
valuesSum += values[i];
558561
}
559562
}
560563

561564
final result = effectiveMinValues.toList(growable: false);
562-
if (valuesSum > .0) {
565+
if (valuesCount > 0) {
563566
for (var i = 0; i < values.length; i++) {
564-
if (result[i] == 0) {
567+
if (result[i] != .0) {
568+
continue;
569+
}
570+
571+
if (valuesSum.isFinite) {
565572
// calculate widths using weighted distribution
566573
// e.g. if a column has huge dry width, it will have bigger width
567574
result[i] = values[i] / valuesSum * remaining;
575+
} else {
576+
// split the remaining width equally if SUM(values) is not usable
577+
result[i] = remaining / valuesCount;
568578
}
569579
}
570580
}

packages/core/test/tag_table_test.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,57 @@ Future<void> main() async {
380380
});
381381
});
382382

383+
group('width', () {
384+
testWidgets('renders without width', (WidgetTester tester) async {
385+
const html = '<table><tr><td>Foo</td></tr></table>';
386+
final e = await explain(tester, html, useExplainer: false);
387+
expect(e, contains('└HtmlTableCell(columnStart: 0, rowStart: 0)'));
388+
});
389+
390+
testWidgets('renders width: 50px', (WidgetTester tester) async {
391+
const html = '<table><tr><td style="width: 50px">Foo</td></tr></table>';
392+
final explained = await explain(tester, html, useExplainer: false);
393+
expect(
394+
explained,
395+
isNot(contains('└HtmlTableCell(columnStart: 0, rowStart: 0)')),
396+
);
397+
expect(
398+
explained,
399+
contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 50.0)'),
400+
);
401+
});
402+
403+
testWidgets('renders width: 100%', (WidgetTester tester) async {
404+
const html = '<table><tr><td style="width: 100%">Foo</td></tr></table>';
405+
final explained = await explain(tester, html, useExplainer: false);
406+
expect(
407+
explained,
408+
isNot(contains('└HtmlTableCell(columnStart: 0, rowStart: 0)')),
409+
);
410+
expect(
411+
explained,
412+
contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 100.0%)'),
413+
);
414+
});
415+
416+
testWidgets('renders width: 100% within TABLE', (tester) async {
417+
const html = '<table><tr><td>'
418+
'<table><tr><td style="width: 100%">'
419+
'Foo'
420+
'</td></tr></table>'
421+
'</td></tr></table>';
422+
final explained = await explain(tester, html, useExplainer: false);
423+
expect(
424+
explained,
425+
contains('└HtmlTableCell(columnStart: 0, rowStart: 0)'),
426+
);
427+
expect(
428+
explained,
429+
contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 100.0%)'),
430+
);
431+
});
432+
});
433+
383434
group('error handling', () {
384435
testWidgets('missing header', (WidgetTester tester) async {
385436
const html = '<table><tbody>'
@@ -857,6 +908,18 @@ Future<void> main() async {
857908
<td style="background: red; width: 30%">Foo</td>
858909
<td style="background: green; width: 70%">Bar</td>
859910
</tr>
911+
</table>''',
912+
'width_in_percent_100_nested': '''
913+
<table border="1">
914+
<tr>
915+
<td>
916+
<table border="1">
917+
<tr>
918+
<td style="width: 100%">Foo</td>
919+
</tr>
920+
</table>
921+
</td>
922+
</tr>
860923
</table>''',
861924
'width_in_px': '''
862925
<table border="1">

0 commit comments

Comments
 (0)