From 4d1667cee240fe7edc0ae93883763a1a6587533e Mon Sep 17 00:00:00 2001 From: TheCarpetMerchant Date: Tue, 15 Aug 2023 20:50:54 +0200 Subject: [PATCH 1/4] Added the 'max-width' css attribute --- lib/src/css_box_widget.dart | 18 +++++++++++++++++- lib/src/css_parser.dart | 6 ++++++ lib/src/style.dart | 10 ++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/src/css_box_widget.dart b/lib/src/css_box_widget.dart index c6870a3929..1fddafda36 100644 --- a/lib/src/css_box_widget.dart +++ b/lib/src/css_box_widget.dart @@ -59,8 +59,24 @@ class CssBoxWidget extends StatelessWidget { final direction = _checkTextDirection(context, textDirection); final padding = style.padding?.resolve(direction); + Width? maxWidthCalculated; + if (style.maxWidth != null && style.width != null) { + if (style.maxWidth!.unit == Unit.percent && + style.width!.unit == Unit.px) { + // If our max is a percentage, we want to look at the size available and not be bigger than that. + try { + double width = + MediaQuery.of(context).size.width * (style.maxWidth!.value / 100); + maxWidthCalculated = Width(width, style.width!.unit); + } catch (_) {} + } else if (style.width!.unit == style.maxWidth!.unit && + style.width!.value > style.maxWidth!.value) { + maxWidthCalculated = Width(style.maxWidth!.value, style.maxWidth!.unit); + } + } + return _CSSBoxRenderer( - width: style.width ?? Width.auto(), + width: maxWidthCalculated ?? style.width ?? Width.auto(), height: style.height ?? Height.auto(), paddingSize: padding?.collapsedSize ?? Size.zero, borderSize: style.border?.dimensions.collapsedSize ?? Size.zero, diff --git a/lib/src/css_parser.dart b/lib/src/css_parser.dart index 57169787bc..c01b182e8b 100644 --- a/lib/src/css_parser.dart +++ b/lib/src/css_parser.dart @@ -654,6 +654,10 @@ Style declarationsToStyle(Map> declarations) { style.width = ExpressionMapping.expressionToWidth(value.first) ?? style.width; break; + case 'max-width': + style.maxWidth = ExpressionMapping.expressionToWidth(value.first) ?? + style.maxWidth; + break; } } }); @@ -1228,6 +1232,8 @@ class ExpressionMapping { double.parse(value.text.replaceAll(RegExp(r'\s+(\d+\.\d+)\s+'), '')); Unit unit = _unitMap(value.unit); return LengthOrPercent(number, unit); + } else if (value is css.PercentageTerm) { + return LengthOrPercent(double.parse(value.text), Unit.percent); } //Ignore un-parsable input diff --git a/lib/src/style.dart b/lib/src/style.dart index 3d293de8b0..a56a162cb5 100644 --- a/lib/src/style.dart +++ b/lib/src/style.dart @@ -192,6 +192,12 @@ class Style { /// Default: Width.auto() Width? width; + /// CSS attribute "`max-width`" + /// + /// Inherited: no, + /// Default: null + Width? maxWidth; + /// CSS attribute "`word-spacing`" /// /// Inherited: yes, @@ -261,6 +267,7 @@ class Style { this.verticalAlign = VerticalAlign.baseline, this.whiteSpace, this.width, + this.maxWidth, this.wordSpacing, this.before, this.after, @@ -353,6 +360,7 @@ class Style { verticalAlign: other.verticalAlign, whiteSpace: other.whiteSpace, width: other.width, + maxWidth: other.maxWidth, wordSpacing: other.wordSpacing, before: other.before, after: other.after, @@ -438,6 +446,7 @@ class Style { VerticalAlign? verticalAlign, WhiteSpace? whiteSpace, Width? width, + Width? maxWidth, double? wordSpacing, String? before, String? after, @@ -481,6 +490,7 @@ class Style { verticalAlign: verticalAlign ?? this.verticalAlign, whiteSpace: whiteSpace ?? this.whiteSpace, width: width ?? this.width, + maxWidth: maxWidth ?? this.maxWidth, wordSpacing: wordSpacing ?? this.wordSpacing, before: beforeAfterNull == true ? null : before ?? this.before, after: beforeAfterNull == true ? null : after ?? this.after, From 3e5b069067027713e15612e5a4f313a20a5b7732 Mon Sep 17 00:00:00 2001 From: TheCarpetMerchant Date: Tue, 15 Aug 2023 20:51:44 +0200 Subject: [PATCH 2/4] Made network image be shrinkWrapped to work with auto margins in Flutter 3.10 --- lib/src/builtins/image_builtin.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/builtins/image_builtin.dart b/lib/src/builtins/image_builtin.dart index d07b3051a3..d692d75bef 100644 --- a/lib/src/builtins/image_builtin.dart +++ b/lib/src/builtins/image_builtin.dart @@ -199,6 +199,7 @@ class ImageBuiltIn extends HtmlExtension { return CssBoxWidget( style: imageStyle, childIsReplaced: true, + shrinkWrap: true, child: Image.network( element.src, width: imageStyle.width?.value, From b6d117301c8731947d71be943078e3e325030202 Mon Sep 17 00:00:00 2001 From: TheCarpetMerchant Date: Fri, 29 Sep 2023 16:50:49 +0200 Subject: [PATCH 3/4] Changed shrinkWrap for BoxFit.contain, seemingly achieves the same --- lib/src/builtins/image_builtin.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/builtins/image_builtin.dart b/lib/src/builtins/image_builtin.dart index d692d75bef..bc137bb7f8 100644 --- a/lib/src/builtins/image_builtin.dart +++ b/lib/src/builtins/image_builtin.dart @@ -199,12 +199,11 @@ class ImageBuiltIn extends HtmlExtension { return CssBoxWidget( style: imageStyle, childIsReplaced: true, - shrinkWrap: true, child: Image.network( element.src, width: imageStyle.width?.value, height: imageStyle.height?.value, - fit: BoxFit.fill, + fit: BoxFit.contain, headers: networkHeaders, errorBuilder: (ctx, error, stackTrace) { return Text( From db25c352dc4a0df4706929dc72b87994690f0d00 Mon Sep 17 00:00:00 2001 From: TheCarpetMerchant Date: Tue, 3 Oct 2023 18:56:25 +0200 Subject: [PATCH 4/4] maxWidth calculation in _calculateMaxedWidth, annotated --- lib/src/css_box_widget.dart | 42 ++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/lib/src/css_box_widget.dart b/lib/src/css_box_widget.dart index 1fddafda36..8cbe9afbb4 100644 --- a/lib/src/css_box_widget.dart +++ b/lib/src/css_box_widget.dart @@ -59,24 +59,9 @@ class CssBoxWidget extends StatelessWidget { final direction = _checkTextDirection(context, textDirection); final padding = style.padding?.resolve(direction); - Width? maxWidthCalculated; - if (style.maxWidth != null && style.width != null) { - if (style.maxWidth!.unit == Unit.percent && - style.width!.unit == Unit.px) { - // If our max is a percentage, we want to look at the size available and not be bigger than that. - try { - double width = - MediaQuery.of(context).size.width * (style.maxWidth!.value / 100); - maxWidthCalculated = Width(width, style.width!.unit); - } catch (_) {} - } else if (style.width!.unit == style.maxWidth!.unit && - style.width!.value > style.maxWidth!.value) { - maxWidthCalculated = Width(style.maxWidth!.value, style.maxWidth!.unit); - } - } - return _CSSBoxRenderer( - width: maxWidthCalculated ?? style.width ?? Width.auto(), + width: + _calculateMaxedWidth(context, style) ?? style.width ?? Width.auto(), height: style.height ?? Height.auto(), paddingSize: padding?.collapsedSize ?? Size.zero, borderSize: style.border?.dimensions.collapsedSize ?? Size.zero, @@ -106,6 +91,29 @@ class CssBoxWidget extends StatelessWidget { ); } + /// Returns the width capped with maxWidth if necessary. + static Width? _calculateMaxedWidth(BuildContext context, Style style) { + // We only need to calculate something if we have a width and it needs to be capped. + if (style.maxWidth == null || style.width == null) return null; + + // If our max is a percentage, we want to look at the size available and not be bigger than that. + // TODO In the else case, we should have something to compare across different units, as for now some cases won't be handled. + if (style.maxWidth!.unit == Unit.percent && style.width!.unit == Unit.px) { + return Width( + MediaQuery.of(context).size.width * (style.maxWidth!.value / 100), + style.width!.unit, + ); + } else if (style.width!.unit == style.maxWidth!.unit && + style.width!.value > style.maxWidth!.value) { + return Width( + style.maxWidth!.value, + style.maxWidth!.unit, + ); + } else { + return null; + } + } + /// Takes a list of InlineSpan children and generates a Text.rich Widget /// containing those children. static Widget _generateWidgetChild(List children, Style style) {