computeContentBoxLogicalWidth method
void
computeContentBoxLogicalWidth()
Implementation
void computeContentBoxLogicalWidth() {
RenderBoxModel current = renderBoxModel!;
RenderStyle renderStyle = this;
double? logicalWidth;
CSSDisplay? effectiveDisplay = renderStyle.effectiveDisplay;
switch (effectiveDisplay) {
case CSSDisplay.block:
case CSSDisplay.flex:
case CSSDisplay.sliver:
// Use width directly if defined.
if (renderStyle.width.isNotAuto) {
logicalWidth = renderStyle.width.computedValue;
} else if (renderStyle.parent != null) {
RenderStyle parentRenderStyle = renderStyle.parent!;
RenderBoxModel parent = parentRenderStyle.renderBoxModel!;
// Block element (except replaced element) will stretch to the content width of its parent in flow layout.
// Replaced element also stretch in flex layout if align-items is stretch.
if (current is! RenderReplaced || parent is RenderFlexLayout) {
RenderStyle? ancestorRenderStyle = _findAncestorWithNoDisplayInline();
// Should ignore renderStyle of display inline when searching for ancestors to stretch width.
if (ancestorRenderStyle != null) {
logicalWidth = ancestorRenderStyle.contentBoxLogicalWidth;
// Should subtract horizontal margin of own from its parent content width.
if (logicalWidth != null) {
logicalWidth -= renderStyle.margin.horizontal;
}
}
}
}
break;
case CSSDisplay.inlineBlock:
case CSSDisplay.inlineFlex:
if (renderStyle.width.isNotAuto) {
logicalWidth = renderStyle.width.computedValue;
// The width of positioned, non-replaced element is determined as following algorithm.
// https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
} else if ((renderStyle.position == CSSPositionType.absolute ||
renderStyle.position == CSSPositionType.fixed)
&& current is! RenderReplaced
&& renderStyle.width.isAuto
&& renderStyle.left.isNotAuto
&& renderStyle.right.isNotAuto
) {
if (current.parent is! RenderBoxModel) {
logicalWidth = null;
}
// Should access the renderStyle of renderBoxModel parent but not renderStyle parent
// cause the element of renderStyle parent may not equal to containing block.
RenderBoxModel parent = current.parent as RenderBoxModel;
// Get the renderStyle of outer scrolling box cause the renderStyle of scrolling
// content box is only a fraction of the complete renderStyle.
RenderStyle parentRenderStyle = parent.isScrollingContentBox
? (parent.parent as RenderBoxModel).renderStyle
: parent.renderStyle;
// Width of positioned element should subtract its horizontal margin.
logicalWidth = (parentRenderStyle.paddingBoxLogicalWidth ?? 0)
- renderStyle.left.computedValue - renderStyle.right.computedValue
- renderStyle.marginLeft.computedValue - renderStyle.marginRight.computedValue;
} else if (current.hasSize && current.constraints.hasTightWidth) {
logicalWidth = current.constraints.maxWidth;
}
break;
case CSSDisplay.inline:
break;
case CSSDisplay.none:
break;
}
// Get width by intrinsic ratio for replaced element if width is auto.
if (logicalWidth == null && intrinsicRatio != null) {
logicalWidth = renderStyle.getWidthByIntrinsicRatio();
}
// Constrain width by min-width and max-width.
if (renderStyle.minWidth.isNotAuto) {
double minWidth = renderStyle.minWidth.computedValue;
if (logicalWidth != null && logicalWidth < minWidth) {
logicalWidth = minWidth;
}
}
if (renderStyle.maxWidth.isNotNone) {
double maxWidth = renderStyle.maxWidth.computedValue;
if (logicalWidth != null && logicalWidth > maxWidth) {
logicalWidth = maxWidth;
}
}
double? logicalContentWidth;
// Subtract padding and border width to get content width.
if (logicalWidth != null) {
logicalContentWidth = logicalWidth -
renderStyle.border.horizontal -
renderStyle.padding.horizontal;
// Logical width may be smaller than its border and padding width,
// in this case, content width will be negative which is illegal.
logicalContentWidth = math.max(0, logicalContentWidth);
}
_contentBoxLogicalWidth = logicalContentWidth;
}