From 8d97533ea7d676ea68663a3b0d570c4a8a7f5285 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sat, 19 Apr 2025 06:20:46 +0700 Subject: [PATCH 01/14] Register block op for table cells --- packages/core/lib/src/core_widget_factory.dart | 6 +++--- packages/core/lib/src/internal/ops/style_sizing.dart | 6 +++--- packages/core/lib/src/internal/ops/tag_table.dart | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) 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..56c54b508 100644 --- a/packages/core/lib/src/internal/ops/style_sizing.dart +++ b/packages/core/lib/src/internal/ops/style_sizing.dart @@ -18,7 +18,7 @@ class StyleSizing { 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 +27,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 +37,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); } diff --git a/packages/core/lib/src/internal/ops/tag_table.dart b/packages/core/lib/src/internal/ops/tag_table.dart index 55ec640ce..fb5bbd8d5 100644 --- a/packages/core/lib/src/internal/ops/tag_table.dart +++ b/packages/core/lib/src/internal/ops/tag_table.dart @@ -407,7 +407,7 @@ class _TagTableRow { cellTree.register(_cellOp); StyleBorder.skip(cellTree); - StyleSizing.skip(cellTree); + StyleSizing.registerBlockOp(cellTree); } static StylesMap _cssVerticalAlignFromAttribute(dom.Element element) { From 95b9bff89d4a8aaccdf388f465b905d4460a5007 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sat, 19 Apr 2025 06:55:01 +0700 Subject: [PATCH 02/14] Update tests --- packages/core/test/tag_table_test.dart | 108 ++++++------------------- 1 file changed, 23 insertions(+), 85 deletions(-) diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index f1c1c569b..ad128ccb5 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -653,81 +653,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 +672,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 +692,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)]]]' ']]', ), ); @@ -1214,8 +1139,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 +1161,7 @@ Future main() async { - +
First Name
Adam Johnson6767
''', 'rtl': ''' @@ -1282,6 +1208,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': '''
@@ -1528,8 +1466,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 = []; From 4229f4f9deb8da9b8afac53c57c7f3b14563bd62 Mon Sep 17 00:00:00 2001 From: Cirrus CI Date: Sat, 19 Apr 2025 00:06:21 +0000 Subject: [PATCH 03/14] [skip ci] Update golden images --- demo_app/test/table/row_color.png | Bin 11034 -> 11010 bytes demo_app/test/table/text_align_center.png | Bin 0 -> 6210 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 demo_app/test/table/text_align_center.png diff --git a/demo_app/test/table/row_color.png b/demo_app/test/table/row_color.png index e8bd41620b06f5d2703819bc9db1d99c59134cfb..8472cfda3c9f21128afa0c428a0e16c77255b9b8 100644 GIT binary patch literal 11010 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 Jb@Ixse+N#l8g~Ey literal 0 HcmV?d00001 From af7469c9822fb3ecc66a0d66f9b83da7cdff53ed Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sat, 19 Apr 2025 23:59:26 +0700 Subject: [PATCH 04/14] [skip ci] Take min width into account when render table / table cell --- demo_app/test/table/height_1px.png | Bin 4789 -> 0 bytes demo_app/test/table/sizing_height_1px.png | Bin 0 -> 4309 bytes .../test/table/sizing_width_100_percent.png | Bin 0 -> 4167 bytes demo_app/test/table/width_in_percent.png | Bin 3252 -> 3327 bytes .../table/width_in_percent_100_nested.png | Bin 2776 -> 2865 bytes .../width_in_percent_100_nested_stretch.png | Bin 0 -> 4375 bytes .../width_in_percent_100_nested_with_gaps.png | Bin 0 -> 4383 bytes demo_app/test/table/width_in_px.png | Bin 3213 -> 3369 bytes .../test/table/width_redistribution_wide.png | Bin 5628 -> 6129 bytes .../test/table/width_redistribution_wide2.png | Bin 6432 -> 6929 bytes .../lib/src/internal/ops/style_sizing.dart | 12 +- .../core/lib/src/internal/ops/tag_table.dart | 9 +- packages/core/lib/src/widgets/html_table.dart | 148 ++++++++++-------- packages/core/test/tag_table_test.dart | 99 ++++++------ 14 files changed, 130 insertions(+), 138 deletions(-) delete mode 100644 demo_app/test/table/height_1px.png create mode 100644 demo_app/test/table/sizing_height_1px.png create mode 100644 demo_app/test/table/sizing_width_100_percent.png create mode 100644 demo_app/test/table/width_in_percent_100_nested_stretch.png create mode 100644 demo_app/test/table/width_in_percent_100_nested_with_gaps.png diff --git a/demo_app/test/table/height_1px.png b/demo_app/test/table/height_1px.png deleted file mode 100644 index 51276c7bf023b06fa8dda905c5ef12f7096f3c21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4789 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 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 0000000000000000000000000000000000000000..de110ee5797ff21672a348f08a3fffd67126b243 GIT binary patch literal 4309 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 yq5p#UlMngEfHCZh|2Y8I9}WQfZs@~aoOFBX zrX3=Lh&v!P(^E57Zl^)6-rl@towx`$bFMgpx|dWwXMgeKd#Ao3+`Tn_S~RuacQ8A% zh*p*Ms81bm@tLoVBa(KjbSOrM9}wb&=){$*ewIRoW6^@6#63Maz)6x%pEm$pa<|CW z1(NK=lp zD*oyRz^zx{(b&{P+KtZNl0uuBGE)M5&?}n^RckIb*Q0HmT9Qg{|14C|=t)5{bA%fk z7jK27u&!}2x>FlgmRzG}a1UWAo@*Jg`gbRFy(h^Vf#C~BALt^FaUk@6u77iIKk%t- z8vtB0um>)E$H^;KCx1=B1baasE(?R7m=+d9ajzI#jBT9bh*zvVVq>|olC0$kr$@{V zjASN*taekbi`meEjcGd#o~@)@nEb64`lh$e$LDP@^Y6Bw2pMoaR5awF~D>vt#|U-bIO&U{aiHtIXO!r^23E` zgsvIV)7zw36VYLBty%cmGjYO+gi%baiFqL2=3-G%!^M!qJgM3|{mG9rWse;fR)05P z9W}HLA!f993cH+!gv9H%f;;JU$6)W99DXr!^s+m*5t`#MS7Y1eBl{H||NKS)N{|p{ z1KV1caC!;~qNn(S)w{)_BqWlx&c?gx=otkOBb`)od;HR`v#x?gMs0e))cuI6*1Vm{ z_Kx=W-GYPhg5e5t^y5Mo)WR=NFO``+?o-7gE0E`tH|~sS_K2%u4-hm)X=&P|nx$um z%T#uBaq8UM9BsGB!Wlc^R6HQG-d#F~EO@8G$Q*UH(lM%fqhuqfIy;>hFJckuX-ekklG{D>gkI?|y@uP{yOrHyu{?~$ zm8;9IA4-^bURK;Svpi7_r^6d?e}#>4U)KNH85B4|=RZ9E@^*7H#a3GpJ7+O8(XE~^ z)S0*#ho~b}91mNR*;%nf2%L?fnNR!CRs(EQXlSTa-tq&Sx`ziNrp$IZh2h`)7KxuU z6>--pH5}d!#wvGPW<$RY>c3gKJ!-C!hqchP@S!A`F{1_!aSyShOVN2p&VKuH{uFKX zw&A#{hbP!DA9q=4FSigrVnC#f=>}CsKUCb(EDhHb3ZYbwxNqQ$9fcIm2?QlP))fl2 zYSPYIvN8+iz9`+F%zsw=wS1XabOO6zrmj}5B@mLK;-Il(7^fzqbn7Ay4aGW z#^Yj$ckbVJsEW$TaipC;m)0Ygn)Mdzd7_?_k+!Hw5P5ZM)y3`fp#&`ncY1mta8QnI zYHDgya`Fg8qe$uQ=~2A)GekWuEP)eePh@^s*&1G7cxc4fHJ6IG362DxiOD}V93@ljV_uYg~Q$XvP5#92arONN~#R4I6WCN_d>+P2rKfk_Ut5KCQJG zsRWG_yYnWpnTwJ(h=rT{ChpA=NTAZ>`6yXE(ED)_@|w&6`i^2T;q|5by}dX!o<0WC zmgzx}YV~HXqD~q_G@3y)6nUqoSmms}jK-U`@lAF{{3z0XHQ36Ie$DhaYV+GdJJ@N< zbbo$FS*CbOKod5M>?_c7Z!sLH0>O#RkyK|;@2c;7_oK910r``iNS={3_{1JIPwo7o z!>P_%)Q9`kD?O8f;>qOQ&qvnfBOr1k|Df`Lk>~25k@x27dLu*3XN1hRKbyOrKWl|w zD`V8VK!gps(K8S)XMPE?iI%h1ddyD<>1T-Xs%xeZ41KAxB`ZNTf2z+F`}RmOyCs;| zo|O?lEl;2~9aE0Oy&ZP8*0bhfJ74n6n?L-$^tr^PNmvmUozyE{Sy~#7qO1(BDvdcy zQp7l{%!XW#y5NJ`HlR0|w~bO_+aSpoE(~{7P6erF+PAUmOGQ@RUUhYKBv%!Y(W_v# z_b!QpOmbPd^1<)*(4sqmf8i`bS5KB4#`}Yct*}FjHN3(;WgZDfzgsM^a8C>3_2+57 zt;0{WqpCs*w4%^D#{+&s<#C;5?vgfXhMl6r0VN*JQY$al zuo!gaA{XL5kiBw<5NHab{%C$sw;47QjOzuM&o=||2neRZDVxH zwGT7YCrL$)thMs$Sy3mP5TzQj4PDJubAxEIMQyg&;Ly-9=A!h9Dw?pe9%DQs7hE*Qc z03u*lBEh1ujI7KAxoMRhjE{R2SL#jN)7CeXy#^S%ZHKCbZ)L>=Zd8@ z_PY&lv~w>JKa><+3DW>dWOIy_PK zQ}0q`+1l)|nf5O%qIc-i(@I9V!=?MLT3V9;Ap0Jt68z9#A2^#*Q>h=Us{^F;+;{wN zKhTzEuYLZJRrv$=@-Fm0tlc|t-ih;{cK;m{@0fVU#DBXC|KHuACVX(fqU>mF>D~_l O0Cp*6%O|3}L(|91{+FIyMsc12#MiN?-BBh`e5+KNfqEH?rmY5JpARty{ zlthnFG$8Sz4d$POq(YPjd5EpX0w#r!2S}3u7BLAA0)~h&T29b2O`5kgM5?8)$t&O zN5#Wjg$_G%4uI9Xs6AiCQ)?&n#$0`&pKPX3&f1>c-;~`(NjcUQwcfTn;LeS8m;M>+ z?csL^UUU<_=(ZUCH_FYAA0Drv^3L5zeexFR{b1(s=Y18h){0(7x*W0F(!bqtxwfjR zRs^rN5XRM+Cy#EMn<)*K+h}XCKMz)ioiD9mKwV-F=0|1=CTe4<< zTl+rvLVNUSI_7D?`^kO6>61jgb!?YqW!RfT#c$&{+KCY$ju0M=AjXv8a8^wqC(%;h z#a$RlCi3iCs19}wQNY>cmgWnw4fyqL1WhKV)`iOF% z_jt46d+B2zCa%ra>xfW7KCyy)^F=^4QKe;Mog70}%=5DR7{<|St z%Js*rmoRp7!?l!gg_A;0ZqG2{$hLVCVPmc;i!#acni@=_NX37DjF;t@`}+Q6n_b_7 z!>P;?bN6%_PRU?5jJy_S`q%OtwoP|@nDhRzp*xcrJGF6*w&@0ZXUdoXl#yG3lGv7#rfq4%QgUu$DMdG36gk&~ZIlVf#=*p`Oh_ZD; zp#ZHKDAom7cGGN{eS!66eRP(_8CKpSwj0`2C)nm%|Kd+->G}#n$E`FR?z&QM_9H-5 zqOfoIx&%wFM2|jhld`D=w~EeQfgs4V#)3dl@8SdXKH%jAvLc;a^ZXR!b_U}`J|BXT zwyKI+BwOxyKE|d?JHM6{&`O6g4#({*w34tjy z5oNowY2*#9NGw)>7vbVqF*q78rCt<pNY-C>DaxQcMY1Q-cXOoJ-IwUq>3Z9V~wHXSnq-fvjtZnMJL>V$qRg zTL}2mmHoB$4?P+?hcHEYKlP~UJkmDLP|bGq1)2Lt9--}!QeubS&OI?Rmc=)%;gjyR zom{puJ=&G`*2~eMLdVPQuZx{LhI;U4yoArIa8f%|@gV};zFrj^&P*WY2`I1U&=1bx zDQnC`MDgf?aXTLAeEy6)%3XlCkm(@ZlS5U`RQhcO$?7vf-l^Z2*Y2Y*-k{zaVc?XM zVt4V59aZ4J8PrQDACB?L>iU?~xnya2X@;Qx)lx#EwcUyjK6pFMJYVn9?x?4E}3^i%%^bPlJo literal 3252 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 a3uf_8lGW#8%alUwcM2iF5kX=)JMSM0u?e>T diff --git a/demo_app/test/table/width_in_percent_100_nested_stretch.png b/demo_app/test/table/width_in_percent_100_nested_stretch.png new file mode 100644 index 0000000000000000000000000000000000000000..712fe92d52ff6c88a600813873175942337a472f GIT binary patch literal 4375 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 F{})wK)2{#k literal 3213 zcmeH~{ZkT17{?bawaE0wOG^^FnyF?k^yZ96N$JHR&lmEAFnmGtMoUyo#RN6AcQ2Le zy)4T*Q{&ZA!Ac}u^M)?7CDX<48B--!s?S%RSy^9wZRIH) zc6W^LW6$0E6P`Qgu7pg7JkOFfP2WH^hIS3-gkVp4!VF8>lY_@ApaRSj7)s!*Rc8%O z=B4euqbv|B`whyM7;Uy<%uwLebEBEX0^sPPXKx??7-1!|f%EbP0Pf9l1?$h!2H70qx=z(VJ;?h~b!L$|I5b%st zv8o_5kSk`_i8E`yFP`2huwfb7Fm09!rn%7He5hx3HD=Fm&R|JM0t6hKvkDad^l58; zM@e(e-`=TDT5fn6iTfXTN$Nhr&kGrbcdwIcTv#%d%|iXId7nOh1Y^9Sgrbn3mDQmXdj3sot} z!px7sVzK3mP<%N3^{dK&p((m%{Ip}GJJ{6}0A+vN>s2ph5#;-C>C~MxsOmI<#K}MV zQZ6)~S6H~(_#9kZ;jmQy;DD37f#Jv+i?f(j{URZ6OD_V3%3xzX^P9q|)?HI6ur*w> zmMW#^kvUVtkBn`4RJVVys}#!GuFo6zktd2k4P+*T`qHuvEVl>l973JLSkb!@x=J8^ zyKm|(&I5mJEI#VO%l@dn(*=qC28}1VyFMI`r%Fx}q@^ox%^z$tygXZ*VxGtiR4vADxP1GMOwEE5rDz z9C?)*h(w{}9Y>saK`!EGo^YBNx)38W`6tJ({i9;t`v-@gH~|fez92f~GHpBKSik)m zp(Pi#Car$Y<;8Lj0v?Yo3%I(40gp>hhmkY0v;7TqN|o#a<>OPb{e1SEp$@rGuZFos zqj}0vfhF8}TGlP-h?J@j@hdAUQ=e6jREje<2tRZM>tzZB6A{Dj*6cWI$Ya#j#+!eE z6z{9Xd1ZO7uD@l6bW)AS5(orphMJvTRfWtPG-3F=*GDo6`4mNbpC3BkCxWMGy(DXo zQLBBtxh_^G1&j9td90flylq6wySsT+k=b4s;t&V~a_@BOVaZ&exnq3o&c>B33}+E| zT>j*wRw<)Ilhi0S@A)#Uw8S1B-BI|eho}=E2l~)xwA$NS6rEJD@P*s5(c@f|)sYbU zdG+P#F!e_ah7=igDb^~E$2aSR9LGz}pvO%gl;DxulSq{=Ajmv)BeGtqT2q0kkvBi7z=QP&W?R+z4q8B%p4l4hE2gg&a5 zt1sO@mfCwuDQ!q>PyO&iJNfm4TH0i);2e7 zRAnTg%d80|}vtN8TQE!o8hpk@<5VScgkh?Kq|33;ROy>Xq diff --git a/demo_app/test/table/width_redistribution_wide.png b/demo_app/test/table/width_redistribution_wide.png index a74182a6f60253fb03ac98ab4213a39460cd8db3..912b15d21845161440f6399bb7e6443ae999b436 100644 GIT binary patch literal 6129 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 FzW_7~!_EKz delta 3876 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 diff --git a/demo_app/test/table/width_redistribution_wide2.png b/demo_app/test/table/width_redistribution_wide2.png index cd6f440776c323b16dcabf9ff681cc720b560193..426f51ed354bc5b08b016d9263b28dfc97ef8c90 100644 GIT binary patch literal 6929 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 V7X-Nkyw(DFpM?F`a3cKYzXMCFyCDDo literal 6432 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 diff --git a/packages/core/lib/src/internal/ops/style_sizing.dart b/packages/core/lib/src/internal/ops/style_sizing.dart index 56c54b508..23b0f81d4 100644 --- a/packages/core/lib/src/internal/ops/style_sizing.dart +++ b/packages/core/lib/src/internal/ops/style_sizing.dart @@ -16,7 +16,6 @@ class StyleSizing { static final _elementTree = Expando(); static final _treeIsBlock = Expando(); - static final _skipBuilding = Expando(); static void maybeRegisterChildOp(BuildTree tree) { final parentElement = tree.element.parent; @@ -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 fb5bbd8d5..fa7e5753a 100644 --- a/packages/core/lib/src/internal/ops/tag_table.dart +++ b/packages/core/lib/src/internal/ops/tag_table.dart @@ -97,6 +97,7 @@ class TagTable { borderCollapse: borderCollapse == kCssBorderCollapseCollapse, borderSpacing: borderSpacing?.getValue(resolved) ?? 0.0, maxWidth: maxWidth, + minWidth: bc.minWidth, textDirection: resolved.directionOrLtr, children: List.from( data.builders @@ -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, ), ); } @@ -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/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 6cc21d143..6a67b6795 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -4,8 +4,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; -import 'css_sizing.dart'; - /// A TABLE widget. class HtmlTable extends MultiChildRenderObjectWidget { /// The table border sides. @@ -24,6 +22,9 @@ class HtmlTable extends MultiChildRenderObjectWidget { /// If non-null, overwrites the incoming [BoxConstraints.maxWidth]. final double? maxWidth; + /// If non-null, overwrites the incoming [BoxConstraints.minWidth]. + final double? minWidth; + /// Determines the order to lay children out horizontally. /// /// Default: [TextDirection.ltr]. @@ -36,6 +37,7 @@ class HtmlTable extends MultiChildRenderObjectWidget { this.borderSpacing = 0.0, required super.children, this.maxWidth, + this.minWidth, this.textDirection = TextDirection.ltr, super.key, }); @@ -47,6 +49,7 @@ class HtmlTable extends MultiChildRenderObjectWidget { borderCollapse: borderCollapse, borderSpacing: borderSpacing, maxWidth: maxWidth, + minWidth: minWidth, ); @override @@ -63,7 +66,8 @@ class HtmlTable extends MultiChildRenderObjectWidget { ); properties .add(DoubleProperty('borderSpacing', borderSpacing, defaultValue: 0.0)); - properties.add(DoubleProperty('maxWidth', maxWidth)); + properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: null)); + properties.add(DoubleProperty('minWidth', minWidth, defaultValue: null)); properties.add( DiagnosticsProperty( 'textDirection', @@ -80,6 +84,7 @@ class HtmlTable extends MultiChildRenderObjectWidget { ..setBorderCollapse(borderCollapse) ..setBorderSpacing(borderSpacing) ..setMaxWidth(maxWidth) + ..setMinWidth(minWidth) ..setTextDirection(textDirection); } } @@ -116,9 +121,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 +132,6 @@ class HtmlTableCell extends ParentDataWidget<_TableCellData> { Key? key, int rowSpan, required int rowStart, - CssSizingValue? width, }) = HtmlTableCell._; const HtmlTableCell._({ @@ -142,7 +143,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 +184,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 +200,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 +257,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 +333,44 @@ class _TableRenderLayouter { child = data.nextSibling; } - // 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; + + var wc = const BoxConstraints(); + final troMinWidth = tro._minWidth; + if (troMinWidth != null && troMinWidth > 0) { + // only apply width constrains if a specific min value has been set + // this will be used mostly in percentage calculations + wc = BoxConstraints(maxWidth: maxWidth, minWidth: troMinWidth); } return _TableDataStep1( - availableWidth: availableWidth, cells: cells, children: children, columnCount: columnCount, - maxWidth: maxWidth, + remainingMaxWidth: + _TableDataStep1._calculateRemainingWidth(tro, columnCount, maxWidth), + remainingMinWidth: _TableDataStep1._calculateRemainingWidth( + tro, columnCount, wc.minWidth), rowCount: rowCount, + widthConstraints: wc, ); } _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 remainingMinWidth = step1.remainingMinWidth; + if (remainingMinWidth != null && step1.columnCount > 0) { + final cellMinWidth = remainingMinWidth / 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), @@ -390,12 +379,12 @@ class _TableRenderLayouter { _TableDataStep3 step3MinIntrinsicWidth(_TableDataStep2 step2) { final step1 = step2.step1; - final availableWidth = step1.availableWidth; final cells = step1.cells; final children = step1.children; + final remainingMaxWidth = step1.remainingMaxWidth; - final cellSizes = List.filled(children.length, null); final childMinWidths = List.filled(children.length, null); + final childSizes = List.filled(children.length, null); final maxColumnWidths = step2.naiveColumnWidths.map((v) => v ?? .0).toList(); final minColumnWidths = List.filled(step1.columnCount, .0); @@ -404,9 +393,10 @@ class _TableRenderLayouter { // it only considers min value when the columns don't fit var columnWidths = maxColumnWidths; if (columnWidths.zeros.isEmpty && - (availableWidth == null || columnWidths.sum <= availableWidth)) { + (remainingMaxWidth == null || columnWidths.sum <= remainingMaxWidth)) { return _TableDataStep3( step2, + childSizes: childSizes, columnWidths: columnWidths, ); } @@ -419,14 +409,13 @@ class _TableRenderLayouter { final child = children[i]; final data = cells[i]; - if (step2.cellWidths[i] == null && cellSizes[i] == null) { + if (childSizes[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()); - cellSizes[i] = layoutSize; + // layout cells for the initial width + final layoutSize = layouter(child, step1.widthConstraints); + childSizes[i] = layoutSize; maxColumnWidths.setMaxColumnWidths(tro, data, layoutSize.width); - logger.fine('Got child#$i size without contraints: $layoutSize'); + logger.fine('Got child#$i $layoutSize@${step1.widthConstraints}'); shouldLoop = true; } @@ -458,9 +447,9 @@ class _TableRenderLayouter { } } - if (availableWidth != null) { + if (remainingMaxWidth != null) { columnWidths = redistributeValues( - available: availableWidth, + available: remainingMaxWidth, maxValues: maxColumnWidths, minValues: minColumnWidths, ); @@ -469,6 +458,7 @@ class _TableRenderLayouter { return _TableDataStep3( step2, + childSizes: childSizes, columnWidths: columnWidths, ); } @@ -482,7 +472,7 @@ class _TableRenderLayouter { required List minColumnWidths, }) { final step1 = step2.step1; - final availableWidth = step1.availableWidth; + final remainingMaxWidth = step1.remainingMaxWidth; final widthSum = columnWidths.sumRange(data); final maxWidthSum = maxColumnWidths.sumRange(data); @@ -490,12 +480,12 @@ class _TableRenderLayouter { // cell has been allocated more than its requested value // skip measuring if not absolutely needed because it's expensive - if (availableWidth == null) { - // unlimited available space + if (remainingMaxWidth == null) { + // unbounded width constraints return null; } - if (columnWidths.sum <= availableWidth) { + if (columnWidths.sum <= remainingMaxWidth) { // current widths are good enough return null; } @@ -516,6 +506,7 @@ class _TableRenderLayouter { final step1 = step2.step1; final cells = step1.cells; final children = step1.children; + final existingChildSizes = step3.childSizes; final childSizes = List.filled(children.length, Size.zero); final rowHeights = List.filled(step1.rowCount, .0); @@ -525,12 +516,18 @@ class _TableRenderLayouter { final data = cells[i]; 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'); - childSizes[i] = childSize; + var childSize = existingChildSizes[i]; + if (childSize?.width == childWidth) { + // no need to re-layout if the width is the same + childSizes[i] = childSize!; + } else { + // side effect + // layout with tight constraints to get the expected width + final cc1 = BoxConstraints.tightFor(width: childWidth); + childSize = layouter(child, cc1); + logger.fine('Got child#$i $childSize@$cc1'); + childSizes[i] = childSize; + } // distribute cell height across spanned rows final rowHeight = @@ -670,33 +667,40 @@ class _TableRenderLayouter { @immutable class _TableDataStep1 { - final double? availableWidth; final List<_TableCellData> cells; final List children; final int columnCount; - final double maxWidth; + final double? remainingMaxWidth; + final double? remainingMinWidth; final int rowCount; + final BoxConstraints widthConstraints; const _TableDataStep1({ - this.availableWidth, required this.cells, required this.children, required this.columnCount, - required this.maxWidth, + required this.remainingMaxWidth, + required this.remainingMinWidth, required this.rowCount, + required this.widthConstraints, }); + + static double _calculateRemainingWidth( + _TableRenderObject tro, int columnCount, double width) { + final columnGapsSum = (columnCount + 1) * tro.columnGap; + final gapsAndPaddings = tro.paddingLeft + columnGapsSum + tro.paddingRight; + return width - gapsAndPaddings; + } } @immutable class _TableDataStep2 { final _TableDataStep1 step1; - final List cellWidths; final List naiveColumnWidths; const _TableDataStep2( this.step1, { - required this.cellWidths, required this.naiveColumnWidths, }); } @@ -705,10 +709,12 @@ class _TableDataStep2 { class _TableDataStep3 { final _TableDataStep2 step2; + final List childSizes; final List columnWidths; const _TableDataStep3( this.step2, { + required this.childSizes, required this.columnWidths, }); } @@ -740,10 +746,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 +787,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 ad128ccb5..b4ce28fdf 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 @@ -1093,12 +1042,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': ''' @@ -1240,6 +1206,7 @@ Future main() async {
''', + // TODO: doesn't match browser output 'width_in_percent': ''' @@ -1258,6 +1225,32 @@ Future main() async {
+''', + 'width_in_percent_100_nested_with_gaps': ''' + + + + + +
Foo foo foo
+ + + + +
Foo
+
''', + 'width_in_percent_100_nested_stretch': ''' + + + + +
Foo foo foo
+ + + + +
Foo
+
''', 'width_in_px': ''' From d6382c2f9406d06bf490cbeef712ce6743df5396 Mon Sep 17 00:00:00 2001 From: Cirrus CI Date: Sat, 19 Apr 2025 17:03:38 +0000 Subject: [PATCH 05/14] [skip ci] Update golden images --- demo_app/test/goldens/inline/margin/auto.png | Bin 17359 -> 17359 bytes demo_app/test/table/collapsed_border.png | Bin 3684 -> 2972 bytes demo_app/test/table/sizing_height_1px.png | Bin 4309 -> 4134 bytes .../test/table/sizing_width_100_percent.png | Bin 4167 -> 3980 bytes demo_app/test/table/width_in_percent.png | Bin 3327 -> 3270 bytes .../table/width_in_percent_100_nested.png | Bin 2865 -> 2776 bytes .../width_in_percent_100_nested_stretch.png | Bin 4375 -> 4126 bytes .../width_in_percent_100_nested_with_gaps.png | Bin 4383 -> 4136 bytes demo_app/test/table/width_in_px.png | Bin 3369 -> 3214 bytes .../test/table/width_redistribution_wide.png | Bin 6129 -> 5628 bytes .../test/table/width_redistribution_wide2.png | Bin 6929 -> 6432 bytes 11 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demo_app/test/goldens/inline/margin/auto.png b/demo_app/test/goldens/inline/margin/auto.png index 058463d96cc81811a9559570941041a5b797eae9..04116a7e076d51b3b8f16c7a913934a5402324a0 100644 GIT binary patch literal 17359 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 Kszk~p@P7dBT=3Zd literal 17359 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 diff --git a/demo_app/test/table/collapsed_border.png b/demo_app/test/table/collapsed_border.png index 28d5d90793ceb309c3240e7c40b0acbebbc28085..674a69cef0e9c9af1e7d726c333948c54bbc5041 100644 GIT binary patch delta 1277 zcmYL|eNfVO9LK+AOUsmP?IfR8x65oxah_3xp=PF64eJWjLez4lVW;^32qM4gR-0$& zPHuMdk;`=^PilrFBtGWWgPv>sz;Hg4i3-v$MTVg0@cN_ApP&1@?>_I>`}29{TaErT z5^{?<7JZmhP;DGNd7I4i>wkl6{o|(%M{b_axK;cMV-IOLIEqO5XCa+@U>Ck`=azly zhr6i1(~`WM%Q4>K2O-*TN=|RTBI=KN8HL5RVK%#s+`Le^HS|lt@e|w6@3ttKC0LB! z9pMqCSn-y)+}+3mf4ur&Lj(4878-z%4wp5=34k3~{&iO$ui+OKXtwC#v~w`-(fNn_ zrNhGmL;!fYjr@7nJ&<@^)VVwbvC5Zw(n|DNe%`8KS`@AnzE>HfTANHFyV`wYf2*pWHOe{`p&xE z@%KzbW0LMS#G+oc1yM3rSFDXGZeR%KH~wx6x+2i2LYlNjhU}a~p{vZK{eAZ+UH_`_ zTzl?Cf_1V^Ju#6gXF3B;2Ay+*ZU~aAgX>sQhH?0;-EPM!)*=aEHWS+l-5Xc`h3+Jk zai&M!cW(evS^|f^Y?O~CYl2m(3NGjJXy-)=udGhEEg&vGJqScP=T9B3??C>Y^8i<| zl`Ma>oFc*J>3$%SiK}T3Y9lz0bb~bsd$S&g$WTC#Bi+;7AF!JS*Dy(B_}OoJ4S6Eu z{to-Z&#*>wN9*FZ?#D%~BUXuo`chbA;6>Q)`BVYmJ@CBNiJ#;8J!H5{Y#TwiA0tdG zWEb%|amf;fvI2$DJZ?A9-Y%vXOw2Lr$PUi^O)f6V4lgiqL^8Qe+|tsbH7(V$XM9lV z%%;xd>{WX<{X?TOcHcfy7{fR>cpO~YG>dDFiHV`v6?7T>xmr6viokt+(KUyx)3%-> z3v7yoJTy<9mW-a=0){>h4eLmqsflpn&M6G~m#;`Q5s*q{mBiA<9=AJ!BVei6u!ygK z;9Gonx87*i_{XN;<6}#Gr3@t%#j#)4F7pGFE$dkD9^(1pVxbVvT`35nw25st8_nw8 zOP^hs%9?Wq8P%n0(Kz=7sMNKaqE^vD`Cnx&FSES5mk1ScnDYQ&QIKTFjJ*OWU@ z{d!(m?*zhg9X7pvd_;sYq>-31MoMdlgOQY?dmeKUr$R5im>G<6e9b4o=Gm$&q0Ay} z%$pvB`<4pKi<}R$XwU@gsySHb~_9cTf4VRL7ITIjQFVR7g2Pc}@~f zRd5a-asz_)kMJzvb%mxRv)K%PaPR#%J>O~PeT^qs0u#?b9J`D?g=$gTdUXSTRuuU3)(BoU3CE<5)kc!aaebjvbAQmPV!C_#Y;Umcjr4 delta 1957 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 diff --git a/demo_app/test/table/sizing_width_100_percent.png b/demo_app/test/table/sizing_width_100_percent.png index 63deb574e3d1dd15781f70f9bc8a8971fcc676a3..f396b4d9d562910a72c2fa4bf1d6b2d4bb67e49d 100644 GIT binary patch literal 3980 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 O0Cpulw18owkZ3Td7y@Fn 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 A&Hw-a diff --git a/demo_app/test/table/width_in_percent_100_nested.png b/demo_app/test/table/width_in_percent_100_nested.png index 66777e4298061fc1255799fdc68a76c21fa0d4c1..deecfdb7f1038a6267c5434bb1c69de7f294c29c 100644 GIT binary patch literal 2776 zcmeHJ{ZEru6h0IXgrR8XL|TxbBQX}Wpp_}MvBEmSXPncDqc*+>3IYP51uQKx6_J8W z;%D)56F0$1CBUpus?ok8qo|Am3N5p=l#i~!1PYY0ciAsS|AcXqlY8!SlauG3^E}Bd zh>BpiIJr9kfJ?|XK|29(OaPk_#|0RYw#oAnw%MfbWY9sZBo1H)yL5WUE=O$f9Ai%d zIOT-|ZQqqyX6y+UUOl)X_s_bQoI`ur3xi)?IMrDsl?NA)f}Vj-`RBNTr(Oc*nf#^l z+frMy`?5FQQP!WmUfI8+yBHKtd%uqTa-jUwhVUcJ(RBB6p)A>RY*fp)5fLpAS&-)nSPPfceG}j4k=NJ-FgON%l=gq%iBO-A!RjyK+pk+QN(9 zOFI#OIaE!qQn+bv=d71amfBHL-ahDD1;AW_gFn>m3ss`>jF>~dju2L=b*dzv9HJ*~ z2lg8xmtC}GOVb;yQsFin$oG{+VL(7rTADqCtzG=k7M@0!?S{fjSac~JxJ(79DOAaw@WCZgi2h)Lam^v7&fh#zr_8)YL;G7UfG zpJfU3lZ}K)qfF4vX-?8EkF@a0CT_MV>STW#$=tr@t5G{(mhghjW;~71Xf>u3TdhrJ z1qT9;YW_+!=yo6-4U@w7xe-(n*K&odaMRT5RHG+D*L&^}Obw<^-~CSe3Y`#&YBd|F z8R{%VNUlv%ZxPG%Yqbyit%2*z@9oEb0WcK=R*9wWULc-n`?JRgb)AiZIp&;XoS{t+ zl9hXpDVdKr#(<-}CM0fZY;^egH4mN1eIsjLI5~TeEYLlanpFseV+Nt_n{GgIxRO$SSpRu)PAk zw^`%I=S{{SGpZzn&*u+!)*#)M@f4xIG5~wCqNqc&fn)8vCP`=?(Eje>|4Wi`M` z*WD)oBzWrMD}B);M&@!Hv>8s|60fN8BCTUh&pd6Q*A4YxwjE6yzg`w=18sf3VYd-t zOy}qGyKUfrY0xgwy(2FLmAV4+$bZ(BzOn(xMZH|8xf?}GoI a3uf_8lGW#8%alUwcM2iF5kX=)JMSM0u?e>T literal 2865 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 WYz^?0ozQt0fP?#k_ObWG{Ppij({{xG literal 4375 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 Lhwq~Ah(GstO)!Yz literal 4383 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 literal 3369 zcmeH~Yg7_g9>A|!>4cA3x6DRk+T5Iznx-WtD4SWvWLjg5nueMvrDHxw(E!PHdX8v9 zrRJ-r_8{>Uh6;qvYATO$sjz&ffaYri#Rmw>?%6XR_QQUeuih{B+UFi&usnH^#A}f)DhqB0Wb^!z~Gk2I{i+{zHNp2$pH7gpAV=K+KlTLYj8fOlP3B> zG{Ia4z*LO#J#aF;WU4=bUY<&7pA95j+IpWUI5%a({`$cNPfvfCZ^GHr8=kJ&d}58j z{X&~7GsZG$=k~pcyoLc zlK{NTclqou7Y7N^j8QvzxC9x@;g%T7O9xX|bl5&2bn4S40OH#6RQmLyDQ^tHx0d=E zVhkbRzJH_vxc!wQxa^v>794jUzJqqb4?IxE{;3C&=Up3B?*}dy%-_t~MCSL1u4e)j z{=!B>aGU+ymfqj?MaY}BZLDeJ)U*Wb0t_p{rV#6F@+f-ispte!^p(Z6L-W5l`TY0j zoz(zzuGtL!_7RO7<@CCV5VV)bfyVY(BMT3gpbCHM>F`I>PbP{zW8%y`hAy8d{R*U$ z(gj(sG@TBLd9H4GTf4|(g~S?eoVW&;JXN2cAc&d*yAD}}-;OAO9yMwERB(Wr99x>hB5Bci zUhWRTFZr4sa(Rw;5Ed72092(L32#@JqW-&eLNE9NgNqzQbG_xIy56O_;>4|F9HZD!yf)cm4|odndGU=wbLp-W3#eLN|A{@1oKkCmY9NWc(u5Xlp@icdwN+ zm%Hq<)6^6r?SGN-frXVrwc}7_d}WEJ=FXiDBvzj!_#J;9F#0Rf*@~0km@9j-#@MN;)8dAfs>!26aUCp&6{wDe>iuvP5 zYNb~F%&uemH5&!(z`At`rCTgUEEBX^Ka2ZRe?IimXB3M1M4wp>jI*aJI6OZFsy$K> zSX^eIkul`P$aF+y3GutknBf+BC_!{C&lF4=A0D-)vv6g)E!poEi1A}RUhyC7P%`L# zq#IU9)M~!GKPZQJ*X$V_tlrLTj^rK5Ik_jQC6bC!RtQ2@UcL_{%zWxg>NgAJOe%;& z`~~dt-1sA}zkq7!mi&fETO2%Mus{!`!J4BK=km-zPOZcyWTc(a^#&peoJ#J_$|7o+ zy~_3ibcvFz!_(}JZg%dVl)sJ|D|*qjo8=hRp!MhqMv#9_{&$J~2Blw9+6vuDuZDBmNSM}bgWS_$WrW>EBkkNtZjt`t5||hIJ?nSWGtBTL zIDVR6aje)i^~<}B_ip_;GZ0ieQx+>P1$d6#FVDzafNzLkwBI=+fv6#-a9u!=zc!d-R2A4jm_Z0}TP*<*PzR{x&>s6zq1RX&k_ F{})wK)2{#k diff --git a/demo_app/test/table/width_redistribution_wide.png b/demo_app/test/table/width_redistribution_wide.png index 912b15d21845161440f6399bb7e6443ae999b436..a74182a6f60253fb03ac98ab4213a39460cd8db3 100644 GIT binary patch delta 3876 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 literal 6129 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 FzW_7~!_EKz diff --git a/demo_app/test/table/width_redistribution_wide2.png b/demo_app/test/table/width_redistribution_wide2.png index 426f51ed354bc5b08b016d9263b28dfc97ef8c90..cd6f440776c323b16dcabf9ff681cc720b560193 100644 GIT binary patch literal 6432 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 literal 6929 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 V7X-Nkyw(DFpM?F`a3cKYzXMCFyCDDo From df0ea48017ff92521685e11f8e945aec81652960 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 00:19:06 +0700 Subject: [PATCH 06/14] Fix collapsed border --- demo_app/test/table/collapsed_border.png | Bin 2972 -> 3684 bytes packages/core/lib/src/widgets/html_table.dart | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/demo_app/test/table/collapsed_border.png b/demo_app/test/table/collapsed_border.png index 674a69cef0e9c9af1e7d726c333948c54bbc5041..28d5d90793ceb309c3240e7c40b0acbebbc28085 100644 GIT binary patch delta 1957 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 diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 6a67b6795..d4e335694 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -415,7 +415,7 @@ class _TableRenderLayouter { final layoutSize = layouter(child, step1.widthConstraints); childSizes[i] = layoutSize; maxColumnWidths.setMaxColumnWidths(tro, data, layoutSize.width); - logger.fine('Got child#$i $layoutSize@${step1.widthConstraints}'); + logger.fine('[3] Got child#$i $layoutSize@${step1.widthConstraints}'); shouldLoop = true; } @@ -525,7 +525,7 @@ class _TableRenderLayouter { // layout with tight constraints to get the expected width final cc1 = BoxConstraints.tightFor(width: childWidth); childSize = layouter(child, cc1); - logger.fine('Got child#$i $childSize@$cc1'); + logger.fine('[4] Got child#$i $childSize@$cc1'); childSizes[i] = childSize; } @@ -687,6 +687,10 @@ class _TableDataStep1 { static double _calculateRemainingWidth( _TableRenderObject tro, int columnCount, double width) { + if (width.isZero) { + return 0; + } + final columnGapsSum = (columnCount + 1) * tro.columnGap; final gapsAndPaddings = tro.paddingLeft + columnGapsSum + tro.paddingRight; return width - gapsAndPaddings; From c4a75fd54419f7c2829172179c12f7249c7d3f47 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 05:05:00 +0700 Subject: [PATCH 07/14] Fix tests --- packages/core/test/tag_table_test.dart | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index b4ce28fdf..0db640a06 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -443,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); @@ -989,14 +989,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:')))); }); }); From 37b6eb2bc8f3aefeb55e9551a480727aaff1960e Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 05:21:16 +0700 Subject: [PATCH 08/14] Revert optimization to skip re-layout in step4 --- packages/core/lib/src/widgets/html_table.dart | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index d4e335694..e5de7fd13 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -383,8 +383,8 @@ class _TableRenderLayouter { final children = step1.children; final remainingMaxWidth = step1.remainingMaxWidth; + final cellSizes = List.filled(children.length, null); final childMinWidths = List.filled(children.length, null); - final childSizes = List.filled(children.length, null); final maxColumnWidths = step2.naiveColumnWidths.map((v) => v ?? .0).toList(); final minColumnWidths = List.filled(step1.columnCount, .0); @@ -396,7 +396,6 @@ class _TableRenderLayouter { (remainingMaxWidth == null || columnWidths.sum <= remainingMaxWidth)) { return _TableDataStep3( step2, - childSizes: childSizes, columnWidths: columnWidths, ); } @@ -409,11 +408,11 @@ class _TableRenderLayouter { final child = children[i]; final data = cells[i]; - if (childSizes[i] == null) { + if (cellSizes[i] == null) { // side effect // layout cells for the initial width final layoutSize = layouter(child, step1.widthConstraints); - childSizes[i] = layoutSize; + cellSizes[i] = layoutSize; maxColumnWidths.setMaxColumnWidths(tro, data, layoutSize.width); logger.fine('[3] Got child#$i $layoutSize@${step1.widthConstraints}'); shouldLoop = true; @@ -458,7 +457,6 @@ class _TableRenderLayouter { return _TableDataStep3( step2, - childSizes: childSizes, columnWidths: columnWidths, ); } @@ -506,7 +504,6 @@ class _TableRenderLayouter { final step1 = step2.step1; final cells = step1.cells; final children = step1.children; - final existingChildSizes = step3.childSizes; final childSizes = List.filled(children.length, Size.zero); final rowHeights = List.filled(step1.rowCount, .0); @@ -515,19 +512,13 @@ 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); - var childSize = existingChildSizes[i]; - if (childSize?.width == childWidth) { - // no need to re-layout if the width is the same - childSizes[i] = childSize!; - } else { - // side effect - // layout with tight constraints to get the expected width - final cc1 = BoxConstraints.tightFor(width: childWidth); - childSize = layouter(child, cc1); - logger.fine('[4] Got child#$i $childSize@$cc1'); - childSizes[i] = childSize; - } + final cc1 = BoxConstraints.tightFor(width: childWidth); + final childSize = layouter(child, cc1); + logger.fine('[4] Got child#$i $childSize@$cc1'); + childSizes[i] = childSize; // distribute cell height across spanned rows final rowHeight = @@ -713,12 +704,10 @@ class _TableDataStep2 { class _TableDataStep3 { final _TableDataStep2 step2; - final List childSizes; final List columnWidths; const _TableDataStep3( this.step2, { - required this.childSizes, required this.columnWidths, }); } From 8d18bda0edb298cb1a02514d849867ee1a2d7e5e Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 22:35:39 +0700 Subject: [PATCH 09/14] [skip ci] Switch to use sizing hints --- .../core/lib/src/internal/ops/tag_table.dart | 16 +-- packages/core/lib/src/widgets/css_sizing.dart | 19 +++- packages/core/lib/src/widgets/html_table.dart | 107 ++++++++---------- packages/core/test/tag_table_test.dart | 18 +-- 4 files changed, 70 insertions(+), 90 deletions(-) diff --git a/packages/core/lib/src/internal/ops/tag_table.dart b/packages/core/lib/src/internal/ops/tag_table.dart index fa7e5753a..5f53c2d69 100644 --- a/packages/core/lib/src/internal/ops/tag_table.dart +++ b/packages/core/lib/src/internal/ops/tag_table.dart @@ -85,19 +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, - minWidth: bc.minWidth, textDirection: resolved.directionOrLtr, children: List.from( data.builders @@ -108,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; } diff --git a/packages/core/lib/src/widgets/css_sizing.dart b/packages/core/lib/src/widgets/css_sizing.dart index 8e33dbc8c..4ef3993ed 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 are 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 e5de7fd13..72b7d4bee 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -4,6 +4,8 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; +import 'css_sizing.dart' show CssSizingHint; + /// A TABLE widget. class HtmlTable extends MultiChildRenderObjectWidget { /// The table border sides. @@ -19,12 +21,6 @@ class HtmlTable extends MultiChildRenderObjectWidget { /// Default: `0.0`. final double borderSpacing; - /// If non-null, overwrites the incoming [BoxConstraints.maxWidth]. - final double? maxWidth; - - /// If non-null, overwrites the incoming [BoxConstraints.minWidth]. - final double? minWidth; - /// Determines the order to lay children out horizontally. /// /// Default: [TextDirection.ltr]. @@ -36,21 +32,22 @@ class HtmlTable extends MultiChildRenderObjectWidget { this.borderCollapse = false, this.borderSpacing = 0.0, required super.children, - this.maxWidth, - this.minWidth, this.textDirection = TextDirection.ltr, super.key, }); @override - RenderObject createRenderObject(BuildContext context) => _TableRenderObject( - border, - textDirection, - borderCollapse: borderCollapse, - borderSpacing: borderSpacing, - maxWidth: maxWidth, - minWidth: minWidth, - ); + 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) { @@ -66,8 +63,6 @@ class HtmlTable extends MultiChildRenderObjectWidget { ); properties .add(DoubleProperty('borderSpacing', borderSpacing, defaultValue: 0.0)); - properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: null)); - properties.add(DoubleProperty('minWidth', minWidth, defaultValue: null)); properties.add( DiagnosticsProperty( 'textDirection', @@ -79,12 +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) - ..setMinWidth(minWidth) + ..setMaxWidth(hint?.maxWidth) + ..setMinWidth(hint?.minWidth) ..setTextDirection(textDirection); } } @@ -333,26 +329,28 @@ class _TableRenderLayouter { child = data.nextSibling; } + final columnGapsSum = (columnCount + 1) * tro.columnGap; + final gapsAndPaddings = tro.paddingLeft + columnGapsSum + tro.paddingRight; + + double? availableWidth; final maxWidth = tro._maxWidth ?? constraints.maxWidth; + if (maxWidth.isFinite && maxWidth > 0) { + availableWidth = maxWidth - gapsAndPaddings; + } - var wc = const BoxConstraints(); - final troMinWidth = tro._minWidth; - if (troMinWidth != null && troMinWidth > 0) { - // only apply width constrains if a specific min value has been set - // this will be used mostly in percentage calculations - wc = BoxConstraints(maxWidth: maxWidth, minWidth: troMinWidth); + 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, - remainingMaxWidth: - _TableDataStep1._calculateRemainingWidth(tro, columnCount, maxWidth), - remainingMinWidth: _TableDataStep1._calculateRemainingWidth( - tro, columnCount, wc.minWidth), + requiredWidth: requiredWidth, rowCount: rowCount, - widthConstraints: wc, ); } @@ -360,9 +358,9 @@ class _TableRenderLayouter { final cells = step1.cells; final naiveColumnWidths = List.filled(step1.columnCount, .0); - final remainingMinWidth = step1.remainingMinWidth; - if (remainingMinWidth != null && step1.columnCount > 0) { - final cellMinWidth = remainingMinWidth / step1.columnCount; + 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); @@ -379,9 +377,9 @@ class _TableRenderLayouter { _TableDataStep3 step3MinIntrinsicWidth(_TableDataStep2 step2) { final step1 = step2.step1; + final availableWidth = step1.availableWidth; final cells = step1.cells; final children = step1.children; - final remainingMaxWidth = step1.remainingMaxWidth; final cellSizes = List.filled(children.length, null); final childMinWidths = List.filled(children.length, null); @@ -393,7 +391,7 @@ class _TableRenderLayouter { // it only considers min value when the columns don't fit var columnWidths = maxColumnWidths; if (columnWidths.zeros.isEmpty && - (remainingMaxWidth == null || columnWidths.sum <= remainingMaxWidth)) { + (availableWidth == null || columnWidths.sum <= availableWidth)) { return _TableDataStep3( step2, columnWidths: columnWidths, @@ -411,10 +409,10 @@ class _TableRenderLayouter { if (cellSizes[i] == null) { // side effect // layout cells for the initial width - final layoutSize = layouter(child, step1.widthConstraints); + final layoutSize = layouter(child, constraints); cellSizes[i] = layoutSize; maxColumnWidths.setMaxColumnWidths(tro, data, layoutSize.width); - logger.fine('[3] Got child#$i $layoutSize@${step1.widthConstraints}'); + logger.fine('[3] Got child#$i $layoutSize@$constraints'); shouldLoop = true; } @@ -446,9 +444,9 @@ class _TableRenderLayouter { } } - if (remainingMaxWidth != null) { + if (availableWidth != null) { columnWidths = redistributeValues( - available: remainingMaxWidth, + available: availableWidth, maxValues: maxColumnWidths, minValues: minColumnWidths, ); @@ -470,7 +468,7 @@ class _TableRenderLayouter { required List minColumnWidths, }) { final step1 = step2.step1; - final remainingMaxWidth = step1.remainingMaxWidth; + final availableWidth = step1.availableWidth; final widthSum = columnWidths.sumRange(data); final maxWidthSum = maxColumnWidths.sumRange(data); @@ -478,12 +476,12 @@ class _TableRenderLayouter { // cell has been allocated more than its requested value // skip measuring if not absolutely needed because it's expensive - if (remainingMaxWidth == null) { - // unbounded width constraints + if (availableWidth == null) { + // unlimited available space return null; } - if (columnWidths.sum <= remainingMaxWidth) { + if (columnWidths.sum <= availableWidth) { // current widths are good enough return null; } @@ -658,34 +656,21 @@ class _TableRenderLayouter { @immutable class _TableDataStep1 { + final double? availableWidth; final List<_TableCellData> cells; final List children; final int columnCount; - final double? remainingMaxWidth; - final double? remainingMinWidth; + final double? requiredWidth; final int rowCount; - final BoxConstraints widthConstraints; const _TableDataStep1({ + required this.availableWidth, required this.cells, required this.children, required this.columnCount, - required this.remainingMaxWidth, - required this.remainingMinWidth, + required this.requiredWidth, required this.rowCount, - required this.widthConstraints, }); - - static double _calculateRemainingWidth( - _TableRenderObject tro, int columnCount, double width) { - if (width.isZero) { - return 0; - } - - final columnGapsSum = (columnCount + 1) * tro.columnGap; - final gapsAndPaddings = tro.paddingLeft + columnGapsSum + tro.paddingRight; - return width - gapsAndPaddings; - } } @immutable diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index 0db640a06..008c12159 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -686,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; @@ -994,7 +978,7 @@ Future main() async { final goldenSkipEnvVar = Platform.environment['GOLDEN_SKIP']; final goldenSkip = goldenSkipEnvVar == null - ? Platform.isLinux + ? Platform.isMacOS ? null : 'Linux only' : 'GOLDEN_SKIP=$goldenSkipEnvVar'; From d0f70fd33fa049bdea2bdcc6c96f9e610a2f2b1c Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 22:40:12 +0700 Subject: [PATCH 10/14] Oops --- packages/core/test/tag_table_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index 008c12159..531d95ca0 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -978,7 +978,7 @@ Future main() async { final goldenSkipEnvVar = Platform.environment['GOLDEN_SKIP']; final goldenSkip = goldenSkipEnvVar == null - ? Platform.isMacOS + ? Platform.isLinux ? null : 'Linux only' : 'GOLDEN_SKIP=$goldenSkipEnvVar'; From 781ec5016497ec2f5572372930e8dc17cd985d5a Mon Sep 17 00:00:00 2001 From: Cirrus CI Date: Sun, 20 Apr 2025 15:43:39 +0000 Subject: [PATCH 11/14] [skip ci] Update goldens --- demo_app/test/table/aspect_ratio_img.png | Bin 5423 -> 4890 bytes demo_app/test/table/sizing_height_1px.png | Bin 4134 -> 4081 bytes demo_app/test/table/width_in_percent.png | Bin 3270 -> 3249 bytes .../width_in_percent_100_nested_stretch.png | Bin 4126 -> 4049 bytes .../width_in_percent_100_nested_with_gaps.png | Bin 4136 -> 4126 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demo_app/test/table/aspect_ratio_img.png b/demo_app/test/table/aspect_ratio_img.png index fb72e7f739699823c8affea914670cc42ef4317b..524620f6bd791aec4b9e9ca40fb3a63078dfacba 100644 GIT binary patch literal 4890 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 Mkk7%A{h06m4*3TQr~m)} literal 5423 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 delta 2382 zcmV-U39ZJW4>L{8BmUsom4C0a%8gh<+ z7>M_pN<Zu%dFRHt@Fp;zrCO5x1Yb>>-p`opDyiNI}SPm06>|hH+upA0RP_z zlfeltf7l)cR(pGU&b{!weD|JduN#~G@88Q;zW&w9xd8yYE$vZYtz5Y>%a$+Cy!+>; z!*4_b0PNBp1=gY`7UgfQxi*_OZ_Y1%`OAGbD*%AEu}%lpf9=?jx%1}bl%c0&%;+<- z=Q^$nbwsYbYI2@=_L;rCW&nVFs?&kB zbm`J`>)JKP9&=2F3>lJn^XFy9jvYH4Gi~}k>D{YW?wWdM&K-YFK7Gl>*|2d#l4Q-= zf3=w~X<|mUo{`xz?oDe;YbH#Zn3p!ZI^Hs(B~Lv0WaG7-dG6U|*b?eq7$)d*>W!OiDB}snzv!7=F{r1cG=boQK4ml(r8v3D(`}ny0 z_^BUPeii@#B{~&YZEbCtHFtJ~3?7ms>DH}V#*99*5l?^cu6Mm_r|lDtKRz$LfAmt4 z&RX?`K0&f=S!Dl^XAQYVBvxc955hBvUc6NJpSYp z8Qwag@i%?O_p)*0#y{uU0RZ-iZk;*k*~QOg_3G7`bopiJ()4PRZQHgj2Oo5BF1=)8 z-tmri?DD)F?fZxqszCEMP7?}gRAJ`cC z_?WZu*()aRbpHPiIskyTf=&h2qmMqC>#w~o=bm#;V_$oFM=qXtaTfo4aRv?;n7kHU ze{AK-l^Hx}aFV3Y(S5RF#fpp=etKhk*|KFh?%3lR+d~Eo&Lx*k%E zM;viPX3d$M?%lgLVs88P?P+dq-uo*D0N6)%yF|EU>z2%#Gb^VK8TN}}qBtr)eNpo{^zIoHPvVQ>XaD@*WGY^ zo_^-(`cDJ^;Lo(%z@!df7TH#Ise@AbMQe2 zHTE?(H|NH${bOGK?aMjm!t?U^FMc5(JMCjR`TZwXdB% zq{}aRQ{Nu|U{6>ge*^$1)~Ro>{@{&XF0?EN0K6UTQDEf_TrRXM2mriYb!v(5_B-!r ze0z1`N&WKa37^Td>G$OKzyE!w-sFWBUP$jg@69W(yz=MG769OFpwstYed-f`l_Ys& z;lsJ+s;e{izPXt@@4kIGHvoXQrA{vq?zjJbNs=KS9@^OVf8(D#mFsS}zSD1Z;z|AX zXmaDv9=}J&0|2}g?9n|~e|-Pd{O{kN`{vKflyBXfBx!4F%U$2SJNM3>mA^Rn;G8{n zT+SMER+^fc^1=%*CZ}004^Y)ngjguV0@T zGiPK}>luxGH{Eh`Hf-FG+isqcFMi>RnK5f-9$oa{CmM&kGK_48nH&X`y*yp;m zZ+)#={)D&6liW}G%aigiH~w?p_rCY#?DNjaKm7fdbHee*zuD6Q0C=6nQ3ilZ5;o=f(P=$M}L&Bf8}dwYirA};iqQKy|eS!qDAS_rAxMK z*^*}$KbQUX-#?o+ZOSoy`s{MP003{cJ-W&LupWmcNe=6AST6a@gnX>^^h}y~X_DlK zBaX=QyQl4RPE*&eyL_$Y=H}OpwRd!+t*tFdfAY?EzB4T&TJrqLm3iXHCo=i+E3<9; zw%j)L+d1TrL()2;CEdF1@guwd0NxOLT`3)Tb!D-sOH+j*cu_ zf4(f;yLZnA2MpZXX#)W4bDh4)ee2e3*|cd>Hf`FJmB08!Zn2YX} zOuqceeB+;P%&K3l%7%>_@~_|gx7_o+dv^I+V@98uyQbZphaP!28-Kkq3l=WOj9D`? zYUIeqG5!1X&(u3^&*{U5r>Uta-MV&7e``x?zJ2@D^zGZX=IQ|e_JK|Z)_3myP6iGg zlz~GBmC&o#!cyyA+Sc*2R9e9cw)^n}l(scTclkK6Tgta|qBnOkp~ zk~wqdWbF8HS@_U{x#PB}jc>n_q<61g>EEw^27X{bW8a{GgL3lwPtK7&kKFq!6b1m; z$9DT)ga82SnZ0@r761T$nzNA!N(Pf~3P%?GHvvkw=0$MQkN^Mx07*qoM6N<$f~Lb3 AU;qFB diff --git a/demo_app/test/table/width_in_percent.png b/demo_app/test/table/width_in_percent.png index a25ef24ed95ba9b2cf9cdd5648b8361ce0c35697..22ee9f6e6c4e979d5842275625a4b0eaff4647fe 100644 GIT binary patch delta 1507 zcmV<91swXu8L=6VL4R9GL_t(|obBC9jGc8I$Kl_ZIcM(EX-jX46i_54g@g?zm?*7@ z8gB$xXk3U&l!zfQhMgN1E_6qTn3yO5qH*DdsKLv^R2I5{jS<*@ffl59+L<}ixt)uP zfoVbQ^*bF0pJ(@;_sq#}lDFySyzl>gr_r15_X_}kn1S^k00aQw-A0qq1{;5Cp6?CU z-f;bunFIh}gE;Wg%jevG-oUz$4*>x9e{mrvpIjmY00_IFGgxnNxsZ)$@9lf*iANu+ z{eRwHU;X;M>pczt8`Q;I(YvU?s;WBp&sQ$?M_}FT|Hwz{v9q@K+`6a!aLZHcI1vCF z(KSE4?xNoB5+MLUn7{%62orx;003bE3jiSOq8GWp<*|uP^}VUB|MvR#Po1c*%*|fz zT(G7FmImtTCw8xHFK=0{#a#>4-ZN9nTb9>#HUKuhOAf56s(a>U>w(!*Z+mUL-@n|M z;EFl=`NP$jT&_m9QKJXOYU}>(b?kG8t2fkJ@6iC*z%DDW#`?Y5)$M=grhzN0JKC-8 z_{uRnd(%u!{(Vz5Pqk`k$KraA2EYb(S%Gyfi;YJ8e0;K=9Gj?KRo#8MUH8n**6>+p zxPCu6R=*sZte2au`qaYdy01N5I|Uo-s6SBE=r&fjhmH@`#B-Z!_|Ql#ZC|X}n`dfi z=SqAH9UHE#Pj9RCO*4Nr{=#IPy#07BUA451(*y9oV$Bx0KRmg)UT6)~BX1n5AHQ*| zo@)))qZ6A}_y2KZtbQ^vRS(Xds$U&HT$_8{`tIhds#A?~elDzqMz2xhFHTf%v|CHt zRw8L|u36iEx2sNnaITKr^?IGYv0dB#w7muv&iu1!oorR3)2M$FpEz2}Q`T+)u;Q}L zVEtlzvVJ={zPi0 z#HM;+cDim^S~(kVe|x6Bux(d8Gdx_kEiPQ{?*$iR$5T72->4c~9H_?fKpp+;;p(?m z)?f98yLIHQ*Qn!-RacsZl?|n4%TqLUw;`MsUMy?e%8(<4EIyl&@+b(A) zxCkdcetcz-d%sbw6GOH2>1}oFGe@d3wOsvXzXlctYs-J%rmFSEP&GP@YMyLWqj#pJ z`U8D&1;D>qlSS^Wsv3I7-Gu$BTCPSdHyYKfm3@QnxZ$wZsOmKQZ^e~!_9FMrM5l%i zjnwGD(VD$^xtg=hx@!NnIC{NSUmshXuNPab)%~4Dqn;fascSo(|MIDDg}mALtrJ7FxMOkUj>3U{ zRllmy@dW^Y^IMa<2)B2;^_`hh_0Xox^{v_I>Q~jnlT-EW*;BQxw{o`N-u6uWXmWFH z?e%I$w_8t+jn{a;SGO)%f5nwExG+%t)?ih?QA2;nhHB#Z$vS%Hp{lCtj(2P1wb2@W zeWZG0-5UGH_{yb1kH`YxJl5b|YpYq;O9JLl)>%V#~|ec!@-wHpKV zgH2oN(BNQwa^ZA6bn^Jy9^(LOZO3m`F8OsPI<>TOv5tNE$m*jOmbNd}^oLK@)U#Wv z-|Sk|+=tpVbIWu!I{v~G0Oxkef%Uca%sKau_WN~zd%Es#PyfgLjjFn1ey;AApS#o% z;F9%*diClzUODgk=5B1)+>PxsFTDTE@w&8qu?~IdwY3@%fDO!7ag!kj6;r$Dy9jq* zecjqj0&C&GtF`yK53FuJ|IG7s%`=W+0M^z;1=fL=US7LNV2$nDyU#HUz!l*VApk(w z1)agV_J-@%ei8tHcZo)C-ruGH07!C)5VO$--UPFt2c-cP>|b;mx(`z2Gq?Z%002ov JPDHLkV1ir;Hs1gM delta 1528 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 literal 4126 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 WYz^?0ozQt0fP?#k_ObWG{Ppij({{xG diff --git a/demo_app/test/table/width_in_percent_100_nested_with_gaps.png b/demo_app/test/table/width_in_percent_100_nested_with_gaps.png index 191a55a8b5a55bd6c503892791c78c8c0ca6e23c..a850c09b3f7211184288eea17f0866d28439ada2 100644 GIT binary patch literal 4126 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 WYz^?0ozQt0fP?#k_ObWG{Ppij({{xG delta 2558 zcmX|Dd05j&8XjN;ik#Yn)+s8%lzzBjImX!!0Akq*ZlAnrVtpaUP zxk(j6LJ|_N1|%VzN>ng_kOTq=AP6<#in)-Gu%Wx#?|J5*nR#Zu_nYs1=dIXE+WPZB z=-sg+2hXIJ&5E%1L>J3BvgF~$-u+dN9exwW*W4?z`hDx>3l=u4)BikaYGA{^yvauR z?oh)T(TuUD#^gpDNpYjs+7$IjibAg}ocd$+6Ah5+Q)7i=@Php6$% zF30DJzTW4Wk$nk?q*w&BK#;o;uswpcppwbN{V?xE*9@a{)eu6eIER>c7v(wfCZ( z9bq;Jg+k+tmLMkG{$xz9qX*N{S5Z5X5Y>@ffu%9)e}H)L#9(^LM5l$&Z$*0qq3v+- zKUd%q>Rq2TFkh@n`NXKpr&!TSs}Z{W4g`n8p^TY6wEWkX7WuNliF{r=(uQXe>|JNQYe|ziBjZG+ z&8=fiuHM~AO9@d-^D@vIrizn2&F%5e7rw{12?MMkl+I)IK>_?+%6htys zJqPRbQ5D5XI04J2;BeR?e*FMk4o!LO>ntes5^xaFQN*6b%UM$CO1MXG=_x0CRt8E` zkIMHJE2_MBD~VShi!lm~B$_V{iH=Y|$mv|{aMGO=T>T`pTj4kGnV#wah8ev&B8kPo zed@DLU;bgdISfN*5&bW}xx>zPo#N7#R$P6$lGp@mx3I7fF(k{&oW8#kJ==a% z`SN8ndDKsRUa3$FNEpZjUDIc@;?#G%Vdvu{S42`*^y(SDnbm9PVwH2oQK2R z+}wBr0|ULbqo2hXNperiZ*gV&D=lG@y*_e{v|$A#LbSPri7V^66x9*KTc?oA#5N@(*|1sfY#?#j1f$t&8m(NC_eC z_tRtfM%rD>NE3;a*-knv3W~$l=n0smEgdC!1P8Fky;b`=*KwSpw|{q!3dhutYliE2 z9r^yJ8%9(gn2V3^YP3uP(9vS_gh?!5^Xb5g9rKS&O+p_xk{Hczk24faaM%6Jx&NKLctW009&{=n4^l18T=U<1X zNI#YA)jrd*&A~N))#t7XwfX^dD3m)ymm7g5JFi9~aC25}MGe>@nLRXo1GHXGYK5-D z4?mB*6tMxM!)lMN1sj}e0cii5_5T$9t}(xyGEdegs7j|cVuP;Ofon$LlaV*wF|Tjg z2$nPCOMYHy-GhpK0GLqI{}N$^{uH|X;mq}XZn>{i#Rs>Vd&f|z`_4bwb zFvh2PD~7gsmNCPRkTg4KpEw7Xg~8#1-O%|nP?oS7-S*jLAi~oB`B{2oh+uMnXvhRHE?{^!JB|SWILn2IJ|e zP1#wgCwVGYk7jiyQx7OR?$umd=J3sRyrH3Udh$rKXvn}&H0mQ+)o_BEZRtY__Ln^o zDkwp04vWQ-w%v9lzbZ{81KTZk@B7~7`(@8%%p*LlW7^LbZSLKMflUiV{XqO ziNr1dcNGqgO#8@5_*j@+oxL6x=y2uLHf0T@Ih*U?QI%KfgC;#(2lm7qw$|4yl~xo< z5zwl=m~EC*jnXQ_Yaa6PK#qyF=C$LY-U9Q3*0^*3Pq z^QD;8Yog?ffAm!%=VrV;FT<-R-CxL~jOW~lZRYpo0B z_%ZYTpXFRw@~bIBFlb|BN!2@-;&baj>z)gDH>}zZdW^+~`Y}pfVbXO=102McAPH$Z-BHNz26~(ePfSi^;X^Vi|4MEH| ob^j;A?+vCW*A#3uziqu@5 Date: Sun, 20 Apr 2025 22:51:52 +0700 Subject: [PATCH 12/14] Clean up PR --- .../width_in_percent_100_nested_stretch.png | Bin 4049 -> 0 bytes .../width_in_percent_100_nested_with_gaps.png | Bin 4126 -> 0 bytes packages/core/lib/src/widgets/css_sizing.dart | 2 +- packages/core/lib/src/widgets/html_table.dart | 5 +++- packages/core/test/tag_table_test.dart | 26 ------------------ 5 files changed, 5 insertions(+), 28 deletions(-) delete mode 100644 demo_app/test/table/width_in_percent_100_nested_stretch.png delete mode 100644 demo_app/test/table/width_in_percent_100_nested_with_gaps.png diff --git a/demo_app/test/table/width_in_percent_100_nested_stretch.png b/demo_app/test/table/width_in_percent_100_nested_stretch.png deleted file mode 100644 index 57ce45957bd0943b0c84864a544e96ee6f831e43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4049 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 WYz^?0ozQt0fP?#k_ObWG{Ppij({{xG diff --git a/packages/core/lib/src/widgets/css_sizing.dart b/packages/core/lib/src/widgets/css_sizing.dart index 4ef3993ed..e0855750d 100644 --- a/packages/core/lib/src/widgets/css_sizing.dart +++ b/packages/core/lib/src/widgets/css_sizing.dart @@ -287,7 +287,7 @@ class _RenderCssSizing extends RenderProxyBox { minWidth: stableChildSize?.width ?? preferredWidth ?? minWidth, ); - // after everything... if the incoming are tight then we must follow it + // 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; diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 72b7d4bee..8171b93cc 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -4,7 +4,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; -import 'css_sizing.dart' show CssSizingHint; +import 'css_sizing.dart'; /// A TABLE widget. class HtmlTable extends MultiChildRenderObjectWidget { @@ -332,12 +332,15 @@ class _TableRenderLayouter { 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) { 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) { diff --git a/packages/core/test/tag_table_test.dart b/packages/core/test/tag_table_test.dart index 531d95ca0..e22a088ac 100644 --- a/packages/core/test/tag_table_test.dart +++ b/packages/core/test/tag_table_test.dart @@ -1201,32 +1201,6 @@ Below''',
-''', - 'width_in_percent_100_nested_with_gaps': ''' - - - - - -
Foo foo foo
- - - - -
Foo
-
''', - 'width_in_percent_100_nested_stretch': ''' - - - - -
Foo foo foo
- - - - -
Foo
-
''', 'width_in_px': ''' From 3961b78dfb791cfabff7e84fe70cc96daa6acbcf Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 22:57:05 +0700 Subject: [PATCH 13/14] Optimize step4 to skip re-layout if width matches --- packages/core/lib/src/widgets/html_table.dart | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 8171b93cc..672697e9d 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -397,6 +397,7 @@ class _TableRenderLayouter { (availableWidth == null || columnWidths.sum <= availableWidth)) { return _TableDataStep3( step2, + cellSizes: cellSizes, columnWidths: columnWidths, ); } @@ -458,6 +459,7 @@ class _TableRenderLayouter { return _TableDataStep3( step2, + cellSizes: cellSizes, columnWidths: columnWidths, ); } @@ -504,22 +506,27 @@ class _TableRenderLayouter { final step2 = step3.step2; final step1 = step2.step1; final cells = step1.cells; + final cellSizes = step3.cellSizes; final children = step1.children; final childSizes = List.filled(children.length, Size.zero); final rowHeights = List.filled(step1.rowCount, .0); for (var i = 0; i < children.length; i++) { + final cellSize = cellSizes[i]; 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); - final cc1 = BoxConstraints.tightFor(width: childWidth); - final childSize = layouter(child, cc1); - logger.fine('[4] Got child#$i $childSize@$cc1'); - childSizes[i] = childSize; + Size childSize; + if (cellSize != null && cellSize.width == childWidth) { + childSize = cellSize; + } else { + final cc1 = BoxConstraints.tightFor(width: childWidth); + childSize = layouter(child, cc1); + logger.fine('[4] Got child#$i $childSize@$cc1'); + childSizes[i] = childSize; + } // distribute cell height across spanned rows final rowHeight = @@ -692,10 +699,12 @@ class _TableDataStep2 { class _TableDataStep3 { final _TableDataStep2 step2; + final List cellSizes; final List columnWidths; const _TableDataStep3( this.step2, { + required this.cellSizes, required this.columnWidths, }); } From db553783f03fb3516379873752d65407642a83ce Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sun, 20 Apr 2025 23:40:48 +0700 Subject: [PATCH 14/14] Revert "Optimize step4 to skip re-layout if width matches" This reverts commit 3961b78dfb791cfabff7e84fe70cc96daa6acbcf. --- packages/core/lib/src/widgets/html_table.dart | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/core/lib/src/widgets/html_table.dart b/packages/core/lib/src/widgets/html_table.dart index 672697e9d..8171b93cc 100644 --- a/packages/core/lib/src/widgets/html_table.dart +++ b/packages/core/lib/src/widgets/html_table.dart @@ -397,7 +397,6 @@ class _TableRenderLayouter { (availableWidth == null || columnWidths.sum <= availableWidth)) { return _TableDataStep3( step2, - cellSizes: cellSizes, columnWidths: columnWidths, ); } @@ -459,7 +458,6 @@ class _TableRenderLayouter { return _TableDataStep3( step2, - cellSizes: cellSizes, columnWidths: columnWidths, ); } @@ -506,27 +504,22 @@ class _TableRenderLayouter { final step2 = step3.step2; final step1 = step2.step1; final cells = step1.cells; - final cellSizes = step3.cellSizes; final children = step1.children; final childSizes = List.filled(children.length, Size.zero); final rowHeights = List.filled(step1.rowCount, .0); for (var i = 0; i < children.length; i++) { - final cellSize = cellSizes[i]; 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); - Size childSize; - if (cellSize != null && cellSize.width == childWidth) { - childSize = cellSize; - } else { - final cc1 = BoxConstraints.tightFor(width: childWidth); - childSize = layouter(child, cc1); - logger.fine('[4] Got child#$i $childSize@$cc1'); - childSizes[i] = childSize; - } + final cc1 = BoxConstraints.tightFor(width: childWidth); + final childSize = layouter(child, cc1); + logger.fine('[4] Got child#$i $childSize@$cc1'); + childSizes[i] = childSize; // distribute cell height across spanned rows final rowHeight = @@ -699,12 +692,10 @@ class _TableDataStep2 { class _TableDataStep3 { final _TableDataStep2 step2; - final List cellSizes; final List columnWidths; const _TableDataStep3( this.step2, { - required this.cellSizes, required this.columnWidths, }); }