applyPositionedChildOffset static method

void applyPositionedChildOffset(
  1. RenderBoxModel parent,
  2. RenderBoxModel child
)

Implementation

static void applyPositionedChildOffset(
  RenderBoxModel parent,
  RenderBoxModel child,
) {
  final RenderLayoutParentData childParentData = child.parentData as RenderLayoutParentData;
  Size size = child.boxSize!;
  Size parentSize = parent.boxSize!;
  RenderStyle parentRenderStyle = parent.renderStyle;

  // Calculate offset to overflow container box first, then subtract border and padding
  // to get the offset to scrolling content box.
  if (parent.isScrollingContentBox) {
    RenderLayoutBox overflowContainerBox = parent.parent as RenderLayoutBox;
    parentRenderStyle = overflowContainerBox.renderStyle;

    // Overflow scroll container has width and height specified surely.
    if (overflowContainerBox.widthSizeType == BoxSizeType.specified &&
        overflowContainerBox.heightSizeType == BoxSizeType.specified) {
      parentSize = Size(overflowContainerBox.renderStyle.width.computedValue,
          overflowContainerBox.renderStyle.height.computedValue);
    }
  }

  CSSLengthValue parentBorderLeftWidth = parentRenderStyle.effectiveBorderLeftWidth;
  CSSLengthValue parentBorderRightWidth = parentRenderStyle.effectiveBorderRightWidth;
  CSSLengthValue parentBorderTopWidth = parentRenderStyle.effectiveBorderTopWidth;
  CSSLengthValue parentBorderBottomWidth = parentRenderStyle.effectiveBorderBottomWidth;
  CSSLengthValue parentPaddingLeft = parentRenderStyle.paddingLeft;
  CSSLengthValue parentPaddingTop = parentRenderStyle.paddingTop;

  // The containing block of not an inline box is formed by the padding edge of the ancestor.
  // Thus the final offset of child need to add the border of parent.
  // https://www.w3.org/TR/css-position-3/#def-cb
  Size containingBlockSize = Size(
      parentSize.width - parentBorderLeftWidth.computedValue - parentBorderRightWidth.computedValue,
      parentSize.height - parentBorderTopWidth.computedValue - parentBorderBottomWidth.computedValue);

  RenderStyle childRenderStyle = child.renderStyle;
  CSSLengthValue left = childRenderStyle.left;
  CSSLengthValue right = childRenderStyle.right;
  CSSLengthValue top = childRenderStyle.top;
  CSSLengthValue bottom = childRenderStyle.bottom;
  CSSLengthValue marginLeft = childRenderStyle.marginLeft;
  CSSLengthValue marginRight = childRenderStyle.marginRight;
  CSSLengthValue marginTop = childRenderStyle.marginTop;
  CSSLengthValue marginBottom = childRenderStyle.marginBottom;

  // ScrollTop and scrollLeft will be added to offset of renderBox in the paint stage
  // for positioned fixed element.
  if (childRenderStyle.position == CSSPositionType.fixed) {
    Element rootElement = parentRenderStyle.target;
    child.scrollingOffsetX = rootElement.scrollLeft;
    child.scrollingOffsetY = rootElement.scrollTop;
  }

  // The static position of positioned element is its offset when its position property had been static
  // which equals to the position of its placeholder renderBox.
  // https://www.w3.org/TR/CSS2/visudet.html#static-position
  Offset staticPositionOffset = _getPlaceholderToParentOffset(child.renderPositionPlaceholder, parent);

  double x = _computePositionedOffset(
    Axis.horizontal,
    parent.isScrollingContentBox,
    parentBorderLeftWidth,
    parentPaddingLeft,
    containingBlockSize.width,
    size.width,
    staticPositionOffset.dx,
    left,
    right,
    marginLeft,
    marginRight,
  );

  double y = _computePositionedOffset(
    Axis.vertical,
    parent.isScrollingContentBox,
    parentBorderTopWidth,
    parentPaddingTop,
    containingBlockSize.height,
    size.height,
    staticPositionOffset.dy,
    top,
    bottom,
    marginTop,
    marginBottom,
  );

  childParentData.offset = Offset(x, y);
}