diff --git a/lib/src/builtins/image_builtin.dart b/lib/src/builtins/image_builtin.dart index d07b3051a3..bc137bb7f8 100644 --- a/lib/src/builtins/image_builtin.dart +++ b/lib/src/builtins/image_builtin.dart @@ -203,7 +203,7 @@ class ImageBuiltIn extends HtmlExtension { element.src, width: imageStyle.width?.value, height: imageStyle.height?.value, - fit: BoxFit.fill, + fit: BoxFit.contain, headers: networkHeaders, errorBuilder: (ctx, error, stackTrace) { return Text( diff --git a/lib/src/css_box_widget.dart b/lib/src/css_box_widget.dart index c6870a3929..8cbe9afbb4 100644 --- a/lib/src/css_box_widget.dart +++ b/lib/src/css_box_widget.dart @@ -60,7 +60,8 @@ class CssBoxWidget extends StatelessWidget { final padding = style.padding?.resolve(direction); return _CSSBoxRenderer( - width: 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, @@ -90,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) { 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,