// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/intersection_observer/intersection_geometry.h"

#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"

namespace blink {

namespace {

// Convert a Length value to physical pixels.
LayoutUnit ComputeMargin(const Length& length,
                         float reference_length,
                         float zoom) {
  if (length.IsPercent()) {
    return LayoutUnit(
        static_cast<int>(reference_length * length.Percent() / 100.0));
  }
  DCHECK(length.IsFixed());
  return LayoutUnit(length.Value() * zoom);
}

PhysicalBoxStrut ResolveMargin(const Vector<Length>& margin,
                               const gfx::SizeF& reference_size,
                               float zoom) {
  DCHECK_EQ(margin.size(), 4u);

  return PhysicalBoxStrut(
      ComputeMargin(margin[0], reference_size.height(), zoom),
      ComputeMargin(margin[1], reference_size.width(), zoom),
      ComputeMargin(margin[2], reference_size.height(), zoom),
      ComputeMargin(margin[3], reference_size.width(), zoom));
}

// Expand rect by the given margin values.
void ApplyMargin(PhysicalRect& expand_rect,
                 const Vector<Length>& margin,
                 float zoom,
                 const gfx::SizeF& reference_size) {
  if (margin.empty())
    return;
  expand_rect.Expand(ResolveMargin(margin, reference_size, zoom));
}

void ApplyMargin(gfx::RectF& expand_rect,
                 const Vector<Length>& margin,
                 float zoom,
                 const gfx::SizeF& reference_size) {
  if (margin.empty()) {
    return;
  }
  expand_rect.Outset(
      gfx::OutsetsF(ResolveMargin(margin, reference_size, zoom)));
}

// Returns the root intersect rect for the given root object, with the given
// margins applied, in the coordinate system of the root object.
//
//   https://w3c.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle
gfx::RectF InitializeRootRect(const LayoutObject* root,
                              const Vector<Length>& margin) {
  DCHECK(margin.empty() || margin.size() == 4);
  PhysicalRect result;
  auto* layout_view = DynamicTo<LayoutView>(root);
  if (layout_view && root->GetDocument().GetFrame()->IsOutermostMainFrame()) {
    // The main frame is a bit special as the scrolling viewport can differ in
    // size from the LayoutView itself. There's two situations this occurs in:
    // 1) The ForceZeroLayoutHeight quirk setting is used in Android WebView for
    // compatibility and sets the initial-containing-block's (a.k.a.
    // LayoutView) height to 0. Thus, we can't use its size for intersection
    // testing. Use the FrameView geometry instead.
    // 2) An element wider than the ICB can cause us to resize the FrameView so
    // we can zoom out to fit the entire element width.
    result = layout_view->OverflowClipRect(PhysicalOffset());
  } else if (auto* layout_box = DynamicTo<LayoutBox>(root)) {
    if (layout_box->ShouldClipOverflowAlongBothAxis()) {
      // TODO(https://github.com/w3c/IntersectionObserver/issues/518):
      // This doesn't strictly conform to the current spec (which says we
      // should use the padding box rect) when there is overflow-clip-margin.
      // We should also consider overflow-clip along only one axis.
      result = layout_box->OverflowClipRect(PhysicalOffset());
    } else {
      result = layout_box->PhysicalBorderBoxRect();
    }
  } else {
    result = To<LayoutInline>(root)->PhysicalLinesBoundingBox();
  }
  ApplyMargin(result, margin, root->StyleRef().EffectiveZoom(),
              gfx::SizeF(result.size));
  return gfx::RectF(result);
}

gfx::RectF GetBoxBounds(const LayoutBox* box, bool use_overflow_clip_edge) {
  PhysicalRect bounds(box->PhysicalBorderBoxRect());
  // Only use overflow clip rect if we need to use overflow clip edge and
  // overflow clip margin may have an effect, meaning we clip to the overflow
  // clip edge and not something else.
  if (use_overflow_clip_edge && box->ShouldApplyOverflowClipMargin()) {
    // OverflowClipRect() may be larger than PhysicalBorderBoxRect().
    bounds.Unite(box->OverflowClipRect(PhysicalOffset()));
  }
  return gfx::RectF(bounds);
}

// Return the bounding box of target in target's own coordinate system.
gfx::RectF InitializeTargetRect(const LayoutObject* target, unsigned flags) {
  if (flags & IntersectionGeometry::kForFrameViewportIntersection) {
    return gfx::RectF(To<LayoutEmbeddedContent>(target)->ReplacedContentRect());
  }
  if (target->IsSVGChild()) {
    return target->DecoratedBoundingBox();
  }
  if (auto* layout_box = DynamicTo<LayoutBox>(target)) {
    return GetBoxBounds(layout_box,
                        flags & IntersectionGeometry::kUseOverflowClipEdge);
  }
  if (auto* layout_inline = DynamicTo<LayoutInline>(target)) {
    return layout_inline->LocalBoundingBoxRectF();
  }
  return gfx::RectF(To<LayoutText>(target)->PhysicalLinesBoundingBox());
}

// Returns true if target has visual effects applied, or if rect, given in
// absolute coordinates, is overlapped by any content painted after target
//
//   https://w3c.github.io/IntersectionObserver/v2/#calculate-visibility-algo
bool ComputeIsVisible(const LayoutObject* target, const PhysicalRect& rect) {
  if (!target->GetDocument().GetFrame() ||
      target->GetDocument().GetFrame()->LocalFrameRoot().GetOcclusionState() !=
          mojom::blink::FrameOcclusionState::kGuaranteedNotOccluded) {
    return false;
  }
  if (target->HasDistortingVisualEffects())
    return false;
  // TODO(layout-dev): This should hit-test the intersection rect, not the
  // target rect; it's not helpful to know that the portion of the target that
  // is clipped is also occluded.
  HitTestResult result(target->HitTestForOcclusion(rect));
  const Node* hit_node = result.InnerNode();
  if (!hit_node || hit_node == target->GetNode())
    return true;
  // TODO(layout-dev): This IsDescendantOf tree walk could be optimized by
  // stopping when hit_node's containing LayoutBlockFlow is reached.
  if (target->IsLayoutInline())
    return hit_node->IsDescendantOf(target->GetNode());
  return false;
}

// Returns the transform that maps from object's local coordinates to the
// containing view's coordinates. Note that this doesn't work if `object` has
// multiple block fragments.
gfx::Transform ObjectToViewTransform(const LayoutObject& object) {
  // Use faster GeometryMapper when possible.
  PropertyTreeStateOrAlias container_properties =
      PropertyTreeState::Uninitialized();
  const LayoutObject* property_container =
      IntersectionGeometry::CanUseGeometryMapper(object)
          ? object.GetPropertyContainer(nullptr, &container_properties)
          : nullptr;
  if (property_container) {
    gfx::Transform transform = GeometryMapper::SourceToDestinationProjection(
        container_properties.Transform(),
        object.View()->FirstFragment().LocalBorderBoxProperties().Transform());
    transform.Translate(gfx::Vector2dF(object.FirstFragment().PaintOffset()));
    return transform;
  }

  // Fall back to MapLocalToAncestor.
  TransformState transform_state(TransformState::kApplyTransformDirection);
  object.MapLocalToAncestor(nullptr, transform_state, 0);
  return transform_state.AccumulatedTransform();
}

void ScrollingContentsToBorderBoxSpace(const LayoutBox* box, gfx::RectF& rect) {
  DCHECK(box->IsScrollContainer());
  const PaintLayerScrollableArea* scrollable_area = box->GetScrollableArea();
  CHECK(scrollable_area);
  rect.Offset(-scrollable_area->ScrollPosition().OffsetFromOrigin());
}

bool ClipsSelf(const LayoutObject& object) {
  return object.HasClip() || object.HasClipPath() || object.HasMask() ||
         // For simplicity, assume all SVG children clip self (with e.g.
         // SVG mask).
         object.IsSVGChild();
}

bool ClipsContents(const LayoutObject& object) {
  // An objects that clips itself also clips contents.
  if (ClipsSelf(object)) {
    return true;
  }
  // TODO(wangxianzhu): Ideally we should ignore clippers that don't have
  // a scrollable overflow, but that caused crbug.com/41492283. Investigate.
  return object.ShouldClipOverflowAlongEitherAxis();
}

static const unsigned kConstructorFlagsMask =
    IntersectionGeometry::kShouldReportRootBounds |
    IntersectionGeometry::kShouldComputeVisibility |
    IntersectionGeometry::kShouldTrackFractionOfRoot |
    IntersectionGeometry::kForFrameViewportIntersection |
    IntersectionGeometry::kShouldConvertToCSSPixels |
    IntersectionGeometry::kUseOverflowClipEdge |
    IntersectionGeometry::kRespectFilters |
    IntersectionGeometry::kScrollAndVisibilityOnly;

}  // namespace

IntersectionGeometry::RootGeometry::RootGeometry(const LayoutObject* root,
                                                 const Vector<Length>& margin) {
  if (!root || !root->GetNode() || !root->GetNode()->isConnected() ||
      // TODO(crbug.com/1456208): Support inline root.
      !root->IsBox()) {
    return;
  }
  zoom = root->StyleRef().EffectiveZoom();
  local_root_rect = InitializeRootRect(root, margin);
  if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
    root_to_view_transform = ObjectToViewTransform(*root);
  } else {
    TransformState transform_state(TransformState::kApplyTransformDirection);
    root->MapLocalToAncestor(nullptr, transform_state, 0);
    root_to_view_transform = transform_state.AccumulatedTransform();
  }
}

bool IntersectionGeometry::RootGeometry::operator==(
    const RootGeometry& other) const {
  return zoom == other.zoom && local_root_rect == other.local_root_rect &&
         root_to_view_transform == other.root_to_view_transform;
}

#if CHECK_SKIPPED_UPDATE_ON_SCROLL()
String IntersectionGeometry::CachedRects::ToString() const {
  auto transform_to_string = [](const gfx::Transform& t) {
    return t.IsIdentityOr2dTranslation() ? t.To2dTranslation().ToString()
                                         : t.ToString();
  };
  return String::Format(
      "%d target_rect: %s %s root_rect: %s %s intersection: %s %s %s "
      "min_to_update %s %s target_t: %s root_t: %s intersect: %d "
      "rel: %d r_scrolls_t: %d",
      valid, local_target_rect.ToString().c_str(),
      target_rect.ToString().c_str(), local_root_rect.ToString().c_str(),
      root_rect.ToString().c_str(),
      unscrolled_unclipped_intersection_rect.ToString().c_str(),
      unclipped_intersection_rect.ToString().c_str(),
      intersection_rect.ToString().c_str(),
      computed_min_scroll_delta_to_update.ToString().c_str(),
      min_scroll_delta_to_update.ToString().c_str(),
      transform_to_string(target_to_view_transform).c_str(),
      transform_to_string(root_to_view_transform).c_str(), does_intersect,
      relationship, root_scrolls_target);
}
#endif

const LayoutObject* IntersectionGeometry::GetExplicitRootLayoutObject(
    const Node& root_node) {
  if (!root_node.isConnected()) {
    return nullptr;
  }
  if (root_node.IsDocumentNode()) {
    return To<Document>(root_node).GetLayoutView();
  }
  return root_node.GetLayoutObject();
}

IntersectionGeometry::IntersectionGeometry(
    const Node* root_node,
    const Element& target_element,
    const Vector<Length>& root_margin,
    const Vector<float>& thresholds,
    const Vector<Length>& target_margin,
    const Vector<Length>& scroll_margin,
    unsigned flags,
    std::optional<RootGeometry>& root_geometry,
    CachedRects* cached_rects)
    : flags_(flags & kConstructorFlagsMask) {
  // Only one of root_margin or target_margin can be specified.
  DCHECK(root_margin.empty() || target_margin.empty());

  if (!root_node) {
    flags_ |= kRootIsImplicit;
  }

  RootAndTarget root_and_target(root_node, target_element,
                                !target_margin.empty(), !scroll_margin.empty());
  UpdateShouldUseCachedRects(root_and_target, cached_rects);
  if (root_and_target.relationship == RootAndTarget::kInvalid) {
    return;
  }

  if (root_geometry) {
    DCHECK(*root_geometry == RootGeometry(root_and_target.root, root_margin));
  } else {
    root_geometry.emplace(root_and_target.root, root_margin);
  }

  ComputeGeometry(*root_geometry, root_and_target, thresholds, target_margin,
                  scroll_margin, cached_rects);
}

IntersectionGeometry::RootAndTarget::RootAndTarget(
    const Node* root_node,
    const Element& target_element,
    bool has_target_margin,
    bool has_scroll_margin)
    : target(GetTargetLayoutObject(target_element)),
      root(target ? GetRootLayoutObject(root_node) : nullptr) {
  ComputeRelationship(!root_node, has_target_margin, has_scroll_margin);
}

bool IsAllowedLayoutObjectType(const LayoutObject& target) {
  return target.IsBoxModelObject() || target.IsText() || target.IsSVG();
}

// Validates the given target element and returns its LayoutObject
const LayoutObject* IntersectionGeometry::GetTargetLayoutObject(
    const Element& target_element) {
  if (!target_element.isConnected()) {
    return nullptr;
  }
  LayoutObject* target = target_element.GetLayoutObject();
  if (!target || !IsAllowedLayoutObjectType(*target)) {
    return nullptr;
  }
  // If the target is inside a locked subtree, it isn't ever visible.
  if (UNLIKELY(target->GetFrameView()->IsDisplayLocked() ||
               DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
                   target_element))) {
    return nullptr;
  }

  DCHECK(!target_element.GetDocument().View()->NeedsLayout());
  return target;
}

// If root_node is non-null, it is treated as the explicit root of an
// IntersectionObserver; if it is valid, its LayoutObject is returned.
//
// If root_node is null, returns the object to be used to compute intersection
// for a given target with the implicit root. Note that if the target is in
// a remote frame, the returned object is the LayoutView of the local frame
// root instead of the topmost main frame.
//
//   https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-root
const LayoutObject* IntersectionGeometry::RootAndTarget::GetRootLayoutObject(
    const Node* root_node) const {
  if (root_node) {
    return GetExplicitRootLayoutObject(*root_node);
  }
  if (const LocalFrame* frame = target->GetDocument().GetFrame()) {
    return frame->LocalFrameRoot().ContentLayoutObject();
  }
  return nullptr;
}

void IntersectionGeometry::RootAndTarget::ComputeRelationship(
    bool root_is_implicit,
    bool has_target_margin,
    bool has_scroll_margin) {
  if (!root || !target || root == target) {
    relationship = kInvalid;
    return;
  }

  if (root_is_implicit && !target->GetFrame()->IsOutermostMainFrame()) {
    relationship = kTargetInSubFrame;
    DCHECK(root->IsScrollContainer());
    DCHECK(root->IsLayoutView());
    if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
      root_scrolls_target = To<LayoutView>(root)->HasScrollableOverflow();
      if (root_scrolls_target) {
        // Check if target's ancestor container under root is fixed-position.
        // If yes, reset root_scroll_target to false.
        const LayoutObject* container = target;
        while (container->GetFrame() != root->GetFrame()) {
          container = container->GetFrame()->OwnerLayoutObject();
          if (!container) {
            relationship = kInvalid;
            return;
          }
        }
        while (true) {
          const LayoutObject* next_container = container->Container();
          if (next_container == root) {
            root_scrolls_target = !container->IsFixedPositioned();
            break;
          }
          container = next_container;
        }
      }
    } else {
      root_scrolls_target = true;
    }

    if (!has_scroll_margin) {
      // When scroll margins are defined intermediate_scrollers still needs to
      // get populated.
      return;
    }
  }

  if (target->GetFrame() != root->GetFrame() && !root_is_implicit) {
    // The case of different frame with implicit root has been covered by the
    // previous condition.
    // The target and the explicit root are required to be in the same frame.
    relationship = kInvalid;
    return;
  }

  bool has_intermediate_clippers = false;
  const LayoutObject* previous_container = nullptr;
  const LayoutObject* container = target;
  bool have_crossed_frame_boundary = false;
  if (ClipsSelf(*target)) {
    has_intermediate_clippers = true;
  }
  while (container != root) {
    has_filter |=
        !have_crossed_frame_boundary && container->HasFilterInducingProperty();

    // Don't check for filters if we've already found one.
    LayoutObject::AncestorSkipInfo skip_info(root, !has_filter);
    previous_container = container;
    container = container->Container(&skip_info);
    if (!has_filter && !have_crossed_frame_boundary) {
      has_filter = skip_info.FilterSkipped();
    }

    if (skip_info.AncestorSkipped()) {
      DCHECK(!have_crossed_frame_boundary);

      // The root is not in the containing block chain of the target.
      relationship = kInvalid;
      return;
    }

    if (!container) {
      if (!root_is_implicit) {
        relationship = kInvalid;
        return;
      }

      // We need to jump up the frame tree
      DCHECK(previous_container->IsLayoutView());

      // previous_container is the layout view of the iframe.
      // OwnerLayoutObject jumps the iframe boundary.
      // owner is the iframe element node.
      auto* owner =
          previous_container->GetFrameView()->GetFrame().OwnerLayoutObject();
      if (!owner) {
        return;
      }

      container = owner;
      have_crossed_frame_boundary = true;

      // We can continue to top of loop since iframe element is not a scroller.
      continue;
    }

    if (!has_intermediate_clippers && !have_crossed_frame_boundary &&
        container != root && ClipsContents(*container)) {
      has_intermediate_clippers = true;
    }

    if (container != root && has_scroll_margin &&
        container->IsScrollContainer()) {
      intermediate_scrollers.push_back(To<LayoutBox>(container));
    }
  }

  DCHECK(previous_container);
  if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
    root_scrolls_target =
        root->IsScrollContainer() &&
        To<LayoutBox>(root)->HasScrollableOverflow() &&
        !(root->IsLayoutView() && previous_container->IsFixedPositioned());
  } else {
    root_scrolls_target = root->IsScrollContainer();
  }

  if (have_crossed_frame_boundary) {
    DCHECK_EQ(relationship, kTargetInSubFrame);
  } else if (has_intermediate_clippers) {
    relationship = kHasIntermediateClippers;
  } else if (root_scrolls_target) {
    relationship = kScrollableByRootOnly;
  } else {
    relationship = kNotScrollable;
  }
}

bool IntersectionGeometry::CanUseGeometryMapper(const LayoutObject& object) {
  // This checks for cases where we didn't just complete a successful lifecycle
  // update, e.g., if the frame is throttled.
  LayoutView* layout_view = object.GetDocument().GetLayoutView();
  return layout_view && !layout_view->NeedsPaintPropertyUpdate() &&
         !layout_view->DescendantNeedsPaintPropertyUpdate();
}

void IntersectionGeometry::UpdateShouldUseCachedRects(
    const RootAndTarget& root_and_target,
    CachedRects* cached_rects) {
  if (!cached_rects || !cached_rects->valid) {
    return;
  }

  cached_rects->valid = false;

  if (root_and_target.relationship == RootAndTarget::kInvalid) {
    return;
  }

  if (!root_and_target.intermediate_scrollers.empty()) {
    // This happens when there are scroll margins. We can't use cached rects
    // because we need to call ApplyClip for each scroller to apply the
    // scroll margins.
    return;
  }

  if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
    if (!(flags_ & kScrollAndVisibilityOnly)) {
      return;
    }
    // Cached rects can only be used if there are no scrollable objects in the
    // hierarchy between target and root (a scrollable root is ok). The reason
    // is that a scroll change in an intermediate scroller would change the
    // intersection geometry, but we intentionally don't invalidate cached
    // rects and schedule intersection update to enable the minimul-scroll-
    // delta-to-update optimization.
    if (root_and_target.relationship != RootAndTarget::kNotScrollable &&
        root_and_target.relationship != RootAndTarget::kScrollableByRootOnly) {
      return;
    }
  } else {
    if (RootIsImplicit()) {
      return;
    }
    // Cached rects can only be used if there are no scrollable objects in the
    // hierarchy between target and root (a scrollable root is ok). The reason
    // is that a scroll change in an intermediate scroller would change the
    // intersection geometry, but it would not properly trigger an invalidation
    // of the cached rects.
    PaintLayer* root_layer = root_and_target.target->View()->Layer();
    if (!root_layer) {
      return;
    }
    if (root_and_target.target->DeprecatedEnclosingScrollableBox() !=
        root_and_target.root) {
      return;
    }
  }

  flags_ |= kShouldUseCachedRects;
}

void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
                                           const RootAndTarget& root_and_target,
                                           const Vector<float>& thresholds,
                                           const Vector<Length>& target_margin,
                                           const Vector<Length>& scroll_margin,
                                           CachedRects* cached_rects) {
  CHECK_GE(thresholds.size(), 1u);
  DCHECK(cached_rects || !ShouldUseCachedRects());
  flags_ |= kDidComputeGeometry;

  const LayoutObject* root = root_and_target.root;
  const LayoutObject* target = root_and_target.target;
  CHECK(root);
  CHECK(target);

  // Initially:
  //   target_rect_ is in target's coordinate system
  //   root_rect_ is in root's coordinate system
  //   The coordinate system for unclipped_intersection_rect_ depends on whether
  //       or not we can use previously cached geometry...
  bool pre_margin_target_rect_is_empty;
  if (ShouldUseCachedRects()) {
    target_rect_ = cached_rects->local_target_rect;
    pre_margin_target_rect_is_empty =
        cached_rects->pre_margin_target_rect_is_empty;

    // The cached intersection rect has already been mapped/clipped up to the
    // root, except that the root's scroll offset and overflow clip have not
    // been applied.
    unclipped_intersection_rect_ =
        cached_rects->unscrolled_unclipped_intersection_rect;
  } else {
    target_rect_ = InitializeTargetRect(target, flags_);
    pre_margin_target_rect_is_empty = target_rect_.IsEmpty();
    ApplyMargin(target_rect_, target_margin, root_geometry.zoom,
                InitializeRootRect(root, {} /* margin */).size());

    // We have to map/clip target_rect_ up to the root, so we begin with the
    // intersection rect in target's coordinate system. After ClipToRoot, it
    // will be in root's coordinate system.
    unclipped_intersection_rect_ = target_rect_;
  }
  if (cached_rects) {
    cached_rects->local_target_rect = target_rect_;
    cached_rects->pre_margin_target_rect_is_empty =
        pre_margin_target_rect_is_empty;
  }
  root_rect_ = root_geometry.local_root_rect;

  bool does_intersect =
      ClipToRoot(root_and_target, root_rect_, unclipped_intersection_rect_,
                 intersection_rect_, scroll_margin, cached_rects);

  gfx::Transform target_to_view_transform = ObjectToViewTransform(*target);
  target_rect_ = target_to_view_transform.MapRect(target_rect_);

  if (does_intersect) {
    gfx::RectF unclipped_intersection_rect;
    if (RootIsImplicit()) {
      // Generate matrix to transform from the space of the implicit root to
      // the absolute coordinates of the target document.
      TransformState implicit_root_to_target_document_transform(
          TransformState::kUnapplyInverseTransformDirection);
      target->View()->MapAncestorToLocal(
          nullptr, implicit_root_to_target_document_transform,
          kTraverseDocumentBoundaries | kApplyRemoteMainFrameTransform);
      gfx::Transform matrix =
          implicit_root_to_target_document_transform.AccumulatedTransform()
              .InverseOrIdentity();
      intersection_rect_ =
          matrix.ProjectQuad(gfx::QuadF(intersection_rect_)).BoundingBox();
      unclipped_intersection_rect =
          matrix.ProjectQuad(gfx::QuadF(unclipped_intersection_rect_))
              .BoundingBox();
    } else {
      // `intersection_rect` is in root's coordinate system; map it up to
      // absolute coordinates for target's containing document (which is the
      // same as root's document).
      intersection_rect_ =
          root_geometry.root_to_view_transform.MapRect(intersection_rect_);
      unclipped_intersection_rect =
          root_geometry.root_to_view_transform.MapRect(
              unclipped_intersection_rect);
    }
    unclipped_intersection_rect_ = unclipped_intersection_rect;
  } else {
    intersection_rect_ = gfx::RectF();
  }
  // Map root_rect_ from root's coordinate system to absolute coordinates.
  root_rect_ =
      root_geometry.root_to_view_transform.MapRect(gfx::RectF(root_rect_));

  // Some corner cases for threshold index:
  //   - If target rect is zero area, because it has zero width and/or zero
  //     height,
  //     only two states are recognized:
  //     - 0 means not intersecting.
  //     - 1 means intersecting.
  //     No other threshold crossings are possible.
  //   - Otherwise:
  //     - If root and target do not intersect, the threshold index is 0.

  //     - If root and target intersect but the intersection has zero-area
  //       (i.e., they have a coincident edge or corner), we consider the
  //       intersection to have "crossed" a zero threshold, but not crossed
  //       any non-zero threshold.

  if (does_intersect) {
    const gfx::RectF& comparison_rect =
        ShouldTrackFractionOfRoot() ? root_rect_ : target_rect_;
    // Note that if we are checking whether target is empty, we have to consider
    // the fact that we might have padded the rect with a target margin. If we
    // did, `pre_margin_target_rect_is_empty` would be true. Use this
    // information to force the rect to be empty for the purposes of this
    // computation. Note that it could also be the case that the rect started as
    // non-empty and was transformed to be empty. In this case, we rely on
    // target_rect_.IsEmpty() to be true, so we need to check the rect itself as
    // well.
    // In the fraction of root case, we can just check the comparison rect.
    bool empty_override =
        !ShouldTrackFractionOfRoot() && pre_margin_target_rect_is_empty;
    if (comparison_rect.IsEmpty() || empty_override) {
      intersection_ratio_ = 1;
    } else {
      const gfx::SizeF& intersection_size = intersection_rect_.size();
      const float intersection_area = intersection_size.GetArea();
      const gfx::SizeF& comparison_size = comparison_rect.size();
      const float area_of_interest = comparison_size.GetArea();
      intersection_ratio_ = std::min(intersection_area / area_of_interest, 1.f);
    }
    threshold_index_ =
        FirstThresholdGreaterThan(intersection_ratio_, thresholds);
  } else {
    intersection_ratio_ = 0;
    threshold_index_ = 0;
  }
  if (IsIntersecting() && ShouldComputeVisibility() &&
      ComputeIsVisible(target,
                       PhysicalRect::FastAndLossyFromRectF(target_rect_))) {
    flags_ |= kIsVisible;
  }

  if (cached_rects) {
    cached_rects->min_scroll_delta_to_update = ComputeMinScrollDeltaToUpdate(
        root_and_target, target_to_view_transform,
        root_geometry.root_to_view_transform, thresholds, scroll_margin);
    cached_rects->valid = true;

    UMA_HISTOGRAM_COUNTS_1000(
        "Blink.IntersectionObservation.MinScrollDeltaToUpdateX",
        base::saturated_cast<int>(
            cached_rects->min_scroll_delta_to_update.x()));
    UMA_HISTOGRAM_COUNTS_1000(
        "Blink.IntersectionObservation.MinScrollDeltaToUpdateY",
        base::saturated_cast<int>(
            cached_rects->min_scroll_delta_to_update.y()));

#if CHECK_SKIPPED_UPDATE_ON_SCROLL()
    // TODO(wangxianzhu): Remove or clean up this code after fixing
    // crbug.com/41492283.
    PropertyTreeStateOrAlias target_properties =
        PropertyTreeState::Uninitialized();
    if (root_and_target.target->GetPropertyContainer(nullptr,
                                                     &target_properties)) {
      cached_rects->clip_tree = target_properties.Clip().ToTreeString();
      cached_rects->transform_tree =
          target_properties.Transform().ToTreeString();
      cached_rects->scroll_tree = target_properties.Transform()
                                      .Unalias()
                                      .NearestScrollTranslationNode()
                                      .ScrollNode()
                                      ->ToTreeString();
    } else {
      cached_rects->clip_tree = cached_rects->transform_tree =
          cached_rects->scroll_tree = "No properties";
    }
    cached_rects->computed_min_scroll_delta_to_update =
        cached_rects->min_scroll_delta_to_update;
    cached_rects->local_root_rect = root_geometry.local_root_rect;
    cached_rects->root_rect = root_rect_;
    cached_rects->target_rect = target_rect_;
    cached_rects->intersection_rect = intersection_rect_;
    cached_rects->unclipped_intersection_rect = unclipped_intersection_rect_;
    cached_rects->target_to_view_transform = target_to_view_transform;
    cached_rects->root_to_view_transform = root_geometry.root_to_view_transform;
    cached_rects->relationship = static_cast<int>(root_and_target.relationship);
    cached_rects->root_scrolls_target = root_and_target.root_scrolls_target;
#endif
  }

  // This must be the last step after all calculations in zoomed coordinates.
  if (flags_ & kShouldConvertToCSSPixels) {
    AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(target_rect_,
                                                           *target);
    AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(intersection_rect_,
                                                           *target);
    AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(root_rect_, *root);
  }
}

bool IntersectionGeometry::ClipToRoot(const RootAndTarget& root_and_target,
                                      const gfx::RectF& root_rect,
                                      gfx::RectF& unclipped_intersection_rect,
                                      gfx::RectF& intersection_rect,
                                      const Vector<Length>& scroll_margin,
                                      CachedRects* cached_rects) {
  const LayoutObject* root = root_and_target.root;
  // TODO(crbug.com/1456208): Support inline root.
  if (!root->IsBox()) {
    return false;
  }

  const LayoutObject* target = root_and_target.target;

  const LayoutBox* local_ancestor = nullptr;

  bool ignore_local_clip_path = false;
  if (!scroll_margin.empty()) {
    // Apply clip and scroll margin for each intermediate scroller.
    for (const LayoutBox* scroller : root_and_target.intermediate_scrollers) {
      gfx::RectF scroller_rect =
          gfx::RectF(scroller->OverflowClipRect(PhysicalOffset()));
      if (std::optional<gfx::RectF> clip_path_box =
              ClipPathClipper::LocalClipPathBoundingBox(*scroller)) {
        scroller_rect.Intersect(*clip_path_box);
      }

      local_ancestor = To<LayoutBox>(scroller);
      if (!ApplyClip(target, local_ancestor, scroller, scroller_rect,
                     unclipped_intersection_rect, intersection_rect,
                     scroll_margin, ignore_local_clip_path,
                     /*root_scrolls_target=*/true, cached_rects)) {
        return false;
      }

      unclipped_intersection_rect = intersection_rect;
      target = scroller;
      // We have already applied clip-path on scroller (now target) above, so
      // we don't need to apply clip-path on target in the next ApplyClip().
      ignore_local_clip_path = true;
    }
  }

  // Map and clip rect into root element coordinates.
  if (!RootIsImplicit() ||
      root->GetDocument().GetFrame()->IsOutermostMainFrame()) {
    local_ancestor = To<LayoutBox>(root);
  }

  return ApplyClip(target, local_ancestor, root_and_target.root, root_rect,
                   unclipped_intersection_rect, intersection_rect,
                   scroll_margin, ignore_local_clip_path,
                   root_and_target.root_scrolls_target, cached_rects);
}

bool IntersectionGeometry::ApplyClip(const LayoutObject* target,
                                     const LayoutBox* local_ancestor,
                                     const LayoutObject* root,
                                     const gfx::RectF& root_rect,
                                     gfx::RectF& unclipped_intersection_rect,
                                     gfx::RectF& intersection_rect,
                                     const Vector<Length>& scroll_margin,
                                     bool ignore_local_clip_path,
                                     bool root_scrolls_target,
                                     CachedRects* cached_rects) {
  unsigned flags = kDefaultVisualRectFlags | kEdgeInclusive |
                   kDontApplyMainFrameOverflowClip;
  if (!ShouldRespectFilters()) {
    flags |= kIgnoreFilters;
  }
  if (CanUseGeometryMapper(*target)) {
    flags |= kUseGeometryMapper;
  }
  if (ignore_local_clip_path) {
    flags |= kIgnoreLocalClipPath;
  }

  bool does_intersect = false;

  if (ShouldUseCachedRects()) {
    does_intersect = cached_rects->does_intersect;
  } else {
    does_intersect = target->MapToVisualRectInAncestorSpace(
        local_ancestor, unclipped_intersection_rect,
        static_cast<VisualRectFlags>(flags));
    if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled() &&
        local_ancestor && local_ancestor->IsScrollContainer() &&
        !root_scrolls_target) {
      // Convert the rect from the scrolling contents space to the border box
      // space, so that we can use cached rects and avoid update on scroll of
      // root.
      ScrollingContentsToBorderBoxSpace(local_ancestor,
                                        unclipped_intersection_rect);
    }
  }
  if (cached_rects) {
    cached_rects->unscrolled_unclipped_intersection_rect =
        unclipped_intersection_rect;
    cached_rects->does_intersect = does_intersect;
  }

  intersection_rect = gfx::RectF();

  // If the target intersects with the unclipped root, calculate the clipped
  // intersection.
  if (does_intersect) {
    if (local_ancestor) {
      if (root_scrolls_target) {
        ScrollingContentsToBorderBoxSpace(local_ancestor,
                                          unclipped_intersection_rect);
      } else {
        // In case the ancestor in an SVG element with a viewbox property
        // we need to convert the child's coordinates to the SVG coordinates
        if (auto* properties =
                local_ancestor->FirstFragment().PaintProperties()) {
          if (auto* replaced_transform =
                  properties->ReplacedContentTransform()) {
            gfx::Transform invert_replaced_transform =
                GeometryMapper::SourceToDestinationProjection(
                    *replaced_transform, *replaced_transform->Parent());
            unclipped_intersection_rect =
                invert_replaced_transform.MapRect(unclipped_intersection_rect);
          }
        }
      }

      gfx::RectF root_clip_rect = root_rect;
      if (!scroll_margin.empty() && root->IsScrollContainer()) {
        // If the root is scrollable, apply the scroll margin to inflate the
        // root_clip_rect.
        ApplyMargin(root_clip_rect, scroll_margin,
                    root->StyleRef().EffectiveZoom(), root_clip_rect.size());
      }

      intersection_rect = unclipped_intersection_rect;
      does_intersect &= intersection_rect.InclusiveIntersect(root_clip_rect);
    } else {
      // Note that we don't clip to root_rect here. That's ok because
      // (!local_ancestor) implies that the root is implicit and the
      // main frame is remote, in which case there can't be any root margin
      // applied to root_rect (root margin is disallowed for implicit-root
      // cross-origin observation). We still need to apply the remote main
      // frame's overflow clip here, because the
      // kDontApplyMainFrameOverflowClip flag above, means it hasn't been
      // done yet.
      LocalFrame* local_root_frame = root->GetDocument().GetFrame();
      gfx::Rect clip_rect(local_root_frame->RemoteViewportIntersection());
      if (clip_rect.IsEmpty()) {
        intersection_rect = gfx::RectF();
        does_intersect = false;
      } else {
        // Map clip_rect from the coordinate system of the local root frame to
        // the coordinate system of the remote main frame.
        clip_rect = ToPixelSnappedRect(
            local_root_frame->ContentLayoutObject()->LocalToAncestorRect(
                PhysicalRect(clip_rect), nullptr,
                kTraverseDocumentBoundaries | kApplyRemoteMainFrameTransform));
        intersection_rect = unclipped_intersection_rect;
        does_intersect &=
            intersection_rect.InclusiveIntersect(gfx::RectF(clip_rect));
      }
    }
  }

  return does_intersect;
}

wtf_size_t IntersectionGeometry::FirstThresholdGreaterThan(
    float ratio,
    const Vector<float>& thresholds) const {
  wtf_size_t result = 0;
  while (result < thresholds.size() && thresholds[result] <= ratio)
    ++result;
  return result;
}

gfx::Vector2dF IntersectionGeometry::ComputeMinScrollDeltaToUpdate(
    const RootAndTarget& root_and_target,
    const gfx::Transform& target_to_view_transform,
    const gfx::Transform& root_to_view_transform,
    const Vector<float>& thresholds,
    const Vector<Length>& scroll_margin) const {
  if (!RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
    return gfx::Vector2dF();
  }

  if (!scroll_margin.empty()) {
    return gfx::Vector2dF();
  }

  if (ShouldComputeVisibility()) {
    // We don't have enough data (e.g. the occluded area of target and the
    // occluding areas of the covering elements) to calculate the minimum
    // scroll delta affecting visibility.
    return gfx::Vector2dF();
  }
  if (root_and_target.relationship == RootAndTarget::kTargetInSubFrame) {
    return gfx::Vector2dF();
  }
  if (root_and_target.relationship == RootAndTarget::kNotScrollable) {
    // Intersection is not affected by scroll.
    return kInfiniteScrollDelta;
  }
  if (root_and_target.has_filter && ShouldRespectFilters()) {
    // With filters, the intersection rect can be non-empty even if root_rect_
    // and target_rect_ don't intersect.
    return gfx::Vector2dF();
  }
  if (!target_to_view_transform.IsIdentityOr2dTranslation() ||
      !root_to_view_transform.IsIdentityOr2dTranslation()) {
    return gfx::Vector2dF();
  }
  CHECK_GE(thresholds.size(), 1u);
  if (thresholds[0] == 1) {
    if (ShouldTrackFractionOfRoot()) {
      if (root_rect_.width() > target_rect_.width() ||
          root_rect_.height() > target_rect_.height()) {
        // The intersection rect (which is contained by target_rect_) can never
        // cover root_rect_ 100%.
        return kInfiniteScrollDelta;
      }
      if (target_rect_.Contains(root_rect_) &&
          root_and_target.relationship ==
              RootAndTarget::kHasIntermediateClippers) {
        // When target_rect_ fully contains root_rect_, whether the intersection
        // rect fully covers root_rect_ depends on intermediate clips, so there
        // is no minimum scroll delta.
        return gfx::Vector2dF();
      }
    } else {
      if (target_rect_.width() > root_rect_.width() ||
          target_rect_.height() > root_rect_.height()) {
        // The intersection rect (which is contained by root_rect_) can never
        // cover target_rect_ 100%.
        return kInfiniteScrollDelta;
      }
      if (root_rect_.Contains(target_rect_) &&
          root_and_target.relationship ==
              RootAndTarget::kHasIntermediateClippers) {
        // When root_rect_ fully contains target_rect_, whether target_rect_
        // is fully visible depends on intermediate clips, so there is no
        // minimum scroll delta.
        return gfx::Vector2dF();
      }
    }
    // Otherwise, we can skip update until target_rect_/root_rect_ is or isn't
    // fully contained by root_rect_/target_rect_.
    return gfx::Vector2dF(
        std::min(std::abs(root_rect_.x() - target_rect_.x()),
                 std::abs(root_rect_.right() - target_rect_.right())),
        std::min(std::abs(root_rect_.y() - target_rect_.y()),
                 std::abs(root_rect_.bottom() - target_rect_.bottom())));
  }
  // Otherwise, if root_rect_ and target_rect_ intersect, the intersection
  // status may change on any scroll in case of intermediate clips or non-zero
  // thresholds. kMinimumThreshold equivalent to 0 for minimum scroll delta.
  gfx::RectF root_target_intersection_rect = root_rect_;
  bool inclusively_intersects =
      root_target_intersection_rect.InclusiveIntersect(target_rect_);
  if (inclusively_intersects &&
      (thresholds.size() != 1 || thresholds[0] > kMinimumThreshold ||
       root_and_target.relationship ==
           RootAndTarget::kHasIntermediateClippers ||
       IsForFrameViewportIntersection())) {
    return gfx::Vector2dF();
  }
  // Otherwise we can skip update until root_rect_ and target_rect_ is about
  // to change intersection status in either direction.
  return gfx::Vector2dF(
      std::min(std::abs(root_rect_.right() - target_rect_.x()),
               std::abs(target_rect_.right() - root_rect_.x())),
      std::min(std::abs(root_rect_.bottom() - target_rect_.y()),
               std::abs(target_rect_.bottom() - root_rect_.y())));
}

}  // namespace blink
