From dd6c532e09e754ee16411e7123edc42c5420feb4 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Wed, 7 Jul 2021 19:03:56 +0800 Subject: [PATCH 01/17] feat: support length parse for rem and em --- kraken/lib/src/css/animation.dart | 18 ++- kraken/lib/src/css/background.dart | 17 +-- kraken/lib/src/css/box.dart | 113 +++++++--------- kraken/lib/src/css/filter.dart | 8 +- kraken/lib/src/css/flexbox.dart | 24 ++-- kraken/lib/src/css/flow.dart | 6 +- kraken/lib/src/css/margin.dart | 8 +- kraken/lib/src/css/offset.dart | 10 +- kraken/lib/src/css/render_style.dart | 128 +++++++++--------- kraken/lib/src/css/style_declaration.dart | 17 +-- kraken/lib/src/css/text.dart | 80 ++++++----- kraken/lib/src/css/transform.dart | 59 ++++---- kraken/lib/src/css/values/length.dart | 31 ++++- kraken/lib/src/css/values/position.dart | 4 +- kraken/lib/src/dom/element.dart | 88 +++--------- .../lib/src/dom/elements/canvas/canvas.dart | 6 +- .../elements/canvas/canvas_context_2d.dart | 4 +- kraken/lib/src/dom/elements/img.dart | 4 +- kraken/lib/src/rendering/box_model.dart | 35 ++--- 19 files changed, 297 insertions(+), 363 deletions(-) diff --git a/kraken/lib/src/css/animation.dart b/kraken/lib/src/css/animation.dart index addebb7052..ee4e05b8c2 100644 --- a/kraken/lib/src/css/animation.dart +++ b/kraken/lib/src/css/animation.dart @@ -454,14 +454,22 @@ class KeyframeEffect extends AnimationEffect { // Similarly, a playback rate of -1 will cause the animation’s current time to decrease at the same rate as the time values from its timeline increase. double _playbackRate = 1; - KeyframeEffect(this.style, this.target, List keyframes, EffectTiming? options, this.viewportSize) { + KeyframeEffect( + this.style, + this.target, + List keyframes, + EffectTiming? options, + this.viewportSize, + this.renderStyle + ) { timing = options == null ? EffectTiming() : options; _propertySpecificKeyframeGroups = _makePropertySpecificKeyframeGroups(keyframes); - _interpolations = _makeInterpolations(_propertySpecificKeyframeGroups, viewportSize); + _interpolations = _makeInterpolations(_propertySpecificKeyframeGroups, viewportSize, renderStyle); } Size? viewportSize; + RenderStyle? renderStyle; static _defaultParse(value) { return value; @@ -471,7 +479,7 @@ class KeyframeEffect extends AnimationEffect { return progress < 0.5 ? start : end; } - static List<_Interpolation> _makeInterpolations(Map> propertySpecificKeyframeGroups, Size? viewportSize) { + static List<_Interpolation> _makeInterpolations(Map> propertySpecificKeyframeGroups, Size? viewportSize, RenderStyle? renderStyle) { List<_Interpolation> interpolations = []; propertySpecificKeyframeGroups.forEach((String property, List keyframes) { @@ -509,8 +517,8 @@ class KeyframeEffect extends AnimationEffect { startOffset, endOffset, _parseEasing(keyframes[startIndex].easing), - parseProperty(left, viewportSize), - parseProperty(right, viewportSize), + parseProperty(left, viewportSize, renderStyle), + parseProperty(right, viewportSize, renderStyle), handlers[1] ); diff --git a/kraken/lib/src/css/background.dart b/kraken/lib/src/css/background.dart index 1d6be59a41..6faa435426 100644 --- a/kraken/lib/src/css/background.dart +++ b/kraken/lib/src/css/background.dart @@ -144,7 +144,6 @@ class CSSBackground { static Gradient? getBackgroundGradient(CSSStyleDeclaration? style, RenderBoxModel renderBoxModel, CSSFunctionalNotation method) { Gradient? gradient; - Size viewportSize = renderBoxModel.renderStyle.viewportSize; if (method.args.length > 1) { List colors = []; @@ -176,7 +175,7 @@ class CSSBackground { end = Alignment.centerLeft; } if (style![WIDTH].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], viewportSize); + gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], renderStyle: renderBoxModel.renderStyle); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentWidth(renderBoxModel); } @@ -195,7 +194,7 @@ class CSSBackground { end = Alignment.topCenter; } if (style![HEIGHT].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], viewportSize); + gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], renderStyle: renderBoxModel.renderStyle); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentHeight(renderBoxModel); } @@ -215,7 +214,7 @@ class CSSBackground { } if (style![WIDTH].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], viewportSize); + gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], renderStyle: renderBoxModel.renderStyle); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentWidth(renderBoxModel); } @@ -235,7 +234,7 @@ class CSSBackground { end = Alignment.bottomCenter; } if (style![HEIGHT].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], viewportSize); + gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], renderStyle: renderBoxModel.renderStyle); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentHeight(renderBoxModel); } @@ -363,8 +362,6 @@ class CSSBackground { strings = src.split(' '); } - Size viewportSize = renderBoxModel.renderStyle.viewportSize; - if (strings.length >= 1) { double? stop = defaultStop; if (strings.length >= 2) { @@ -376,11 +373,7 @@ class CSSBackground { stop = CSSAngle.parseAngle(strings[i])! / (math.pi * 2); } else if (CSSLength.isLength(strings[i])) { if (gradientLength != null) { - stop = CSSLength.toDisplayPortValue(strings[i], viewportSize)! / gradientLength; - } else if (!renderBoxModel.attached) { - /// When node is not attached and has no width/height, gradient length - /// cannot be obtained, so wait for renderBoxModel attached to recalculate gradient length - renderBoxModel.shouldRecalGradient = true; + stop = CSSLength.toDisplayPortValue(strings[i], renderStyle: renderBoxModel.renderStyle)! / gradientLength; } } colorGradients.add(CSSColorStop(CSSColor.parseColor(strings[0]), stop)); diff --git a/kraken/lib/src/css/box.dart b/kraken/lib/src/css/box.dart index 9eb61c6266..0679e0ad31 100644 --- a/kraken/lib/src/css/box.dart +++ b/kraken/lib/src/css/box.dart @@ -185,9 +185,9 @@ mixin CSSBoxMixin on RenderStyleBase { } else if (property == BACKGROUND_COLOR) { updateBackgroundColor(); } else if (property == BACKGROUND_POSITION_X) { - backgroundPositionX = CSSPosition.parsePosition(present, viewportSize, true); + backgroundPositionX = CSSPosition.parsePosition(present, renderStyle, true); } else if (property == BACKGROUND_POSITION_Y) { - backgroundPositionY = CSSPosition.parsePosition(present, viewportSize, false); + backgroundPositionY = CSSPosition.parsePosition(present, renderStyle, false); } else if (property.startsWith(BACKGROUND)) { // Including BACKGROUND_REPEAT, BACKGROUND_IMAGE, // BACKGROUND_SIZE, BACKGROUND_ORIGIN, BACKGROUND_CLIP. @@ -212,14 +212,12 @@ mixin CSSBoxMixin on RenderStyleBase { } void updateBoxShadow(String property) { - CSSBoxDecoration? prevBoxDecoration = decoration; - Size viewportSize = renderBoxModel!.renderStyle.viewportSize; if (prevBoxDecoration != null) { decoration = CSSBoxDecoration( // Only modify boxShadow. - boxShadow: getBoxShadow(style!, viewportSize), + boxShadow: getBoxShadow(), color: prevBoxDecoration.color, image: prevBoxDecoration.image, border: prevBoxDecoration.border, @@ -229,12 +227,12 @@ mixin CSSBoxMixin on RenderStyleBase { shape: prevBoxDecoration.shape ); } else { - decoration = CSSBoxDecoration(boxShadow: getBoxShadow(style!, viewportSize)); + decoration = CSSBoxDecoration(boxShadow: getBoxShadow()); } } void updateBackgroundColor([Color? color]) { - Color? bgColor = color ?? CSSBackground.getBackgroundColor(style!); + Color? bgColor = color ?? CSSBackground.getBackgroundColor(style); CSSBoxDecoration? prevBoxDecoration = decoration; // If change bg color from some color to null, which must be explicitly transparent. @@ -264,7 +262,7 @@ mixin CSSBoxMixin on RenderStyleBase { DecorationImage? decorationImage; Gradient? gradient; - List methods = CSSFunction.parseFunction(style![BACKGROUND_IMAGE]); + List methods = CSSFunction.parseFunction(style[BACKGROUND_IMAGE]); for (CSSFunctionalNotation method in methods) { if (method.name == 'url') { decorationImage = CSSBackground.getDecorationImage(style, method, contextId: contextId); @@ -284,9 +282,9 @@ mixin CSSBoxMixin on RenderStyleBase { shape: prevBoxDecoration.shape, ); - if (CSSBackground.hasScrollBackgroundImage(style!)) { + if (CSSBackground.hasScrollBackgroundImage(style)) { decoration = updateBoxDecoration; - } else if (CSSBackground.hasLocalBackgroundImage(style!)) { + } else if (CSSBackground.hasLocalBackgroundImage(style)) { // @FIXME: support local background image decoration = updateBoxDecoration; } else { @@ -313,9 +311,10 @@ mixin CSSBoxMixin on RenderStyleBase { // topLeft topRight bottomRight bottomLeft int? index = _borderRadiusMapping[property]; + RenderStyle renderStyle = this as RenderStyle; if (index != null) { - Radius? newRadius = CSSBorderRadius.getRadius(present, viewportSize); + Radius? newRadius = CSSBorderRadius.getRadius(present, renderStyle); BorderRadius? borderRadius = decoration!.borderRadius as BorderRadius?; decoration = decoration!.clone(borderRadius: BorderRadius.only( topLeft: index == 0 ? newRadius! : borderRadius?.topLeft ?? Radius.zero, @@ -328,6 +327,7 @@ mixin CSSBoxMixin on RenderStyleBase { void updateBorder(String property, {Color? borderColor, double? borderWidth}) { Border? border = decoration!.border as Border?; + RenderStyle renderStyle = this as RenderStyle; bool isBorderWidthChange = property == BORDER_TOP_WIDTH || property == BORDER_RIGHT_WIDTH || property == BORDER_BOTTOM_WIDTH || property == BORDER_LEFT_WIDTH; @@ -345,13 +345,13 @@ mixin CSSBoxMixin on RenderStyleBase { bool updateAll = false; if (property.contains(BORDER_LEFT)) { - left = CSSBorderSide.getBorderSide(style!, CSSBorderSide.LEFT, viewportSize, borderColor, borderWidth); + left = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.LEFT, borderColor, borderWidth); } else if (property.contains(BORDER_TOP)) { - top = CSSBorderSide.getBorderSide(style!, CSSBorderSide.TOP, viewportSize, borderColor, borderWidth); + top = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.TOP, borderColor, borderWidth); } else if (property.contains(BORDER_RIGHT)) { - right = CSSBorderSide.getBorderSide(style!, CSSBorderSide.RIGHT, viewportSize, borderColor, borderWidth); + right = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.RIGHT, borderColor, borderWidth); } else if (property.contains(BORDER_BOTTOM)) { - bottom = CSSBorderSide.getBorderSide(style!, CSSBorderSide.BOTTOM, viewportSize, borderColor, borderWidth); + bottom = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.BOTTOM, borderColor, borderWidth); } else { updateAll = true; } @@ -380,10 +380,11 @@ mixin CSSBoxMixin on RenderStyleBase { } List? _getBorderSides([Color? borderColor, double? borderWidth]) { - BorderSide? leftSide = CSSBorderSide.getBorderSide(style!, CSSBorderSide.LEFT, viewportSize, borderColor, borderWidth); - BorderSide? topSide = CSSBorderSide.getBorderSide(style!, CSSBorderSide.TOP, viewportSize, borderColor, borderWidth); - BorderSide? rightSide = CSSBorderSide.getBorderSide(style!, CSSBorderSide.RIGHT, viewportSize, borderColor, borderWidth); - BorderSide? bottomSide = CSSBorderSide.getBorderSide(style!, CSSBorderSide.BOTTOM, viewportSize, borderColor, borderWidth); + RenderStyle renderStyle = this as RenderStyle; + BorderSide? leftSide = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.LEFT, borderColor, borderWidth); + BorderSide? topSide = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.TOP, borderColor, borderWidth); + BorderSide? rightSide = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.RIGHT, borderColor, borderWidth); + BorderSide? bottomSide = CSSBorderSide.getBorderSide(renderStyle, CSSBorderSide.BOTTOM, borderColor, borderWidth); bool hasBorder = leftSide != null || topSide != null || @@ -398,11 +399,12 @@ mixin CSSBoxMixin on RenderStyleBase { } List? _getBorderRadius() { + RenderStyle renderStyle = this as RenderStyle; // border radius add border topLeft topRight bottomLeft bottomRight - Radius? topLeftRadius = CSSBorderRadius.getRadius(style![BORDER_TOP_LEFT_RADIUS], viewportSize); - Radius? topRightRadius = CSSBorderRadius.getRadius(style![BORDER_TOP_RIGHT_RADIUS], viewportSize); - Radius? bottomRightRadius = CSSBorderRadius.getRadius(style![BORDER_BOTTOM_RIGHT_RADIUS], viewportSize); - Radius? bottomLeftRadius = CSSBorderRadius.getRadius(style![BORDER_BOTTOM_LEFT_RADIUS], viewportSize); + Radius? topLeftRadius = CSSBorderRadius.getRadius(style[BORDER_TOP_LEFT_RADIUS], renderStyle); + Radius? topRightRadius = CSSBorderRadius.getRadius(style[BORDER_TOP_RIGHT_RADIUS], renderStyle); + Radius? bottomRightRadius = CSSBorderRadius.getRadius(style[BORDER_BOTTOM_RIGHT_RADIUS], renderStyle); + Radius? bottomLeftRadius = CSSBorderRadius.getRadius(style[BORDER_BOTTOM_LEFT_RADIUS], renderStyle); bool hasBorderRadius = topLeftRadius != null || topRightRadius != null || @@ -427,11 +429,11 @@ mixin CSSBoxMixin on RenderStyleBase { /// borderColor: CSSBoxDecoration? getCSSBoxDecoration() { // Backgroud color - Color? bgColor = CSSBackground.getBackgroundColor(style!); + Color? bgColor = CSSBackground.getBackgroundColor(style); // Background image DecorationImage? decorationImage; Gradient? gradient; - List methods = CSSFunction.parseFunction(style![BACKGROUND_IMAGE]); + List methods = CSSFunction.parseFunction(style[BACKGROUND_IMAGE]); for (CSSFunctionalNotation method in methods) { if (method.name == 'url') { decorationImage = CSSBackground.getDecorationImage(style, method); @@ -441,7 +443,7 @@ mixin CSSBoxMixin on RenderStyleBase { } List? radius = _getBorderRadius(); - List? boxShadow = getBoxShadow(style!, viewportSize); + List? boxShadow = getBoxShadow(); List? borderSides = _getBorderSides(); if (bgColor == null && @@ -483,8 +485,10 @@ mixin CSSBoxMixin on RenderStyleBase { ); } - List? getBoxShadow(CSSStyleDeclaration style, Size viewportSize) { + List? getBoxShadow() { List? boxShadow; + RenderStyle renderStyle = this as RenderStyle; + CSSStyleDeclaration style = renderStyle.style; if (style.contains(BOX_SHADOW)) { boxShadow = []; @@ -497,10 +501,10 @@ mixin CSSBoxMixin on RenderStyleBase { colorDefinition = style.getCurrentColor(); } Color? color = CSSColor.parseColor(colorDefinition); - double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], viewportSize) ?? 0; - double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], viewportSize) ?? 0; - double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], viewportSize) ?? 0; - double spreadRadius = CSSLength.toDisplayPortValue(shadowDefinitions[4], viewportSize) ?? 0; + double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], renderStyle: renderStyle) ?? 0; + double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], renderStyle: renderStyle) ?? 0; + double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], renderStyle: renderStyle) ?? 0; + double spreadRadius = CSSLength.toDisplayPortValue(shadowDefinitions[4], renderStyle: renderStyle) ?? 0; bool inset = shadowDefinitions[5] == INSET; if (color != null) { @@ -552,7 +556,7 @@ class CSSBorderSide { static String TOP = 'Top'; static String BOTTOM = 'Bottom'; - static double? getBorderWidth(String input, Size viewportSize) { + static double? getBorderWidth(String input, RenderStyle renderStyle) { // https://drafts.csswg.org/css2/#border-width-properties // The interpretation of the first three values depends on the user agent. // The following relationships must hold, however: @@ -569,7 +573,7 @@ class CSSBorderSide { borderWidth = 5; break; default: - borderWidth = CSSLength.toDisplayPortValue(input, viewportSize); + borderWidth = CSSLength.toDisplayPortValue(input, renderStyle: renderStyle); } return borderWidth; } @@ -582,10 +586,11 @@ class CSSBorderSide { return CSSLength.isLength(value) || value == THIN || value == MEDIUM || value == THICK; } - static double? getBorderSideWidth(CSSStyleDeclaration style, String side, Size viewportSize) { + static double? getBorderSideWidth(RenderStyle renderStyle, String side) { + CSSStyleDeclaration style = renderStyle.style; String property = 'border${side}Width'; String value = style[property]; - return value.isEmpty ? defaultBorderWidth : getBorderWidth(value, viewportSize); + return value.isEmpty ? defaultBorderWidth : getBorderWidth(value, renderStyle); } static Color? getBorderSideColor(CSSStyleDeclaration style, String side) { @@ -594,36 +599,12 @@ class CSSBorderSide { return value.isEmpty ? defaultBorderColor : CSSColor.parseColor(value); } - static EdgeInsets getBorderEdgeInsets(CSSStyleDeclaration style, Size viewportSize) { - double left = 0.0; - double top = 0.0; - double bottom = 0.0; - double right = 0.0; - - if (style[BORDER_LEFT_STYLE].isNotEmpty && style[BORDER_LEFT_STYLE] != NONE) { - left = getBorderWidth(style[BORDER_LEFT_WIDTH], viewportSize) ?? defaultBorderWidth; - } - - if (style[BORDER_TOP_STYLE].isNotEmpty && style[BORDER_TOP_STYLE] != NONE) { - top = getBorderWidth(style[BORDER_TOP_WIDTH], viewportSize) ?? defaultBorderWidth; - } - - if (style[BORDER_RIGHT_STYLE].isNotEmpty && style[BORDER_RIGHT_STYLE] != NONE) { - right = getBorderWidth(style[BORDER_RIGHT_WIDTH], viewportSize) ?? defaultBorderWidth; - } - - if (style[BORDER_BOTTOM_STYLE].isNotEmpty && style[BORDER_BOTTOM_STYLE] != NONE) { - bottom = getBorderWidth(style[BORDER_BOTTOM_WIDTH], viewportSize) ?? defaultBorderWidth; - } - - return EdgeInsets.fromLTRB(left, top, right, bottom); - } - static BorderSide none = BorderSide(color: defaultBorderColor, width: 0.0, style: BorderStyle.none); - static BorderSide? getBorderSide(CSSStyleDeclaration style, String side, Size viewportSize, [Color? borderColor, double? borderWidth]) { + static BorderSide? getBorderSide(RenderStyle renderStyle, String side, [Color? borderColor, double? borderWidth]) { + CSSStyleDeclaration style = renderStyle.style; BorderStyle? borderStyle = CSSBorderStyle.getBorderSideStyle(style, side); - double? width = borderWidth ?? getBorderSideWidth(style, side, viewportSize); + double? width = borderWidth ?? getBorderSideWidth(renderStyle, side); Color? color = borderColor ?? getBorderSideColor(style, side); // Flutter will print border event if width is 0.0. So we needs to set borderStyle to none to prevent this. if (borderStyle == BorderStyle.none || width == 0.0) { @@ -641,16 +622,16 @@ class CSSBorderSide { class CSSBorderRadius { static Radius none = Radius.zero; - static Radius? getRadius(String radius, Size viewportSize) { + static Radius? getRadius(String radius, RenderStyle renderStyle) { if (radius.isNotEmpty) { // border-top-left-radius: horizontal vertical List values = radius.split(_spaceRegExp); if (values.length == 1) { - double? circular = CSSLength.toDisplayPortValue(values[0], viewportSize); + double? circular = CSSLength.toDisplayPortValue(values[0], renderStyle: renderStyle); if (circular != null) return Radius.circular(circular); } else if (values.length == 2) { - double? x = CSSLength.toDisplayPortValue(values[0], viewportSize); - double? y = CSSLength.toDisplayPortValue(values[1], viewportSize); + double? x = CSSLength.toDisplayPortValue(values[0], renderStyle: renderStyle); + double? y = CSSLength.toDisplayPortValue(values[1], renderStyle: renderStyle); if (x != null && y != null) return Radius.elliptical(x, y); } } diff --git a/kraken/lib/src/css/filter.dart b/kraken/lib/src/css/filter.dart index e11b0c6a9d..c2d8d75d1d 100644 --- a/kraken/lib/src/css/filter.dart +++ b/kraken/lib/src/css/filter.dart @@ -138,13 +138,13 @@ mixin CSSFilterEffectsMixin { } // Get the image filter. - static ImageFilter? _parseImageFilters(List functions, Size viewportSize) { + static ImageFilter? _parseImageFilters(List functions, RenderStyle renderStyle) { if (functions.length > 0) { for (int i = 0; i < functions.length; i ++) { CSSFunctionalNotation f = functions[i]; switch (f.name.toLowerCase()) { case BLUR: - double amount = CSSLength.parseLength(f.args.first, viewportSize)!; + double amount = CSSLength.parseLength(f.args.first, renderStyle: renderStyle)!; return ImageFilter.blur(sigmaX: amount, sigmaY: amount); } } @@ -159,8 +159,8 @@ mixin CSSFilterEffectsMixin { renderBoxModel.colorFilter = colorFilter; } - Size viewportSize = renderBoxModel.renderStyle.viewportSize; - ImageFilter? imageFilter = _parseImageFilters(functions, viewportSize); + RenderStyle renderStyle = renderBoxModel.renderStyle; + ImageFilter? imageFilter = _parseImageFilters(functions, renderStyle); if (imageFilter != null) { renderBoxModel.imageFilter = imageFilter; } diff --git a/kraken/lib/src/css/flexbox.dart b/kraken/lib/src/css/flexbox.dart index 753cb25e7f..2c91ccba4b 100644 --- a/kraken/lib/src/css/flexbox.dart +++ b/kraken/lib/src/css/flexbox.dart @@ -4,7 +4,6 @@ * Copyright (C) 2019-present Alibaba Inc. All rights reserved. * Author: Kraken Team. */ -import 'package:flutter/rendering.dart'; import 'package:kraken/rendering.dart'; import 'package:kraken/css.dart'; @@ -275,18 +274,18 @@ mixin CSSFlexboxMixin on RenderStyleBase { } void updateFlexbox() { - flexDirection = _getFlexDirection(style!); - flexWrap = _getFlexWrap(style!); - justifyContent = _getJustifyContent(style!); - alignItems = _getAlignItems(style!); - alignContent = _getAlignContent(style!); + flexDirection = _getFlexDirection(style); + flexWrap = _getFlexWrap(style); + justifyContent = _getJustifyContent(style); + alignItems = _getAlignItems(style); + alignContent = _getAlignContent(style); } void updateFlexItem() { - flexGrow = _getFlexGrow(style!); - flexShrink = _getFlexShrink(style!); - flexBasis = _getFlexBasis(style!, viewportSize); - alignSelf = _getAlignSelf(style!); + flexGrow = _getFlexGrow(style); + flexShrink = _getFlexShrink(style); + flexBasis = _getFlexBasis(style); + alignSelf = _getAlignSelf(style); } FlexDirection _getFlexDirection(CSSStyleDeclaration style) { @@ -422,9 +421,10 @@ mixin CSSFlexboxMixin on RenderStyleBase { return flexShrink != null && flexShrink >= 0 ? flexShrink : 1.0; } - double? _getFlexBasis(CSSStyleDeclaration style, Size viewportSize) { + double? _getFlexBasis(CSSStyleDeclaration style) { String basisStr = style[FLEX_BASIS]; - double? flexBasis = CSSLength.toDisplayPortValue(basisStr, viewportSize); + RenderStyle renderStyle = this as RenderStyle; + double? flexBasis = CSSLength.toDisplayPortValue(basisStr, renderStyle: renderStyle); if (basisStr.isNotEmpty && basisStr != AUTO) { if (flexBasis! < 0) { flexBasis = null; diff --git a/kraken/lib/src/css/flow.dart b/kraken/lib/src/css/flow.dart index b18aae961b..29fffa8f3e 100644 --- a/kraken/lib/src/css/flow.dart +++ b/kraken/lib/src/css/flow.dart @@ -27,7 +27,7 @@ mixin CSSFlowMixin on RenderStyleBase { if (_textAlign == value) return; _textAlign = value; // Update all the children flow layout with specified style property not set due to style inheritance. - _markFlowLayoutNeedsLayout(renderBoxModel!, TEXT_ALIGN); + _markFlowLayoutNeedsLayout(renderBoxModel, TEXT_ALIGN); } /// Mark flow layout and all the children flow layout with specified style property not set needs layout. @@ -37,7 +37,7 @@ mixin CSSFlowMixin on RenderStyleBase { renderBoxModel.visitChildren((RenderObject child) { if (child is RenderFlowLayout) { // Only need to layout when the specified style property is not set. - if (child.renderStyle.style?[styleProperty].isEmpty) { + if (child.renderStyle.style[styleProperty].isEmpty) { _markFlowLayoutNeedsLayout(child, styleProperty); } } @@ -46,7 +46,7 @@ mixin CSSFlowMixin on RenderStyleBase { } void updateFlow() { - CSSStyleDeclaration style = this.style!; + CSSStyleDeclaration style = this.style; textAlign = _getTextAlign(style); } diff --git a/kraken/lib/src/css/margin.dart b/kraken/lib/src/css/margin.dart index 6d2417e253..878e5a3e57 100644 --- a/kraken/lib/src/css/margin.dart +++ b/kraken/lib/src/css/margin.dart @@ -50,28 +50,28 @@ mixin CSSMarginMixin on RenderStyleBase { CSSMargin get marginTop { _resolve(); double length = _resolvedMargin != null ? _resolvedMargin!.top : 0; - bool isAuto = style![MARGIN_TOP] == AUTO; + bool isAuto = style[MARGIN_TOP] == AUTO; return CSSMargin(length: length, isAuto: isAuto); } CSSMargin get marginRight { _resolve(); double length = _resolvedMargin != null ? _resolvedMargin!.right : 0; - bool isAuto = style![MARGIN_RIGHT] == AUTO; + bool isAuto = style[MARGIN_RIGHT] == AUTO; return CSSMargin(length: length, isAuto: isAuto); } CSSMargin get marginBottom { _resolve(); double length = _resolvedMargin != null ? _resolvedMargin!.bottom : 0; - bool isAuto = style![MARGIN_BOTTOM] == AUTO; + bool isAuto = style[MARGIN_BOTTOM] == AUTO; return CSSMargin(length: length, isAuto: isAuto); } CSSMargin get marginLeft { _resolve(); double length = _resolvedMargin != null ? _resolvedMargin!.left : 0; - bool isAuto = style![MARGIN_LEFT] == AUTO; + bool isAuto = style[MARGIN_LEFT] == AUTO; return CSSMargin(length: length, isAuto: isAuto); } diff --git a/kraken/lib/src/css/offset.dart b/kraken/lib/src/css/offset.dart index 2120715eaf..8455ea1c22 100644 --- a/kraken/lib/src/css/offset.dart +++ b/kraken/lib/src/css/offset.dart @@ -105,16 +105,16 @@ mixin CSSPositionMixin on RenderStyleBase { void updateOffset(String property, double value, {bool shouldMarkNeedsLayout = true}) { switch (property) { case TOP: - top = CSSOffset(length: value, isAuto: style![TOP] == AUTO); + top = CSSOffset(length: value, isAuto: style[TOP] == AUTO); break; case LEFT: - left = CSSOffset(length: value, isAuto: style![LEFT] == AUTO); + left = CSSOffset(length: value, isAuto: style[LEFT] == AUTO); break; case RIGHT: - right = CSSOffset(length: value, isAuto: style![RIGHT] == AUTO); + right = CSSOffset(length: value, isAuto: style[RIGHT] == AUTO); break; case BOTTOM: - bottom = CSSOffset(length: value, isAuto: style![BOTTOM] == AUTO); + bottom = CSSOffset(length: value, isAuto: style[BOTTOM] == AUTO); break; } /// Should mark parent needsLayout directly cause positioned element is rendered as relayoutBoundary @@ -126,7 +126,7 @@ mixin CSSPositionMixin on RenderStyleBase { void updatePosition(String property, String present) { RenderStyle renderStyle = this as RenderStyle; - position = parsePositionType(style![POSITION]); + position = parsePositionType(style[POSITION]); // Position change may affect transformed display // https://www.w3.org/TR/css-display-3/#transformations renderStyle.transformedDisplay = renderStyle.getTransformedDisplay(); diff --git a/kraken/lib/src/css/render_style.dart b/kraken/lib/src/css/render_style.dart index d3f3da98fd..da72dcd711 100644 --- a/kraken/lib/src/css/render_style.dart +++ b/kraken/lib/src/css/render_style.dart @@ -31,12 +31,12 @@ class RenderStyle CSSOpacityMixin { RenderBoxModel? renderBoxModel; - CSSStyleDeclaration? style; + late CSSStyleDeclaration style; late Size viewportSize; RenderStyle({ this.renderBoxModel, - this.style, + required this.style, required this.viewportSize }); @@ -47,6 +47,7 @@ class RenderStyle return false; } + RenderStyle renderStyle = this; final RenderLayoutParentData childParentData = renderBoxModel!.parentData as RenderLayoutParentData; double parentActualContentHeight = parent.size.height - parent.renderStyle.borderTop - parent.renderStyle.borderBottom - @@ -87,28 +88,28 @@ class RenderStyle /// Update sizing double relativeParentWidth = childParentData.isPositioned ? parentPaddingBoxWidth : parentContentBoxWidth; - if (CSSLength.isPercentage(style![WIDTH])) { + if (CSSLength.isPercentage(style[WIDTH])) { updateSizing( WIDTH, - relativeParentWidth * CSSLength.parsePercentage(style![WIDTH]), + relativeParentWidth * CSSLength.parsePercentage(style[WIDTH]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MIN_WIDTH])) { + if (CSSLength.isPercentage(style[MIN_WIDTH])) { updateSizing( MIN_WIDTH, - relativeParentWidth * CSSLength.parsePercentage(style![MIN_WIDTH]), + relativeParentWidth * CSSLength.parsePercentage(style[MIN_WIDTH]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MAX_WIDTH])) { + if (CSSLength.isPercentage(style[MAX_WIDTH])) { updateSizing( MAX_WIDTH, - relativeParentWidth * CSSLength.parsePercentage(style![MAX_WIDTH]), + relativeParentWidth * CSSLength.parsePercentage(style[MAX_WIDTH]), shouldMarkNeedsLayout: false ); isPercentageExist = true; @@ -117,28 +118,28 @@ class RenderStyle if (parentContentHeight != null) { double relativeParentHeight = childParentData.isPositioned ? parentPaddingBoxHeight : parentContentBoxHeight; - if (CSSLength.isPercentage(style![HEIGHT])) { + if (CSSLength.isPercentage(style[HEIGHT])) { updateSizing( HEIGHT, - relativeParentHeight * CSSLength.parsePercentage(style![HEIGHT]), + relativeParentHeight * CSSLength.parsePercentage(style[HEIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MIN_HEIGHT])) { + if (CSSLength.isPercentage(style[MIN_HEIGHT])) { updateSizing( MIN_HEIGHT, - relativeParentHeight * CSSLength.parsePercentage(style![MIN_HEIGHT]), + relativeParentHeight * CSSLength.parsePercentage(style[MIN_HEIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MAX_HEIGHT])) { + if (CSSLength.isPercentage(style[MAX_HEIGHT])) { updateSizing( MAX_HEIGHT, - relativeParentHeight * CSSLength.parsePercentage(style![MAX_HEIGHT]), + relativeParentHeight * CSSLength.parsePercentage(style[MAX_HEIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; @@ -148,37 +149,37 @@ class RenderStyle /// Percentage of padding and margin refer to the logical width of containing block /// Update padding /// https://www.w3.org/TR/css-box-3/#padding-physical - if (CSSLength.isPercentage(style![PADDING_TOP])) { + if (CSSLength.isPercentage(style[PADDING_TOP])) { updatePadding( PADDING_TOP, - relativeParentWidth * CSSLength.parsePercentage(style![PADDING_TOP]), + relativeParentWidth * CSSLength.parsePercentage(style[PADDING_TOP]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![PADDING_RIGHT])) { + if (CSSLength.isPercentage(style[PADDING_RIGHT])) { updatePadding( PADDING_RIGHT, - relativeParentWidth * CSSLength.parsePercentage(style![PADDING_RIGHT]), + relativeParentWidth * CSSLength.parsePercentage(style[PADDING_RIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![PADDING_BOTTOM])) { + if (CSSLength.isPercentage(style[PADDING_BOTTOM])) { updatePadding( PADDING_BOTTOM, - relativeParentWidth * CSSLength.parsePercentage(style![PADDING_BOTTOM]), + relativeParentWidth * CSSLength.parsePercentage(style[PADDING_BOTTOM]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![PADDING_LEFT])) { + if (CSSLength.isPercentage(style[PADDING_LEFT])) { updatePadding( PADDING_LEFT, - relativeParentWidth * CSSLength.parsePercentage(style![PADDING_LEFT]), + relativeParentWidth * CSSLength.parsePercentage(style[PADDING_LEFT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; @@ -186,37 +187,37 @@ class RenderStyle /// Update margin /// https://www.w3.org/TR/css-box-3/#margin-physical - if (CSSLength.isPercentage(style![MARGIN_TOP])) { + if (CSSLength.isPercentage(style[MARGIN_TOP])) { updateMargin( MARGIN_TOP, - relativeParentWidth * CSSLength.parsePercentage(style![MARGIN_TOP]), + relativeParentWidth * CSSLength.parsePercentage(style[MARGIN_TOP]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MARGIN_RIGHT])) { + if (CSSLength.isPercentage(style[MARGIN_RIGHT])) { updateMargin( MARGIN_RIGHT, - relativeParentWidth * CSSLength.parsePercentage(style![MARGIN_RIGHT]), + relativeParentWidth * CSSLength.parsePercentage(style[MARGIN_RIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MARGIN_BOTTOM])) { + if (CSSLength.isPercentage(style[MARGIN_BOTTOM])) { updateMargin( MARGIN_BOTTOM, - relativeParentWidth * CSSLength.parsePercentage(style![MARGIN_BOTTOM]), + relativeParentWidth * CSSLength.parsePercentage(style[MARGIN_BOTTOM]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![MARGIN_LEFT])) { + if (CSSLength.isPercentage(style[MARGIN_LEFT])) { updateMargin( MARGIN_LEFT, - relativeParentWidth * CSSLength.parsePercentage(style![MARGIN_LEFT]), + relativeParentWidth * CSSLength.parsePercentage(style[MARGIN_LEFT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; @@ -224,44 +225,44 @@ class RenderStyle /// Update offset /// Offset of positioned element starts from the edge of padding box of containing block - if (CSSLength.isPercentage(style![TOP])) { + if (CSSLength.isPercentage(style[TOP])) { updateOffset( TOP, - parentPaddingBoxHeight * CSSLength.parsePercentage(style![TOP]), + parentPaddingBoxHeight * CSSLength.parsePercentage(style[TOP]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![RIGHT])) { + if (CSSLength.isPercentage(style[RIGHT])) { updateOffset( RIGHT, - parentPaddingBoxWidth * CSSLength.parsePercentage(style![RIGHT]), + parentPaddingBoxWidth * CSSLength.parsePercentage(style[RIGHT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![BOTTOM])) { + if (CSSLength.isPercentage(style[BOTTOM])) { updateOffset( BOTTOM, - parentPaddingBoxHeight * CSSLength.parsePercentage(style![BOTTOM]), + parentPaddingBoxHeight * CSSLength.parsePercentage(style[BOTTOM]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } - if (CSSLength.isPercentage(style![LEFT])) { + if (CSSLength.isPercentage(style[LEFT])) { updateOffset( LEFT, - parentPaddingBoxWidth * CSSLength.parsePercentage(style![LEFT]), + parentPaddingBoxWidth * CSSLength.parsePercentage(style[LEFT]), shouldMarkNeedsLayout: false ); isPercentageExist = true; } /// border-radius - String? parsedTopLeftRadius = parsePercentageBorderRadius(style![BORDER_TOP_LEFT_RADIUS], size); + String? parsedTopLeftRadius = parsePercentageBorderRadius(style[BORDER_TOP_LEFT_RADIUS], size); if (parsedTopLeftRadius != null) { updateBorderRadius( @@ -271,7 +272,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedTopRightRadius = parsePercentageBorderRadius(style![BORDER_TOP_RIGHT_RADIUS], size); + String? parsedTopRightRadius = parsePercentageBorderRadius(style[BORDER_TOP_RIGHT_RADIUS], size); if (parsedTopRightRadius != null) { updateBorderRadius( BORDER_TOP_RIGHT_RADIUS, @@ -280,7 +281,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedBottomLeftRadius = parsePercentageBorderRadius(style![BORDER_BOTTOM_LEFT_RADIUS], size); + String? parsedBottomLeftRadius = parsePercentageBorderRadius(style[BORDER_BOTTOM_LEFT_RADIUS], size); if (parsedBottomLeftRadius != null) { updateBorderRadius( BORDER_BOTTOM_LEFT_RADIUS, @@ -289,7 +290,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedBottomRightRadius = parsePercentageBorderRadius(style![BORDER_BOTTOM_RIGHT_RADIUS], size); + String? parsedBottomRightRadius = parsePercentageBorderRadius(style[BORDER_BOTTOM_RIGHT_RADIUS], size); if (parsedBottomRightRadius != null) { updateBorderRadius( BORDER_BOTTOM_RIGHT_RADIUS, @@ -299,7 +300,7 @@ class RenderStyle } /// Transform translate - Matrix4? transformValue = parsePercentageTransformTranslate(style![TRANSFORM], size, viewportSize); + Matrix4? transformValue = parsePercentageTransformTranslate(style[TRANSFORM], size, renderStyle); if (transformValue != null) { updateTransform( transformValue, @@ -320,9 +321,10 @@ class RenderStyle } bool isPercentageExist = false; Size? size = renderBoxModel!.boxSize; + RenderStyle renderStyle = this; /// border-radius - String? parsedTopLeftRadius = parsePercentageBorderRadius(style![BORDER_TOP_LEFT_RADIUS], size); + String? parsedTopLeftRadius = parsePercentageBorderRadius(style[BORDER_TOP_LEFT_RADIUS], size); if (parsedTopLeftRadius != null) { updateBorderRadius( @@ -332,7 +334,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedTopRightRadius = parsePercentageBorderRadius(style![BORDER_TOP_RIGHT_RADIUS], size); + String? parsedTopRightRadius = parsePercentageBorderRadius(style[BORDER_TOP_RIGHT_RADIUS], size); if (parsedTopRightRadius != null) { updateBorderRadius( BORDER_TOP_RIGHT_RADIUS, @@ -341,7 +343,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedBottomLeftRadius = parsePercentageBorderRadius(style![BORDER_BOTTOM_LEFT_RADIUS], size); + String? parsedBottomLeftRadius = parsePercentageBorderRadius(style[BORDER_BOTTOM_LEFT_RADIUS], size); if (parsedBottomLeftRadius != null) { updateBorderRadius( BORDER_BOTTOM_LEFT_RADIUS, @@ -350,7 +352,7 @@ class RenderStyle isPercentageExist = true; } - String? parsedBottomRightRadius = parsePercentageBorderRadius(style![BORDER_BOTTOM_RIGHT_RADIUS], size); + String? parsedBottomRightRadius = parsePercentageBorderRadius(style[BORDER_BOTTOM_RIGHT_RADIUS], size); if (parsedBottomRightRadius != null) { updateBorderRadius( BORDER_BOTTOM_RIGHT_RADIUS, @@ -360,7 +362,7 @@ class RenderStyle } /// Transform translate - Matrix4? transformValue = parsePercentageTransformTranslate(style![TRANSFORM], size, viewportSize); + Matrix4? transformValue = parsePercentageTransformTranslate(style[TRANSFORM], size, renderStyle); if (transformValue != null) { updateTransform( transformValue, @@ -389,17 +391,17 @@ class RenderStyle double? parentContentHeight = childParentData.isPositioned || parent.parent is RenderFlexLayout ? parentActualContentHeight : parentLogicalContentHeight; - if (CSSLength.isPercentage(style![WIDTH]) || - CSSLength.isPercentage(style![MIN_WIDTH]) || - CSSLength.isPercentage(style![MAX_WIDTH]) + if (CSSLength.isPercentage(style[WIDTH]) || + CSSLength.isPercentage(style[MIN_WIDTH]) || + CSSLength.isPercentage(style[MAX_WIDTH]) ) { return true; } if (parentContentHeight != null && ( - CSSLength.isPercentage(style![HEIGHT]) || - CSSLength.isPercentage(style![MIN_HEIGHT]) || - CSSLength.isPercentage(style![MAX_HEIGHT]) + CSSLength.isPercentage(style[HEIGHT]) || + CSSLength.isPercentage(style[MIN_HEIGHT]) || + CSSLength.isPercentage(style[MAX_HEIGHT]) )) { return true; } @@ -407,11 +409,11 @@ class RenderStyle } bool isPercentageToOwnExist() { - if (isBorderRadiusPercentage(style![BORDER_TOP_LEFT_RADIUS]) || - isBorderRadiusPercentage(style![BORDER_TOP_RIGHT_RADIUS]) || - isBorderRadiusPercentage(style![BORDER_BOTTOM_LEFT_RADIUS]) || - isBorderRadiusPercentage(style![BORDER_BOTTOM_RIGHT_RADIUS]) || - isTransformTranslatePercentage(style![TRANSFORM]) + if (isBorderRadiusPercentage(style[BORDER_TOP_LEFT_RADIUS]) || + isBorderRadiusPercentage(style[BORDER_TOP_RIGHT_RADIUS]) || + isBorderRadiusPercentage(style[BORDER_BOTTOM_LEFT_RADIUS]) || + isBorderRadiusPercentage(style[BORDER_BOTTOM_RIGHT_RADIUS]) || + isTransformTranslatePercentage(style[TRANSFORM]) ) { return true; } @@ -470,7 +472,7 @@ class RenderStyle /// Parse percentage transform translate value /// Returns the parsed result if percentage found, otherwise returns null - static Matrix4? parsePercentageTransformTranslate(String transformStr, Size? size, Size viewportSize) { + static Matrix4? parsePercentageTransformTranslate(String transformStr, Size? size, RenderStyle renderStyle) { List methods = CSSFunction.parseFunction(transformStr); final String TRANSLATE = 'translate'; bool isPercentageExist = false; @@ -488,7 +490,7 @@ class RenderStyle translateY = (size!.height * percentage).toString() + 'px'; isPercentageExist = true; } - y = CSSLength.toDisplayPortValue(translateY, viewportSize) ?? 0; + y = CSSLength.toDisplayPortValue(translateY, renderStyle: renderStyle) ?? 0; } else { y = 0; } @@ -498,7 +500,7 @@ class RenderStyle translateX = (size!.width * percentage).toString() + 'px'; isPercentageExist = true; } - x = CSSLength.toDisplayPortValue(translateX, viewportSize) ?? 0; + x = CSSLength.toDisplayPortValue(translateX, renderStyle: renderStyle) ?? 0; transform = Matrix4.identity()..translate(x, y); } if (transform != null) { @@ -564,7 +566,7 @@ mixin RenderStyleBase { // Follwing properties used for exposing APIs // for class that extends [RenderStyleBase]. RenderBoxModel? renderBoxModel; - CSSStyleDeclaration? style; + late CSSStyleDeclaration style; late Size viewportSize; } diff --git a/kraken/lib/src/css/style_declaration.dart b/kraken/lib/src/css/style_declaration.dart index 520547ddfa..e5e4797fe1 100644 --- a/kraken/lib/src/css/style_declaration.dart +++ b/kraken/lib/src/css/style_declaration.dart @@ -171,7 +171,7 @@ class CSSStyleDeclaration { return _propertyRunningTransition.containsKey(property); } - void _transition(String propertyName, begin, end, Size? viewportSize) { + void _transition(String propertyName, begin, end, Size? viewportSize, RenderStyle? renderStyle) { if (_hasRunningTransition(propertyName)) { Animation animation = _propertyRunningTransition[propertyName]!; animation.cancel(); @@ -203,7 +203,7 @@ class CSSStyleDeclaration { Keyframe(propertyName, begin, 0, LINEAR), Keyframe(propertyName, end, 1, LINEAR), ]; - KeyframeEffect effect = KeyframeEffect(this, target, keyframes, options, viewportSize); + KeyframeEffect effect = KeyframeEffect(this, target, keyframes, options, viewportSize, renderStyle); Animation animation = Animation(effect); _propertyRunningTransition[propertyName] = animation; @@ -459,7 +459,7 @@ class CSSStyleDeclaration { /// Modifies an existing CSS property or creates a new CSS property in /// the declaration block. - void setProperty(String propertyName, value, [Size? viewportSize]) { + void setProperty(String propertyName, value, [Size? viewportSize, RenderStyle? renderStyle]) { // Null or empty value means should be removed. if (isNullOrEmptyValue(value)) { removeProperty(propertyName); @@ -543,7 +543,7 @@ class CSSStyleDeclaration { if (!CSSBackground.isValidBackgroundRepeatValue(normalizedValue)) return; break; case TRANSFORM: - if (!CSSTransform.isValidTransformValue(normalizedValue, viewportSize)) { + if (!CSSTransform.isValidTransformValue(normalizedValue, viewportSize, renderStyle)) { return; } break; @@ -563,7 +563,7 @@ class CSSStyleDeclaration { } if (_shouldTransition(propertyName, prevValue, normalizedValue)) { - _transition(propertyName, prevValue, normalizedValue, viewportSize); + _transition(propertyName, prevValue, normalizedValue, viewportSize, renderStyle); } else { setRenderStyleProperty(propertyName, prevValue, normalizedValue); } @@ -611,13 +611,6 @@ class CSSStyleDeclaration { _propertyRunningTransition.clear(); } - double? getLengthByPropertyName(String propertyName, ElementManager elementManager) { - double viewportWidth = elementManager.viewportWidth; - double viewportHeight = elementManager.viewportHeight; - Size viewportSize = Size(viewportWidth, viewportHeight); - return CSSLength.toDisplayPortValue(getPropertyValue(propertyName), viewportSize); - } - static bool isNullOrEmptyValue(value) { return value == null || value == ''; } diff --git a/kraken/lib/src/css/text.dart b/kraken/lib/src/css/text.dart index 16b2a35995..483961c88b 100644 --- a/kraken/lib/src/css/text.dart +++ b/kraken/lib/src/css/text.dart @@ -106,7 +106,7 @@ mixin CSSTextMixin on RenderStyleBase { List? _fontFamily; List? get fontFamily { if (CSSText.DEFAULT_FONT_FAMILY_FALLBACK != null) { - return CSSText.getFontFamilyFallback(renderBoxModel!.renderStyle.style!); + return CSSText.getFontFamilyFallback(renderBoxModel!.renderStyle.style); } // Get style from self or closest parent if specified style property is not set // due to style inheritance. @@ -255,7 +255,7 @@ mixin CSSTextMixin on RenderStyleBase { renderBoxModel.visitChildren((RenderObject child) { if (child is RenderLayoutBox) { // Only need to layout when the specified style property is not set. - if (child.renderStyle.style?[styleProperty].isEmpty) { + if (child.renderStyle.style[styleProperty].isEmpty) { _markChildrenNeedsLayoutByLineHeight(child, styleProperty); } } else if (child is RenderTextBox) { @@ -276,7 +276,7 @@ mixin CSSTextMixin on RenderStyleBase { renderBoxModel.visitChildren((RenderObject child) { if (child is RenderLayoutBox) { // Only need to layout when the specified style property is not set. - if (child.renderStyle.style?[styleProperty].isEmpty) { + if (child.renderStyle.style[styleProperty].isEmpty) { _markChildrenNeedsLayoutByWhiteSpace(child, styleProperty); } } else if (child is RenderTextBox) { @@ -319,7 +319,7 @@ mixin CSSTextMixin on RenderStyleBase { renderBoxModel.visitChildren((RenderObject child) { if (child is RenderBoxModel) { // Only need to update child text when style property is not set. - if (child.renderStyle.style?[styleProperty].isEmpty) { + if (child.renderStyle.style[styleProperty].isEmpty) { _updateNestChildrenText(child, styleProperty); } } else if (child is RenderTextBox) { @@ -342,7 +342,7 @@ mixin CSSTextMixin on RenderStyleBase { viewportSize = parentElement.viewportSize; parentRenderBoxModel = parentElement.renderBoxModel; } else { - parentStyle = parentRenderBoxModel!.renderStyle.style!; + parentStyle = parentRenderBoxModel!.renderStyle.style; viewportSize = parentRenderBoxModel.renderStyle.viewportSize; } @@ -387,15 +387,15 @@ mixin CSSTextMixin on RenderStyleBase { FontStyle? fontStyle = parentRenderStyle != null ? parentRenderStyle.fontStyle : CSSText.getFontStyle(parentStyle); double? fontSize = parentRenderStyle != null ? - parentRenderStyle.fontSize : CSSText.getFontSize(parentStyle, viewportSize); + parentRenderStyle.fontSize : CSSText.getFontSize(parentStyle, viewportSize: viewportSize); List? fontFamily = parentRenderStyle != null ? parentRenderStyle.fontFamily : CSSText.getFontFamilyFallback(parentStyle); double? letterSpacing = parentRenderStyle != null ? - parentRenderStyle.letterSpacing : CSSText.getLetterSpacing(parentStyle, viewportSize); + parentRenderStyle.letterSpacing : CSSText.getLetterSpacing(parentStyle, viewportSize: viewportSize); double? wordSpacing = parentRenderStyle != null ? - parentRenderStyle.wordSpacing : CSSText.getWordSpacing(parentStyle, viewportSize); + parentRenderStyle.wordSpacing : CSSText.getWordSpacing(parentStyle, viewportSize: viewportSize); List? textShadow = parentRenderStyle != null ? - parentRenderStyle.textShadow : CSSText.getTextShadow(parentStyle, viewportSize); + parentRenderStyle.textShadow : CSSText.getTextShadow(parentStyle, viewportSize: viewportSize); return TextStyle( color: color, @@ -418,51 +418,53 @@ mixin CSSTextMixin on RenderStyleBase { } void updateTextStyle(String? property) { + RenderStyle renderStyle = this as RenderStyle; + switch (property) { case COLOR: - color = CSSText.getTextColor(style!); + color = CSSText.getTextColor(style); break; case TEXT_DECORATION_LINE: - textDecorationLine = CSSText.getTextDecorationLine(style!); + textDecorationLine = CSSText.getTextDecorationLine(style); break; case TEXT_DECORATION_STYLE: - textDecorationColor = CSSText.getTextDecorationColor(style!); + textDecorationColor = CSSText.getTextDecorationColor(style); break; case TEXT_DECORATION_COLOR: - textDecorationStyle = CSSText.getTextDecorationStyle(style!); + textDecorationStyle = CSSText.getTextDecorationStyle(style); break; case FONT_WEIGHT: - fontWeight = CSSText.getFontWeight(style!); + fontWeight = CSSText.getFontWeight(style); break; case FONT_STYLE: - fontStyle = CSSText.getFontStyle(style!); + fontStyle = CSSText.getFontStyle(style); break; case FONT_FAMILY: - fontFamily = CSSText.getFontFamilyFallback(style!); + fontFamily = CSSText.getFontFamilyFallback(style); break; case FONT_SIZE: - fontSize = CSSText.getFontSize(style!, viewportSize); + fontSize = CSSText.getFontSize(style, renderStyle: renderStyle); break; case LINE_HEIGHT: - lineHeight = CSSText.getLineHeight(style!, viewportSize); + lineHeight = CSSText.getLineHeight(style, renderStyle: renderStyle); break; case LETTER_SPACING: - letterSpacing = CSSText.getLetterSpacing(style!, viewportSize); + letterSpacing = CSSText.getLetterSpacing(style, renderStyle: renderStyle); break; case WORD_SPACING: - wordSpacing = CSSText.getWordSpacing(style!, viewportSize); + wordSpacing = CSSText.getWordSpacing(style, renderStyle: renderStyle); break; case TEXT_SHADOW: - textShadow = CSSText.getTextShadow(style!, viewportSize); + textShadow = CSSText.getTextShadow(style, renderStyle: renderStyle); break; case WHITE_SPACE: - whiteSpace = CSSText.getWhiteSpace(style!); + whiteSpace = CSSText.getWhiteSpace(style); break; case TEXT_OVERFLOW: textOverflow = CSSText.getTextOverflow(renderStyle: this as RenderStyle); break; case LINE_CLAMP: - lineClamp = CSSText.getLineClamp(style!); + lineClamp = CSSText.getLineClamp(style); break; } } @@ -495,15 +497,16 @@ class CSSText { return value == 'solid' || value == 'double' || value == 'dotted' || value == 'dashed' || value == 'wavy'; } - static double? getLineHeight(CSSStyleDeclaration style, Size viewportSize) { - return parseLineHeight(style[LINE_HEIGHT], getFontSize(style, viewportSize), viewportSize); + static double? getLineHeight(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { + return parseLineHeight(style[LINE_HEIGHT], getFontSize(style, viewportSize: viewportSize, renderStyle: renderStyle), + viewportSize: viewportSize, renderStyle: renderStyle); } - static double? parseLineHeight(String value, double fontSize, Size viewportSize) { + static double? parseLineHeight(String value, double fontSize, { Size? viewportSize, RenderStyle? renderStyle }) { double? lineHeight; if (value.isNotEmpty) { if (CSSLength.isLength(value)) { - double lineHeightValue = CSSLength.toDisplayPortValue(value, viewportSize)!; + double lineHeightValue = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderStyle)!; if (lineHeightValue > 0) { lineHeight = lineHeightValue; } @@ -747,31 +750,34 @@ class CSSText { } static double DEFAULT_FONT_SIZE = 16.0; - static double getFontSize(CSSStyleDeclaration style, Size viewportSize) { + static double getFontSize(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { if (style.contains(FONT_SIZE)) { - return CSSLength.toDisplayPortValue(style[FONT_SIZE], viewportSize) ?? DEFAULT_FONT_SIZE; + return CSSLength.toDisplayPortValue(style[FONT_SIZE], viewportSize: viewportSize, renderStyle: renderStyle) + ?? DEFAULT_FONT_SIZE; } else { return DEFAULT_FONT_SIZE; } } - static double getLetterSpacing(CSSStyleDeclaration style, Size viewportSize) { + static double getLetterSpacing(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { if (style.contains(LETTER_SPACING)) { String _letterSpacing = style[LETTER_SPACING]; if (_letterSpacing == NORMAL) return DEFAULT_LETTER_SPACING; - return CSSLength.toDisplayPortValue(_letterSpacing, viewportSize) ?? DEFAULT_LETTER_SPACING; + return CSSLength.toDisplayPortValue(_letterSpacing, viewportSize: viewportSize, renderStyle: renderStyle) + ?? DEFAULT_LETTER_SPACING; } else { return DEFAULT_LETTER_SPACING; } } - static double getWordSpacing(CSSStyleDeclaration style, Size viewportSize) { + static double getWordSpacing(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { if (style.contains(WORD_SPACING)) { String _wordSpacing = style[WORD_SPACING]; if (_wordSpacing == NORMAL) return DEFAULT_WORD_SPACING; - return CSSLength.toDisplayPortValue(_wordSpacing, viewportSize) ?? DEFAULT_WORD_SPACING; + return CSSLength.toDisplayPortValue(_wordSpacing, viewportSize: viewportSize, renderStyle: renderStyle) + ?? DEFAULT_WORD_SPACING; } else { return DEFAULT_WORD_SPACING; } @@ -792,7 +798,7 @@ class CSSText { return null; } - static List getTextShadow(CSSStyleDeclaration style, Size viewportSize) { + static List getTextShadow(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { List textShadows = []; if (style.contains(TEXT_SHADOW)) { var shadows = CSSStyleProperty.getShadowValues(style[TEXT_SHADOW]); @@ -800,9 +806,9 @@ class CSSText { for (var shadowDefinitions in shadows) { // Specifies the color of the shadow. If the color is absent, it defaults to currentColor. Color? color = CSSColor.parseColor(shadowDefinitions[0] ?? style.getCurrentColor()); - double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], viewportSize) ?? 0; - double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], viewportSize) ?? 0; - double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], viewportSize) ?? 0; + double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; if (color != null) { textShadows.add(Shadow( diff --git a/kraken/lib/src/css/transform.dart b/kraken/lib/src/css/transform.dart index a04f943a0f..cd2f84fcb0 100644 --- a/kraken/lib/src/css/transform.dart +++ b/kraken/lib/src/css/transform.dart @@ -12,7 +12,7 @@ import 'package:kraken/dom.dart'; // CSS Transforms: https://drafts.csswg.org/css-transforms/ final RegExp _spaceRegExp = RegExp(r'\s+(?![^(]*\))'); -Color? _parseColor(String color, [Size? viewportSize]) { +Color? _parseColor(String color, [Size? viewportSize, RenderStyle? renderStyle]) { return CSSColor.parseColor(color); } @@ -47,8 +47,8 @@ void _updateColor(Color oldColor, Color newColor, double progress, String proper } } -double? _parseLength(String _length, [Size? viewportSize]) { - return CSSLength.parseLength(_length, viewportSize); +double? _parseLength(String _length, [Size? viewportSize, RenderStyle? renderStyle]) { + return CSSLength.parseLength(_length, viewportSize: viewportSize, renderStyle: renderStyle); } void _updateLength(double oldLength, double newLength, double progress, String property, RenderStyle renderStyle) { @@ -106,7 +106,7 @@ void _updateLength(double oldLength, double newLength, double progress, String p } } -FontWeight _parseFontWeight(String fontWeight, [Size? viewportSize]) { +FontWeight _parseFontWeight(String fontWeight, [Size? viewportSize, RenderStyle? renderStyle]) { return CSSText.parseFontWeight(fontWeight); } @@ -119,7 +119,7 @@ void _updateFontWeight(FontWeight oldValue, FontWeight newValue, double progress } } -double? _parseNumber(String number, [Size? viewportSize]) { +double? _parseNumber(String number, [Size? viewportSize, RenderStyle? renderStyle]) { return CSSNumber.parseNumber(number); } @@ -145,7 +145,7 @@ void _updateNumber(double oldValue, double newValue, double progress, String pro } } -String _parseLineHeight(String lineHeight, [Size? viewportSize]) { +String _parseLineHeight(String lineHeight, [Size? viewportSize, RenderStyle? renderStyle]) { return lineHeight; } @@ -154,8 +154,8 @@ void _updateLineHeight(String oldValue, String newValue, double progress, String double? lineHeight; if (CSSLength.isLength(oldValue) && CSSLength.isLength(newValue)) { - double left = CSSLength.parseLength(oldValue, viewportSize)!; - double right = CSSLength.parseLength(newValue, viewportSize)!; + double left = CSSLength.parseLength(oldValue, viewportSize: viewportSize, renderStyle: renderStyle)!; + double right = CSSLength.parseLength(newValue, viewportSize: viewportSize, renderStyle: renderStyle)!; lineHeight = _getNumber(left, right, progress); } else if (CSSNumber.isNumber(oldValue) && CSSNumber.isNumber(newValue)) { double left = CSSNumber.parseNumber(oldValue)!; @@ -170,8 +170,8 @@ void _updateLineHeight(String oldValue, String newValue, double progress, String } } -Matrix4? _parseTransform(String value, [Size? viewportSize]) { - return CSSTransform.parseTransform(value, viewportSize); +Matrix4? _parseTransform(String value, [Size? viewportSize, RenderStyle? renderStyle]) { + return CSSTransform.parseTransform(value, viewportSize, renderStyle); } double _lerpDouble(double begin, double to, double t) { @@ -799,18 +799,18 @@ class CSSTransform { return [translate, scale, angle, m11, m12, m21, m22]; } - static bool isValidTransformValue(String value, [Size? viewportSize]) { - return value == NONE || parseTransform(value, viewportSize) != null; + static bool isValidTransformValue(String value, [Size? viewportSize, RenderStyle? renderStyle]) { + return value == NONE || parseTransform(value, viewportSize, renderStyle) != null; } static Matrix4 initial = Matrix4.identity(); - static Matrix4? parseTransform(String value, [Size? viewportSize]) { + static Matrix4? parseTransform(String value, [Size? viewportSize, RenderStyle? renderStyle]) { List methods = CSSFunction.parseFunction(value); Matrix4? matrix4; for (CSSFunctionalNotation method in methods) { - Matrix4? transform = _parseTransform(method, viewportSize); + Matrix4? transform = _parseTransform(method, viewportSize, renderStyle); if (transform != null) { if (matrix4 == null) { matrix4 = transform; @@ -844,7 +844,7 @@ class CSSTransform { static const String SKEW_Y = 'skewy'; static const String PERSPECTIVE = 'perspective'; - static Matrix4? _parseTransform(CSSFunctionalNotation method, [Size? viewportSize]) { + static Matrix4? _parseTransform(CSSFunctionalNotation method, [Size? viewportSize, RenderStyle? renderStyle]) { switch (method.name) { case MATRIX: if (method.args.length == 6) { @@ -869,11 +869,11 @@ class CSSTransform { if (method.args.length >= 1 && method.args.length <= 2) { double y; if (method.args.length == 2) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize) ?? 0; + y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; } else { y = 0; } - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; return Matrix4.identity()..translate(x, y); } break; @@ -885,31 +885,31 @@ class CSSTransform { if (method.args.length >= 1 && method.args.length <= 3) { double y = 0, z = 0; if (method.args.length == 2) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize) ?? 0; + y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; } if (method.args.length == 3) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize) ?? 0; - z = CSSLength.toDisplayPortValue(method.args[2].trim(), viewportSize) ?? 0; + y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + z = CSSLength.toDisplayPortValue(method.args[2].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; } - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; return Matrix4.identity()..translate(x, y, z); } break; case TRANSLATE_X: if (method.args.length == 1) { - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; return Matrix4.identity()..translate(x); } break; case TRANSLATE_Y: if (method.args.length == 1) { - double y = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double y = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; return Matrix4.identity()..translate(0.0, y); } break; case TRANSLATE_Z: if (method.args.length == 1) { - double z = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double z = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; return Matrix4.identity()..translate(0.0, 0.0, z); } break; @@ -1008,7 +1008,7 @@ class CSSTransform { // 0, 0, 1, perspective, // 0, 0, 0, 1] if (method.args.length == 1) { - double p = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize) ?? 0; + double p = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; p = (-1 / p); return Matrix4.identity()..storage[11] = p; } @@ -1024,7 +1024,7 @@ class CSSOrigin { CSSOrigin(this.offset, this.alignment); - static CSSOrigin? parseOrigin(String origin, Size viewportSize) { + static CSSOrigin? parseOrigin(String origin, RenderStyle renderStyle) { if (origin.isNotEmpty) { List originList = origin.trim().split(_spaceRegExp); String? x, y; @@ -1051,7 +1051,7 @@ class CSSOrigin { // handle x if (CSSLength.isLength(x)) { - offsetX = CSSLength.toDisplayPortValue(x, viewportSize) ?? offsetX; + offsetX = CSSLength.toDisplayPortValue(x, renderStyle: renderStyle) ?? offsetX; } else if (CSSPercentage.isPercentage(x)) { alignX = CSSPercentage.parsePercentage(x!)! * 2 - 1; } else if (x == CSSPosition.LEFT) { @@ -1064,7 +1064,7 @@ class CSSOrigin { // handle y if (CSSLength.isLength(y)) { - offsetY = CSSLength.toDisplayPortValue(y, viewportSize) ?? offsetY; + offsetY = CSSLength.toDisplayPortValue(y, renderStyle: renderStyle) ?? offsetY; } else if (CSSPercentage.isPercentage(y)) { alignY = CSSPercentage.parsePercentage(y!)! * 2 - 1; } else if (y == CSSPosition.TOP) { @@ -1131,7 +1131,8 @@ mixin CSSTransformMixin on RenderStyleBase { } void updateTransformOrigin(String present, [CSSOrigin? newOrigin]) { - CSSOrigin? transformOriginValue = newOrigin ?? CSSOrigin.parseOrigin(present, viewportSize); + RenderStyle renderStyle = this as RenderStyle; + CSSOrigin? transformOriginValue = newOrigin ?? CSSOrigin.parseOrigin(present, renderStyle); if (transformOriginValue == null) return; Offset oldOffset = transformOffset; diff --git a/kraken/lib/src/css/values/length.dart b/kraken/lib/src/css/values/length.dart index f44e254a6a..d4f39788c2 100644 --- a/kraken/lib/src/css/values/length.dart +++ b/kraken/lib/src/css/values/length.dart @@ -8,6 +8,7 @@ import 'dart:ui'; import 'package:kraken/css.dart'; +import 'package:kraken/rendering.dart'; // https://drafts.csswg.org/css-values-3/#absolute-lengths const _1in = 96; // 1in = 2.54cm = 96px @@ -17,7 +18,7 @@ const _1Q = _1cm / 40; // 1Q = 1/40th of 1cm const _1pc = _1in / 6; // 1pc = 1/6th of 1in const _1pt = _1in / 72; // 1pt = 1/72th of 1in -final _lengthRegExp = RegExp(r'^[+-]?(\d+)?(\.\d+)?px|rpx|vw|vh|vmin|vmax|in|cm|mm|pc|pt$', caseSensitive: false); +final _lengthRegExp = RegExp(r'^[+-]?(\d+)?(\.\d+)?px|rpx|vw|vh|vmin|vmax|rem|em|in|cm|mm|pc|pt$', caseSensitive: false); final _percentageRegExp = RegExp(r'^\d+\%$', caseSensitive: false); // CSS Values and Units: https://drafts.csswg.org/css-values-3/#lengths @@ -34,6 +35,8 @@ class CSSLength { static const String PC = 'pc'; static const String PT = 'pt'; static const String Q = 'q'; + static const String EM = 'em'; + static const String REM = 'rem'; static double? toDouble(value) { if (value is double) { @@ -71,23 +74,39 @@ class CSSLength { return double.tryParse(percentage.split('%')[0])! / 100; } - static double? parseLength(String unitedValue, Size? viewportSize) { - return toDisplayPortValue(unitedValue, viewportSize); + static double? parseLength(String unitedValue, { Size? viewportSize, RenderStyle? renderStyle }) { + return toDisplayPortValue(unitedValue, viewportSize: viewportSize, renderStyle: renderStyle); } - static double? toDisplayPortValue(String? unitedValue, Size? viewportSize) { + static double? toDisplayPortValue(String? unitedValue, { Size? viewportSize, RenderStyle? renderStyle }) { if (unitedValue == null || unitedValue.isEmpty) return null; unitedValue = unitedValue.trim(); if (unitedValue == INITIAL) return null; double? displayPortValue; - double viewportWidth = viewportSize!.width; - double viewportHeight = viewportSize.height; + Size _viewportSize = renderStyle != null ? renderStyle.viewportSize : viewportSize!; + double viewportWidth = _viewportSize.width; + double viewportHeight = _viewportSize.height; // Only '0' is accepted with no unit. if (unitedValue == ZERO) { return 0; + } else if (unitedValue.endsWith(REM)) { + double? currentValue = double.tryParse(unitedValue.split(REM)[0]); + if (currentValue == null || renderStyle == null) return null; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + RenderBoxModel? documentRoot = renderBoxModel.getDocumentRoot(); + if (documentRoot != null) { + double rootFontSize = documentRoot.renderStyle.fontSize; + return rootFontSize * currentValue; + } + return null; + } else if (unitedValue.endsWith(EM)) { + double? currentValue = double.tryParse(unitedValue.split(EM)[0]); + if (currentValue == null || renderStyle == null) return null; + double fontSize = renderStyle.fontSize; + return fontSize * currentValue; } else if (unitedValue.endsWith(RPX)) { double? currentValue = double.tryParse(unitedValue.split(RPX)[0]); if (currentValue == null) return null; diff --git a/kraken/lib/src/css/values/position.dart b/kraken/lib/src/css/values/position.dart index e37a570225..ecbc9c9925 100644 --- a/kraken/lib/src/css/values/position.dart +++ b/kraken/lib/src/css/values/position.dart @@ -53,11 +53,11 @@ class CSSPosition { } /// Parse background-position-x/background-position-y from string to CSSBackgroundPosition type. - static CSSBackgroundPosition parsePosition(String input, Size viewportSize, bool isHorizontal) { + static CSSBackgroundPosition parsePosition(String input, RenderStyle renderStyle, bool isHorizontal) { if (CSSLength.isPercentage(input)) { return CSSBackgroundPosition(percentage: _gatValuePercentage(input)); } else if (CSSLength.isLength(input)) { - return CSSBackgroundPosition(length: CSSLength.toDisplayPortValue(input, viewportSize)); + return CSSBackgroundPosition(length: CSSLength.toDisplayPortValue(input, renderStyle: renderStyle)); } else { if (isHorizontal) { switch (input) { diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index 12b31742ac..2004dbf9e9 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -209,10 +209,10 @@ class Element extends Node void _beforeRendererAttach() { willAttachRenderer(); - style.applyTargetProperties(); } void _afterRendererAttach() { + style.applyTargetProperties(); didAttachRenderer(); ensureChildAttached(); } @@ -538,54 +538,11 @@ class Element extends Node CSSDisplay display = CSSDisplayMixin.getDisplay(style[DISPLAY] ?? defaultDisplay); if (display != CSSDisplay.none) { willAttachRenderer(); - style.applyTargetProperties(); - - CSSDisplay? parentDisplayValue = parent.renderBoxModel!.renderStyle.display; - // InlineFlex or Flex - bool isParentFlexDisplayType = parentDisplayValue == CSSDisplay.flex || - parentDisplayValue == CSSDisplay.inlineFlex; - parent.addChildRenderObject(this, after: after); - ensureChildAttached(); + style.applyTargetProperties(); - /// Update flex siblings. - if (isParentFlexDisplayType) { - for (Element child in parent.children) { - RenderBoxModel? childRenderBoxModel = child.renderBoxModel; - if (parent.renderBoxModel is RenderFlexLayout && childRenderBoxModel != null) { - childRenderBoxModel.renderStyle.updateFlexItem(); - childRenderBoxModel.markNeedsLayout(); - } - } - } - - RenderBoxModel selfRenderBoxModel = renderBoxModel!; - - /// Recalculate gradient after node attached when gradient length cannot be obtained from style - if (selfRenderBoxModel.shouldRecalGradient) { - String backgroundImage = style[BACKGROUND_IMAGE]; - int contextId = elementManager.contextId; - selfRenderBoxModel.renderStyle.updateBox(BACKGROUND_IMAGE, backgroundImage, backgroundImage, contextId); - selfRenderBoxModel.shouldRecalGradient = false; - } - - /// Calculate font-size which is percentage when node attached - /// where it can access the font-size of its parent element - if (selfRenderBoxModel.shouldLazyCalFontSize) { - _updatePercentageFontSize(); - selfRenderBoxModel.shouldLazyCalFontSize = false; - } - - /// Calculate line-height which is percentage when node attached - /// where it can access the font-size of its own element - if (selfRenderBoxModel.shouldLazyCalLineHeight) { - _updatePercentageLineHeight(); - selfRenderBoxModel.shouldLazyCalLineHeight = false; - } - - RenderStyle renderStyle = selfRenderBoxModel.renderStyle; - + RenderStyle renderStyle = renderBoxModel!.renderStyle; /// Set display and transformedDisplay when display is not set in style renderStyle.initDisplay(style, defaultDisplay); didAttachRenderer(); @@ -1002,9 +959,10 @@ class Element extends Node return; } - double? presentValue = CSSLength.toDisplayPortValue(present, viewportSize); + RenderStyle renderStyle = renderBoxModel!.renderStyle; + double? presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle); if (presentValue == null) return; - renderBoxModel!.renderStyle.updateOffset(property, presentValue); + renderStyle.updateOffset(property, presentValue); } void _styleTextAlignChangedListener(String property, String? original, String present) { @@ -1042,8 +1000,9 @@ class Element extends Node return; } - double presentValue = CSSLength.toDisplayPortValue(present, viewportSize) ?? 0; - selfRenderBoxModel.renderStyle.updatePadding(property, presentValue); + RenderStyle renderStyle = selfRenderBoxModel.renderStyle; + double presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle) ?? 0; + renderStyle.updatePadding(property, presentValue); } void _styleSizeChangedListener(String property, String? original, String present) { @@ -1057,8 +1016,9 @@ class Element extends Node return; } - double? presentValue = CSSLength.toDisplayPortValue(present, viewportSize); - selfRenderBoxModel.renderStyle.updateSizing(property, presentValue); + RenderStyle renderStyle = selfRenderBoxModel.renderStyle; + double? presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle); + renderStyle.updateSizing(property, presentValue); } void _styleMarginChangedListener(String property, String? original, String present) { @@ -1072,8 +1032,8 @@ class Element extends Node return; } - double presentValue = CSSLength.toDisplayPortValue(present, viewportSize) ?? 0; RenderStyle renderStyle = selfRenderBoxModel.renderStyle; + double presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle) ?? 0; renderStyle.updateMargin(property, presentValue); // Margin change in flex layout may affect transformed display // https://www.w3.org/TR/css-display-3/#transformations @@ -1157,8 +1117,9 @@ class Element extends Node return; } - Matrix4? matrix4 = CSSTransform.parseTransform(present, viewportSize); - selfRenderBoxModel.renderStyle.updateTransform(matrix4); + RenderStyle renderStyle = selfRenderBoxModel.renderStyle; + Matrix4? matrix4 = CSSTransform.parseTransform(present, renderStyle.viewportSize, renderStyle); + renderStyle.updateTransform(matrix4); } void _styleTransformOriginChangedListener(String property, String? original, String present) { @@ -1168,26 +1129,17 @@ class Element extends Node // Update text related style void _updateTextStyle(String property) { - RenderBoxModel selfRenderBoxModel = renderBoxModel!; /// Percentage font-size should be resolved when node attached /// cause it needs to know its parents style if (property == FONT_SIZE && CSSLength.isPercentage(style[FONT_SIZE])) { - if (selfRenderBoxModel.attached) { - _updatePercentageFontSize(); - } else { - selfRenderBoxModel.shouldLazyCalFontSize = true; - } + _updatePercentageFontSize(); return; } /// Percentage line-height should be resolved when node attached /// cause it needs to know other style in its own element if (property == LINE_HEIGHT && CSSLength.isPercentage(style[LINE_HEIGHT])) { - if (selfRenderBoxModel.attached) { - _updatePercentageLineHeight(); - } else { - selfRenderBoxModel.shouldLazyCalLineHeight = true; - } + _updatePercentageLineHeight(); return; } renderBoxModel!.renderStyle.updateTextStyle(property); @@ -1220,14 +1172,14 @@ class Element extends Node // then trigger the animation phase. if (key == TRANSITION) { SchedulerBinding.instance!.addPostFrameCallback((timestamp) { - style.setProperty(key, value, viewportSize); + style.setProperty(key, value, viewportSize, renderBoxModel?.renderStyle); }); return; } else { CSSDisplay originalDisplay = CSSDisplayMixin.getDisplay(style[DISPLAY] ?? defaultDisplay); // @NOTE: See [CSSStyleDeclaration.setProperty], value change will trigger // [StyleChangeListener] to be invoked in sync. - style.setProperty(key, value, viewportSize); + style.setProperty(key, value, viewportSize, renderBoxModel?.renderStyle); // When renderer and style listener is not created when original display is none, // thus it needs to create renderer when style changed. diff --git a/kraken/lib/src/dom/elements/canvas/canvas.dart b/kraken/lib/src/dom/elements/canvas/canvas.dart index 5c09d72886..61a545b449 100644 --- a/kraken/lib/src/dom/elements/canvas/canvas.dart +++ b/kraken/lib/src/dom/elements/canvas/canvas.dart @@ -102,16 +102,12 @@ class CanvasElement extends Element { // RenderingContext? getContext(DOMString contextId, optional any options = null); CanvasRenderingContext2D getContext(String contextId, {dynamic options}) { - double viewportWidth = elementManager.viewportWidth; - double viewportHeight = elementManager.viewportHeight; - Size viewportSize = Size(viewportWidth, viewportHeight); - switch (contextId) { case '2d': if (painter.context == null) { CanvasRenderingContext2D context2d = CanvasRenderingContext2D(); context2d.canvas = this; - context2d.viewportSize = viewportSize; + context2d.renderStyle = renderBoxModel!.renderStyle; painter.context = context2d; } return painter.context!; diff --git a/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart b/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart index ba1ff2a83f..8f0b5da9cb 100644 --- a/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart +++ b/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart @@ -363,7 +363,7 @@ class CanvasRenderingContext2D { CanvasRenderingContext2DSettings getContextAttributes() => _settings; - late Size viewportSize; + late RenderStyle renderStyle; late CanvasElement canvas; // HACK: We need record the current matrix state because flutter canvas not export resetTransform now. // https://github.com/flutter/engine/pull/25449 @@ -869,7 +869,7 @@ class CanvasRenderingContext2D { if (_fontProperties.isEmpty) { _parseFont(_DEFAULT_FONT); } - double? fontSize = CSSLength.toDisplayPortValue(_fontProperties[FONT_SIZE] ?? '10px', viewportSize); + double? fontSize = CSSLength.toDisplayPortValue(_fontProperties[FONT_SIZE] ?? '10px', renderStyle: renderStyle); var fontFamilyFallback = CSSText.parseFontFamilyFallback(_fontProperties[FONT_FAMILY] ?? 'sans-serif'); FontWeight fontWeight = CSSText.parseFontWeight(_fontProperties[FONT_WEIGHT]); if (shouldStrokeText) { diff --git a/kraken/lib/src/dom/elements/img.dart b/kraken/lib/src/dom/elements/img.dart index d1a6c97f5b..7a939e987e 100644 --- a/kraken/lib/src/dom/elements/img.dart +++ b/kraken/lib/src/dom/elements/img.dart @@ -380,14 +380,14 @@ class ImageElement extends Element { value += 'px'; } - _propertyWidth = CSSLength.toDisplayPortValue(value, viewportSize); + _propertyWidth = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderBoxModel?.renderStyle); _resize(); } else if (key == HEIGHT) { if (value is String && _isNumberString(value)) { value += 'px'; } - _propertyHeight = CSSLength.toDisplayPortValue(value, viewportSize); + _propertyHeight = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderBoxModel?.renderStyle); _resize(); } } diff --git a/kraken/lib/src/rendering/box_model.dart b/kraken/lib/src/rendering/box_model.dart index 899638a7b8..0f678e2d3e 100644 --- a/kraken/lib/src/rendering/box_model.dart +++ b/kraken/lib/src/rendering/box_model.dart @@ -523,31 +523,6 @@ class RenderBoxModel extends RenderBox return _contentConstraints; } - /// Whether need to recalculate gradient when setting style used in cases - /// when linear-gradient has length specified and layout has no size in gradient direction - /// such as 'linear-gradient(to right, red 0px, red 50px, orange 50px, orange 80px)' and style has no width set - bool _shouldRecalGradient = false; - - bool get shouldRecalGradient => _shouldRecalGradient; - - set shouldRecalGradient(bool value) { - if (_shouldRecalGradient != value) { - _shouldRecalGradient = value; - } - } - - /// Used when setting percentage font-size style, it needs to be calculated when node attached - /// where it needs to know the font-size of its parent element - bool _shouldLazyCalFontSize = false; - - bool get shouldLazyCalFontSize => _shouldLazyCalFontSize; - - set shouldLazyCalFontSize(bool value) { - if (_shouldLazyCalFontSize != value) { - _shouldLazyCalFontSize = value; - } - } - /// Used when setting percentage line-height style, it needs to be calculated when node attached /// where it needs to know the font-size of its own element bool _shouldLazyCalLineHeight = false; @@ -1576,7 +1551,7 @@ class RenderBoxModel extends RenderBox RenderBoxModel? getSelfParentWithSpecifiedStyle(String styleProperty) { RenderObject? _parent = this; while (_parent != null && _parent is! RenderViewportBox) { - if (_parent is RenderBoxModel && _parent.renderStyle.style![styleProperty].isNotEmpty) { + if (_parent is RenderBoxModel && _parent.renderStyle.style[styleProperty].isNotEmpty) { break; } if (_parent.parent != null) { @@ -1592,6 +1567,14 @@ class RenderBoxModel extends RenderBox return _parent != null ? _parent as RenderBoxModel : null; } + RenderBoxModel? getDocumentRoot() { + RenderBoxModel _self = this; + while (_self.parent != null && _self.parent is! RenderViewportBox) { + _self = _self.parent as RenderBoxModel; + } + return _self.parent is RenderViewportBox ? _self : null; + } + @override bool hitTestSelf(Offset position) { return size.contains(position); From 930e49f0c8562b6841e4afb506fa8c8ab5ab0b93 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Wed, 7 Jul 2021 20:07:41 +0800 Subject: [PATCH 02/17] chore: upgrade kraken_webview version --- integration_tests/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/pubspec.yaml b/integration_tests/pubspec.yaml index 3658144525..e6418d382d 100644 --- a/integration_tests/pubspec.yaml +++ b/integration_tests/pubspec.yaml @@ -30,7 +30,7 @@ dependencies: kraken_video_player: ^0.4.0 kraken_websocket: ^0.2.0 kraken_animation_player: ^0.2.0 - kraken_webview: ^0.6.0 + kraken_webview: ^0.7.0-dev.1 dev_dependencies: test: ^1.16.8 From cd494180192f66cc9c066f9dcd90d0c49b16cfda Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Wed, 7 Jul 2021 20:38:39 +0800 Subject: [PATCH 03/17] fix: set style timing --- kraken/lib/src/dom/element.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index 2004dbf9e9..96b09ec6f4 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -538,9 +538,10 @@ class Element extends Node CSSDisplay display = CSSDisplayMixin.getDisplay(style[DISPLAY] ?? defaultDisplay); if (display != CSSDisplay.none) { willAttachRenderer(); + parent.addChildRenderObject(this, after: after); - ensureChildAttached(); style.applyTargetProperties(); + ensureChildAttached(); RenderStyle renderStyle = renderBoxModel!.renderStyle; /// Set display and transformedDisplay when display is not set in style From 935ac6d8ef3d6bed7d3fe7ea491601068f6bca3d Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 14:13:53 +0800 Subject: [PATCH 04/17] fix: position sticky element change to repaint boundary error --- kraken/lib/src/dom/element.dart | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index 96b09ec6f4..cb3fb4b00b 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -368,6 +368,14 @@ class Element extends Node ContainerParentDataMixin? _parentData = _renderBoxModel.parentData as ContainerParentDataMixin?; if (_parentData != null) { previousSibling = _parentData.previousSibling; + // Get the renderBox before the RenderPositionHolder to find the renderBox to insert after + // cause renderPositionHolder of sticky element lays before the renderBox. + if (previousSibling is RenderPositionHolder) { + ContainerParentDataMixin? _parentData = previousSibling.parentData as ContainerParentDataMixin?; + if (_parentData != null) { + previousSibling = _parentData.previousSibling; + } + } parentRenderObject.remove(_renderBoxModel); } } @@ -393,10 +401,6 @@ class Element extends Node RenderBoxModel _renderBoxModel = renderBoxModel!; Element _parentElement = parentElement!; - if (_renderBoxModel.parent is RenderLayoutBox) { - _renderBoxModel.renderStyle.position = currentPosition; - } - // Remove fixed children before convert to non repaint boundary renderObject if (currentPosition != CSSPositionType.fixed) { _removeFixedChild(_renderBoxModel); @@ -525,7 +529,7 @@ class Element extends Node parentRenderLayoutBox.insert(child.renderBoxModel!, after: after); if (positionType == CSSPositionType.sticky) { - _addPositionHolder(parentRenderLayoutBox, child); + _addPositionHolder(parentRenderLayoutBox, child, positionType); } } break; @@ -538,14 +542,11 @@ class Element extends Node CSSDisplay display = CSSDisplayMixin.getDisplay(style[DISPLAY] ?? defaultDisplay); if (display != CSSDisplay.none) { willAttachRenderer(); - + parent.addChildRenderObject(this, after: after); + style.applyTargetProperties(); ensureChildAttached(); - - RenderStyle renderStyle = renderBoxModel!.renderStyle; - /// Set display and transformedDisplay when display is not set in style - renderStyle.initDisplay(style, defaultDisplay); didAttachRenderer(); } } @@ -683,14 +684,14 @@ class Element extends Node _setPositionedChildParentData(parentRenderLayoutBox, child); parentRenderLayoutBox.add(childRenderBoxModel); - _addPositionHolder(parentRenderLayoutBox, child); + _addPositionHolder(parentRenderLayoutBox, child, position); } - void _addPositionHolder(RenderLayoutBox parentRenderLayoutBox, Element child) { + void _addPositionHolder(RenderLayoutBox parentRenderLayoutBox, Element child, CSSPositionType position) { Size preferredSize = Size.zero; RenderBoxModel childRenderBoxModel = child.renderBoxModel!; RenderStyle childRenderStyle = childRenderBoxModel.renderStyle; - if (childRenderStyle.position == CSSPositionType.sticky) { + if (position == CSSPositionType.sticky) { preferredSize = Size(0, 0); } else if (childRenderStyle.display != CSSDisplay.inline) { preferredSize = Size( @@ -702,7 +703,7 @@ class Element extends Node childRenderBoxModel.renderPositionHolder = childPositionHolder; childPositionHolder.realDisplayedBox = childRenderBoxModel; - if (childRenderStyle.position == CSSPositionType.sticky) { + if (position == CSSPositionType.sticky) { // Placeholder of sticky renderBox need to inherit offset from original renderBox, // so it needs to layout before original renderBox RenderBox? preSibling = parentRenderLayoutBox.childBefore(childRenderBoxModel); @@ -927,12 +928,12 @@ class Element extends Node void _stylePositionChangedListener(String property, String? original, String present) { /// Update position. - CSSPositionType prevPosition = CSSPositionMixin.parsePositionType(original); + CSSPositionType prevPosition = renderBoxModel!.renderStyle.position; CSSPositionType currentPosition = CSSPositionMixin.parsePositionType(present); - renderBoxModel!.renderStyle.updatePosition(property, present); // Position changed. if (prevPosition != currentPosition) { + renderBoxModel!.renderStyle.updatePosition(property, present); _updatePosition(prevPosition, currentPosition); } } From bb91807b7a46b34c1233cca2633bc885c5b1dbf4 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 14:36:39 +0800 Subject: [PATCH 05/17] fix: should init transformed display after node is attached --- kraken/lib/src/dom/element.dart | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index cb3fb4b00b..8e6aad2c4b 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -246,9 +246,6 @@ class Element extends Node renderStyle = renderLayoutBox.renderStyle; } - /// Set display and transformedDisplay when display is not set in style - renderStyle.initDisplay(style, defaultDisplay); - return renderer!; } @@ -262,6 +259,9 @@ class Element extends Node void didAttachRenderer() { RenderBoxModel _renderBoxModel = renderBoxModel!; + // Set display and transformedDisplay when display is not set in style. + _renderBoxModel.renderStyle.initDisplay(style, defaultDisplay); + // Bind pointer responder. addEventResponder(_renderBoxModel); @@ -541,13 +541,9 @@ class Element extends Node void attachTo(Element parent, {RenderBox? after}) { CSSDisplay display = CSSDisplayMixin.getDisplay(style[DISPLAY] ?? defaultDisplay); if (display != CSSDisplay.none) { - willAttachRenderer(); - + _beforeRendererAttach(); parent.addChildRenderObject(this, after: after); - - style.applyTargetProperties(); - ensureChildAttached(); - didAttachRenderer(); + _afterRendererAttach(); } } From 51e9b1e3f4174b16e4c51b2ff6044cd52133faf5 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 14:41:08 +0800 Subject: [PATCH 06/17] fix: lint --- kraken/lib/src/dom/element.dart | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index 8e6aad2c4b..592ebbfa45 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -230,20 +230,17 @@ class Element extends Node return renderer!; } - RenderStyle? renderStyle; // Content children layout, BoxModel content. if (_isIntrinsicBox) { - RenderIntrinsic renderIntrinsic = _renderIntrinsic = createRenderIntrinsic( + _renderIntrinsic = createRenderIntrinsic( this, repaintSelf: repaintSelf, ); - renderStyle = renderIntrinsic.renderStyle; } else { - RenderLayoutBox renderLayoutBox = _renderLayoutBox = createRenderLayout( + _renderLayoutBox = createRenderLayout( this, repaintSelf: repaintSelf, ); - renderStyle = renderLayoutBox.renderStyle; } return renderer!; From eab3cfa833b8420e9ad1ebff3673ff9e4904cb27 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 14:59:09 +0800 Subject: [PATCH 07/17] test: mod test for em --- integration_tests/specs/css/css-flexbox/align-items.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/integration_tests/specs/css/css-flexbox/align-items.ts b/integration_tests/specs/css/css-flexbox/align-items.ts index 81b5a2360c..5833db9703 100644 --- a/integration_tests/specs/css/css-flexbox/align-items.ts +++ b/integration_tests/specs/css/css-flexbox/align-items.ts @@ -144,7 +144,7 @@ describe('align-items', () => { await snapshot(); }); - it('004', async () => { + fit('004', async () => { let div1; let div2; let div3; @@ -165,7 +165,8 @@ describe('align-items', () => { height: '100px', width: '300px', color: 'yellow', - font: '20px/1em Ahem', + // @TODO: disable line-height cause line-height rule for inline level element differs from browser. + font: '20px Ahem', 'box-sizing': 'border-box', }, }, From 2586820d398dcb18c4d9f595419cc713d557fdb2 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 15:01:51 +0800 Subject: [PATCH 08/17] test: update snapshot --- .../css-flexbox/align-items.ts.c4b9cf121.png | Bin 6855 -> 7580 bytes .../specs/css/css-flexbox/align-items.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/snapshots/css/css-flexbox/align-items.ts.c4b9cf121.png b/integration_tests/snapshots/css/css-flexbox/align-items.ts.c4b9cf121.png index acf68867095b233397462fa0a6dd31c018a0fbaa..d38d250212f90cca2cc654f2b9d470b05cde68da 100644 GIT binary patch literal 7580 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 delta 4783 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 diff --git a/integration_tests/specs/css/css-flexbox/align-items.ts b/integration_tests/specs/css/css-flexbox/align-items.ts index 5833db9703..6fe12742b4 100644 --- a/integration_tests/specs/css/css-flexbox/align-items.ts +++ b/integration_tests/specs/css/css-flexbox/align-items.ts @@ -144,7 +144,7 @@ describe('align-items', () => { await snapshot(); }); - fit('004', async () => { + it('004', async () => { let div1; let div2; let div3; From 2670ac01b209664aa65ca24085e961a13d0cb7e1 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 16:31:01 +0800 Subject: [PATCH 09/17] feat: add font-size change logic for children style with rem & em. --- kraken/lib/src/css/style_declaration.dart | 20 ++++++++++++ kraken/lib/src/css/text.dart | 40 ++++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/kraken/lib/src/css/style_declaration.dart b/kraken/lib/src/css/style_declaration.dart index e5e4797fe1..a296d55b06 100644 --- a/kraken/lib/src/css/style_declaration.dart +++ b/kraken/lib/src/css/style_declaration.dart @@ -601,6 +601,26 @@ class CSSStyleDeclaration { setRenderStyleProperty(key, null, normalizedValue); }); } + + /// Set all style properties with em unit. + void applyEmProperties() { + _properties.forEach((key, value) { + if (value.endsWith(CSSLength.EM)) { + String normalizedValue = _normalizeValue(value); + setRenderStyleProperty(key, null, normalizedValue); + } + }); + } + + /// Set all style properties with rem unit. + void applyRemProperties() { + _properties.forEach((key, value) { + if (value.endsWith(CSSLength.REM)) { + String normalizedValue = _normalizeValue(value); + setRenderStyleProperty(key, null, normalizedValue); + } + }); + } void dispose() { target = null; diff --git a/kraken/lib/src/css/text.dart b/kraken/lib/src/css/text.dart index 483961c88b..beb15cbd65 100644 --- a/kraken/lib/src/css/text.dart +++ b/kraken/lib/src/css/text.dart @@ -136,8 +136,11 @@ mixin CSSTextMixin on RenderStyleBase { set fontSize(double value) { if (_fontSize == value) return; _fontSize = value; + // Need update all em unit style of own element when font size changed. + style.applyEmProperties(); + // Update all the children text with specified style property not set due to style inheritance. - _updateNestChildrenText(renderBoxModel!, FONT_SIZE); + _updateFontSize(renderBoxModel!, renderBoxModel!.isDocumentRootBox); } double? _lineHeight; @@ -321,6 +324,10 @@ mixin CSSTextMixin on RenderStyleBase { // Only need to update child text when style property is not set. if (child.renderStyle.style[styleProperty].isEmpty) { _updateNestChildrenText(child, styleProperty); + // Need update all em unit style of child when its font size is inherited. + if (styleProperty == FONT_SIZE) { + child.renderStyle.style.applyEmProperties(); + } } } else if (child is RenderTextBox) { // Need to recreate text span cause text style can not be set alone. @@ -331,6 +338,37 @@ mixin CSSTextMixin on RenderStyleBase { } }); } + + // Update font-size may affect following style: + // 1. Nested children text size due to style inheritance. + // 2. Em unit: style of own element with em unit and nested children with no font-size set due to style inheritance. + // 3. Rem unit: nested children with rem set. + void _updateFontSize(RenderBoxModel renderBoxModel, bool isDocumentRoot) { + renderBoxModel.visitChildren((RenderObject child) { + if (child is RenderBoxModel) { + // Only need to update child text when style property is not set. + if (isDocumentRoot || child.renderStyle.style[FONT_SIZE].isEmpty) { + _updateFontSize(child, isDocumentRoot); + // Need update all em unit style of child when its font size is inherited. + child.renderStyle.style.applyEmProperties(); + + if (isDocumentRoot) { + child.renderStyle.style.applyRemProperties(); + } + } + + // Only need to update text when its parent has no font-size set. + } else if (child is RenderTextBox && + renderBoxModel.renderStyle.style[FONT_SIZE].isEmpty + ) { + // Need to recreate text span cause text style can not be set alone. + RenderBoxModel parentRenderBoxModel = child.parent as RenderBoxModel; + KrakenRenderParagraph renderParagraph = child.child as KrakenRenderParagraph; + String? text = renderParagraph.text.text; + child.text = CSSTextMixin.createTextSpan(text, parentRenderBoxModel: parentRenderBoxModel); + } + }); + } static TextSpan createTextSpan(String? text, {Element? parentElement, RenderBoxModel? parentRenderBoxModel}) { TextStyle? textStyle; From 10702d83cd8cfe49e1b5c6670dad9753794bc056 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 19:37:19 +0800 Subject: [PATCH 10/17] test: add tests for rem & em --- .../css/css-values/em.ts.0b1ac8f51.png | Bin 0 -> 4621 bytes .../css/css-values/em.ts.1adc28f21.png | Bin 0 -> 3455 bytes .../css/css-values/em.ts.1adc28f22.png | Bin 0 -> 4381 bytes .../css/css-values/em.ts.402b54bc1.png | Bin 0 -> 3828 bytes .../css/css-values/em.ts.402b54bc2.png | Bin 0 -> 3828 bytes .../css/css-values/em.ts.cd38c6b41.png | Bin 0 -> 3455 bytes .../css/css-values/em.ts.cd38c6b42.png | Bin 0 -> 4381 bytes .../css/css-values/em.ts.f2d770321.png | Bin 0 -> 3456 bytes .../css/css-values/rem.ts.1c56ea2d1.png | Bin 0 -> 4431 bytes .../css/css-values/rem.ts.76b2d84f1.png | Bin 0 -> 3455 bytes .../css/css-values/rem.ts.76b2d84f2.png | Bin 0 -> 4513 bytes .../css/css-values/rem.ts.e8873e161.png | Bin 0 -> 4522 bytes .../css/css-values/rem.ts.e8873e162.png | Bin 0 -> 3830 bytes integration_tests/specs/css/css-values/em.ts | 255 ++++++++++++++++++ integration_tests/specs/css/css-values/rem.ts | 152 +++++++++++ kraken/lib/src/css/style_declaration.dart | 4 +- kraken/lib/src/css/text.dart | 8 +- 17 files changed, 413 insertions(+), 6 deletions(-) create mode 100644 integration_tests/snapshots/css/css-values/em.ts.0b1ac8f51.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.1adc28f21.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.1adc28f22.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.402b54bc1.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.402b54bc2.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.cd38c6b41.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.cd38c6b42.png create mode 100644 integration_tests/snapshots/css/css-values/em.ts.f2d770321.png create mode 100644 integration_tests/snapshots/css/css-values/rem.ts.1c56ea2d1.png create mode 100644 integration_tests/snapshots/css/css-values/rem.ts.76b2d84f1.png create mode 100644 integration_tests/snapshots/css/css-values/rem.ts.76b2d84f2.png create mode 100644 integration_tests/snapshots/css/css-values/rem.ts.e8873e161.png create mode 100644 integration_tests/snapshots/css/css-values/rem.ts.e8873e162.png create mode 100644 integration_tests/specs/css/css-values/em.ts create mode 100644 integration_tests/specs/css/css-values/rem.ts diff --git a/integration_tests/snapshots/css/css-values/em.ts.0b1ac8f51.png b/integration_tests/snapshots/css/css-values/em.ts.0b1ac8f51.png new file mode 100644 index 0000000000000000000000000000000000000000..f9849f580f803e70af4d4613d195f3bc4c0cb9c5 GIT binary patch literal 4621 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 P9R#?`Z)frLu*|;!*1>GM literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/em.ts.1adc28f21.png b/integration_tests/snapshots/css/css-values/em.ts.1adc28f21.png new file mode 100644 index 0000000000000000000000000000000000000000..47965dc42c55dd50677f3be5a843df05dfae9733 GIT binary patch literal 3455 zcmeH~`%hB`6vqqgEVy9>qb6#t8!_lm5jEk_(IUe!G*YH+mx%&5 zT3-Wa3KdyWlqrtFy+A2d7uqOlWkpN5Z7&Z;EpS^N<(AUdnry%AAJ{U^FQ1%~oFC4~ z_k5F6m70+XicI|b8rs`7V;pU3SwLs^w zlgvVjcCDlI_^vmite26>(xZsOL|2Nmpj0|Tqf%wXuPd$;qVs8G1iMl<=>kp_S!5G< z+;D+^(8|rPa9?QIE(aavabbi7SU|PxR%lna5S1JK9}%yc?Wm;X-6@Mw z%>sT0>D?1}zmf!zzxySNZN$o84=c%KX^+Zt4gei;h8`ORg zixL*Uhy>a9N!C9iN}OPAzH?k-r~u<0qH2a6=|Za^g907OHLM5S_VRi-_E*f#W z-jX*E9}$i7XfO5KSY9ryow^xY@&@Ei-Mr58fD|JZ4D&d!Jr5{^9Z|uaA{gc-dRD`k zJ*XXWkAf%joc*i_9X2hvekFn`w>*Vn+UUk$6I&k{<{1RJ8Atg&$Q-Gf2$uDg&s(GA zmU9}nH&!lAg5<@pN^Dd&gJlcmLBH4sl+b5k)&Lun?|iPgr>(DH>##tHLY>r0f0)&? z_-RDm1Q9Cpnypqn21wu(xXdJoSB$S9p%9~wf?)mJX_q?A0HSnAK3%9cg}!C#Fgwi4 zf@|wG0%nk|!=$TnZjZ0gHo1F22J%C+7&w*m)+iq<=;km1&0IZ%Qu3uvXsU8-A5u7^ zas>8TjgcSoM~qJV$XA(ilmW?Eu!bS5Q}g*s!CgU83M4_5djjKC+k2X3Eg7_eIK_9P zagc7Hu9P_5LvFNJL!_Adzzj&yVUuuX8~PjQ9wg_@9i-mz9)@YACu1hc8nq7FDk);N zq7mHZRrogj*97--L-bQ_zd~HYP-GhnXZp>>KRLlNt02Y-v7HSpq&@4*=*$kSvyrUX z+A@f-qV5CAT*pb6manQ(!7nc0)9a3Xz!5{Cmr00ifg-9=clKq(ncGUIb}+fT_TFZn zl;)$=KsKC~@BD?u?#_0H)zy&L&cUkPsod&d8)WSW8EYViVf9@o7j!=n^qUV`3ewcH z?MO$~{*m_}owCJJ>5xM1vHV24LpbM3vqT3jJR{c*XV|W>nDQ)w=anElwO%%sJqj0# z(p{IR{BRrvCy5u6evVktMCYrbmNTX3frw8$vt&(Bl+-;!gfLfSLF=V|B z@*>p+TPG26&*opgs5aeG+W}fD->?}zqZS+>^1oLR)!g)>_N&yCc>lI^nUpf+ttD%N z=^U$9xGJs-<#R=O-3Fn74vsaO?8pUorj0`F(JkB{b2L_`aMAJD)8}~1EAbjm%+tm< zT4r;(Gx|w;31ae%eO-JO_19B*q;;G2-}bvhSi(P6FtMo9wKvn2;dY!L{AH4Vd*#0x zMed==mc^C0j?2M&;%~&`69fMP7-*OJqL~(e^Uyc^JCVmIlpI}nbrQY*WP=ry`TN;XT9&U z-`|dS9ay=-d<6soS&2Qk_ZS4C7Y2bWNnNh5o2fD%eyr>C;*K5I1F7IxjOhl;;`U&@ zm+M;c^5Clw$g20)y}P}Ws8fO~q{zhGOewy%9exZ^lWJC#7jCk;)!W2Q3O5fhF-gC+ zKRInv^D>8?($%H|cmGt52qWd*J^I?rbM=pFdQ{iUudg{ObSl@&I5YG0Wli~oLI1t4 zJLNe8kqUO7ptx8tHBEP>;gDm6#g1_t4wgY2aTZe>^2;g>jC!s|9B9%vIIn>(&JB+G z#eTAdv~({szk6%f(pzi7QjaZJdF0Sty+c22+x66>7xOI*n6n}TZttZ~lG*pleuDVw ztNHxDzI#A!c2^v^k+}WJ zVR9wvO}yTXqKsYI-6KMEHr5TzdWdx!@AL_e$5Yg;kt#=W^2gN`?FrN9aZ|{R!i-&v zb4blK0O7)p=VzginSo?cCV&Bdoj}Sp*eI;*S0I4!ZeodrvtgQ>W8q@8`&r#-hOx)vqwZQjI+x3x0}tIBr;(aNuI`jt>Jqoj|4U>RF0<#2ApW)>oNLCSj{ z`VN4eTU1&4Ph8qR^C(v(18VJ0XGspqO5wA1v&XUiFM>;Y!olcTCnjj(<~Nzxm8jF zJ#e`%uj*tGsfmLRv4F~2J$ypU#mBKF+X%(MlSjcIGKiIp^0{v3SrMT~iN7FU=@L*R z>O#7mb-gW`f@Xb0r?m3Wh03`k+pejY*zEVTV(EpTw`2VJVozBjRB{@*L=yl7?b3w9 zWKk>B-9(Ipk>V)5Ft3ypU!6SK0Evg}B$SvdVb4F&)KLh{h@e;J3lZ%3Q7}re6UI@q z9CWJb7cEXu%DDLrLz#T;_9#qk_Sb3AXUZ6l(=BnvV;D|BVd4PCH%-?nIcj2KQbP(- za-8f64k@EK$<%?HqD26tN>lo1%DL%0D6y|4rYeiuh@g57P(>(;T?$n*PkIu)Ov?cn z4Wf7qsGwdL-NO3f3o1nT#L8FA3-TPw*i>d<1&0$f^{gH(Y!b{c{gT!W8+$$i?OD7? z=}vCPe0t4L{?gN^!HZ?4`2z7-qm?>QWMK~OQD3x*81Z*)^QIr{m0uWu4v(8Te>0*2*~TG5>L?O{tK5- zuJ$NN6RpH^fL>X%)QER2EoC5Bg>ASE*3T&i!?W+u1ts#$>pAPP&W;d~uu-$nIJ-G} zdhb(!OBFP4Ge|U7%b{;~vs_|FOnceR0wW2>1(4k%A(l8t8HY|@z%jy-=To~)Tz<6G zzpPrV{Xw_$^T-K(;dQ)VOSVwACybN#2J>}5Z6*w8{ssOFKV0AtBjrtz)7tBbsVu!Me zRxAmg`jf1iA0&448YUz&bD_i-D^~5{X@*VE@(ZZ!q2?_@;}KIRaW=cQ9ba4QZxTj7 zfA?{26KFPz!&yc*oA*bRg^=8kPXAFCZ9(X|Okfl&ZC zCd~3;)oJOb8@AS6y66XbjL=eS;^pDlJ@mKccyzJDqb7&QSSw-nhZC;U7+D9?M!{uI zXWBmM9isX8SzYwgX#(f}3Y;J-!62lD^m%O!dF;#hIg1swLm$~Nxb&VWO>4q;m5!8> z<|3Sng6l0gR?05Z0z(S}TYc40sF_pGOm!rf&{JNB>6+T{%sw2Bqk7W#2^Hyy(M(K4 z9*M5;*-@^>k=3K3#qzot!?r2AsH~rn;HcpKEZ^08mCF_%i*&F3-YHH(P=#`Q^X)!B zyDi=KiBH;!Lk!Li`z1ZBP2YyLo8|xmcVbGF4;&R23$BkviC>cpk!K4;$3xre?1YIR zar=83CFYJQN|VTxa(?#0Q(rEsbkWPE=zRdL_ALsjD5W_sNb;aGV49VL>38*IMm0M_ z&P@KfGpF4Jh!jrN%wki5vy_z`uhzcbI3^>3x8j8^VqWm<%^G}&B+ad$DogzmK8uF4 za1}H460TaxG7k20h%SV2L+_f^x>u`96Ix=bx4x??diEABB-Im{V+?4n~ z_fp;6JRUFSG92>iCi>s(-XEFp|1_uH(dr!fcM`sn@Xx>6cO`sR!hcH%pR`Nuy#o@m UoTqzqB@PI7pV!`sJ%NAuJFiIc`Tzg` literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/em.ts.402b54bc1.png b/integration_tests/snapshots/css/css-values/em.ts.402b54bc1.png new file mode 100644 index 0000000000000000000000000000000000000000..34227becfffa0b91c359835fdd440488ad18f6b0 GIT binary patch literal 3828 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%0D6y|4rYeiuh@g57P(>(;T?$n*PkIu)Ov?cn z4Wf7qsGwdL-NO3f3o1nT#L8FA3-TPw*i>d<1&0$f^{gH(Y!b{c{gT!W8+$$i?OD7? z=}vCPe0t4L{?gN^!HZ?4`2z7-qm?>QWMK~OQD3x*81Z*)^QIr{m0uWu4v(8Te>0*2*~TG5>L?O{tK5- zuJ$NN6RpH^fL>X%)QER2EoC5Bg>ASE*3T&i!?W+u1ts#$>pAPP&W;d~uu-$nIJ-G} zdhb(!OBFP4Ge|U7%b{;~vs_|FOnceR0wW2>1(4k%A(l8t8HY|@z%jy-=To~)Tz<6G zzpPrV{Xw_$^T-K(;dQ)VOSVwACybN#2J>}5Z6*w8{ssOFKV0AtBjrtz)7tBbsVu!Me zRxAmg`jf1iA0&448YUz&bD_i-D^~5{X@*VE@(ZZ!q2?_@;}KIRaW=cQ9ba4QZxTj7 zfA?{26KFPz!&yc*oA*bRg^=8kPXAFCZ9(X|Okfl&ZC zCd~3;)oJOb8@AS6y66XbjL=eS;^pDlJ@mKccyzJDqb7&QSSw-nhZC;U7+D9?M!{uI zXWBmM9isX8SzYwgX#(f}3Y;J-!62lD^m%O!dF;#hIg1swLm$~Nxb&VWO>4q;m5!8> z<|3Sng6l0gR?05Z0z(S}TYc40sF_pGOm!rf&{JNB>6+T{%sw2Bqk7W#2^Hyy(M(K4 z9*M5;*-@^>k=3K3#qzot!?r2AsH~rn;HcpKEZ^08mCF_%i*&F3-YHH(P=#`Q^X)!B zyDi=KiBH;!Lk!Li`z1ZBP2YyLo8|xmcVbGF4;&R23$BkviC>cpk!K4;$3xre?1YIR zar=83CFYJQN|VTxa(?#0Q(rEsbkWPE=zRdL_ALsjD5W_sNb;aGV49VL>38*IMm0M_ z&P@KfGpF4Jh!jrN%wki5vy_z`uhzcbI3^>3x8j8^VqWm<%^G}&B+ad$DogzmK8uF4 za1}H460TaxG7k20h%SV2L+_f^x>u`96Ix=bx4x??diEABB-Im{V+?4n~ z_fp;6JRUFSG92>iCi>s(-XEFp|1_uH(dr!fcM`sn@Xx>6cO`sR!hcH%pR`Nuy#o@m UoTqzqB@PI7pV!`sJ%NAuJFiIc`Tzg` literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/em.ts.f2d770321.png b/integration_tests/snapshots/css/css-values/em.ts.f2d770321.png new file mode 100644 index 0000000000000000000000000000000000000000..fba35d6692cc99d49f72f7dd9816037811052311 GIT binary patch literal 3456 zcmeH~TToM16o$jaf>N7N+fsoLr`XaKl%iF%A>k?!rx2=k97QfxEnYYY5SpMN34#g; z6GqWW6-dPyK`lXro&dSE-l%dnpx{Yz(1;MsNeqD#!^x$2=!?&NsWa@Cf7V{JU;g>l zzh{-FBvThJ@>_(%;T9)uj^B#IxgEga+>5;5bKTtZd*0|0H|ADqEKbxHpmP3 z-mX*Vy|2vm=&Qu|nC%6%h$^)S;KX#9U<%OOCOCKXv&8)ehIG?Q&wO-z(@^;35W>Th z%b{zIH$|7FgqE#XS{&M-k0pD`X9gB{aK1iu`-{%<6WbHc3|~@~pDNpSy)@jH(*b2= z95A-Z3n;{z%5@Vp%*t@$W46Ou6+Uqe(Pu{?S_c^ylgH@ycHcrkFgGBFv z8@uo6w_?k0ZVjSz%&ZXG`#^;nwE;r*MruAa5b}~PD8hg0n=k<1KzziqpCDSsqi3pe zA%va<_&K9q?m4ttcY8g+P@`PP@iWzC03!fwNYXB&sn9X7sqP9ORWSV2+qyLFCPaf{^j1;tYnPsn^` zx4i%Yy#8EfoI)QF))EwL$YIuZgvcyN!tO~_^j#BJ+JLG+JzTo*x6?yghaa zt%Wm|?~I}uCkBBQ7&SFo%ohM6?^{-p;Cfft^i`6(y&0mI+oon4$00HIw$5n&-h|iJ zv^WNQF3$Z0!2CIkB(@uLpppf*1`V`GdgHKW<#d;rI|D>InKUtgRRLiXg2n1>-2vLw zAUuNZZ|q8!BUNI%-qWwCy%7_T; zsLxnua-?QYvE&|1STKm)gGy^3%krVBY-|Iv105^K0$>^fQ)7IJ#zFGKT{CyJX(CH0 z>B_eBKM+WiYWZC`O%roff@M|W3tnFBkrB&Z$}_2-5ak9F9JNZwE|na8c+fgRkQ;1= zDxTCE6qek2%imy&3f&253QJ~%`MW4mWN&a^v^vQ}vs}BSvXoUj!kGhM4eCQmXrxK* zq>(Lcg=WE*Cw$dE`YSqvUiPa|yyRoGFQw0%A=9oLyUyNS%pU9pxwC>LZ{kRz=pzn6 zb-7WMn`a84JDYKlZpp_e#LXE2DSU^3@u8d!olh^Yog-cG7qRV`wmCGa4as7~=aCX7 zgskc~PM2WgBoj}^#?$;43j2R>kyNwluv9#*m8mL^aWP~zI6aEY6e<3+KV#s2_ao83YH literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/rem.ts.1c56ea2d1.png b/integration_tests/snapshots/css/css-values/rem.ts.1c56ea2d1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b57593d6bbf56dab9ec53f15f5ecf41b8e0f433 GIT binary patch literal 4431 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 literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/rem.ts.76b2d84f1.png b/integration_tests/snapshots/css/css-values/rem.ts.76b2d84f1.png new file mode 100644 index 0000000000000000000000000000000000000000..47965dc42c55dd50677f3be5a843df05dfae9733 GIT binary patch literal 3455 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 CJvK}L literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/rem.ts.e8873e161.png b/integration_tests/snapshots/css/css-values/rem.ts.e8873e161.png new file mode 100644 index 0000000000000000000000000000000000000000..d74557c6b8092252674a3a1b1dd949a363692835 GIT binary patch literal 4522 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 { + it("should works with style of font size", async () => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + fontSize: "2em", + width: "100px", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + }); + + it("should works with style other than font size", async () => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "8em", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + }); + + it("should works with font size of own change", async (done) => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "5em", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + + window.requestAnimationFrame(async () => { + div3.style.fontSize = '30px'; + await snapshot(); + done(); + }) + + }); + + it("should works with font size of parent change when own element has no font size", async (done) => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "5em", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + + window.requestAnimationFrame(async () => { + div.style.fontSize = '30px'; + await snapshot(); + done(); + }) + + }); + + it("should works with font size of parent change when own element has font size", async (done) => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + fontSize: '20px', + width: "5em", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + + window.requestAnimationFrame(async () => { + div.style.fontSize = '30px'; + await snapshot(); + done(); + }) + + }); + +}); diff --git a/integration_tests/specs/css/css-values/rem.ts b/integration_tests/specs/css/css-values/rem.ts new file mode 100644 index 0000000000..28ec3641c1 --- /dev/null +++ b/integration_tests/specs/css/css-values/rem.ts @@ -0,0 +1,152 @@ +describe("rem", () => { + it("should works with font size of html", async (done) => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "5em", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + + window.requestAnimationFrame(async () => { + document.documentElement.style.fontSize = '2rem'; + await snapshot(); + done(); + }) + + }); + + it("should works with style other than font-size of html", async () => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "200px", + height: "200px", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "150px", + height: "150px", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "8rem", + height: "100px", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + }); + + it("should works with html font size changes", async (done) => { + let div; + let div2; + let div3; + div = createElement( + "div", + { + style: { + position: "relative", + width: "10rem", + height: "10rem", + backgroundColor: "green" + } + }, + [ + (div2 = createElement( + "div", + { + style: { + width: "8rem", + height: "8rem", + backgroundColor: "yellow" + } + }, + [ + (div3 = createElement( + "div", + { + style: { + width: "6rem", + height: "6rem", + backgroundColor: "blue" + } + }, + [createText("font-size")] + )) + ] + )) + ] + ); + + BODY.appendChild(div); + + await snapshot(); + + window.requestAnimationFrame(async () => { + document.documentElement.style.fontSize = '20px'; + await snapshot(); + done(); + }); + }); +}); diff --git a/kraken/lib/src/css/style_declaration.dart b/kraken/lib/src/css/style_declaration.dart index a296d55b06..798e7e2548 100644 --- a/kraken/lib/src/css/style_declaration.dart +++ b/kraken/lib/src/css/style_declaration.dart @@ -605,7 +605,7 @@ class CSSStyleDeclaration { /// Set all style properties with em unit. void applyEmProperties() { _properties.forEach((key, value) { - if (value.endsWith(CSSLength.EM)) { + if (key != FONT_SIZE && value.endsWith(CSSLength.EM)) { String normalizedValue = _normalizeValue(value); setRenderStyleProperty(key, null, normalizedValue); } @@ -615,7 +615,7 @@ class CSSStyleDeclaration { /// Set all style properties with rem unit. void applyRemProperties() { _properties.forEach((key, value) { - if (value.endsWith(CSSLength.REM)) { + if (key != FONT_SIZE && value.endsWith(CSSLength.REM)) { String normalizedValue = _normalizeValue(value); setRenderStyleProperty(key, null, normalizedValue); } diff --git a/kraken/lib/src/css/text.dart b/kraken/lib/src/css/text.dart index beb15cbd65..a0460a1ea9 100644 --- a/kraken/lib/src/css/text.dart +++ b/kraken/lib/src/css/text.dart @@ -140,7 +140,7 @@ mixin CSSTextMixin on RenderStyleBase { style.applyEmProperties(); // Update all the children text with specified style property not set due to style inheritance. - _updateFontSize(renderBoxModel!, renderBoxModel!.isDocumentRootBox); + _updateFontSize(renderBoxModel!, renderBoxModel!, renderBoxModel!.isDocumentRootBox); } double? _lineHeight; @@ -343,12 +343,12 @@ mixin CSSTextMixin on RenderStyleBase { // 1. Nested children text size due to style inheritance. // 2. Em unit: style of own element with em unit and nested children with no font-size set due to style inheritance. // 3. Rem unit: nested children with rem set. - void _updateFontSize(RenderBoxModel renderBoxModel, bool isDocumentRoot) { + void _updateFontSize(RenderBoxModel renderBoxModel, RenderBoxModel oriRenderBoxModel, bool isDocumentRoot) { renderBoxModel.visitChildren((RenderObject child) { if (child is RenderBoxModel) { // Only need to update child text when style property is not set. if (isDocumentRoot || child.renderStyle.style[FONT_SIZE].isEmpty) { - _updateFontSize(child, isDocumentRoot); + _updateFontSize(child, oriRenderBoxModel, isDocumentRoot); // Need update all em unit style of child when its font size is inherited. child.renderStyle.style.applyEmProperties(); @@ -359,7 +359,7 @@ mixin CSSTextMixin on RenderStyleBase { // Only need to update text when its parent has no font-size set. } else if (child is RenderTextBox && - renderBoxModel.renderStyle.style[FONT_SIZE].isEmpty + (renderBoxModel == oriRenderBoxModel || renderBoxModel.renderStyle.style[FONT_SIZE].isEmpty) ) { // Need to recreate text span cause text style can not be set alone. RenderBoxModel parentRenderBoxModel = child.parent as RenderBoxModel; From 543e2a1d7e1dc47ea900be49d723209bedfc9d6b Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 19:57:46 +0800 Subject: [PATCH 11/17] fix: modify documentElement font size to default to avoid affection on other tests --- .../css/css-values/rem.ts.e8873e161.png | Bin 4522 -> 3830 bytes .../css/css-values/rem.ts.e8873e162.png | Bin 3830 -> 3449 bytes integration_tests/specs/css/css-values/rem.ts | 13 ++++--------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/integration_tests/snapshots/css/css-values/rem.ts.e8873e161.png b/integration_tests/snapshots/css/css-values/rem.ts.e8873e161.png index d74557c6b8092252674a3a1b1dd949a363692835..37abe31da87ac103b41e7cadfdbe3ce14f787001 100644 GIT binary patch delta 1591 zcmV-72FUrUBlaDTKz|OPNklkdh-%NT>69im=L^5=}uou1?_Np3RdDgTr4oV%yzIFjVoNv=<_KgrE!_B}e? zzvQ}Ux$@W>aX4e_{AiL}PUp94X8Y}?*DxEb>$19q%zq!R{zsClrscho++vgG39vCI zCFdpCljPuZ*R7_X-#Yz#eUcAnMEUkf9++fbM!YV}i1w^+PLF?Xl9whqEo030ff+G- zeU_vA#%bRrd#2m-Ht`Y;XN;BKGRb{2#+vV*g6XS$|0$oaEFbPfK!W6Xy%CF}p{g@0H{O(_I%%%d@BDM>0a2B+pNBM#ebqr;>ay z$z@5tof{4td}3OjljQzMewF0&N#2&^K}nvO3=x8l6*PI7c-*&qx?S&odDZ!W(<1X zIPl+-+$m$2;_FEsKeO$cj4R{cCizN6=#%6dNuDsRe=Z}$OD;3J`ip8FA- zKY#sgW(<03j6t)L*7>5!l^Jn9Bge)$8AA$7SD-(f^Vmn{*f=N2W2WUFHh6kRGQzv^ zcJ0hQr%uc3vo+TwdFr(OnJmXS8Szb$SLE2S@spE0eOkY4i^m5z);gcWT{SK5y~_6e z)ACnyw#~arz4@H`*7A}hpPqC7`;)wET7SPFV~AvbMl8>nZnxURaTYViy$>XL<@B7h zelabtNb>uPG3UQzyjgs2+IDyo#{*d3I)PsL;PA9nwx2#NH+n_9S?6ZV##rg0Gwbh5 zamUlc(r?b*V0=p;48>ZV&lYAj#rpU810>9R{bdr24$!ju(N-oa)sdalZ-mJcu z5#!S{-n8aTGXyw3))|Ao>$JQ)^FP45a#|j*tH-T=AaiDt*Clz*^z+Zx+5hT{sdGv4 zrOdxtPnKWbDH&gMxlP0w*lz0tdVhb$mF0nqtH)V~vOGQR>}<{6X?bwXy*B1(lJ89G zyVlt6-x>3#k0g0}lEN4_V`}AAig8?2PYc zeBorJcV@gvy*Oi>`jU(4NH<6|b!r{>tdWVhsb8KHhnMwDm0 zJjt6@+_%uTHHnlT)4$#i>CHWui`jIjTB#r@}Je1T=HUl9I2v;O5(_IXuCp!Z}% z{B=n_ndGx`jt6jjEo|;Tja>a}#;^0Y&iDZFc>lfsLrMOb@gdx1{>$FtH?=!w^M5zw#PLOyt?@+_cG4!xa$3gUyVx$9nY%perqk_2*qt$)vUj~5 z0k*_{c?Gkv4P5~YYWL#e!cLz90CTv4laUIH3+-Nb^G=@v0Q0zllaUIH3@t1!E-vo$ pNdRy|uCrkdG6S;^4g~`i{{`mM3IoTPSC{|*002ovPDHLkV1fabO@ROa delta 2314 zcmV+l3HA2&9jYUcKz|WbNklC>M57jp%k!yRwHcyC0e6Nv7%tZ zMWccS#Te@)sc1k@BVxglKtoW3G-}i$#)yWC6>Et18zzWVWAO$>X{=z0g@)LIZ9yuQ z+VPKXCbMSEK4;I&nag`P&y!5fUNdX<{$@_{+iQROTWeO5wH>ve%8>-;?A`N&X?ptx4`m^3Wu&Nb)s@G_=ojA5U^t zj{9E#oc0#f;r$sAzJ0;&mmlzOP6u}-`O+jGUf=%LB#%G3;Q+N31p10>jq`a)9+Biz zNgjA8gZj+&-fYG>N!}BI1{RqG`dvwWZ?gTyB;R|8!`TlX&lvNkGJd>&KRnvuY;)mk z`w>Sn3ZUOC(AQ6He??BcI48-+vh_)(&F5vz@86PfTC!zF)ZheNQ}p!4U3C^1R9R&t=RX|4NcS%~(}(dy>_R)g{kJ^1>t!nBC9o zlKfM)KFK7>b0@b~lDsO(qfaoN-MBf)HA(&@$p~sH<?cn>bPV(Z6C$Q6t3-%xN z2#!|!1^bWf{A9v^hfQvOG|AJlJ))0G^10bOn%wY)jP<^MmE{q*Y_`3+;BnrYD91UvnU% z1NP>O7szs>IJ-r2`~oC*2*$?YpMg7^CwN3nmLo3%*T?vwByV3I-+yQ8|Icfa{MR1F3mlX^T#Mra zNq%9neND!H(d_)3mxpBp>)DgfU6JJfmfZhpl6NQh?u^sRlX2Aj_$0qM+jlyBa4gB0 z3&wHg>|;M((oUy!Ub5gZlQ9qd<@@khb8k!XGn4J>l6=u@pXuw?i<10V#w(ktvooFq zFPeOAK1~7~r9A}t9kcE4TC)ESPj26m?MJwCS7!Tv$s8Ll%$P>maNCmmIt+(-EsdKq z=Gr&BD9N|a_E}5v+p~R+H^wtEo(MO*=VS*6?4v!@<=vCp-;m9t+~c`)wtZv9Jm~Q( zTO)jaHY5MPOZHvn`YeB0e`dx?hp8uIa}M{)jOl^1PI4^Ed@{+mPPV@~i{GUDaJEiA zJ!Q#%{XTYbyWt5B*szB{e`Ip|kvrIbB_paEZyJ7V$^P@@b8~0!;4ydV@{FVU6Isoe z2cP=BY%ZU>CgYU&XJsry{Q7L4PS_96&*qcDYR1&YnG5#&=xlo>WB&fGjNkp8vwv@# z?0e5Xju$vtdkFO1liNEzndQ;h4D{V6+VK>B@xqKtvA%VE`x6<<1Fv1*z9i#Ky7{{C zy?TAddi4!|kmElI%vZczu#3mp?eae0AnhU0pPt-abOg7^^r-m0-9O}k*;pxZB8z^; z2W7lrdHMQ%yk++F8!}F)d0CR5I>|Ag{zk#~n$& zd9wZNY+qtG_t~@U>oNj-&icng);}J!$1wqiWe{gS+9!vUP3r)Z4Rlt?tXSzsuwnnIC2TD)aTQxO~HN3_d) zFv)jJwqKB~CzI^ND<-#ZNb&>OzWi>(eHrV)e|49S0UWeF%t5at`PpnN##Q$onGvby<>aPWuFsfbzBI{~WX$iL zlX0YeYsS*M>D>Ht=6A5fi?Ve}=%y_H;|a$yF3gEj@Zx%i!n@%{OtZRr@%ql<9W(Y%s4WB>Ev_Q9%tWV^WsMjIl(^r>E+pfy82;y?T{yB zf9Ap8nXT8)UgVduyLHIP_A?uoJ;sLHvKi=PTmm?Z%PWrYJ?6aEWM>8&J^esCa(y}uNcQVFjW=u02#Oj6fGF~wp&uYe$!i`COaKYE- zZ(`1W-u+tsc43mg%b2=B5)(OSmo(|2Y31(*k}-}gaZlVh*$$>t?T@5@*({W(d#AY<&O zCl~BL>Jc2RQ{aOA`(Y(xj&~>5<~U3%8PR;yvK{w$-{a2_lBRzK6jzEb$ ztl|LRFbK0D2{8f-j;*b&9Q7CgSiljJQ3m4+>e$LFk9r6IEaC{0F$&`hwX(LhwszEm k0AM>uv(X5H1Q)6Q2fsyq#uq8O0{{R307*qoM6N<$f>7Z8;s5{u diff --git a/integration_tests/snapshots/css/css-values/rem.ts.e8873e162.png b/integration_tests/snapshots/css/css-values/rem.ts.e8873e162.png index 37abe31da87ac103b41e7cadfdbe3ce14f787001..4b5a693a1373bdb64a1803fdee9c2891c2c80093 100644 GIT binary patch literal 3449 zcmeHK>rYb$6u&46YJeciAY!SrF1n})dx2it0)a910H-cZL`24zvUytyg@SFVs0h9= z$`}|P6*d8*ATV}Ypio3z6%=sgF?#z@kQSkr(hB!dF1KC(3ipNc<(G4EPEPX6d0spa z8||@v(|P~^JYv3#JO}_TCjns98TYkLOY^4jIw!bf9E^?t8v8fDaVoAE5iy6|og#Gq zvCtVri-`53X4)2)fj>qy1w3;V*6sSF0{wDm>Iz5bP^xLs)9%LKK5q zcI7i;S;m#%Buk~(p8PB)1qA&|4JK3X?O8`}d0-|E3Vs(eWjBdH0sv&ed20(do;*{3 zchtTtffOC68Kw&m-(&sW+7c!90mtPf?Mc4(dKmcsR*NMbafm-8nRvU5L(5nFu2(<9)34KnLw&wMSB54{G;-C zNmGfCKDcw5hgU;hr--*IlFueuAe_^Yegro_4pEYiBKP#NFWmWZUQS3mg$S+AC`4h& zev<5ljU2)VhRU6ZYc~*%aeoueiN*D&+r=d6zejGk&zI{@9L;7jGu@OfbFcWBf~Q3{ zixPF%0$A%=)r`_X!yl3kG#VCZU@3>tLD$%z z03COub+T@hZuz_bQ-b5myFtSvDuQ)wm>IwY_9RO;%;{*d)14k^?T*Ac{OuGRa*7yI z5joG{Yjg@2rW{U=v^}Ea*)d4MKeBK^Wu+htbRM_WFS_xcvBdNF-;#qcHIyW^NUoWO zq;{CK-czIcSJfnzYV$!D7SAe2j|xKU8OY^WrHBz>ABMyVG(;+zeA8SC5ycQQBya7{ zZ0=Qc;wgcy@v%*F4%~{{DWwyY#D$qEyaIBhm1`Br(VO=yji?y?aXY%$%KGIfV$kb+ zd=3gTwOAt*N2g~o9Aq0Y~TA(WzTD8UxPt7>erbl z7Y(IqzlO;vSpP3J4pIL^mFDB+9IZDg(P3+R1DKAc>=AfiUjt!<#BIs3n{Q3NPn)VU zt7Ez@+sRhpw8x0H!B@f#N!P<>B-lvKLQFX-$oeKuV@mI2s)H-7y^x-(ZLh2RO$?)l zvMRFW+Wn#3lWmWK@V#Kq;#}r6$AeVcy$;Q=Pi&uZ)|zQ##mh0CLllyuqaj^CAx4g% z&tpXVcdBg;j;jh?ohkJT7aNOq1_!9QKbW5)xhIf4vwoF~H-Y?xXDaJ%u=c%UY30ze zx~PnqfiP!}@Fap_qvEtOrkiD!xteQA*+e^qHdl~!G|y_HZ1>UsHSv0!rMJbqECz+H zSrTp$al^gPqY#=+!~!iWdCvYX&N-FEH61jb}wm0%&jOlXRw zBEv*e!Wn_m9KJeo-KSx{hOK~;f&@C)kv^sbx;^~fB`*n`*4jRXE5Lr_zG=%>w_Ivm z-vvzfjyWZT>IyhYy;n+Lr3+RD!O9R^*#j%9@PEDrhTL4(AGPQxDXJFd`vk;9#YQ$p H96$RXOK8qX literal 3830 zcmeHKX;72r7XDaVYA;x%6(Xx+K)td^q7Wb^$`bko2uh_Ctk5x(fKZU7kU$`yy)B)_ z>&zEHkSr7`+?GuUikO7d786s}X>15WNrew0hLDX5vgUH{?M(mstDWKfbLKr~&b()y z^UOKV`{h|ugw37rXcabT)x%UI;aMuY%uL(X$s7wfzb z@cizrL*JcJ0RXmjVAz@SRJQil^a>=!LSmqFW^}rO!r{1ti>!Z98yxqZJ$GsM-;)ly zy)C>!EpxB0-?_s;caRN3;Xezjm;AeeaPjfr!^_MpXT0!alcTl6cnNe?DNn`VvX;2t@H$ z)+eZz8)e8_r0zAXz6WT@POX@BLFDwh%VMB)FPRHzBwgq)YwligWYktM#%8AhXSX-| zO?AU0<27VFGSJk=BS0y^YIYI_euiAG4xGHsqm5i3yPgP6FEr|qW-#}ohZ5t) z*QGuw%BW_JaJaA!n1xawHM0zCL6aH-!J}YXOebD8NLe}+^s5+tnBHSlI^|%<^XqBQ z1(LcuBXv#NIC|WvMbr849|Lafn-NfRm+Se(+~jZAXG>vL zs!*~LwB)vq3wIn_D$a!7Lrr=?cA8Te6Ip^OL%b&~SK>5~0J^f_r^uMd+%$Xjn|J*L z5p}vs*h+rUfz;1$nu$P#)FOvtatRX5LK8$kF8dhlzA$bvm&9wJ@?jkqgP_iCG_HnW7<&Pc_6ooIFzmb6uN6**x=-lKcwZ^Hq`vs3?8G>OrxSQAId)l(YK70=h+W*(bXd9Dx%FIcb>$UWZ5 z@Hx~M=|ePDF-I7SO8J9F9RY@Y5cAl|cuR+>0ip*?6JK$g=kwAf?@*x+xiC(?T8zT= z(TUJkeC)cheU9c^!(Fqh#czDF^;`z?44{O}_e93m;n^l-gj$I? zEF(A0xcO6yB2YgFj0M^OTob8Z!#_ESq`mCgtnrctA`H<`Jgn?6uvplVL~-U<(p?xu z5U=mzNpGF#r=<T{yc(E7KZ7NaLy zdaLcG<><+-*=V#i2B$z=>(z7#u_pZYg4{&c_GW2ose4{3H0nVcS~Lxhj+tLFzs&=U zcLv0XF;&T`qlo1Ep6EV=GD~A!#E?|Zlrx*9314(#Pc6)64o;@it_+I&XVV~Elt!RX z>Qo3*(+wo87?QSj=o*@4!fWvAmG1(VEiwm#LY)I5jgv^Uc&OgCQujmO?M;~OaO*eDGj$aD^OQS< zsX|bMA+uK@rtc&6Ex!%@4TOou;LSXDEt@8Ljx^0G#VOq|4e@npG~p&igq794Khdp- z(_9{(yzS?lBg-$2_22*EG4rmO`glW4p_hN$n*7!#j=wn*w?vC0)Geokt$zyQYG8ie zKX+ZBduJ}-uWw{X+D+XB`m6RDd6bNA#u9Mq|TU@<%A1o?gGb7sK3 zV2X(m0QVWfD_afW?-cy(*`J#zQ3;ejwKW2)rctg9Q*!*+orNM7i~D^H+K&GX&Noh+ zK3cx>h{p(U$NE6s&C^yl_x&+dw}V@&<@G?gygW7a1Bqt^ { - it("should works with font size of html", async (done) => { + it("should works with font size of html", async () => { let div; let div2; let div3; @@ -41,15 +41,9 @@ describe("rem", () => { ); BODY.appendChild(div); + document.documentElement.style.fontSize = '2rem'; await snapshot(); - - window.requestAnimationFrame(async () => { - document.documentElement.style.fontSize = '2rem'; - await snapshot(); - done(); - }) - }); it("should works with style other than font-size of html", async () => { @@ -140,11 +134,12 @@ describe("rem", () => { ); BODY.appendChild(div); + document.documentElement.style.fontSize = '20px'; await snapshot(); window.requestAnimationFrame(async () => { - document.documentElement.style.fontSize = '20px'; + document.documentElement.style.fontSize = '16px'; await snapshot(); done(); }); From f327a324fb834798f5e52e3ae361156faa57a483 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Thu, 8 Jul 2021 20:09:35 +0800 Subject: [PATCH 12/17] test: update snapshots --- .../position-sticky.ts.454f0a8f1.png | Bin 0 -> 2402 bytes .../position-sticky.ts.454f0a8f2.png | Bin 0 -> 2397 bytes .../css/css-values/rem.ts.76b2d84f1.png | Bin 3455 -> 4513 bytes .../specs/css/css-position/position-sticky.ts | 35 ++++++++++++++++++ integration_tests/specs/css/css-values/rem.ts | 2 +- 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 integration_tests/snapshots/css/css-position/position-sticky.ts.454f0a8f1.png create mode 100644 integration_tests/snapshots/css/css-position/position-sticky.ts.454f0a8f2.png diff --git a/integration_tests/snapshots/css/css-position/position-sticky.ts.454f0a8f1.png b/integration_tests/snapshots/css/css-position/position-sticky.ts.454f0a8f1.png new file mode 100644 index 0000000000000000000000000000000000000000..c2df232745d66c3d95017df21d4e6d8c76bc9c84 GIT binary patch literal 2402 zcmeAS@N?(olHy`uVBq!ia0y~yV9a1(U~1rC1Bz^vdbAu!F%}28J29*~C-V}>VJUX< z4B-HR8jh3>1_n+ZPZ!6KiaBp@7VJUX< z4B-HR8jh3>1_n-cPZ!6KiaBp@IA%E;3a}mw{K5YHtU9+a$Fb_Ki(awtvq>#9HnvWA zW5xdA+nF)Z8z_^G-YLprcg3(kknh{3Jf)Q05 bz7iKWBK-H#LrE536N$mo)z4*}Q$iB}_i=OV literal 0 HcmV?d00001 diff --git a/integration_tests/snapshots/css/css-values/rem.ts.76b2d84f1.png b/integration_tests/snapshots/css/css-values/rem.ts.76b2d84f1.png index 47965dc42c55dd50677f3be5a843df05dfae9733..8fcd8bb552c1a5dd41ac191dbefa8824f956ac78 100644 GIT binary patch literal 4513 zcmeI0e^k;}AIH&t;O5k)T4OBKR)F?nk-92n2G$hXsEH0y&%nfgCfPmM%nUK6zcfFgYZD6}l5trGSkt zEEXs4#DDFyFw&h!7eJt8;rQSkU#AJQ{VXnxvO_w=7+c5hzWU+q%zv(>fe?qU;cNbN z>`}rKHt7BYpFNl8R+N5pIo`TebMD@qM7FmFXn!L6P6SX zV0c)ptO7{y`qV``KdHtmS`+Q>Wr7=)q@;0noud;HW_|`^1>iFnUV0+nR;{yB0WXjK zgv`Uvj_gAssYL+K+ikcBcf(!Y(JyI47bivl=HM$?A>^!#gMg}dLgFK1c)m_BJ!Zsus92H@> z(yO(d060&(!G&<RiV&F)LCI(1ft$rfOfgJGUYhJ^HwpmLCGJAw)`OuqvUBI3~AE~x0aN+5jryc zG0A!jUwTQqjJ*?3Du#PC=h38F=DCWEc})o6T-Oq_aY2_z10g(=y?NkrWg^Z?z46;E zGIuDY5>2)%I{Ak_oGN>oCfb}551{rWQKd6mkL2s=vo9Ax-EX7I5kY+YoztJml94f| zjT$2rx_{-W=#t8gbegnqXfO0R!t-g=UY{JT3T`QJccrGx&FfmDwlZRN4Wb0FWZEt# zbi)=|Aby^fN-($MOzM&!tIOhIN|!aLl>Qgz)NoyR5=;7dM|??srNkWKi7H_$H;}FO zNK`?Y7$xS; zCJk{Mzn1exzZ+j}eO0Fsxjs4`9j?B?ePD7y;SH5SVmDwjO%$ke^mn-6hc3E+UI$0( zNw*ZHnPeTWW#+T65T%LUS^y3#jisJb%E=l#Lsrvvg#RXTJW?4ox_SC~oMI@t)F&`O ziqDNLj6_<7W%CEg`iqx672Tud<)1z1Z;2GG@_3u+!g87lMfT+lH0w7&zwA%zcuNe= zEkl(RW0Jw<2mASCL04JpH&X0OrB@2YrWiy7rlVm5){D!XxSiTJ(-yRJSZKwYKp&T8Q0RoFyI)2A8gh79_6gzE`E= ztRXT7w~SjMu?=D97_|6cwKA$&Jmi*S17}%&;2TpDgX)hCfMM4I7tcQDX+tOp7xyTC z(Dlz9^(e^sX^mIy@09c~sdGNRN+l(bV%8Iq&6T`S<5r?)bQ+e2)_F}f>3zI)`@b<)~&nS^1$k9&DrO}4z zTFA=CkaEf%>XFMn=($_m6qPK^YKwMc)1}TgR!P)Gz;-$xwE{~O*;hiV9YEzpfg6Ra z-$+)v(6(+m{Xp}M7(s@|?ME3ElV1p@>ppIaK8GzWYmJgL3^9a(;)~dL5l8*-T4u(= z-G%V9eSob4P^_ETjO_d<9&#rM$sn$Gy!(kOB+j((pp{&?%eouD<)|*hhB`L(! zzT^EDZVQK>K&c66TbQUSr}Q*SRMo|fH8BcbtuYGQC9g*MBwmCV?~-~9as7!$Hg0O6 z8`2_@&0nmYmcudnUuC9gycpHTSJCdHiGefKlLlPoSy6Vt??1tVc=GVC2L$?_gPUXp zVt+ri+*8-qEs3iw(((te-VpK;8VX-plGxQ4N(mlY67b+u{#FZ?s^J%lEJ*?rj32|h$y%0*T>P<^Ep65cG%kt%5F3Yz{uJ0K) zGvZS@h5H9rYxV4>kqUpm42veY2R8D8WPBa!hH3V(j{ekJH+%fF_Q!G(XSi8aSlOeD z*6?fVQ(9#v#@0>sc`oESYU6k-nD6M za1P%mrDnqXwsT^luA}MrVSKk~Xyx_0-16yrq$A$*LwFpzFXlETjtYf5mTXW1KUY90 zh1SHZYj?T#B2|TY$T5$Gj6N`XZ*F59rkD?FL=zjQCH<`3iA)|n(PBG5NzpxLcsEqnP2@+LipQm zx)TV5fH9whpgT!#zRUwfuoeH6fd0z$xf323e#r(kt@-<h>x?f{ES3zJZsvlhNtK=_b|;HsU+&inyb CJvK}L literal 3455 zcmeH~`%hB`6vqqgEVy9>qb6#t8!_lm5jEk_(IUe!G*YH+mx%&5 zT3-Wa3KdyWlqrtFy+A2d7uqOlWkpN5Z7&Z;EpS^N<(AUdnry%AAJ{U^FQ1%~oFC4~ z_k5F6m70+XicI|b8rs`7V;pU3SwLs^w zlgvVjcCDlI_^vmite26>(xZsOL|2Nmpj0|Tqf%wXuPd$;qVs8G1iMl<=>kp_S!5G< z+;D+^(8|rPa9?QIE(aavabbi7SU|PxR%lna5S1JK9}%yc?Wm;X-6@Mw z%>sT0>D?1}zmf!zzxySNZN$o84=c%KX^+Zt4gei;h8`ORg zixL*Uhy>a9N!C9iN}OPAzH?k-r~u<0qH2a6=|Za^g907OHLM5S_VRi-_E*f#W z-jX*E9}$i7XfO5KSY9ryow^xY@&@Ei-Mr58fD|JZ4D&d!Jr5{^9Z|uaA{gc-dRD`k zJ*XXWkAf%joc*i_9X2hvekFn`w>*Vn+UUk$6I&k{<{1RJ8Atg&$Q-Gf2$uDg&s(GA zmU9}nH&!lAg5<@pN^Dd&gJlcmLBH4sl+b5k)&Lun?|iPgr>(DH>##tHLY>r0f0)&? z_-RDm1Q9Cpnypqn21wu(xXdJoSB$S9p%9~wf?)mJX_q?A0HSnAK3%9cg}!C#Fgwi4 zf@|wG0%nk|!=$TnZjZ0gHo1F22J%C+7&w*m)+iq<=;km1&0IZ%Qu3uvXsU8-A5u7^ zas>8TjgcSoM~qJV$XA(ilmW?Eu!bS5Q}g*s!CgU83M4_5djjKC+k2X3Eg7_eIK_9P zagc7Hu9P_5LvFNJL!_Adzzj&yVUuuX8~PjQ9wg_@9i-mz9)@YACu1hc8nq7FDk);N zq7mHZRrogj*97--L-bQ_zd~HYP-GhnXZp>>KRLlNt02Y-v7HSpq&@4*=*$kSvyrUX z+A@f-qV5CAT*pb6manQ(!7nc0)9a3Xz!5{Cmr00ifg-9=clKq(ncGUIb}+fT_TFZn zl;)$=KsKC~@BD?u?#_0H)zy&L&cUkPsod&d8)WSW8EYViVf9@o7j!=n^qUV`3ewcH z?MO$~{*m_}owCJJ>5xM1vHV24LpbM3vqT3jJR{c*XV|W>nDQ)w=anElwO%%sJqj0# z(p{IR{BRrvCy5u6evVktMCYrbmNTX3frw8$vt&(Bl+-;!gfLfSLF=V|B z@*>p+TPG26&*opgs5aeG+W}fD->?}zqZS+>^1oLR)!g)>_N&yCc>lI^nUpf+ttD%N z=^U$9xGJs-<#R=O-3Fn74vsaO?8pUorj0`F(JkB{b2L_`aMAJD)8}~1EAbjm%+tm< zT4r;(Gx|w;31ae%eO-JO_19B*q;;G2-}bvhSi(P6FtMo9wKvn2;dY!L{AH4Vd*#0x zMed==mc^C0j?2M&;%~&`69fMP7-*OJqL~(e^Uy { await snapshot(); }); + it('transforms-translate works with position sticky element', async (done) => { + let sticky; + let scroller; + scroller = createElementWithStyle( + 'div', + { + position: 'relative', + width: '100px', + height: '200px', + overflow: 'scroll', + border: '1px solid rgb(0, 0, 0)', + }, + [ + (sticky = createElementWithStyle('div', { + display: 'flex', + top: '50px', + position: 'sticky', + height: '100px', + width: '100px', + 'background-color': 'green', + })), + ] + ); + + BODY.appendChild(scroller); + + await snapshot(); + + requestAnimationFrame(async () => { + sticky.style.transform = 'translateY(-100px)'; + await snapshot(); + done(); + }); + }); + it('should work with image', async () => { let div; div = createElement( diff --git a/integration_tests/specs/css/css-values/rem.ts b/integration_tests/specs/css/css-values/rem.ts index 02f6eab524..51f1a46e2e 100644 --- a/integration_tests/specs/css/css-values/rem.ts +++ b/integration_tests/specs/css/css-values/rem.ts @@ -1,5 +1,5 @@ describe("rem", () => { - it("should works with font size of html", async () => { + fit("should works with font size of html", async () => { let div; let div2; let div3; From a0373ea167aeb16c22b0ed7fff2960378123b5b6 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Fri, 9 Jul 2021 11:10:28 +0800 Subject: [PATCH 13/17] chore: method name opt --- kraken/lib/src/css/values/length.dart | 6 +++--- kraken/lib/src/rendering/box_model.dart | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/kraken/lib/src/css/values/length.dart b/kraken/lib/src/css/values/length.dart index d4f39788c2..2bc8859c13 100644 --- a/kraken/lib/src/css/values/length.dart +++ b/kraken/lib/src/css/values/length.dart @@ -96,9 +96,9 @@ class CSSLength { double? currentValue = double.tryParse(unitedValue.split(REM)[0]); if (currentValue == null || renderStyle == null) return null; RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; - RenderBoxModel? documentRoot = renderBoxModel.getDocumentRoot(); - if (documentRoot != null) { - double rootFontSize = documentRoot.renderStyle.fontSize; + RenderBoxModel? rootBoxModel = renderBoxModel.getRootBoxModel(); + if (rootBoxModel != null) { + double rootFontSize = rootBoxModel.renderStyle.fontSize; return rootFontSize * currentValue; } return null; diff --git a/kraken/lib/src/rendering/box_model.dart b/kraken/lib/src/rendering/box_model.dart index 0f678e2d3e..5f54a95b41 100644 --- a/kraken/lib/src/rendering/box_model.dart +++ b/kraken/lib/src/rendering/box_model.dart @@ -1567,7 +1567,8 @@ class RenderBoxModel extends RenderBox return _parent != null ? _parent as RenderBoxModel : null; } - RenderBoxModel? getDocumentRoot() { + /// Get the root box model of document which corresponds to html element. + RenderBoxModel? getRootBoxModel() { RenderBoxModel _self = this; while (_self.parent != null && _self.parent is! RenderViewportBox) { _self = _self.parent as RenderBoxModel; From 49d93c22e3822fcafa82c52825c0354398090666 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Fri, 9 Jul 2021 17:20:08 +0800 Subject: [PATCH 14/17] feat: use fontSize and rootFontSize instead of renderStyle as toDisplayPortValue params --- kraken/lib/src/css/animation.dart | 12 +- kraken/lib/src/css/background.dart | 45 +++++- kraken/lib/src/css/box.dart | 71 ++++++++- kraken/lib/src/css/filter.dart | 11 +- kraken/lib/src/css/flexbox.dart | 12 +- kraken/lib/src/css/render_style.dart | 18 ++- kraken/lib/src/css/style_declaration.dart | 12 +- kraken/lib/src/css/text.dart | 147 ++++++++++++++---- kraken/lib/src/css/transform.dart | 138 ++++++++++++---- kraken/lib/src/css/values/length.dart | 43 +++-- kraken/lib/src/css/values/position.dart | 12 +- kraken/lib/src/dom/element.dart | 56 ++++++- kraken/lib/src/dom/element_manager.dart | 1 - .../elements/canvas/canvas_context_2d.dart | 11 +- kraken/lib/src/dom/elements/html.dart | 1 + kraken/lib/src/dom/elements/img.dart | 23 ++- 16 files changed, 510 insertions(+), 103 deletions(-) diff --git a/kraken/lib/src/css/animation.dart b/kraken/lib/src/css/animation.dart index ee4e05b8c2..df4bf4417f 100644 --- a/kraken/lib/src/css/animation.dart +++ b/kraken/lib/src/css/animation.dart @@ -482,6 +482,14 @@ class KeyframeEffect extends AnimationEffect { static List<_Interpolation> _makeInterpolations(Map> propertySpecificKeyframeGroups, Size? viewportSize, RenderStyle? renderStyle) { List<_Interpolation> interpolations = []; + double? rootFontSize; + double? fontSize; + if (renderStyle != null) { + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + fontSize = renderStyle.fontSize; + } + propertySpecificKeyframeGroups.forEach((String property, List keyframes) { for (int i = 0; i < keyframes.length - 1; i++) { int startIndex = i; @@ -517,8 +525,8 @@ class KeyframeEffect extends AnimationEffect { startOffset, endOffset, _parseEasing(keyframes[startIndex].easing), - parseProperty(left, viewportSize, renderStyle), - parseProperty(right, viewportSize, renderStyle), + parseProperty(left, viewportSize, rootFontSize, fontSize), + parseProperty(right, viewportSize, rootFontSize, fontSize), handlers[1] ); diff --git a/kraken/lib/src/css/background.dart b/kraken/lib/src/css/background.dart index 6faa435426..7fa8225985 100644 --- a/kraken/lib/src/css/background.dart +++ b/kraken/lib/src/css/background.dart @@ -149,6 +149,11 @@ class CSSBackground { List colors = []; List stops = []; int start = 0; + RenderStyle renderStyle = renderBoxModel.renderStyle; + Size viewportSize = renderStyle.viewportSize; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + switch (method.name) { case 'linear-gradient': case 'repeating-linear-gradient': @@ -175,7 +180,12 @@ class CSSBackground { end = Alignment.centerLeft; } if (style![WIDTH].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], renderStyle: renderBoxModel.renderStyle); + gradientLength = CSSLength.toDisplayPortValue( + style[WIDTH], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentWidth(renderBoxModel); } @@ -194,7 +204,12 @@ class CSSBackground { end = Alignment.topCenter; } if (style![HEIGHT].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], renderStyle: renderBoxModel.renderStyle); + gradientLength = CSSLength.toDisplayPortValue( + style[HEIGHT], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentHeight(renderBoxModel); } @@ -214,7 +229,12 @@ class CSSBackground { } if (style![WIDTH].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[WIDTH], renderStyle: renderBoxModel.renderStyle); + gradientLength = CSSLength.toDisplayPortValue( + style[WIDTH], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentWidth(renderBoxModel); } @@ -234,7 +254,12 @@ class CSSBackground { end = Alignment.bottomCenter; } if (style![HEIGHT].isNotEmpty) { - gradientLength = CSSLength.toDisplayPortValue(style[HEIGHT], renderStyle: renderBoxModel.renderStyle); + gradientLength = CSSLength.toDisplayPortValue( + style[HEIGHT], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } else if (renderBoxModel.attached) { gradientLength = RenderBoxModel.getLogicalContentHeight(renderBoxModel); } @@ -366,6 +391,11 @@ class CSSBackground { double? stop = defaultStop; if (strings.length >= 2) { try { + RenderStyle renderStyle = renderBoxModel.renderStyle; + Size viewportSize = renderStyle.viewportSize; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + for (int i = 1; i < strings.length; i++) { if (CSSPercentage.isPercentage(strings[i])) { stop = CSSPercentage.parsePercentage(strings[i]); @@ -373,7 +403,12 @@ class CSSBackground { stop = CSSAngle.parseAngle(strings[i])! / (math.pi * 2); } else if (CSSLength.isLength(strings[i])) { if (gradientLength != null) { - stop = CSSLength.toDisplayPortValue(strings[i], renderStyle: renderBoxModel.renderStyle)! / gradientLength; + stop = CSSLength.toDisplayPortValue( + strings[i], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )! / gradientLength; } } colorGradients.add(CSSColorStop(CSSColor.parseColor(strings[0]), stop)); diff --git a/kraken/lib/src/css/box.dart b/kraken/lib/src/css/box.dart index 0679e0ad31..b664981acb 100644 --- a/kraken/lib/src/css/box.dart +++ b/kraken/lib/src/css/box.dart @@ -493,6 +493,11 @@ mixin CSSBoxMixin on RenderStyleBase { if (style.contains(BOX_SHADOW)) { boxShadow = []; var shadows = CSSStyleProperty.getShadowValues(style[BOX_SHADOW]); + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + if (shadows != null) { for (var shadowDefinitions in shadows) { // Specifies the color of the shadow. If the color is absent, it defaults to currentColor. @@ -501,10 +506,30 @@ mixin CSSBoxMixin on RenderStyleBase { colorDefinition = style.getCurrentColor(); } Color? color = CSSColor.parseColor(colorDefinition); - double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], renderStyle: renderStyle) ?? 0; - double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], renderStyle: renderStyle) ?? 0; - double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], renderStyle: renderStyle) ?? 0; - double spreadRadius = CSSLength.toDisplayPortValue(shadowDefinitions[4], renderStyle: renderStyle) ?? 0; + double offsetX = CSSLength.toDisplayPortValue( + shadowDefinitions[1], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + double offsetY = CSSLength.toDisplayPortValue( + shadowDefinitions[2], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + double blurRadius = CSSLength.toDisplayPortValue( + shadowDefinitions[3], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + double spreadRadius = CSSLength.toDisplayPortValue( + shadowDefinitions[4], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; bool inset = shadowDefinitions[5] == INSET; if (color != null) { @@ -557,6 +582,11 @@ class CSSBorderSide { static String BOTTOM = 'Bottom'; static double? getBorderWidth(String input, RenderStyle renderStyle) { + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + // https://drafts.csswg.org/css2/#border-width-properties // The interpretation of the first three values depends on the user agent. // The following relationships must hold, however: @@ -573,7 +603,12 @@ class CSSBorderSide { borderWidth = 5; break; default: - borderWidth = CSSLength.toDisplayPortValue(input, renderStyle: renderStyle); + borderWidth = CSSLength.toDisplayPortValue( + input, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } return borderWidth; } @@ -623,15 +658,35 @@ class CSSBorderRadius { static Radius none = Radius.zero; static Radius? getRadius(String radius, RenderStyle renderStyle) { + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + if (radius.isNotEmpty) { // border-top-left-radius: horizontal vertical List values = radius.split(_spaceRegExp); if (values.length == 1) { - double? circular = CSSLength.toDisplayPortValue(values[0], renderStyle: renderStyle); + double? circular = CSSLength.toDisplayPortValue( + values[0], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); if (circular != null) return Radius.circular(circular); } else if (values.length == 2) { - double? x = CSSLength.toDisplayPortValue(values[0], renderStyle: renderStyle); - double? y = CSSLength.toDisplayPortValue(values[1], renderStyle: renderStyle); + double? x = CSSLength.toDisplayPortValue( + values[0], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); + double? y = CSSLength.toDisplayPortValue( + values[1], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); if (x != null && y != null) return Radius.elliptical(x, y); } } diff --git a/kraken/lib/src/css/filter.dart b/kraken/lib/src/css/filter.dart index c2d8d75d1d..8553ec083e 100644 --- a/kraken/lib/src/css/filter.dart +++ b/kraken/lib/src/css/filter.dart @@ -139,12 +139,21 @@ mixin CSSFilterEffectsMixin { // Get the image filter. static ImageFilter? _parseImageFilters(List functions, RenderStyle renderStyle) { + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; if (functions.length > 0) { for (int i = 0; i < functions.length; i ++) { CSSFunctionalNotation f = functions[i]; switch (f.name.toLowerCase()) { case BLUR: - double amount = CSSLength.parseLength(f.args.first, renderStyle: renderStyle)!; + double amount = CSSLength.parseLength( + f.args.first, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )!; return ImageFilter.blur(sigmaX: amount, sigmaY: amount); } } diff --git a/kraken/lib/src/css/flexbox.dart b/kraken/lib/src/css/flexbox.dart index 2c91ccba4b..6e8ef3b00b 100644 --- a/kraken/lib/src/css/flexbox.dart +++ b/kraken/lib/src/css/flexbox.dart @@ -4,6 +4,7 @@ * Copyright (C) 2019-present Alibaba Inc. All rights reserved. * Author: Kraken Team. */ +import 'package:flutter/rendering.dart'; import 'package:kraken/rendering.dart'; import 'package:kraken/css.dart'; @@ -424,7 +425,16 @@ mixin CSSFlexboxMixin on RenderStyleBase { double? _getFlexBasis(CSSStyleDeclaration style) { String basisStr = style[FLEX_BASIS]; RenderStyle renderStyle = this as RenderStyle; - double? flexBasis = CSSLength.toDisplayPortValue(basisStr, renderStyle: renderStyle); + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + double? flexBasis = CSSLength.toDisplayPortValue( + basisStr, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); if (basisStr.isNotEmpty && basisStr != AUTO) { if (flexBasis! < 0) { flexBasis = null; diff --git a/kraken/lib/src/css/render_style.dart b/kraken/lib/src/css/render_style.dart index da72dcd711..b92c393432 100644 --- a/kraken/lib/src/css/render_style.dart +++ b/kraken/lib/src/css/render_style.dart @@ -476,6 +476,10 @@ class RenderStyle List methods = CSSFunction.parseFunction(transformStr); final String TRANSLATE = 'translate'; bool isPercentageExist = false; + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; Matrix4? matrix4; for (CSSFunctionalNotation method in methods) { @@ -490,7 +494,12 @@ class RenderStyle translateY = (size!.height * percentage).toString() + 'px'; isPercentageExist = true; } - y = CSSLength.toDisplayPortValue(translateY, renderStyle: renderStyle) ?? 0; + y = CSSLength.toDisplayPortValue( + translateY, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; } else { y = 0; } @@ -500,7 +509,12 @@ class RenderStyle translateX = (size!.width * percentage).toString() + 'px'; isPercentageExist = true; } - x = CSSLength.toDisplayPortValue(translateX, renderStyle: renderStyle) ?? 0; + x = CSSLength.toDisplayPortValue( + translateX, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; transform = Matrix4.identity()..translate(x, y); } if (transform != null) { diff --git a/kraken/lib/src/css/style_declaration.dart b/kraken/lib/src/css/style_declaration.dart index 798e7e2548..e4ca5c3584 100644 --- a/kraken/lib/src/css/style_declaration.dart +++ b/kraken/lib/src/css/style_declaration.dart @@ -8,6 +8,7 @@ import 'dart:ui'; import 'package:kraken/css.dart'; import 'package:kraken/dom.dart'; +import 'package:kraken/rendering.dart'; import 'package:kraken/src/css/animation.dart'; const String SAFE_AREA_INSET = 'safe-area-inset'; @@ -478,6 +479,15 @@ class CSSStyleDeclaration { return _expandShorthand(propertyName, normalizedValue, viewportSize); } + + double? rootFontSize; + double? fontSize; + if (renderStyle != null) { + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + fontSize = renderStyle.fontSize; + } + switch (propertyName) { case WIDTH: case HEIGHT: @@ -543,7 +553,7 @@ class CSSStyleDeclaration { if (!CSSBackground.isValidBackgroundRepeatValue(normalizedValue)) return; break; case TRANSFORM: - if (!CSSTransform.isValidTransformValue(normalizedValue, viewportSize, renderStyle)) { + if (!CSSTransform.isValidTransformValue(normalizedValue, viewportSize, rootFontSize, fontSize)) { return; } break; diff --git a/kraken/lib/src/css/text.dart b/kraken/lib/src/css/text.dart index a0460a1ea9..954d1f4ec5 100644 --- a/kraken/lib/src/css/text.dart +++ b/kraken/lib/src/css/text.dart @@ -338,7 +338,7 @@ mixin CSSTextMixin on RenderStyleBase { } }); } - + // Update font-size may affect following style: // 1. Nested children text size due to style inheritance. // 2. Em unit: style of own element with em unit and nested children with no font-size set due to style inheritance. @@ -351,12 +351,12 @@ mixin CSSTextMixin on RenderStyleBase { _updateFontSize(child, oriRenderBoxModel, isDocumentRoot); // Need update all em unit style of child when its font size is inherited. child.renderStyle.style.applyEmProperties(); - + if (isDocumentRoot) { child.renderStyle.style.applyRemProperties(); } } - + // Only need to update text when its parent has no font-size set. } else if (child is RenderTextBox && (renderBoxModel == oriRenderBoxModel || renderBoxModel.renderStyle.style[FONT_SIZE].isEmpty) @@ -457,6 +457,10 @@ mixin CSSTextMixin on RenderStyleBase { void updateTextStyle(String? property) { RenderStyle renderStyle = this as RenderStyle; + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double _fontSize = renderStyle.fontSize; switch (property) { case COLOR: @@ -481,19 +485,44 @@ mixin CSSTextMixin on RenderStyleBase { fontFamily = CSSText.getFontFamilyFallback(style); break; case FONT_SIZE: - fontSize = CSSText.getFontSize(style, renderStyle: renderStyle); + fontSize = CSSText.getFontSize( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: _fontSize + ); break; case LINE_HEIGHT: - lineHeight = CSSText.getLineHeight(style, renderStyle: renderStyle); + lineHeight = CSSText.getLineHeight( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); break; case LETTER_SPACING: - letterSpacing = CSSText.getLetterSpacing(style, renderStyle: renderStyle); + letterSpacing = CSSText.getLetterSpacing( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); break; case WORD_SPACING: - wordSpacing = CSSText.getWordSpacing(style, renderStyle: renderStyle); + wordSpacing = CSSText.getWordSpacing( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); break; case TEXT_SHADOW: - textShadow = CSSText.getTextShadow(style, renderStyle: renderStyle); + textShadow = CSSText.getTextShadow( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); break; case WHITE_SPACE: whiteSpace = CSSText.getWhiteSpace(style); @@ -535,16 +564,39 @@ class CSSText { return value == 'solid' || value == 'double' || value == 'dotted' || value == 'dashed' || value == 'wavy'; } - static double? getLineHeight(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { - return parseLineHeight(style[LINE_HEIGHT], getFontSize(style, viewportSize: viewportSize, renderStyle: renderStyle), - viewportSize: viewportSize, renderStyle: renderStyle); + static double? getLineHeight(CSSStyleDeclaration style, { + Size? viewportSize, + double? rootFontSize, + double? fontSize + }) { + double _fontSize = getFontSize( + style, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); + return parseLineHeight( + style[LINE_HEIGHT], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: _fontSize + ); } - static double? parseLineHeight(String value, double fontSize, { Size? viewportSize, RenderStyle? renderStyle }) { + static double? parseLineHeight(String value, { + Size? viewportSize, + double? rootFontSize, + required double fontSize + }) { double? lineHeight; if (value.isNotEmpty) { if (CSSLength.isLength(value)) { - double lineHeightValue = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderStyle)!; + double lineHeightValue = CSSLength.toDisplayPortValue( + value, viewportSize: + viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )!; if (lineHeightValue > 0) { lineHeight = lineHeightValue; } @@ -788,34 +840,58 @@ class CSSText { } static double DEFAULT_FONT_SIZE = 16.0; - static double getFontSize(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { + static double getFontSize(CSSStyleDeclaration style, { + Size? viewportSize, + double? rootFontSize, + double? fontSize + }) { if (style.contains(FONT_SIZE)) { - return CSSLength.toDisplayPortValue(style[FONT_SIZE], viewportSize: viewportSize, renderStyle: renderStyle) - ?? DEFAULT_FONT_SIZE; + return CSSLength.toDisplayPortValue( + style[FONT_SIZE], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? DEFAULT_FONT_SIZE; } else { return DEFAULT_FONT_SIZE; } } - static double getLetterSpacing(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { + static double getLetterSpacing(CSSStyleDeclaration style, { + Size? viewportSize, + double? rootFontSize, + double? fontSize + }) { if (style.contains(LETTER_SPACING)) { String _letterSpacing = style[LETTER_SPACING]; if (_letterSpacing == NORMAL) return DEFAULT_LETTER_SPACING; - return CSSLength.toDisplayPortValue(_letterSpacing, viewportSize: viewportSize, renderStyle: renderStyle) - ?? DEFAULT_LETTER_SPACING; + return CSSLength.toDisplayPortValue( + _letterSpacing, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? DEFAULT_LETTER_SPACING; } else { return DEFAULT_LETTER_SPACING; } } - static double getWordSpacing(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { + static double getWordSpacing(CSSStyleDeclaration style, { + Size? viewportSize, + double? rootFontSize, + double? fontSize + }) { if (style.contains(WORD_SPACING)) { String _wordSpacing = style[WORD_SPACING]; if (_wordSpacing == NORMAL) return DEFAULT_WORD_SPACING; - return CSSLength.toDisplayPortValue(_wordSpacing, viewportSize: viewportSize, renderStyle: renderStyle) - ?? DEFAULT_WORD_SPACING; + return CSSLength.toDisplayPortValue( + _wordSpacing, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? DEFAULT_WORD_SPACING; } else { return DEFAULT_WORD_SPACING; } @@ -836,7 +912,11 @@ class CSSText { return null; } - static List getTextShadow(CSSStyleDeclaration style, { Size? viewportSize, RenderStyle? renderStyle }) { + static List getTextShadow(CSSStyleDeclaration style, { + Size? viewportSize, + double? rootFontSize, + double? fontSize + }) { List textShadows = []; if (style.contains(TEXT_SHADOW)) { var shadows = CSSStyleProperty.getShadowValues(style[TEXT_SHADOW]); @@ -844,9 +924,24 @@ class CSSText { for (var shadowDefinitions in shadows) { // Specifies the color of the shadow. If the color is absent, it defaults to currentColor. Color? color = CSSColor.parseColor(shadowDefinitions[0] ?? style.getCurrentColor()); - double offsetX = CSSLength.toDisplayPortValue(shadowDefinitions[1], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; - double offsetY = CSSLength.toDisplayPortValue(shadowDefinitions[2], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; - double blurRadius = CSSLength.toDisplayPortValue(shadowDefinitions[3], viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double offsetX = CSSLength.toDisplayPortValue( + shadowDefinitions[1], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + double offsetY = CSSLength.toDisplayPortValue( + shadowDefinitions[2], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + double blurRadius = CSSLength.toDisplayPortValue( + shadowDefinitions[3], + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; if (color != null) { textShadows.add(Shadow( diff --git a/kraken/lib/src/css/transform.dart b/kraken/lib/src/css/transform.dart index cd2f84fcb0..4d18d68e39 100644 --- a/kraken/lib/src/css/transform.dart +++ b/kraken/lib/src/css/transform.dart @@ -8,11 +8,12 @@ import 'package:flutter/rendering.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:kraken/css.dart'; import 'package:kraken/dom.dart'; +import 'package:kraken/rendering.dart'; // CSS Transforms: https://drafts.csswg.org/css-transforms/ final RegExp _spaceRegExp = RegExp(r'\s+(?![^(]*\))'); -Color? _parseColor(String color, [Size? viewportSize, RenderStyle? renderStyle]) { +Color? _parseColor(String color, [Size? viewportSize, double? rootFontSize, double? fontSize]) { return CSSColor.parseColor(color); } @@ -47,8 +48,13 @@ void _updateColor(Color oldColor, Color newColor, double progress, String proper } } -double? _parseLength(String _length, [Size? viewportSize, RenderStyle? renderStyle]) { - return CSSLength.parseLength(_length, viewportSize: viewportSize, renderStyle: renderStyle); +double? _parseLength(String _length, [Size? viewportSize, double? rootFontSize, double? fontSize]) { + return CSSLength.parseLength( + _length, + viewportSize: viewportSize!, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } void _updateLength(double oldLength, double newLength, double progress, String property, RenderStyle renderStyle) { @@ -106,7 +112,7 @@ void _updateLength(double oldLength, double newLength, double progress, String p } } -FontWeight _parseFontWeight(String fontWeight, [Size? viewportSize, RenderStyle? renderStyle]) { +FontWeight _parseFontWeight(String fontWeight, [Size? viewportSize, double? rootFontSize, double? fontSize]) { return CSSText.parseFontWeight(fontWeight); } @@ -119,7 +125,7 @@ void _updateFontWeight(FontWeight oldValue, FontWeight newValue, double progress } } -double? _parseNumber(String number, [Size? viewportSize, RenderStyle? renderStyle]) { +double? _parseNumber(String number, [Size? viewportSize, double? rootFontSize, double? fontSize]) { return CSSNumber.parseNumber(number); } @@ -145,17 +151,30 @@ void _updateNumber(double oldValue, double newValue, double progress, String pro } } -String _parseLineHeight(String lineHeight, [Size? viewportSize, RenderStyle? renderStyle]) { +String _parseLineHeight(String lineHeight, [Size? viewportSize, double? rootFontSize, double? fontSize]) { return lineHeight; } void _updateLineHeight(String oldValue, String newValue, double progress, String property, RenderStyle renderStyle) { Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; double? lineHeight; if (CSSLength.isLength(oldValue) && CSSLength.isLength(newValue)) { - double left = CSSLength.parseLength(oldValue, viewportSize: viewportSize, renderStyle: renderStyle)!; - double right = CSSLength.parseLength(newValue, viewportSize: viewportSize, renderStyle: renderStyle)!; + double left = CSSLength.parseLength( + oldValue, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )!; + double right = CSSLength.parseLength( + newValue, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )!; lineHeight = _getNumber(left, right, progress); } else if (CSSNumber.isNumber(oldValue) && CSSNumber.isNumber(newValue)) { double left = CSSNumber.parseNumber(oldValue)!; @@ -170,8 +189,8 @@ void _updateLineHeight(String oldValue, String newValue, double progress, String } } -Matrix4? _parseTransform(String value, [Size? viewportSize, RenderStyle? renderStyle]) { - return CSSTransform.parseTransform(value, viewportSize, renderStyle); +Matrix4? _parseTransform(String value, [Size? viewportSize, double? rootFontSize, double? fontSize]) { + return CSSTransform.parseTransform(value, viewportSize, rootFontSize, fontSize); } double _lerpDouble(double begin, double to, double t) { @@ -799,18 +818,18 @@ class CSSTransform { return [translate, scale, angle, m11, m12, m21, m22]; } - static bool isValidTransformValue(String value, [Size? viewportSize, RenderStyle? renderStyle]) { - return value == NONE || parseTransform(value, viewportSize, renderStyle) != null; + static bool isValidTransformValue(String value, [Size? viewportSize, double? rootFontSize, double? fontSize]) { + return value == NONE || parseTransform(value, viewportSize, rootFontSize, fontSize) != null; } static Matrix4 initial = Matrix4.identity(); - static Matrix4? parseTransform(String value, [Size? viewportSize, RenderStyle? renderStyle]) { + static Matrix4? parseTransform(String value, [Size? viewportSize, double? rootFontSize, double? fontSize]) { List methods = CSSFunction.parseFunction(value); Matrix4? matrix4; for (CSSFunctionalNotation method in methods) { - Matrix4? transform = _parseTransform(method, viewportSize, renderStyle); + Matrix4? transform = _parseTransform(method, viewportSize, rootFontSize, fontSize); if (transform != null) { if (matrix4 == null) { matrix4 = transform; @@ -844,7 +863,7 @@ class CSSTransform { static const String SKEW_Y = 'skewy'; static const String PERSPECTIVE = 'perspective'; - static Matrix4? _parseTransform(CSSFunctionalNotation method, [Size? viewportSize, RenderStyle? renderStyle]) { + static Matrix4? _parseTransform(CSSFunctionalNotation method, [Size? viewportSize, double? rootFontSize, double? fontSize]) { switch (method.name) { case MATRIX: if (method.args.length == 6) { @@ -869,11 +888,21 @@ class CSSTransform { if (method.args.length >= 1 && method.args.length <= 2) { double y; if (method.args.length == 2) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + y = CSSLength.toDisplayPortValue( + method.args[1].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; } else { y = 0; } - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double x = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; return Matrix4.identity()..translate(x, y); } break; @@ -885,31 +914,66 @@ class CSSTransform { if (method.args.length >= 1 && method.args.length <= 3) { double y = 0, z = 0; if (method.args.length == 2) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + y = CSSLength.toDisplayPortValue( + method.args[1].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; } if (method.args.length == 3) { - y = CSSLength.toDisplayPortValue(method.args[1].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; - z = CSSLength.toDisplayPortValue(method.args[2].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + y = CSSLength.toDisplayPortValue( + method.args[1].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; + z = CSSLength.toDisplayPortValue( + method.args[2].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; } - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double x = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; return Matrix4.identity()..translate(x, y, z); } break; case TRANSLATE_X: if (method.args.length == 1) { - double x = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double x = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; return Matrix4.identity()..translate(x); } break; case TRANSLATE_Y: if (method.args.length == 1) { - double y = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double y = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; return Matrix4.identity()..translate(0.0, y); } break; case TRANSLATE_Z: if (method.args.length == 1) { - double z = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double z = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; return Matrix4.identity()..translate(0.0, 0.0, z); } break; @@ -1008,7 +1072,12 @@ class CSSTransform { // 0, 0, 1, perspective, // 0, 0, 0, 1] if (method.args.length == 1) { - double p = CSSLength.toDisplayPortValue(method.args[0].trim(), viewportSize: viewportSize, renderStyle: renderStyle) ?? 0; + double p = CSSLength.toDisplayPortValue( + method.args[0].trim(), + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; p = (-1 / p); return Matrix4.identity()..storage[11] = p; } @@ -1028,6 +1097,11 @@ class CSSOrigin { if (origin.isNotEmpty) { List originList = origin.trim().split(_spaceRegExp); String? x, y; + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + if (originList.length == 1) { // default center x = originList[0]; @@ -1051,7 +1125,12 @@ class CSSOrigin { // handle x if (CSSLength.isLength(x)) { - offsetX = CSSLength.toDisplayPortValue(x, renderStyle: renderStyle) ?? offsetX; + offsetX = CSSLength.toDisplayPortValue( + x, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? offsetX; } else if (CSSPercentage.isPercentage(x)) { alignX = CSSPercentage.parsePercentage(x!)! * 2 - 1; } else if (x == CSSPosition.LEFT) { @@ -1064,7 +1143,12 @@ class CSSOrigin { // handle y if (CSSLength.isLength(y)) { - offsetY = CSSLength.toDisplayPortValue(y, renderStyle: renderStyle) ?? offsetY; + offsetY = CSSLength.toDisplayPortValue( + y, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? offsetY; } else if (CSSPercentage.isPercentage(y)) { alignY = CSSPercentage.parsePercentage(y!)! * 2 - 1; } else if (y == CSSPosition.TOP) { diff --git a/kraken/lib/src/css/values/length.dart b/kraken/lib/src/css/values/length.dart index 2bc8859c13..ff614a4684 100644 --- a/kraken/lib/src/css/values/length.dart +++ b/kraken/lib/src/css/values/length.dart @@ -74,38 +74,49 @@ class CSSLength { return double.tryParse(percentage.split('%')[0])! / 100; } - static double? parseLength(String unitedValue, { Size? viewportSize, RenderStyle? renderStyle }) { - return toDisplayPortValue(unitedValue, viewportSize: viewportSize, renderStyle: renderStyle); + static double? parseLength( + String unitedValue, + { + Size? viewportSize, + double? rootFontSize, + double? fontSize + } + ) { + return toDisplayPortValue( + unitedValue, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); } - static double? toDisplayPortValue(String? unitedValue, { Size? viewportSize, RenderStyle? renderStyle }) { + static double? toDisplayPortValue( + String? unitedValue, + { + Size? viewportSize, + double? rootFontSize, + double? fontSize + } + ) { if (unitedValue == null || unitedValue.isEmpty) return null; unitedValue = unitedValue.trim(); if (unitedValue == INITIAL) return null; double? displayPortValue; - Size _viewportSize = renderStyle != null ? renderStyle.viewportSize : viewportSize!; - double viewportWidth = _viewportSize.width; - double viewportHeight = _viewportSize.height; + double viewportWidth = viewportSize!.width; + double viewportHeight = viewportSize.height; // Only '0' is accepted with no unit. if (unitedValue == ZERO) { return 0; } else if (unitedValue.endsWith(REM)) { double? currentValue = double.tryParse(unitedValue.split(REM)[0]); - if (currentValue == null || renderStyle == null) return null; - RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; - RenderBoxModel? rootBoxModel = renderBoxModel.getRootBoxModel(); - if (rootBoxModel != null) { - double rootFontSize = rootBoxModel.renderStyle.fontSize; - return rootFontSize * currentValue; - } - return null; + if (currentValue == null || rootFontSize == null) return null; + return rootFontSize * currentValue; } else if (unitedValue.endsWith(EM)) { double? currentValue = double.tryParse(unitedValue.split(EM)[0]); - if (currentValue == null || renderStyle == null) return null; - double fontSize = renderStyle.fontSize; + if (currentValue == null || fontSize == null) return null; return fontSize * currentValue; } else if (unitedValue.endsWith(RPX)) { double? currentValue = double.tryParse(unitedValue.split(RPX)[0]); diff --git a/kraken/lib/src/css/values/position.dart b/kraken/lib/src/css/values/position.dart index ecbc9c9925..47fad99c27 100644 --- a/kraken/lib/src/css/values/position.dart +++ b/kraken/lib/src/css/values/position.dart @@ -6,6 +6,7 @@ */ import 'package:flutter/painting.dart'; import 'package:kraken/css.dart'; +import 'package:kraken/rendering.dart'; final RegExp _splitRegExp = RegExp(r'\s+'); @@ -57,7 +58,16 @@ class CSSPosition { if (CSSLength.isPercentage(input)) { return CSSBackgroundPosition(percentage: _gatValuePercentage(input)); } else if (CSSLength.isLength(input)) { - return CSSBackgroundPosition(length: CSSLength.toDisplayPortValue(input, renderStyle: renderStyle)); + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + return CSSBackgroundPosition(length: CSSLength.toDisplayPortValue( + input, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + )); } else { if (isHorizontal) { switch (input) { diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index 592ebbfa45..de86f70994 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -80,6 +80,8 @@ typedef void BeforeRendererAttach(); typedef void AfterRendererAttach(); /// Return the targetId of current element. typedef int GetTargetId(); +/// Get the font size of root element +typedef double GetRootElementFontSize(); /// Delegate methods passed to renderBoxModel for actions involved with element /// (eg. convert renderBoxModel to repaint boundary then attach to element). @@ -90,6 +92,7 @@ class ElementDelegate { BeforeRendererAttach beforeRendererAttach; AfterRendererAttach afterRendererAttach; GetTargetId getTargetId; + GetRootElementFontSize getRootElementFontSize; ElementDelegate( this.markRendererNeedsLayout, @@ -97,7 +100,8 @@ class ElementDelegate { this.detachRenderer, this.beforeRendererAttach, this.afterRendererAttach, - this.getTargetId + this.getTargetId, + this.getRootElementFontSize ); } @@ -188,6 +192,7 @@ class Element extends Node _beforeRendererAttach, _afterRendererAttach, _getTargetId, + _getRootElementFontSize ); } @@ -221,6 +226,15 @@ class Element extends Node return targetId; } + double _getRootElementFontSize() { + Element rootElement = elementManager.viewportElement; + if (rootElement == null) { + return CSSText.DEFAULT_FONT_SIZE; + } + RenderBoxModel rootBoxModel = rootElement.renderBoxModel!; + return rootBoxModel.renderStyle.fontSize; + } + @override RenderObject? get renderer => renderBoxModel?.renderPositionHolder ?? renderBoxModel; @@ -955,7 +969,14 @@ class Element extends Node } RenderStyle renderStyle = renderBoxModel!.renderStyle; - double? presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle); + double rootFontSize = _getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + double? presentValue = CSSLength.toDisplayPortValue( + present, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); if (presentValue == null) return; renderStyle.updateOffset(property, presentValue); } @@ -996,7 +1017,14 @@ class Element extends Node } RenderStyle renderStyle = selfRenderBoxModel.renderStyle; - double presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle) ?? 0; + double rootFontSize = _getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + double? presentValue = CSSLength.toDisplayPortValue( + present, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; renderStyle.updatePadding(property, presentValue); } @@ -1012,7 +1040,14 @@ class Element extends Node } RenderStyle renderStyle = selfRenderBoxModel.renderStyle; - double? presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle); + double rootFontSize = _getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + double? presentValue = CSSLength.toDisplayPortValue( + present, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); renderStyle.updateSizing(property, presentValue); } @@ -1028,7 +1063,14 @@ class Element extends Node } RenderStyle renderStyle = selfRenderBoxModel.renderStyle; - double presentValue = CSSLength.toDisplayPortValue(present, renderStyle: renderStyle) ?? 0; + double rootFontSize = _getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + double? presentValue = CSSLength.toDisplayPortValue( + present, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ) ?? 0; renderStyle.updateMargin(property, presentValue); // Margin change in flex layout may affect transformed display // https://www.w3.org/TR/css-display-3/#transformations @@ -1113,7 +1155,9 @@ class Element extends Node } RenderStyle renderStyle = selfRenderBoxModel.renderStyle; - Matrix4? matrix4 = CSSTransform.parseTransform(present, renderStyle.viewportSize, renderStyle); + double rootFontSize = _getRootElementFontSize(); + double fontSize = renderStyle.fontSize; + Matrix4? matrix4 = CSSTransform.parseTransform(present, viewportSize, rootFontSize, fontSize); renderStyle.updateTransform(matrix4); } diff --git a/kraken/lib/src/dom/element_manager.dart b/kraken/lib/src/dom/element_manager.dart index 153e0017a4..ea7ab918ae 100644 --- a/kraken/lib/src/dom/element_manager.dart +++ b/kraken/lib/src/dom/element_manager.dart @@ -82,7 +82,6 @@ class ElementManager implements WidgetsBindingObserver, ElementsBindingObserver HTMLElement documentElement = HTMLElement(HTML_ID, htmlNativePtrMap[contextId]!, this); setEventTarget(documentElement); - viewportElement = documentElement; viewport.child = viewportElement.renderBoxModel; _viewportRenderObject = viewport; diff --git a/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart b/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart index 8f0b5da9cb..5e607e2de1 100644 --- a/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart +++ b/kraken/lib/src/dom/elements/canvas/canvas_context_2d.dart @@ -13,6 +13,7 @@ import 'package:flutter/painting.dart'; import 'package:kraken/bridge.dart'; import 'package:kraken/css.dart'; import 'package:kraken/dom.dart'; +import 'package:kraken/rendering.dart'; import 'package:vector_math/vector_math_64.dart'; import 'canvas_context.dart'; import 'canvas_path_2d.dart'; @@ -869,7 +870,15 @@ class CanvasRenderingContext2D { if (_fontProperties.isEmpty) { _parseFont(_DEFAULT_FONT); } - double? fontSize = CSSLength.toDisplayPortValue(_fontProperties[FONT_SIZE] ?? '10px', renderStyle: renderStyle); + Size viewportSize = renderStyle.viewportSize; + RenderBoxModel renderBoxModel = renderStyle.renderBoxModel!; + double rootFontSize = renderBoxModel.elementDelegate.getRootElementFontSize(); + double? fontSize = CSSLength.toDisplayPortValue( + _fontProperties[FONT_SIZE] ?? '10px', + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: renderStyle.fontSize + ); var fontFamilyFallback = CSSText.parseFontFamilyFallback(_fontProperties[FONT_FAMILY] ?? 'sans-serif'); FontWeight fontWeight = CSSText.parseFontWeight(_fontProperties[FONT_WEIGHT]); if (shouldStrokeText) { diff --git a/kraken/lib/src/dom/elements/html.dart b/kraken/lib/src/dom/elements/html.dart index 45b9a60394..63d94033a3 100644 --- a/kraken/lib/src/dom/elements/html.dart +++ b/kraken/lib/src/dom/elements/html.dart @@ -27,6 +27,7 @@ class HTMLElement extends Element { if (kProfileMode) { PerformanceTiming.instance().mark(PERF_ROOT_ELEMENT_PROPERTY_INIT); } + elementManager.viewportElement = this; // Init renderer willAttachRenderer(); // Init default render style value diff --git a/kraken/lib/src/dom/elements/img.dart b/kraken/lib/src/dom/elements/img.dart index 7a939e987e..fa3af94d0f 100644 --- a/kraken/lib/src/dom/elements/img.dart +++ b/kraken/lib/src/dom/elements/img.dart @@ -363,9 +363,12 @@ class ImageElement extends Element { @override void setProperty(String key, dynamic value) { super.setProperty(key, value); - double viewportWidth = elementManager.viewportWidth; - double viewportHeight = elementManager.viewportHeight; - Size viewportSize = Size(viewportWidth, viewportHeight); + double? rootFontSize; + double? fontSize; + if (renderBoxModel != null) { + rootFontSize = renderBoxModel!.elementDelegate.getRootElementFontSize(); + fontSize = renderBoxModel!.renderStyle.fontSize; + } // Reset frame number to zero when image needs to reload _frameNumber = 0; @@ -380,14 +383,24 @@ class ImageElement extends Element { value += 'px'; } - _propertyWidth = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderBoxModel?.renderStyle); + _propertyWidth = CSSLength.toDisplayPortValue( + value, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); _resize(); } else if (key == HEIGHT) { if (value is String && _isNumberString(value)) { value += 'px'; } - _propertyHeight = CSSLength.toDisplayPortValue(value, viewportSize: viewportSize, renderStyle: renderBoxModel?.renderStyle); + _propertyHeight = CSSLength.toDisplayPortValue( + value, + viewportSize: viewportSize, + rootFontSize: rootFontSize, + fontSize: fontSize + ); _resize(); } } From e14e85f483ef48cf0808bad5142ab8828530260a Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Fri, 9 Jul 2021 17:27:27 +0800 Subject: [PATCH 15/17] chore: method name opt --- kraken/lib/src/css/style_declaration.dart | 4 ++-- kraken/lib/src/css/text.dart | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kraken/lib/src/css/style_declaration.dart b/kraken/lib/src/css/style_declaration.dart index e4ca5c3584..17a3e38db1 100644 --- a/kraken/lib/src/css/style_declaration.dart +++ b/kraken/lib/src/css/style_declaration.dart @@ -613,7 +613,7 @@ class CSSStyleDeclaration { } /// Set all style properties with em unit. - void applyEmProperties() { + void setEmProperties() { _properties.forEach((key, value) { if (key != FONT_SIZE && value.endsWith(CSSLength.EM)) { String normalizedValue = _normalizeValue(value); @@ -623,7 +623,7 @@ class CSSStyleDeclaration { } /// Set all style properties with rem unit. - void applyRemProperties() { + void setRemProperties() { _properties.forEach((key, value) { if (key != FONT_SIZE && value.endsWith(CSSLength.REM)) { String normalizedValue = _normalizeValue(value); diff --git a/kraken/lib/src/css/text.dart b/kraken/lib/src/css/text.dart index 954d1f4ec5..780402282a 100644 --- a/kraken/lib/src/css/text.dart +++ b/kraken/lib/src/css/text.dart @@ -137,7 +137,7 @@ mixin CSSTextMixin on RenderStyleBase { if (_fontSize == value) return; _fontSize = value; // Need update all em unit style of own element when font size changed. - style.applyEmProperties(); + style.setEmProperties(); // Update all the children text with specified style property not set due to style inheritance. _updateFontSize(renderBoxModel!, renderBoxModel!, renderBoxModel!.isDocumentRootBox); @@ -326,7 +326,7 @@ mixin CSSTextMixin on RenderStyleBase { _updateNestChildrenText(child, styleProperty); // Need update all em unit style of child when its font size is inherited. if (styleProperty == FONT_SIZE) { - child.renderStyle.style.applyEmProperties(); + child.renderStyle.style.setEmProperties(); } } } else if (child is RenderTextBox) { @@ -350,10 +350,10 @@ mixin CSSTextMixin on RenderStyleBase { if (isDocumentRoot || child.renderStyle.style[FONT_SIZE].isEmpty) { _updateFontSize(child, oriRenderBoxModel, isDocumentRoot); // Need update all em unit style of child when its font size is inherited. - child.renderStyle.style.applyEmProperties(); + child.renderStyle.style.setEmProperties(); if (isDocumentRoot) { - child.renderStyle.style.applyRemProperties(); + child.renderStyle.style.setRemProperties(); } } From ce5864e366c8671be1d4b1fd208753cf63733897 Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Fri, 9 Jul 2021 17:43:18 +0800 Subject: [PATCH 16/17] chore: bump kraken_webview ver --- integration_tests/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/pubspec.yaml b/integration_tests/pubspec.yaml index e6418d382d..1c920ce002 100644 --- a/integration_tests/pubspec.yaml +++ b/integration_tests/pubspec.yaml @@ -30,7 +30,7 @@ dependencies: kraken_video_player: ^0.4.0 kraken_websocket: ^0.2.0 kraken_animation_player: ^0.2.0 - kraken_webview: ^0.7.0-dev.1 + kraken_webview: ^0.7.0 dev_dependencies: test: ^1.16.8 From ff5c1f9013d1bb0363d67b6eb5babc856d17d98e Mon Sep 17 00:00:00 2001 From: "zhanwen.zw" Date: Fri, 9 Jul 2021 17:48:53 +0800 Subject: [PATCH 17/17] fix: lint. --- kraken/lib/src/css/values/length.dart | 1 - kraken/lib/src/dom/element.dart | 3 --- 2 files changed, 4 deletions(-) diff --git a/kraken/lib/src/css/values/length.dart b/kraken/lib/src/css/values/length.dart index ff614a4684..fc83b66f4b 100644 --- a/kraken/lib/src/css/values/length.dart +++ b/kraken/lib/src/css/values/length.dart @@ -8,7 +8,6 @@ import 'dart:ui'; import 'package:kraken/css.dart'; -import 'package:kraken/rendering.dart'; // https://drafts.csswg.org/css-values-3/#absolute-lengths const _1in = 96; // 1in = 2.54cm = 96px diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index b7052996e0..9816b25691 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -230,9 +230,6 @@ class Element extends Node double _getRootElementFontSize() { Element rootElement = elementManager.viewportElement; - if (rootElement == null) { - return CSSText.DEFAULT_FONT_SIZE; - } RenderBoxModel rootBoxModel = rootElement.renderBoxModel!; return rootBoxModel.renderStyle.fontSize; }