// Copyright 2014 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/core/layout/layout_inline.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"

namespace blink {

using ::testing::UnorderedElementsAre;

class LayoutInlineTest : public RenderingTest {};

// Helper class to run the same test code with and without LayoutNG
class ParameterizedLayoutInlineTest : public testing::WithParamInterface<bool>,
                                      private ScopedLayoutNGForTest,
                                      public LayoutInlineTest {
 public:
  ParameterizedLayoutInlineTest() : ScopedLayoutNGForTest(GetParam()) {}

 protected:
  bool LayoutNGEnabled() const { return GetParam(); }
};

INSTANTIATE_TEST_CASE_P(All, ParameterizedLayoutInlineTest, testing::Bool());

TEST_P(ParameterizedLayoutInlineTest, LinesBoundingBox) {
  LoadAhem();
  SetBodyInnerHTML(
      "<style>"
      "html { font-family: Ahem; font-size: 13px; }"
      // LayoutNG requires box decorations at this moment. crbug.com/789390
      "span { background-color: yellow; }"
      ".vertical { writing-mode: vertical-rl; }"
      "</style>"
      "<p><span id=ltr1>abc<br>xyz</span></p>"
      "<p><span id=ltr2>12 345 6789</span></p>"
      "<p dir=rtl><span id=rtl1>abc<br>xyz</span></p>"
      "<p dir=rtl><span id=rtl2>12 345 6789</span></p>"
      "<p class=vertical><span id=vertical>abc<br>xyz</span></p>");
  EXPECT_EQ(
      LayoutRect(LayoutPoint(0, 0), LayoutSize(39, 26)),
      ToLayoutInline(GetLayoutObjectByElementId("ltr1"))->LinesBoundingBox());
  EXPECT_EQ(
      LayoutRect(LayoutPoint(0, 0), LayoutSize(143, 13)),
      ToLayoutInline(GetLayoutObjectByElementId("ltr2"))->LinesBoundingBox());
  EXPECT_EQ(
      LayoutRect(LayoutPoint(745, 0), LayoutSize(39, 26)),
      ToLayoutInline(GetLayoutObjectByElementId("rtl1"))->LinesBoundingBox());
  EXPECT_EQ(
      LayoutRect(LayoutPoint(641, 0), LayoutSize(143, 13)),
      ToLayoutInline(GetLayoutObjectByElementId("rtl2"))->LinesBoundingBox());
  EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(26, 39)),
            ToLayoutInline(GetLayoutObjectByElementId("vertical"))
                ->LinesBoundingBox());
}

TEST_F(LayoutInlineTest, SimpleContinuation) {
  SetBodyInnerHTML(
      "<span id='splitInline'><i id='before'></i><h1 id='blockChild'></h1><i "
      "id='after'></i></span>");

  LayoutInline* split_inline_part1 =
      ToLayoutInline(GetLayoutObjectByElementId("splitInline"));
  ASSERT_TRUE(split_inline_part1);
  ASSERT_TRUE(split_inline_part1->FirstChild());
  EXPECT_EQ(split_inline_part1->FirstChild(),
            GetLayoutObjectByElementId("before"));
  EXPECT_FALSE(split_inline_part1->FirstChild()->NextSibling());

  LayoutBlockFlow* block =
      ToLayoutBlockFlow(split_inline_part1->Continuation());
  ASSERT_TRUE(block);
  ASSERT_TRUE(block->FirstChild());
  EXPECT_EQ(block->FirstChild(), GetLayoutObjectByElementId("blockChild"));
  EXPECT_FALSE(block->FirstChild()->NextSibling());

  LayoutInline* split_inline_part2 = ToLayoutInline(block->Continuation());
  ASSERT_TRUE(split_inline_part2);
  ASSERT_TRUE(split_inline_part2->FirstChild());
  EXPECT_EQ(split_inline_part2->FirstChild(),
            GetLayoutObjectByElementId("after"));
  EXPECT_FALSE(split_inline_part2->FirstChild()->NextSibling());
  EXPECT_FALSE(split_inline_part2->Continuation());
}

TEST_F(LayoutInlineTest, RegionHitTest) {
  SetBodyInnerHTML(R"HTML(
    <div><span id='lotsOfBoxes'>
    This is a test line<br>This is a test line<br>This is a test line<br>
    This is a test line<br>This is a test line<br>This is a test line<br>
    This is a test line<br>This is a test line<br>This is a test line<br>
    This is a test line<br>This is a test line<br>This is a test line<br>
    This is a test line<br>This is a test line<br>This is a test line<br>
    This is a test line<br>This is a test line<br>This is a test line<br>
    </span></div>
  )HTML");

  UpdateAllLifecyclePhasesForTest();

  LayoutInline* lots_of_boxes =
      ToLayoutInline(GetLayoutObjectByElementId("lotsOfBoxes"));
  ASSERT_TRUE(lots_of_boxes);

  HitTestRequest hit_request(HitTestRequest::kTouchEvent |
                             HitTestRequest::kListBased);

  LayoutRect hit_rect(1, 3, 2, 4);
  HitTestLocation location(hit_rect);
  HitTestResult hit_result(hit_request, location);
  LayoutPoint hit_offset;

  // The return value of HitTestCulledInline() indicates whether the hit test
  // rect is completely contained by the part of |lots_of_boxes| being hit-
  // tested. Legacy hit tests the entire LayoutObject all at once while NG hit
  // tests line by line. Therefore, legacy returns true while NG is false.
  //
  // Note: The legacy behavior seems wrong. In a full list-based hit testing,
  // after testing the node in the last intersecting line, the |true| return
  // value of HitTestCulledInline() terminates the hit test process, and nodes
  // in the previous lines are not tested.
  //
  // TODO(xiaochengh): Expose this issue in a real Chrome use case.

  if (!lots_of_boxes->IsInLayoutNGInlineFormattingContext()) {
    bool hit_outcome =
        lots_of_boxes->HitTestCulledInline(hit_result, location, hit_offset);
    // Assert checks that we both hit something and that the area covered
    // by "something" totally contains the hit region.
    EXPECT_TRUE(hit_outcome);
    return;
  }

  const LayoutBlockFlow* div = ToLayoutBlockFlow(lots_of_boxes->Parent());
  for (const NGPaintFragment* line : div->PaintFragment()->Children()) {
    DCHECK(line->PhysicalFragment().IsLineBox());
    bool hit_outcome = lots_of_boxes->HitTestCulledInline(hit_result, location,
                                                          hit_offset, line);
    EXPECT_FALSE(hit_outcome);
  }
  // Make sure that the inline is hit
  const Node* span = lots_of_boxes->GetNode();
  EXPECT_EQ(span, hit_result.InnerNode());
}

// crbug.com/844746
TEST_P(ParameterizedLayoutInlineTest, RelativePositionedHitTest) {
  LoadAhem();
  SetBodyInnerHTML(
      "<div style='font: 10px/10px Ahem'>"
      "  <span style='position: relative'>XXX</span>"
      "</div>");

  HitTestRequest hit_request(HitTestRequest::kReadOnly |
                             HitTestRequest::kActive);
  const LayoutPoint container_offset(8, 8);
  const LayoutPoint hit_location(18, 15);
  HitTestLocation location(hit_location);

  Element* div = GetDocument().QuerySelector("div");
  Element* span = GetDocument().QuerySelector("span");
  Node* text = span->firstChild();

  // Shouldn't hit anything in SPAN as it's in another paint layer
  {
    LayoutObject* layout_div = div->GetLayoutObject();
    HitTestResult hit_result(hit_request, location);
    bool hit_outcome =
        layout_div->HitTestAllPhases(hit_result, location, container_offset);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(div, hit_result.InnerNode());
  }

  // SPAN and its descendants can be hit only with a hit test that starts from
  // the SPAN itself.
  {
    LayoutObject* layout_span = span->GetLayoutObject();
    HitTestResult hit_result(hit_request, location);
    bool hit_outcome =
        layout_span->HitTestAllPhases(hit_result, location, container_offset);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(text, hit_result.InnerNode());
  }

  // Hit test from LayoutView to verify that everything works together.
  {
    HitTestResult hit_result(hit_request, location);
    bool hit_outcome = GetLayoutView().HitTest(location, hit_result);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(text, hit_result.InnerNode());
  }
}

TEST_P(ParameterizedLayoutInlineTest, MultilineRelativePositionedHitTest) {
  LoadAhem();
  SetBodyInnerHTML(
      "<div style='font: 10px/10px Ahem; width: 30px'>"
      "  <span id=span style='position: relative'>"
      "    XXX"
      "    <span id=line2 style='background-color: red'>YYY</span>"
      "    <img style='width: 10px; height: 10px; vertical-align: bottom'>"
      "  </span>"
      "</div>");

  LayoutObject* layout_span = GetLayoutObjectByElementId("span");
  HitTestRequest hit_request(HitTestRequest::kReadOnly |
                             HitTestRequest::kActive |
                             HitTestRequest::kIgnorePointerEventsNone);
  const LayoutPoint container_offset(8, 8);

  // Hit test first line
  {
    LayoutPoint hit_location(13, 13);
    HitTestLocation location(hit_location);
    Node* target = GetElementById("span")->firstChild();

    HitTestResult hit_result(hit_request, location);
    bool hit_outcome =
        layout_span->HitTestAllPhases(hit_result, location, container_offset);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(target, hit_result.InnerNode());

    // Initiate a hit test from LayoutView to verify the "natural" process.
    HitTestResult layout_view_hit_result(hit_request, location);
    bool layout_view_hit_outcome =
        GetLayoutView().HitTest(location, layout_view_hit_result);
    EXPECT_TRUE(layout_view_hit_outcome);
    EXPECT_EQ(target, layout_view_hit_result.InnerNode());
  }

  // Hit test second line
  {
    LayoutPoint hit_location(13, 23);
    HitTestLocation location(hit_location);
    Node* target = GetElementById("line2")->firstChild();

    HitTestResult hit_result(hit_request, location);
    bool hit_outcome =
        layout_span->HitTestAllPhases(hit_result, location, container_offset);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(target, hit_result.InnerNode());

    // Initiate a hit test from LayoutView to verify the "natural" process.
    HitTestResult layout_view_hit_result(hit_request, location);
    bool layout_view_hit_outcome =
        GetLayoutView().HitTest(location, layout_view_hit_result);
    EXPECT_TRUE(layout_view_hit_outcome);
    EXPECT_EQ(target, layout_view_hit_result.InnerNode());
  }

  // Hit test image in third line
  {
    LayoutPoint hit_location(13, 33);
    HitTestLocation location(hit_location);
    Node* target = GetDocument().QuerySelector("img");

    HitTestResult hit_result(hit_request, location);
    bool hit_outcome =
        layout_span->HitTestAllPhases(hit_result, location, container_offset);
    EXPECT_TRUE(hit_outcome);
    EXPECT_EQ(target, hit_result.InnerNode());

    // Initiate a hit test from LayoutView to verify the "natural" process.
    HitTestResult layout_view_hit_result(hit_request, location);
    bool layout_view_hit_outcome =
        GetLayoutView().HitTest(location, layout_view_hit_result);
    EXPECT_TRUE(layout_view_hit_outcome);
    EXPECT_EQ(target, layout_view_hit_result.InnerNode());
  }
}

TEST_P(ParameterizedLayoutInlineTest, VisualRectInDocument) {
  LoadAhem();
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin:0px;
        font: 20px/20px Ahem;
      }
    </style>
    <div>
      <span>xx<br>
        <span id="target" tabindex="-1">yy
          <div style="width:111px;height:222px;background:yellow"></div>
          yy
        </span>
      </span>
    </div>
  )HTML");

  LayoutInline* target = ToLayoutInline(GetLayoutObjectByElementId("target"));
  LayoutRect visual_rect = target->VisualRectInDocument();
  EXPECT_EQ(visual_rect.X(), LayoutUnit(0));
  EXPECT_EQ(visual_rect.Y(), LayoutUnit(20));
  EXPECT_EQ(visual_rect.Width(), LayoutUnit(111));
  EXPECT_EQ(visual_rect.Height(), LayoutUnit(222 + 20 * 2));
}

// When adding focus ring rects, we should avoid adding duplicated rect for
// continuations.
TEST_P(ParameterizedLayoutInlineTest, FocusRingRecursiveContinuations) {
  // TODO(crbug.com/835484): The test is broken for LayoutNG.
  if (RuntimeEnabledFeatures::LayoutNGEnabled())
    return;

  LoadAhem();
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0;
        font: 20px/20px Ahem;
      }
    </style>
    <span id="target">SPAN0
      <div>DIV1
        <span>SPAN1
          <div>DIV2</div>
        </span>
      </div>
    </span>
  )HTML");

  Vector<LayoutRect> rects;
  GetLayoutObjectByElementId("target")->AddOutlineRects(
      rects, LayoutPoint(), NGOutlineType::kIncludeBlockVisualOverflow);

  EXPECT_THAT(rects,
              UnorderedElementsAre(LayoutRect(0, 0, 100, 20),    // 'SPAN0'
                                   LayoutRect(0, 20, 800, 40),   // div DIV1
                                   LayoutRect(0, 20, 200, 20),   // 'DIV1 SPAN1'
                                   LayoutRect(0, 40, 800, 20),   // div DIV2
                                   LayoutRect(0, 40, 80, 20)));  // 'DIV2'
}

// When adding focus ring rects, we should avoid adding line box rects of
// recursive inlines repeatedly.
TEST_P(ParameterizedLayoutInlineTest, FocusRingRecursiveInlines) {
  // TODO(crbug.com/835484): The test is broken for LayoutNG.
  if (RuntimeEnabledFeatures::LayoutNGEnabled())
    return;

  LoadAhem();
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0;
        font: 20px/20px Ahem;
      }
    </style>
    <div style="width: 200px">
      <span id="target">
        <b><b><b><i><i><i>INLINE</i></i> <i><i>TEXT</i></i>
        <div style="position: relative; top: -5px">
          <b><b>BLOCK</b> <i>CONTENTS</i></b>
        </div>
        </i></b></b></b>
      </span>
    </div>
  )HTML");

  Vector<LayoutRect> rects;
  GetLayoutObjectByElementId("target")->AddOutlineRects(
      rects, LayoutPoint(), NGOutlineType::kIncludeBlockVisualOverflow);

  EXPECT_THAT(rects,
              UnorderedElementsAre(LayoutRect(0, 0, 120, 20),   // 'INLINE'
                                   LayoutRect(0, 20, 80, 20),   // 'TEXT'
                                   LayoutRect(0, 35, 200, 40),  // the inner div
                                   LayoutRect(0, 35, 100, 20),  // 'BLOCK'
                                   LayoutRect(0, 55, 160, 20)));  // 'CONTENTS'
}

}  // namespace blink
