diff --git a/demo_app/test/goldens/inline/margin/auto.png b/demo_app/test/goldens/inline/margin/auto.png index 058463d96..04116a7e0 100644 Binary files a/demo_app/test/goldens/inline/margin/auto.png and b/demo_app/test/goldens/inline/margin/auto.png differ diff --git a/demo_app/test/table/aspect_ratio_img.png b/demo_app/test/table/aspect_ratio_img.png index fb72e7f73..524620f6b 100644 Binary files a/demo_app/test/table/aspect_ratio_img.png and b/demo_app/test/table/aspect_ratio_img.png differ diff --git a/demo_app/test/table/height_1px.png b/demo_app/test/table/height_1px.png deleted file mode 100644 index 51276c7bf..000000000 Binary files a/demo_app/test/table/height_1px.png and /dev/null differ diff --git a/demo_app/test/table/row_color.png b/demo_app/test/table/row_color.png index e8bd41620..8472cfda3 100644 Binary files a/demo_app/test/table/row_color.png and b/demo_app/test/table/row_color.png differ diff --git a/demo_app/test/table/sizing_height_1px.png b/demo_app/test/table/sizing_height_1px.png new file mode 100644 index 000000000..2a6d50e65 Binary files /dev/null and b/demo_app/test/table/sizing_height_1px.png differ diff --git a/demo_app/test/table/sizing_width_100_percent.png b/demo_app/test/table/sizing_width_100_percent.png new file mode 100644 index 000000000..f396b4d9d Binary files /dev/null and b/demo_app/test/table/sizing_width_100_percent.png differ diff --git a/demo_app/test/table/text_align_center.png b/demo_app/test/table/text_align_center.png new file mode 100644 index 000000000..6cd93faee Binary files /dev/null and b/demo_app/test/table/text_align_center.png differ diff --git a/demo_app/test/table/width_in_percent.png b/demo_app/test/table/width_in_percent.png index c11160fd4..22ee9f6e6 100644 Binary files a/demo_app/test/table/width_in_percent.png and b/demo_app/test/table/width_in_percent.png differ diff --git a/demo_app/test/table/width_in_px.png b/demo_app/test/table/width_in_px.png index 12060e4b6..7e9403f73 100644 Binary files a/demo_app/test/table/width_in_px.png and b/demo_app/test/table/width_in_px.png differ diff --git a/packages/core/lib/src/core_widget_factory.dart b/packages/core/lib/src/core_widget_factory.dart index 8a8628d88..d2239f325 100644 --- a/packages/core/lib/src/core_widget_factory.dart +++ b/packages/core/lib/src/core_widget_factory.dart @@ -1048,7 +1048,7 @@ class WidgetFactory extends WidgetFactoryResetter with AnchorWidgetFactory { case kCssMinHeight: case kCssMinWidth: case kCssWidth: - StyleSizing.registerSizingOp(this, tree); + StyleSizing.registerSizingOp(tree); case kCssLineHeight: final value = style.value; @@ -1114,13 +1114,13 @@ class WidgetFactory extends WidgetFactoryResetter with AnchorWidgetFactory { /// Parses display inline style. void parseStyleDisplay(BuildTree tree, String? value) { - StyleSizing.maybeRegisterChildOp(this, tree); + StyleSizing.maybeRegisterChildOp(tree); switch (value) { case kCssDisplayFlex: tree.register(_styleDisplayFlex ??= StyleDisplayFlex(this).buildOp); case kCssDisplayBlock: - StyleSizing.registerBlockOp(this, tree); + StyleSizing.registerBlockOp(tree); case kCssDisplayInlineBlock: tree.register(displayInlineBlock); case kCssDisplayNone: diff --git a/packages/core/lib/src/internal/ops/style_sizing.dart b/packages/core/lib/src/internal/ops/style_sizing.dart index 2ccb204e3..23b0f81d4 100644 --- a/packages/core/lib/src/internal/ops/style_sizing.dart +++ b/packages/core/lib/src/internal/ops/style_sizing.dart @@ -16,9 +16,8 @@ class StyleSizing { static final _elementTree = Expando(); static final _treeIsBlock = Expando(); - static final _skipBuilding = Expando(); - static void maybeRegisterChildOp(WidgetFactory wf, BuildTree tree) { + static void maybeRegisterChildOp(BuildTree tree) { final parentElement = tree.element.parent; if (parentElement == null || _elementTree[parentElement] == null) { return; @@ -27,7 +26,7 @@ class StyleSizing { tree.register(StyleSizing().childOp); } - static void registerBlockOp(WidgetFactory wf, BuildTree tree) { + static void registerBlockOp(BuildTree tree) { _elementTree[tree.element] = tree; _treeIsBlock[tree] = true; @@ -37,7 +36,7 @@ class StyleSizing { ..register(instance.sizingOp); } - static void registerSizingOp(WidgetFactory wf, BuildTree tree) { + static void registerSizingOp(BuildTree tree) { _elementTree[tree.element] = tree; tree.register(StyleSizing().sizingOp); } @@ -99,7 +98,7 @@ class StyleSizing { } static Widget _sizingBlock(BuildTree tree, WidgetPlaceholder placeholder) { - if (_skipBuilding[tree] == true || placeholder.isEmpty) { + if (placeholder.isEmpty) { return placeholder; } @@ -115,10 +114,6 @@ class StyleSizing { } static void _sizingInline(BuildTree tree) { - if (_skipBuilding[tree] == true) { - return; - } - final input = tree.sizingInput; if (input == null) { return; @@ -145,11 +140,6 @@ class StyleSizing { .wrapWith((c, w) => _build(c, w, input, tree.inheritanceResolvers)); } - static void skip(BuildTree tree) { - assert(_skipBuilding[tree] != true, 'Built ${tree.element} already'); - _skipBuilding[tree] = true; - } - static Widget _build( BuildContext context, Widget child, diff --git a/packages/core/lib/src/internal/ops/tag_table.dart b/packages/core/lib/src/internal/ops/tag_table.dart index 55ec640ce..5f53c2d69 100644 --- a/packages/core/lib/src/internal/ops/tag_table.dart +++ b/packages/core/lib/src/internal/ops/tag_table.dart @@ -85,18 +85,12 @@ class TagTable { final layoutBuilder = LayoutBuilder( builder: (context, bc) { - // wrap the table in a builder to obtain the layout constraints early - // in order to calculate a conservative width - // the whole thing becomes scrollable when columns are too wide - final maxWidth = bc.maxWidth; - final resolved = tableTree.inheritanceResolvers.resolve(context); Widget built = ValignBaselineContainer( child: HtmlTable( border: border.getBorder(resolved), borderCollapse: borderCollapse == kCssBorderCollapseCollapse, borderSpacing: borderSpacing?.getValue(resolved) ?? 0.0, - maxWidth: maxWidth, textDirection: resolved.directionOrLtr, children: List.from( data.builders @@ -107,7 +101,14 @@ class TagTable { ), ); - if (maxWidth.isFinite) { + // provide hints to size the columns properly + built = CssSizingHint( + maxWidth: bc.maxWidth, + minWidth: bc.minWidth, + child: built, + ); + + if (bc.maxWidth.isFinite) { built = wf.buildHorizontalScrollView(tableTree, built) ?? built; } @@ -203,7 +204,6 @@ class TagTable { columnStart: columnStart, rowSpan: rowSpan, rowStart: rowStart, - width: cell.width?.getSizing(resolved), child: child, ); }); @@ -326,7 +326,6 @@ class TagTable { static BuildTree _onTableParsed(BuildTree tableTree) { StyleBorder.skip(tableTree); - StyleSizing.skip(tableTree); return tableTree; } } @@ -379,9 +378,6 @@ class _TagTableRow { } void _onCellRenderedBlock(BuildTree cellTree, Widget block) { - final widthValue = cellTree.getStyle(kCssWidth)?.value; - final width = widthValue != null ? tryParseCssLength(widthValue) : null; - final attributes = cellTree.element.attributes; cells.add( _TagTableDataCell( @@ -389,7 +385,6 @@ class _TagTableRow { child: block, columnSpan: tryParseIntFromMap(attributes, kAttributeColspan) ?? 1, rowSpan: tryParseIntFromMap(attributes, kAttributeRowspan) ?? 1, - width: width, ), ); } @@ -407,7 +402,7 @@ class _TagTableRow { cellTree.register(_cellOp); StyleBorder.skip(cellTree); - StyleSizing.skip(cellTree); + StyleSizing.registerBlockOp(cellTree); } static StylesMap _cssVerticalAlignFromAttribute(dom.Element element) { @@ -484,13 +479,11 @@ class _TagTableDataCell { final int columnSpan; final BuildTree tree; final int rowSpan; - final CssLength? width; const _TagTableDataCell( this.tree, { required this.child, required this.columnSpan, required this.rowSpan, - this.width, }); } diff --git a/packages/core/lib/src/widgets/css_sizing.dart b/packages/core/lib/src/widgets/css_sizing.dart index 8e33dbc8c..e0855750d 100644 --- a/packages/core/lib/src/widgets/css_sizing.dart +++ b/packages/core/lib/src/widgets/css_sizing.dart @@ -73,8 +73,8 @@ class CssSizing extends SingleChildRenderObjectWidget { return _RenderCssSizing( maxHeight: maxHeight ?? hint?.maxHeight.cssSizingValue, maxWidth: maxWidth ?? hint?.maxWidth.cssSizingValue, - minHeight: minHeight, - minWidth: minWidth, + minHeight: minHeight ?? hint?.minHeight.cssSizingValue, + minWidth: minWidth ?? hint?.minWidth.cssSizingValue, preferredAxis: preferredAxis, preferredHeight: preferredHeight, preferredWidth: preferredWidth, @@ -137,17 +137,24 @@ class CssSizing extends SingleChildRenderObjectWidget { class CssSizingHint extends InheritedWidget { final double? maxHeight; final double? maxWidth; + final double? minHeight; + final double? minWidth; const CssSizingHint({ required super.child, super.key, this.maxHeight, this.maxWidth, + this.minHeight, + this.minWidth, }); @override bool updateShouldNotify(CssSizingHint oldWidget) => - maxHeight != oldWidget.maxHeight || maxWidth != oldWidget.maxWidth; + maxHeight != oldWidget.maxHeight || + maxWidth != oldWidget.maxWidth || + minHeight != oldWidget.minHeight || + minWidth != oldWidget.minWidth; } class _RenderCssSizing extends RenderProxyBox { @@ -273,13 +280,17 @@ class _RenderCssSizing extends RenderProxyBox { ) : null; - final cc = BoxConstraints( + var cc = BoxConstraints( maxHeight: stableChildSize?.height ?? preferredHeight ?? maxHeight, maxWidth: stableChildSize?.width ?? preferredWidth ?? maxWidth, minHeight: stableChildSize?.height ?? preferredHeight ?? minHeight, minWidth: stableChildSize?.width ?? preferredWidth ?? minWidth, ); + // after everything... if the incoming is tight then we must follow it + cc = c.hasTightWidth ? cc.tighten(width: c.maxWidth) : cc; + cc = c.hasTightHeight ? cc.tighten(height: c.maxHeight) : cc; + return cc; } diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 6cc21d143..8171b93cc 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -21,9 +21,6 @@ class HtmlTable extends MultiChildRenderObjectWidget { /// Default: `0.0`. final double borderSpacing; - /// If non-null, overwrites the incoming [BoxConstraints.maxWidth]. - final double? maxWidth; - /// Determines the order to lay children out horizontally. /// /// Default: [TextDirection.ltr]. @@ -35,19 +32,22 @@ class HtmlTable extends MultiChildRenderObjectWidget { this.borderCollapse = false, this.borderSpacing = 0.0, required super.children, - this.maxWidth, this.textDirection = TextDirection.ltr, super.key, }); @override - RenderObject createRenderObject(BuildContext context) => _TableRenderObject( - border, - textDirection, - borderCollapse: borderCollapse, - borderSpacing: borderSpacing, - maxWidth: maxWidth, - ); + RenderObject createRenderObject(BuildContext context) { + final hint = context.dependOnInheritedWidgetOfExactType(); + return _TableRenderObject( + border, + textDirection, + borderCollapse: borderCollapse, + borderSpacing: borderSpacing, + maxWidth: hint?.maxWidth, + minWidth: hint?.minWidth, + ); + } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -63,7 +63,6 @@ class HtmlTable extends MultiChildRenderObjectWidget { ); properties .add(DoubleProperty('borderSpacing', borderSpacing, defaultValue: 0.0)); - properties.add(DoubleProperty('maxWidth', maxWidth)); properties.add( DiagnosticsProperty( 'textDirection', @@ -75,11 +74,13 @@ class HtmlTable extends MultiChildRenderObjectWidget { @override void updateRenderObject(BuildContext context, RenderObject renderObject) { + final hint = context.dependOnInheritedWidgetOfExactType(); (renderObject as _TableRenderObject) ..setBorder(border) ..setBorderCollapse(borderCollapse) ..setBorderSpacing(borderSpacing) - ..setMaxWidth(maxWidth) + ..setMaxWidth(hint?.maxWidth) + ..setMinWidth(hint?.minWidth) ..setTextDirection(textDirection); } } @@ -116,9 +117,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { /// The row index this cell should start. final int rowStart; - /// The cell width. - final CssSizingValue? width; - final bool _isCaption; /// Creates a TD (table cell) widget. @@ -130,7 +128,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { Key? key, int rowSpan, required int rowStart, - CssSizingValue? width, }) = HtmlTableCell._; const HtmlTableCell._({ @@ -142,7 +139,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { super.key, this.rowSpan = 1, required this.rowStart, - this.width, }) : assert(columnSpan >= 1), assert(columnStart >= 0), assert(rowSpan >= 1), @@ -184,11 +180,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { needsLayout = true; } - if (data.width != width) { - data.width = width; - needsLayout = true; - } - if (needsLayout) { final parent = renderObject.parent; if (parent is RenderObject) { @@ -205,7 +196,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { properties.add(IntProperty('columnStart', columnStart)); properties.add(IntProperty('rowSpan', rowSpan, defaultValue: 1)); properties.add(IntProperty('rowStart', rowStart)); - properties.add(DiagnosticsProperty('width', width, defaultValue: null)); } @override @@ -263,7 +253,6 @@ class _TableCellData extends ContainerBoxParentData { bool isCaption = false; int rowSpan = 1; int rowStart = 0; - CssSizingValue? width; double calculateHeight(_TableRenderObject tro, List heights) { final gaps = tro._calculateRowGaps(this); @@ -340,48 +329,49 @@ class _TableRenderLayouter { child = data.nextSibling; } + final columnGapsSum = (columnCount + 1) * tro.columnGap; + final gapsAndPaddings = tro.paddingLeft + columnGapsSum + tro.paddingRight; + // calculate the available width if possible // this may be null if table is inside a horizontal scroll view double? availableWidth; final maxWidth = tro._maxWidth ?? constraints.maxWidth; if (maxWidth.isFinite && maxWidth > 0) { - final columnGapsSum = (columnCount + 1) * tro.columnGap; - final gapsAndPaddings = - tro.paddingLeft + columnGapsSum + tro.paddingRight; availableWidth = maxWidth - gapsAndPaddings; } + // calculate the required width if specified (null by default) + double? requiredWidth; + final minWidth = tro._minWidth ?? constraints.minWidth; + if (minWidth.isFinite && minWidth > 0) { + requiredWidth = minWidth - gapsAndPaddings; + } + return _TableDataStep1( availableWidth: availableWidth, cells: cells, children: children, columnCount: columnCount, - maxWidth: maxWidth, + requiredWidth: requiredWidth, rowCount: rowCount, ); } _TableDataStep2 step2NaiveColumnWidths(_TableDataStep1 step1) { final cells = step1.cells; - final cellWidths = cells.map((cell) { - // use width from cell attribute if it is some sensible value - // otherwise, ignore and measure via layouter for real - final cellWidth = cell.width?.clamp(0, step1.maxWidth); - return cellWidth?.isFinite == true ? cellWidth : null; - }).toList(growable: false); - final naiveColumnWidths = List.filled(step1.columnCount, .0); - for (var i = 0; i < cells.length; i++) { - final data = cells[i]; - final cellWidth = cellWidths[i]; - if (cellWidth != null) { - naiveColumnWidths.setMaxColumnWidths(tro, data, cellWidth); + + final requiredWidth = step1.requiredWidth; + if (requiredWidth != null && step1.columnCount > 0) { + final cellMinWidth = requiredWidth / step1.columnCount; + for (var i = 0; i < cells.length; i++) { + final data = cells[i]; + naiveColumnWidths.setMaxColumnWidths(tro, data, cellMinWidth); } } return _TableDataStep2( step1, - cellWidths: cellWidths, naiveColumnWidths: naiveColumnWidths .map((v) => !v.isZero ? v : null) .toList(growable: false), @@ -419,14 +409,13 @@ class _TableRenderLayouter { final child = children[i]; final data = cells[i]; - if (step2.cellWidths[i] == null && cellSizes[i] == null) { + if (cellSizes[i] == null) { // side effect - // no pre-configured width to use - // have to layout cells without constraints for the initial width - final layoutSize = layouter(child, const BoxConstraints()); + // layout cells for the initial width + final layoutSize = layouter(child, constraints); cellSizes[i] = layoutSize; maxColumnWidths.setMaxColumnWidths(tro, data, layoutSize.width); - logger.fine('Got child#$i size without contraints: $layoutSize'); + logger.fine('[3] Got child#$i $layoutSize@$constraints'); shouldLoop = true; } @@ -524,12 +513,12 @@ class _TableRenderLayouter { final child = children[i]; final data = cells[i]; + // always re-layout because we cannot be sure whether + // children will render the same inside an unconstrained and a tight box final childWidth = data.calculateWidth(tro, step3.columnWidths); - // layout with tight constraints to get the expected width final cc1 = BoxConstraints.tightFor(width: childWidth); - // side effect final childSize = layouter(child, cc1); - logger.fine('Got child#$i size with width=$childWidth: $childSize'); + logger.fine('[4] Got child#$i $childSize@$cc1'); childSizes[i] = childSize; // distribute cell height across spanned rows @@ -674,15 +663,15 @@ class _TableDataStep1 { final List<_TableCellData> cells; final List children; final int columnCount; - final double maxWidth; + final double? requiredWidth; final int rowCount; const _TableDataStep1({ - this.availableWidth, + required this.availableWidth, required this.cells, required this.children, required this.columnCount, - required this.maxWidth, + required this.requiredWidth, required this.rowCount, }); } @@ -691,12 +680,10 @@ class _TableDataStep1 { class _TableDataStep2 { final _TableDataStep1 step1; - final List cellWidths; final List naiveColumnWidths; const _TableDataStep2( this.step1, { - required this.cellWidths, required this.naiveColumnWidths, }); } @@ -740,10 +727,12 @@ class _TableRenderObject extends RenderBox required double borderSpacing, required bool borderCollapse, required double? maxWidth, + required double? minWidth, }) : logger = Logger('fwfh.HtmlTable${loggers++}'), _borderCollapse = borderCollapse, _borderSpacing = borderSpacing, - _maxWidth = maxWidth; + _maxWidth = maxWidth, + _minWidth = minWidth; Border? _border; void setBorder(Border? v) { @@ -779,6 +768,14 @@ class _TableRenderObject extends RenderBox } } + double? _minWidth; + void setMinWidth(double? v) { + if (v != _minWidth) { + _minWidth = v; + markNeedsLayout(); + } + } + TextDirection _textDirection; void setTextDirection(TextDirection v) { if (v != _textDirection) { diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index f1c1c569b..e22a088ac 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -418,57 +418,6 @@ Future main() async { }); }); - group('width', () { - testWidgets('renders without width', (WidgetTester tester) async { - const html = '
Foo
'; - final e = await explain(tester, html, useExplainer: false); - expect(e, contains('└HtmlTableCell(columnStart: 0, rowStart: 0)')); - }); - - testWidgets('renders width: 50px', (WidgetTester tester) async { - const html = '
Foo
'; - final explained = await explain(tester, html, useExplainer: false); - expect( - explained, - isNot(contains('└HtmlTableCell(columnStart: 0, rowStart: 0)')), - ); - expect( - explained, - contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 50.0)'), - ); - }); - - testWidgets('renders width: 100%', (WidgetTester tester) async { - const html = '
Foo
'; - final explained = await explain(tester, html, useExplainer: false); - expect( - explained, - isNot(contains('└HtmlTableCell(columnStart: 0, rowStart: 0)')), - ); - expect( - explained, - contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 100.0%)'), - ); - }); - - testWidgets('renders width: 100% within TABLE', (tester) async { - const html = '
' - '
' - 'Foo' - '
' - '
'; - final explained = await explain(tester, html, useExplainer: false); - expect( - explained, - contains('└HtmlTableCell(columnStart: 0, rowStart: 0)'), - ); - expect( - explained, - contains('└HtmlTableCell(columnStart: 0, rowStart: 0, width: 100.0%)'), - ); - }); - }); - group('combos', () { testWidgets('renders nested table', (WidgetTester tester) async { // https://github.com/daohoangson/flutter_widget_from_html/issues/1070 @@ -494,7 +443,7 @@ Future main() async { const windowSize = 100.0; tester.setWindowSize(const Size(windowSize, windowSize)); - const html = '
' + const html = '
' '
Foo
' '
'; await explain(tester, html); @@ -653,81 +602,6 @@ Future main() async { }); }); - group('background', () { - testWidgets('cell color', (WidgetTester tester) async { - // https://github.com/daohoangson/flutter_widget_from_html/issues/171 - const html = '' - '' - '
Foo
'; - final explained = await explain(tester, html); - expect( - explained, - equals( - '[SingleChildScrollView:child=[HtmlTable:children=' - '[HtmlTableCell:child=' - '[Container:color=#FFFF0000,child=' - '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '[RichText:(:Foo)]' - ']]]]]]', - ), - ); - }); - - testWidgets('row color', (WidgetTester tester) async { - // https://github.com/daohoangson/flutter_widget_from_html/issues/1028 - const html = '' - '' - '
FooBar
'; - final explained = await explain(tester, html); - expect( - explained, - equals( - '[SingleChildScrollView:child=[HtmlTable:children=' - '[HtmlTableCell:child=' - '[Container:color=#FFFF0000,child=' - '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '[RichText:(:Foo)]' - ']]]],' - '[HtmlTableCell:child=' - '[Container:color=#FFFF0000,child=' - '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '[RichText:(:Bar)]' - ']]]]' - ']]', - ), - ); - }); - - testWidgets('overwrites row color', (WidgetTester tester) async { - const html = '' - '' - '
FooBar
'; - final explained = await explain(tester, html); - expect( - explained, - equals( - '[SingleChildScrollView:child=[HtmlTable:children=' - '[HtmlTableCell:child=' - '[Container:color=#FFFF0000,child=' - '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '[RichText:(:Foo)]' - ']]]],' - '[HtmlTableCell:child=' - '[Container:color=#FF00FF00,child=' - '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '[RichText:(:Bar)]' - ']]]]' - ']]', - ), - ); - }); - }); - testWidgets('renders display: table', (WidgetTester tester) async { const html = '''
@@ -747,10 +621,10 @@ Future main() async { equals( '[SingleChildScrollView:child=[HtmlTable:children=' '[HtmlTableCaption:child=[RichText:align=center,(:Caption)]],' - '[HtmlTableCell:child=[RichText:(+b:Header 1)]],' - '[HtmlTableCell:child=[RichText:(+b:Header 2)]],' - '[HtmlTableCell:child=[RichText:(:Value 1)]],' - '[HtmlTableCell:child=[RichText:(:Value 2)]]' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(+b:Header 1)]]],' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(+b:Header 2)]]],' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(:Value 1)]]],' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(:Value 2)]]]' ']]', ), ); @@ -767,8 +641,8 @@ Future main() async { explained, equals( '[SingleChildScrollView:child=[HtmlTable:children=' - '[HtmlTableCell:child=[RichText:(:Foo)]],' - '[HtmlTableCell:child=[RichText:(:Bar)]]' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(:Foo)]]],' + '[HtmlTableCell:child=[CssBlock:child=[RichText:(:Bar)]]]' ']]', ), ); @@ -812,22 +686,6 @@ Future main() async { expect(after.borderSpacing, equals(20.0)); }); - testWidgets('updates maxWidths', (WidgetTester tester) async { - await explain( - tester, - '
Foo
', - ); - final before = tester.table; - expect(before.maxWidth, equals(100.0)); - - await explain( - tester, - '
Foo
', - ); - final after = tester.table; - expect(after.maxWidth, equals(200.0)); - }); - testWidgets('updates textDirection', (WidgetTester tester) async { await explain(tester, '
Foo
'); final before = tester.table; @@ -1115,14 +973,6 @@ Future main() async { ]); expect(second.width, equals(first.width)); - - final m = _loggerMessages; - expect(m, contains(contains('Got child#0 min width:'))); - expect(m, contains(contains('Got child#1 min width:'))); - expect(m, contains(contains('Got child#2 size without contraints:'))); - expect(m, isNot(contains(contains('Got child#2 min width:')))); - expect(m, contains(contains('Got child#3 size without contraints:'))); - expect(m, isNot(contains(contains('Got child#3 min width:')))); }); }); @@ -1168,12 +1018,29 @@ Future main() async {
Lorem ipsum dolor sit amet.
FooBar
''', - 'height_1px': 'Above' - '
Foo
Below', 'rowspan': ''' +
$multilineFoo
Bar
''', + // TODO: doesn't match browser output + 'sizing_height_1px': ''' +Above + + + + + +
Foo
+ +Below''', + 'sizing_width_100_percent': ''' + + + + + +
OneTwoThree
''', 'valign_baseline_1a': ''' @@ -1214,8 +1081,9 @@ Future main() async {
Foo
''', + // https://github.com/daohoangson/flutter_widget_from_html/issues/171 + // https://github.com/daohoangson/flutter_widget_from_html/issues/1028 'row_color': ''' - @@ -1235,7 +1103,7 @@ Future main() async { - +
First Name
Adam Johnson6767
''', 'rtl': ''' @@ -1282,6 +1150,18 @@ Future main() async { $multiline ''', + // https://github.com/daohoangson/flutter_widget_from_html/issues/1322 + // https://github.com/daohoangson/flutter_widget_from_html/issues/1446 + 'text_align_center': ''' + + + + + + + +
Long long long text
Short text
+''', 'width_redistribution_wide': '''
@@ -1302,6 +1182,7 @@ Future main() async {
''', + // TODO: doesn't match browser output 'width_in_percent': ''' @@ -1528,8 +1409,8 @@ Future explain( String _padding(String child) => '[HtmlTableCell:child=' '[Padding:(1,1,1,1),child=' - '[Align:alignment=centerLeft,widthFactor=1.0,child=' - '$child]]]'; + '[Align:alignment=centerLeft,widthFactor=1.0,child=[CssBlock:child=' + '$child]]]]'; final _loggerIsGitHubAction = Platform.environment['GITHUB_ACTIONS'] == 'true'; final _loggerMessages = [];