extendMaxScrollableSize method

void extendMaxScrollableSize(
  1. RenderBoxModel child
)

Extend max scrollable size of renderBoxModel by offset of positioned child, get the max scrollable size of children of normal flow and single positioned child.

Implementation

void extendMaxScrollableSize(RenderBoxModel child) {
  Size? childScrollableSize;
  RenderStyle childRenderStyle = child.renderStyle;
  CSSOverflowType overflowX = childRenderStyle.effectiveOverflowX;
  CSSOverflowType overflowY = childRenderStyle.effectiveOverflowY;
  // Only non scroll container need to use scrollable size, otherwise use its own size
  if (overflowX == CSSOverflowType.visible && overflowY == CSSOverflowType.visible) {
    childScrollableSize = child.scrollableSize;
  } else {
    childScrollableSize = child.boxSize;
  }

  Matrix4? transform = (childRenderStyle as CSSRenderStyle).transformMatrix;
  double maxScrollableX = childRenderStyle.left.computedValue + childScrollableSize!.width;

  // maxScrollableX could be infinite due to the percentage value which depends on the parent box size,
  // but in this stage, the parent's size will always to zero during the first initial layout.
  if (maxScrollableX.isInfinite) return;

  if (transform != null) {
    maxScrollableX += transform.getTranslation()[0];
  }

  if (childRenderStyle.right.isNotAuto) {
    if (isScrollingContentBox && (parent as RenderBoxModel).widthSizeType == BoxSizeType.specified) {
      RenderBoxModel overflowContainerBox = parent as RenderBoxModel;
      maxScrollableX = math.max(
          maxScrollableX,
          -childRenderStyle.right.computedValue +
              overflowContainerBox.renderStyle.width.computedValue -
              overflowContainerBox.renderStyle.effectiveBorderLeftWidth.computedValue -
              overflowContainerBox.renderStyle.effectiveBorderRightWidth.computedValue);
    } else {
      maxScrollableX = math.max(maxScrollableX, -childRenderStyle.right.computedValue + _contentSize!.width);
    }
  }

  double maxScrollableY = childRenderStyle.top.computedValue + childScrollableSize.height;

  // maxScrollableX could be infinite due to the percentage value which depends on the parent box size,
  // but in this stage, the parent's size will always to zero during the first initial layout.
  if (maxScrollableY.isInfinite) return;

  if (transform != null) {
    maxScrollableY += transform.getTranslation()[1];
  }
  if (childRenderStyle.bottom.isNotAuto) {
    if (isScrollingContentBox && (parent as RenderBoxModel).heightSizeType == BoxSizeType.specified) {
      RenderBoxModel overflowContainerBox = parent as RenderBoxModel;
      maxScrollableY = math.max(
          maxScrollableY,
          -childRenderStyle.bottom.computedValue +
              overflowContainerBox.renderStyle.height.computedValue -
              overflowContainerBox.renderStyle.effectiveBorderTopWidth.computedValue -
              overflowContainerBox.renderStyle.effectiveBorderBottomWidth.computedValue);
    } else {
      maxScrollableY = math.max(maxScrollableY, -childRenderStyle.bottom.computedValue + _contentSize!.height);
    }
  }

  RenderBoxModel scrollContainer = isScrollingContentBox ? parent as RenderBoxModel : this;
  // Scrollable area of positioned element will ignore padding area of scroll container.
  maxScrollableX -=
      scrollContainer.renderStyle.paddingLeft.computedValue + scrollContainer.renderStyle.paddingRight.computedValue;
  maxScrollableY -=
      scrollContainer.renderStyle.paddingTop.computedValue + scrollContainer.renderStyle.paddingBottom.computedValue;

  maxScrollableX = math.max(maxScrollableX, scrollableSize.width);
  maxScrollableY = math.max(maxScrollableY, scrollableSize.height);

  scrollableSize = Size(maxScrollableX, maxScrollableY);
}