// Copyright 2017 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/editing/rendered_position.h"

#include "build/build_config.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_selection.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/testing/use_mock_scrollbar_settings.h"

namespace blink {

class RenderedPositionTest : public EditingTestBase {
 public:
  void SetUp() override {
    EditingTestBase::SetUp();
    GetPage().GetSettings().SetAcceleratedCompositingEnabled(true);
    GetDocument().View()->SetParentVisible(true);
    GetDocument().View()->SetSelfVisible(true);
    LoadAhem();
  }

  void FocusAndSelectAll(Element* focus, const Node& select) {
    DCHECK(focus);
    focus->focus();
    Selection().SetSelection(
        SelectionInDOMTree::Builder().SelectAllChildren(select).Build(),
        SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
    UpdateAllLifecyclePhases();
  }

  void FocusAndSelectAll(TextControlElement* target) {
    FocusAndSelectAll(target, *target->InnerEditorElement());
  }

 private:
  UseMockScrollbarSettings mock_scrollbars_;
};

TEST_F(RenderedPositionTest, ComputeCompositedSelection) {
  SetBodyContent(R"HTML(
      <!DOCTYPE html>
      input {
        font: 10px/1 Ahem;
        padding: 0;
        border: 0;
      }
      <input id=target width=20 value='test test test test test tes tes test'
      style='width: 100px; height: 20px;'>
  )HTML");

  FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target")));

  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_FALSE(composited_selection.start.hidden);
  EXPECT_TRUE(composited_selection.end.hidden);
}

TEST_F(RenderedPositionTest, PositionInScrollableRoot) {
  SetBodyContent(R"HTML(
      <!DOCTYPE html>
      <style>
        body {
           margin: 0;
           height: 2000px;
           width: 2000px;
        }
        input {
          font: 10px/1 Ahem;
          padding: 0;
          border: 0;
          width: 100px;
          height: 20px;
          position: absolute;
          top: 900px;
          left: 1000px;
        }
      </style>
      <input id=target width=20 value='test test test test test tes tes test'>
  )HTML");

  FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target")));

  ScrollableArea* root_scroller = GetDocument().View()->GetScrollableArea();
  root_scroller->SetScrollOffset(ScrollOffset(800, 500), kProgrammaticScroll);
  ASSERT_EQ(ScrollOffset(800, 500), root_scroller->GetScrollOffset());

  UpdateAllLifecyclePhases();

  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());

  // Top-left corner should be around (1000, 905) - 10px centered in 20px
  // height.
  EXPECT_EQ(FloatPoint(1000, 905),
            composited_selection.start.edge_top_in_layer);
  EXPECT_EQ(FloatPoint(1000, 915),
            composited_selection.start.edge_bottom_in_layer);
  EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer);
  EXPECT_EQ(FloatPoint(1369, 915),
            composited_selection.end.edge_bottom_in_layer);
}

TEST_F(RenderedPositionTest, PositionInScroller) {
  SetBodyContent(R"HTML(
      <!DOCTYPE html>
      <style>
        body {
           margin: 0;
           height: 2000px;
           width: 2000px;
        }
        input {
          font: 10px/1 Ahem;
          padding: 0;
          border: 0;
          width: 100px;
          height: 20px;
          position: absolute;
          top: 900px;
          left: 1000px;
        }

        #scroller {
          width: 300px;
          height: 300px;
          position: absolute;
          left: 300px;
          top: 400px;
          overflow: scroll;
          border: 200px;
          will-change: transform;
        }

        #space {
          width: 2000px;
          height: 2000px;
        }
      </style>
      <div id="scroller">
        <div id="space"></div>
        <input id=target width=20 value='test test test test test tes tes test'>
      </div>
  )HTML");

  FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target")));

  Element* e = GetDocument().getElementById("scroller");
  PaintLayerScrollableArea* scroller =
      ToLayoutBox(e->GetLayoutObject())->GetScrollableArea();
  scroller->SetScrollOffset(ScrollOffset(900, 800), kProgrammaticScroll);
  ASSERT_EQ(ScrollOffset(900, 800), scroller->GetScrollOffset());

  UpdateAllLifecyclePhases();

  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());

  // Top-left corner should be around (1000, 905) - 10px centered in 20px
  // height.
  EXPECT_EQ(FloatPoint(1000, 905),
            composited_selection.start.edge_top_in_layer);
  EXPECT_EQ(FloatPoint(1000, 915),
            composited_selection.start.edge_bottom_in_layer);
  EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer);
  EXPECT_EQ(FloatPoint(1369, 915),
            composited_selection.end.edge_bottom_in_layer);
}

// crbug.com/807930
TEST_F(RenderedPositionTest, ContentEditableLinebreak) {
  SetBodyContent(
      "<div style='font: 10px/10px Ahem;' contenteditable>"
      "test<br><br></div>");
  Element* target = GetDocument().QuerySelector("div");
  FocusAndSelectAll(target, *target);
  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
            FloatPoint(8.0f, 8.0f));
  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
            FloatPoint(8.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
            FloatPoint(8.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
            FloatPoint(8.0f, 28.0f));
}

// crbug.com/807930
TEST_F(RenderedPositionTest, TextAreaLinebreak) {
  SetBodyContent(
      "<textarea style='font: 10px/10px Ahem;'>"
      "test\n</textarea>");
  FocusAndSelectAll(ToTextControl(GetDocument().QuerySelector("textarea")));
  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
            FloatPoint(11.0f, 11.0f));
  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
            FloatPoint(11.0f, 21.0f));
  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
            FloatPoint(11.0f, 21.0f));
  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
            FloatPoint(11.0f, 31.0f));
}

// crbug.com/815099
TEST_F(RenderedPositionTest, CaretBeforeSoftWrap) {
  SetBodyContent(
      "<div style='font: 10px/10px Ahem; width:20px;' "
      "contenteditable>foo</div>");
  Element* target = GetDocument().QuerySelector("div");
  target->focus();
  Node* text_foo = target->firstChild();
  Selection().SetSelection(
      SelectionInDOMTree::Builder()
          .Collapse(
              PositionWithAffinity({text_foo, 2}, TextAffinity::kUpstream))
          .Build(),
      SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
  UpdateAllLifecyclePhases();
  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
            FloatPoint(27.0f, 8.0f));
  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
            FloatPoint(27.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
            FloatPoint(27.0f, 8.0f));
  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
            FloatPoint(27.0f, 18.0f));
}

TEST_F(RenderedPositionTest, CaretAfterSoftWrap) {
  SetBodyContent(
      "<div style='font: 10px/10px Ahem; width:20px;' "
      "contenteditable>foo</div>");
  Element* target = GetDocument().QuerySelector("div");
  target->focus();
  Node* text_foo = target->firstChild();
  Selection().SetSelection(
      SelectionInDOMTree::Builder()
          .Collapse(
              PositionWithAffinity({text_foo, 2}, TextAffinity::kDownstream))
          .Build(),
      SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
  UpdateAllLifecyclePhases();
  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
            FloatPoint(8.0f, 18.0f));
  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
            FloatPoint(8.0f, 28.0f));
  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
            FloatPoint(8.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
            FloatPoint(8.0f, 28.0f));
}

// crbug.com/834686
TEST_F(RenderedPositionTest, RangeBeginAtBlockEnd) {
  const SelectionInDOMTree& selection = SetSelectionTextToBody(
      "<div style='font: 10px/10px Ahem;'>"
      "<div>foo\n^</div><div>ba|r</div></div>");
  Selection().SetSelection(
      selection,
      SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
  Element* target = GetDocument().QuerySelector("div");
  target->focus();
  UpdateAllLifecyclePhases();
  const CompositedSelection& composited_selection =
      RenderedPosition::ComputeCompositedSelection(Selection());
  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
            FloatPoint(38.0f, 8.0f));
  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
            FloatPoint(38.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
            FloatPoint(28.0f, 18.0f));
  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
            FloatPoint(28.0f, 28.0f));
}

}  // namespace blink
