extendMaxScrollableSize method
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);
}