// Copyright 2020 The Chromium Authors. All rights reserved.
// 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/modules/delegated_ink/delegated_ink_trail_presenter.h"

#include "components/viz/common/delegated_ink_metadata.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"

namespace blink {
namespace {

class TestDelegatedInkMetadata {
 public:
  explicit TestDelegatedInkMetadata(viz::DelegatedInkMetadata* metadata)
      : point_(metadata->point()),
        color_(metadata->color()),
        diameter_(metadata->diameter()),
        area_(metadata->presentation_area()),
        is_hovering_(metadata->is_hovering()) {}
  explicit TestDelegatedInkMetadata(gfx::RectF area,
                                    float device_pixel_ratio = 1.0)
      : area_(area) {
    area_.Scale(device_pixel_ratio);
  }
  TestDelegatedInkMetadata() = default;

  void ExpectEqual(TestDelegatedInkMetadata actual) const {
    // LayoutUnits cast floats to ints, causing the actual point and area to be
    // off a small amount from what is expected.
    EXPECT_NEAR(point_.x(), actual.point_.x(), LayoutUnit::Epsilon());
    EXPECT_NEAR(point_.y(), actual.point_.y(), LayoutUnit::Epsilon());
    EXPECT_EQ(color_, actual.color_);
    EXPECT_EQ(diameter_, actual.diameter_);
    EXPECT_NEAR(area_.x(), actual.area_.x(), LayoutUnit::Epsilon());
    EXPECT_NEAR(area_.y(), actual.area_.y(), LayoutUnit::Epsilon());
    EXPECT_NEAR(area_.width(), actual.area_.width(), LayoutUnit::Epsilon());
    EXPECT_NEAR(area_.height(), actual.area_.height(), LayoutUnit::Epsilon());
    EXPECT_EQ(is_hovering_, actual.is_hovering_);
  }

  void SetPoint(gfx::PointF pt) { point_ = pt; }
  void SetColor(SkColor color) { color_ = color; }
  void SetDiameter(double diameter) { diameter_ = diameter; }
  void SetArea(gfx::RectF area) { area_ = area; }
  void SetHovering(bool hovering) { is_hovering_ = hovering; }

 private:
  gfx::PointF point_;
  SkColor color_;
  double diameter_;
  gfx::RectF area_;
  bool is_hovering_;
};

DelegatedInkTrailPresenter* CreatePresenter(Element* element,
                                            LocalFrame* frame) {
  return DelegatedInkTrailPresenter::CreatePresenter(element, frame);
}

}  // namespace

class DelegatedInkTrailPresenterUnitTest : public SimTest {
 public:
  void SetWebViewSize(float width, float height) {
    WebView().MainFrameViewWidget()->Resize(gfx::Size(width, height));
  }

  void SetWebViewSizeGreaterThanCanvas(float width, float height) {
    // The presentation area is intersected with the visible content rect, so
    // make sure that the page size is larger than the canvas to ensure it
    // isn't clipped. Adding 1 to the height and width is enough to ensure that
    // doesn't happen.
    SetWebViewSize(width + 1, height + 1);
  }

  PointerEvent* CreatePointerMoveEvent(gfx::PointF pt, bool hovering) {
    PointerEventInit* init = PointerEventInit::Create();
    init->setClientX(pt.x());
    init->setClientY(pt.y());
    if (!hovering) {
      init->setButtons(MouseEvent::WebInputEventModifiersToButtons(
          WebInputEvent::Modifiers::kLeftButtonDown));
    }
    PointerEvent* event = PointerEvent::Create("pointermove", init);
    event->SetTrusted(true);
    return event;
  }

  TestDelegatedInkMetadata GetActualMetadata() {
    return TestDelegatedInkMetadata(WebView()
                                        .MainFrameViewWidget()
                                        ->LayerTreeHostForTesting()
                                        ->DelegatedInkMetadataForTesting());
  }

  void SetPageZoomFactor(const float zoom) {
    GetDocument().GetFrame()->SetPageZoomFactor(zoom);
  }
};

// Test scenarios with the presentation area extending beyond the edges of the
// window to confirm it gets clipped correctly.
class DelegatedInkTrailPresenterCanvasBeyondViewport
    : public DelegatedInkTrailPresenterUnitTest,
      public testing::WithParamInterface<bool> {
 public:
  bool CanvasShouldBePastViewport() { return GetParam(); }
  float GetViewportWidth() const { return kViewportWidth; }
  float GetViewportHeight() const { return kViewportHeight; }
  void SetWebViewSize() {
    DelegatedInkTrailPresenterUnitTest::SetWebViewSize(kViewportWidth,
                                                       kViewportHeight);
  }

 private:
  const float kViewportWidth = 175.f;
  const float kViewportHeight = 180.f;
};

// Confirm that all the information is collected and transformed correctly, if
// necessary. Numbers and color used were chosen arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport,
       CollectAndPropagateMetadata) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 191px;
      height: 234px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  const float kCanvasWidth = 191.f;
  const float kCanvasHeight = 234.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kCanvasWidth, kCanvasHeight);
    expected_metadata.SetArea(gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight));
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(
        gfx::RectF(0, 0, GetViewportWidth(), GetViewportHeight()));
  }

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      GetDocument().getElementById("canvas"), GetDocument().GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(5);
  style.setColor("blue");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorBLUE);

  gfx::PointF pt(100, 100);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(GetDocument().GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
  expected_metadata.SetHovering(true);
  expected_metadata.SetPoint(pt);

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that everything is still calculated correctly when the
// DevicePixelRatio is not 1. Numbers and color used were chosen arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport,
       NotDefaultDevicePixelRatio) {
  const float kZoom = 1.7;
  SetPageZoomFactor(kZoom);

  SimRequest main_resource("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 281px;
      height: 190px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  const float kCanvasWidth = 281.f;
  const float kCanvasHeight = 190.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kCanvasWidth * kZoom,
                                    kCanvasHeight * kZoom);
    expected_metadata = TestDelegatedInkMetadata(
        gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight), kZoom);
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(
        gfx::RectF(0, 0, GetViewportWidth(), GetViewportHeight()));
  }

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      GetDocument().getElementById("canvas"), GetDocument().GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(101.5);
  style.setColor("magenta");
  expected_metadata.SetDiameter(style.diameter() * kZoom);
  expected_metadata.SetColor(SK_ColorMAGENTA);

  gfx::PointF pt(87, 113);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(GetDocument().GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
  expected_metadata.SetHovering(true);
  pt.Scale(kZoom);
  expected_metadata.SetPoint(pt);

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that the offset is correct. Numbers and color used were chosen
// arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport, CanvasNotAtOrigin) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 250px;
      height: 350px;
      position: fixed;
      top: 59px;
      left: 16px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  const float kCanvasWidth = 250.f;
  const float kCanvasHeight = 350.f;
  const float kCanvasTopOffset = 59.f;
  const float kCanvasLeftOffset = 16.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kCanvasWidth + kCanvasLeftOffset,
                                    kCanvasHeight + kCanvasTopOffset);
    expected_metadata.SetArea(gfx::RectF(kCanvasLeftOffset, kCanvasTopOffset,
                                         kCanvasWidth, kCanvasHeight));
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(
        gfx::RectF(kCanvasLeftOffset, kCanvasTopOffset,
                   GetViewportWidth() - kCanvasLeftOffset,
                   GetViewportHeight() - kCanvasTopOffset));
  }

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      GetDocument().getElementById("canvas"), GetDocument().GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(8.6);
  style.setColor("red");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorRED);

  gfx::PointF pt(380, 175);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(GetDocument().GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
  expected_metadata.SetHovering(false);
  expected_metadata.SetPoint(pt);

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that values, specifically offsets, are transformed correctly when
// the canvas is in an iframe. Numbers and color used were chosen arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport, CanvasInIFrame) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #iframe {
      width: 500px;
      height: 500px;
      position: fixed;
      top: 26px;
      left: 57px;
    }
    </style>
    <iframe id='iframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 250px;
      height: 250px;
      position: fixed;
      top: 33px;
      left: 16px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe that the canvas is in, and the 2px
  // border around the iframe.
  const float kIframeBorder = 2.f;
  const float kIframeLeftOffset = 57.f + kIframeBorder;
  const float kIframeTopOffset = 26.f + kIframeBorder;
  const float kIframeHeight = 500.f;
  const float kIframeWidth = 500.f;
  const float kCanvasLeftOffset = 16.f;
  const float kCanvasTopOffset = 33.f;
  const float kCanvasHeight = 250.f;
  const float kCanvasWidth = 250.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kIframeWidth + kIframeLeftOffset,
                                    kIframeHeight + kIframeTopOffset);
    expected_metadata.SetArea(gfx::RectF(kIframeLeftOffset + kCanvasLeftOffset,
                                         kIframeTopOffset + kCanvasTopOffset,
                                         kCanvasWidth, kCanvasHeight));
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(gfx::RectF(
        kIframeLeftOffset + kCanvasLeftOffset,
        kIframeTopOffset + kCanvasTopOffset,
        GetViewportWidth() - (kIframeLeftOffset + kCanvasLeftOffset),
        GetViewportHeight() - (kIframeTopOffset + kCanvasTopOffset)));
  }

  auto* iframe_element =
      To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
  auto* iframe_localframe = To<LocalFrame>(iframe_element->ContentFrame());
  Document* iframe_document = iframe_element->contentDocument();

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      iframe_localframe->GetDocument()->getElementById("canvas"),
      iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(0.3);
  style.setColor("cyan");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorCYAN);

  gfx::PointF pt(380, 375);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
  expected_metadata.SetHovering(false);
  expected_metadata.SetPoint(
      gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that values, specifically offsets, are transformed correctly when
// the canvas is in a nested iframe. Numbers and color used were chosen
// arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport, NestedIframe) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  SimRequest frame2_resource("https://example.com/iframe2.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #OuterIframe {
      width: 500px;
      height: 500px;
      position: fixed;
      top: 26px;
      left: 57px;
    }
    </style>
    <iframe id='OuterIframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #InnerIframe {
      width: 400px;
      height: 400px;
      position: fixed;
      top: 11px;
      left: 18px;
    }
    </style>
    <iframe id='InnerIframe' src='https://example.com/iframe2.html'>
    </iframe>
    )HTML");

  frame2_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 250px;
      height: 250px;
      position: fixed;
      top: 28px;
      left: 6px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe that the canvas is in, and the 2px
  // border around the iframe.
  const float kIframeBorder = 2.f;
  const float kOuterIframeLeftOffset = 57.f + kIframeBorder;
  const float kOuterIframeTopOffset = 26.f + kIframeBorder;
  const float kOuterIframeHeight = 500.f;
  const float kOuterIframeWidth = 500.f;
  const float kInnerIframeLeftOffset =
      kOuterIframeLeftOffset + 18.f + kIframeBorder;
  const float kInnerIframeTopOffset =
      kOuterIframeTopOffset + 11.f + kIframeBorder;
  const float kCanvasLeftOffset = 6.f;
  const float kCanvasTopOffset = 28.f;
  const float kCanvasHeight = 250.f;
  const float kCanvasWidth = 250.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kOuterIframeWidth + kOuterIframeLeftOffset,
                                    kOuterIframeHeight + kOuterIframeTopOffset);
    expected_metadata.SetArea(gfx::RectF(
        kInnerIframeLeftOffset + kCanvasLeftOffset,
        kInnerIframeTopOffset + kCanvasTopOffset, kCanvasWidth, kCanvasHeight));
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(gfx::RectF(
        kInnerIframeLeftOffset + kCanvasLeftOffset,
        kInnerIframeTopOffset + kCanvasTopOffset,
        GetViewportWidth() - (kInnerIframeLeftOffset + kCanvasLeftOffset),
        GetViewportHeight() - (kInnerIframeTopOffset + kCanvasTopOffset)));
  }

  auto* outer_iframe_element =
      To<HTMLIFrameElement>(GetDocument().getElementById("OuterIframe"));
  auto* inner_iframe_element = To<HTMLIFrameElement>(
      outer_iframe_element->contentDocument()->getElementById("InnerIframe"));
  auto* iframe_localframe =
      To<LocalFrame>(inner_iframe_element->ContentFrame());
  Document* iframe_document = inner_iframe_element->contentDocument();

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      iframe_localframe->GetDocument()->getElementById("canvas"),
      iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(100000.3);
  style.setColor("yellow");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorYELLOW);

  gfx::PointF pt(350, 375);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
  expected_metadata.SetHovering(true);
  expected_metadata.SetPoint(gfx::PointF(pt.x() + kInnerIframeLeftOffset,
                                         pt.y() + kInnerIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that values are correct when an iframe is used and presentation area
// isn't provided. Numbers and color used were chosen arbitrarily.
TEST_P(DelegatedInkTrailPresenterCanvasBeyondViewport,
       IFrameNoPresentationArea) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #iframe {
      width: 500px;
      height: 500px;
      position: fixed;
      top: 56px;
      left: 72px;
    }
    </style>
    <iframe id='iframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    </style>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe, and the 2px border.
  const float kIframeBorder = 2.f;
  const float kIframeLeftOffset = 72.f + kIframeBorder;
  const float kIframeTopOffset = 56.f + kIframeBorder;
  const float kIframeHeight = 500.f;
  const float kIframeWidth = 500.f;

  TestDelegatedInkMetadata expected_metadata;

  if (!CanvasShouldBePastViewport()) {
    SetWebViewSizeGreaterThanCanvas(kIframeWidth + kIframeLeftOffset,
                                    kIframeHeight + kIframeTopOffset);
    expected_metadata.SetArea(gfx::RectF(kIframeLeftOffset, kIframeTopOffset,
                                         kIframeWidth, kIframeHeight));
  } else {
    SetWebViewSize();
    expected_metadata.SetArea(
        gfx::RectF(kIframeLeftOffset, kIframeTopOffset,
                   GetViewportWidth() - kIframeLeftOffset,
                   GetViewportHeight() - kIframeTopOffset));
  }

  Document* iframe_document =
      To<HTMLIFrameElement>(GetDocument().getElementById("iframe"))
          ->contentDocument();

  DelegatedInkTrailPresenter* presenter =
      CreatePresenter(nullptr, iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(0.01);
  style.setColor("white");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorWHITE);

  gfx::PointF pt(380, 375);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
  expected_metadata.SetHovering(true);
  expected_metadata.SetPoint(
      gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

INSTANTIATE_TEST_SUITE_P(,
                         DelegatedInkTrailPresenterCanvasBeyondViewport,
                         testing::Bool());

// Confirm that presentation area defaults to the size of the viewport.
// Numbers and color used were chosen arbitrarily.
TEST_F(DelegatedInkTrailPresenterUnitTest, PresentationAreaNotProvided) {
  const int kViewportHeight = 555;
  const int kViewportWidth = 333;
  SetWebViewSize(kViewportWidth, kViewportHeight);

  DelegatedInkTrailPresenter* presenter =
      CreatePresenter(nullptr, GetDocument().GetFrame());
  DCHECK(presenter);

  TestDelegatedInkMetadata expected_metadata(
      gfx::RectF(0, 0, kViewportWidth, kViewportHeight));

  InkTrailStyle style;
  style.setDiameter(3.6);
  style.setColor("yellow");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorYELLOW);

  gfx::PointF pt(70, 109);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(GetDocument().GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
  expected_metadata.SetHovering(false);
  expected_metadata.SetPoint(pt);

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Test that the presentation area is clipped correctly by the dimensions of
// the iframe, even when the iframe and canvas each fit entirely within the
// visual viewport.
TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasExtendsOutsideOfIframe) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #iframe {
      width: 150px;
      height: 150px;
      position: fixed;
      top: 13px;
      left: 19px;
    }
    </style>
    <iframe id='iframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 199px;
      height: 202px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe that the canvas is in, and the 2px
  // border around the iframe.
  const float kIframeBorder = 2.f;
  const float kIframeLeftOffset = 19.f + kIframeBorder;
  const float kIframeTopOffset = 13.f + kIframeBorder;
  const float kIframeHeight = 150.f;
  const float kIframeWidth = 150.f;
  const float kCanvasHeight = 202.f;
  const float kCanvasWidth = 199.f;

  // Ensure that the webpage is larger than the iframe and canvas.
  SetWebViewSize(kCanvasWidth + kIframeLeftOffset + 1,
                 kCanvasHeight + kIframeTopOffset + 1);

  TestDelegatedInkMetadata expected_metadata(gfx::RectF(
      kIframeLeftOffset, kIframeTopOffset, kIframeWidth, kIframeHeight));

  auto* iframe_element =
      To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
  auto* iframe_localframe = To<LocalFrame>(iframe_element->ContentFrame());
  Document* iframe_document = iframe_element->contentDocument();

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      iframe_localframe->GetDocument()->getElementById("canvas"),
      iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(99.999);
  style.setColor("lime");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorGREEN);

  gfx::PointF pt(102, 67);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
  expected_metadata.SetHovering(false);
  expected_metadata.SetPoint(
      gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Test that the presentation area is clipped correctly when it is offset left
// and above the iframe boundaries.
TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasLeftAndAboveIframeBoundaries) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #iframe {
      width: 300px;
      height: 301px;
      position: fixed;
      top: 13px;
      left: 19px;
    }
    </style>
    <iframe id='iframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 189px;
      height: 145px;
      position: fixed;
      top: -70px;
      left: -99px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe that the canvas is in, and the 2px
  // border around the iframe.
  const float kIframeBorder = 2.f;
  const float kIframeLeftOffset = 19.f + kIframeBorder;
  const float kIframeTopOffset = 13.f + kIframeBorder;
  const float kIframeHeight = 301.f;
  const float kIframeWidth = 300.f;
  const float kCanvasHeight = 145.f;
  const float kCanvasWidth = 189.f;
  const float kCanvasLeftOffset = -99.f;
  const float kCanvasTopOffset = -70.f;

  // Ensure that the webpage is larger than the iframe.
  SetWebViewSize(kIframeHeight + kIframeLeftOffset + 1,
                 kIframeWidth + kIframeTopOffset + 1);

  TestDelegatedInkMetadata expected_metadata(gfx::RectF(
      kIframeLeftOffset, kIframeTopOffset, kCanvasWidth + kCanvasLeftOffset,
      kCanvasHeight + kCanvasTopOffset));

  auto* iframe_element =
      To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
  auto* iframe_localframe = To<LocalFrame>(iframe_element->ContentFrame());
  Document* iframe_document = iframe_element->contentDocument();

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      iframe_localframe->GetDocument()->getElementById("canvas"),
      iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(99.999);
  style.setColor("lime");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorGREEN);

  gfx::PointF pt(102, 67);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
  expected_metadata.SetHovering(true);
  expected_metadata.SetPoint(
      gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

// Confirm that values, specifically presentation area, are transformed
// correctly when the iframe that the canvas is in is clipped by its parent
// iframe. Numbers and color used were chosen arbitrarily.
TEST_F(DelegatedInkTrailPresenterUnitTest, OuterIframeClipsInnerIframe) {
  SimRequest main_resource("https://example.com/test.html", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  SimRequest frame2_resource("https://example.com/iframe2.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #OuterIframe {
      width: 500px;
      height: 500px;
      position: fixed;
      top: 26px;
      left: 57px;
    }
    </style>
    <iframe id='OuterIframe' src='https://example.com/iframe.html'>
    </iframe>
  )HTML");

  frame_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    #InnerIframe {
      width: 400px;
      height: 400px;
      position: fixed;
      top: 311px;
      left: 334px;
    }
    </style>
    <iframe id='InnerIframe' src='https://example.com/iframe2.html'>
    </iframe>
    )HTML");

  frame2_resource.Complete(R"HTML(
    <!DOCTYPE html>
    <style>
    body {
      margin: 0;
    }
    canvas {
      width: 250px;
      height: 250px;
      position: fixed;
      top: 1px;
      left: 2px;
    }
    </style>
    <canvas id='canvas'></canvas>
  )HTML");

  Compositor().BeginFrame();

  // When creating the expected metadata, we have to take into account the
  // offsets that are applied to the iframe that the canvas is in, and the 2px
  // border around the iframe.
  const float kIframeBorder = 2.f;
  const float kOuterIframeLeftOffset = 57.f + kIframeBorder;
  const float kOuterIframeTopOffset = 26.f + kIframeBorder;
  const float kOuterIframeHeight = 500.f;
  const float kOuterIframeWidth = 500.f;
  const float kInnerIframeLeftOffset =
      kOuterIframeLeftOffset + 334.f + kIframeBorder;
  const float kInnerIframeTopOffset =
      kOuterIframeTopOffset + 311.f + kIframeBorder;
  const float kCanvasLeftOffset = 2.f;
  const float kCanvasTopOffset = 1.f;

  // Ensure that the webpage is larger than the iframe and canvas.
  const float kViewportWidth = kOuterIframeWidth + kOuterIframeLeftOffset + 1.f;
  const float kViewportHeight =
      kOuterIframeHeight + kOuterIframeTopOffset + 1.f;
  SetWebViewSize(kViewportWidth, kViewportHeight);

  TestDelegatedInkMetadata expected_metadata(
      gfx::RectF(kInnerIframeLeftOffset + kCanvasLeftOffset,
                 kInnerIframeTopOffset + kCanvasTopOffset,
                 kOuterIframeWidth + kOuterIframeLeftOffset -
                     kInnerIframeLeftOffset - kCanvasLeftOffset,
                 kOuterIframeHeight + kOuterIframeTopOffset -
                     kInnerIframeTopOffset - kCanvasTopOffset));

  auto* outer_iframe_element =
      To<HTMLIFrameElement>(GetDocument().getElementById("OuterIframe"));
  auto* inner_iframe_element = To<HTMLIFrameElement>(
      outer_iframe_element->contentDocument()->getElementById("InnerIframe"));
  auto* iframe_localframe =
      To<LocalFrame>(inner_iframe_element->ContentFrame());
  Document* iframe_document = inner_iframe_element->contentDocument();

  DelegatedInkTrailPresenter* presenter = CreatePresenter(
      iframe_localframe->GetDocument()->getElementById("canvas"),
      iframe_document->GetFrame());
  DCHECK(presenter);

  InkTrailStyle style;
  style.setDiameter(19);
  style.setColor("red");
  expected_metadata.SetDiameter(style.diameter());
  expected_metadata.SetColor(SK_ColorRED);

  gfx::PointF pt(357, 401);
  presenter->updateInkTrailStartPoint(
      ToScriptStateForMainWorld(iframe_document->GetFrame()),
      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
  expected_metadata.SetHovering(false);
  expected_metadata.SetPoint(gfx::PointF(pt.x() + kInnerIframeLeftOffset,
                                         pt.y() + kInnerIframeTopOffset));

  expected_metadata.ExpectEqual(GetActualMetadata());
}

}  // namespace blink
