computeContentBoxLogicalHeight method

void computeContentBoxLogicalHeight()

Implementation

void computeContentBoxLogicalHeight() {
  RenderBoxModel current = renderBoxModel!;
  RenderStyle renderStyle = this;
  double? logicalHeight;

  CSSDisplay? effectiveDisplay = renderStyle.effectiveDisplay;

  // Height applies to all elements except non-replaced inline elements.
  // https://drafts.csswg.org/css-sizing-3/#propdef-height
  if (effectiveDisplay == CSSDisplay.inline && current is! RenderReplaced) {
    _contentBoxLogicalHeight = null;
    return;
  } else {
    if (renderStyle.height.isNotAuto) {
      logicalHeight = renderStyle.height.computedValue;
    } else if ((renderStyle.position == CSSPositionType.absolute || renderStyle.position == CSSPositionType.fixed) &&
        current is! RenderReplaced &&
        renderStyle.height.isAuto &&
        renderStyle.top.isNotAuto &&
        renderStyle.bottom.isNotAuto) {
      // The height of positioned, non-replaced element is determined as following algorithm.
      // https://www.w3.org/TR/css-position-3/#abs-non-replaced-height
      if (current.parent is! RenderBoxModel) {
        logicalHeight = 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;
      // Height of positioned element should subtract its vertical margin.
      logicalHeight = (parentRenderStyle.paddingBoxLogicalHeight ?? 0) -
          renderStyle.top.computedValue -
          renderStyle.bottom.computedValue -
          renderStyle.marginTop.computedValue -
          renderStyle.marginBottom.computedValue;
    } else {
      if (renderStyle.parent != null) {
        RenderStyle parentRenderStyle = renderStyle.parent!;

        if (renderStyle.isHeightStretch) {
          logicalHeight = parentRenderStyle.contentBoxLogicalHeight;
          // Should subtract vertical margin of own from its parent content height.
          if (logicalHeight != null) {
            logicalHeight -= renderStyle.margin.vertical;
          }
        }
      }
    }
  }

  // Get height by aspect ratio for replaced element if height is auto.
  if (logicalHeight == null && aspectRatio != null) {
    logicalHeight = renderStyle.getHeightByAspectRatio();
  }

  // Constrain height by min-height and max-height.
  if (renderStyle.minHeight.isNotAuto) {
    double minHeight = renderStyle.minHeight.computedValue;
    if (logicalHeight != null && logicalHeight < minHeight) {
      logicalHeight = minHeight;
    }
  }
  if (renderStyle.maxHeight.isNotNone) {
    double maxHeight = renderStyle.maxHeight.computedValue;
    if (logicalHeight != null && logicalHeight > maxHeight) {
      logicalHeight = maxHeight;
    }
  }

  double? logicalContentHeight;
  // Subtract padding and border width to get content width.
  if (logicalHeight != null) {
    logicalContentHeight = logicalHeight - renderStyle.border.vertical - renderStyle.padding.vertical;
    // Logical height may be smaller than its border and padding width,
    // in this case, content height will be negative which is illegal.
    logicalContentHeight = math.max(0, logicalContentHeight);
  }

  _contentBoxLogicalHeight = logicalContentHeight;
}