boundingClientRect property

BoundingClientRect get boundingClientRect

Implementation

BoundingClientRect get boundingClientRect {
  BoundingClientRect boundingClientRect = BoundingClientRect.zero(
      BindingContext(
          ownerView, ownerView.contextId, allocateNewBindingObject()));
  if (isRendererAttached) {
    // RenderBoxModel sizedBox = renderBoxModel!;
    if (!renderStyle.isBoxModelHaveSize()) {
      return boundingClientRect;
    }

    // Special handling for inline elements that participate in inline formatting context
    if (renderStyle.display == CSSDisplay.inline &&
        !renderStyle.isSelfRenderReplaced()) {
      // Check if this element participates in an inline formatting context
      RenderObject? parent = renderStyle.attachedRenderBoxModel?.parent;
      while (parent != null) {
        if (parent is RenderFlowLayout &&
            parent.establishIFC &&
            parent.inlineFormattingContext != null) {
          // Get bounds from the inline formatting context
          final ifcBounds = parent.inlineFormattingContext!
              .getBoundsForRenderBox(renderStyle.attachedRenderBoxModel!);
          if (ifcBounds != null) {
            // Convert IFC-relative bounds to viewport-relative bounds
            RenderBoxModel? rootRenderBox = getRootRenderBoxModel();
            Offset containerOffset = Offset.zero;
            if (rootRenderBox != null) {
              containerOffset =
                  parent.localToGlobal(Offset.zero, ancestor: rootRenderBox);
            }

            // Add container's content offset (padding and border)
            final contentOffset = Offset(
              parent.renderStyle.paddingLeft.computedValue +
                  parent.renderStyle.effectiveBorderLeftWidth.computedValue,
              parent.renderStyle.paddingTop.computedValue +
                  parent.renderStyle.effectiveBorderTopWidth.computedValue,
            );

            final absoluteOffset =
                containerOffset + contentOffset + ifcBounds.topLeft;

            boundingClientRect = BoundingClientRect(
                context: BindingContext(ownerView, ownerView.contextId,
                    allocateNewBindingObject()),
                x: absoluteOffset.dx,
                y: absoluteOffset.dy,
                width: ifcBounds.width,
                height: ifcBounds.height,
                top: absoluteOffset.dy,
                right: absoluteOffset.dx + ifcBounds.width,
                bottom: absoluteOffset.dy + ifcBounds.height,
                left: absoluteOffset.dx);
            return boundingClientRect;
          }
          break;
        }
        parent = (parent as RenderObject).parent;
      }
    }

    // Default handling for block elements and replaced elements
    if (renderStyle.isBoxModelHaveSize()) {
      RenderBoxModel? currentRenderBox = renderStyle.attachedRenderBoxModel;
      Offset offset = Offset.zero;

      if (currentRenderBox != null) {
        // Get the WebF viewport
        RenderBox? viewport = getRootViewport();

        // First, try to get offset using the normal ancestor-based approach
        // This will work for elements in the main document tree
        RenderBoxModel? rootRenderBox = getRootRenderBoxModel();
        if (rootRenderBox != null) {
          offset = currentRenderBox.localToGlobal(Offset.zero,
              ancestor: rootRenderBox);
        } else if (viewport != null) {
          // No root render box (shouldn't happen normally)
          // Use global coordinate calculation
          Offset elementGlobal = currentRenderBox.localToGlobal(Offset.zero);
          Offset viewportGlobal = viewport.localToGlobal(Offset.zero);
          offset = elementGlobal - viewportGlobal;
        }
      }

      Size size = renderStyle.boxSize()!;
      boundingClientRect = BoundingClientRect(
          context: BindingContext(
              ownerView, ownerView.contextId, allocateNewBindingObject()),
          x: offset.dx,
          y: offset.dy,
          width: size.width,
          height: size.height,
          top: offset.dy,
          right: offset.dx + size.width,
          bottom: offset.dy + size.height,
          left: offset.dx);
    }
  }

  return boundingClientRect;
}