// Copyright 2015 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/visible_units.h"

#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"

namespace blink {

class VisibleUnitsParagraphTest : public EditingTestBase {
 protected:
  static PositionWithAffinity PositionWithAffinityInDOMTree(
      Node& anchor,
      int offset,
      TextAffinity affinity = TextAffinity::kDownstream) {
    return PositionWithAffinity(CanonicalPositionOf(Position(&anchor, offset)),
                                affinity);
  }

  static VisiblePosition CreateVisiblePositionInDOMTree(
      Node& anchor,
      int offset,
      TextAffinity affinity = TextAffinity::kDownstream) {
    return CreateVisiblePosition(Position(&anchor, offset), affinity);
  }

  static PositionInFlatTreeWithAffinity PositionWithAffinityInFlatTree(
      Node& anchor,
      int offset,
      TextAffinity affinity = TextAffinity::kDownstream) {
    return PositionInFlatTreeWithAffinity(
        CanonicalPositionOf(PositionInFlatTree(&anchor, offset)), affinity);
  }

  static VisiblePositionInFlatTree CreateVisiblePositionInFlatTree(
      Node& anchor,
      int offset,
      TextAffinity affinity = TextAffinity::kDownstream) {
    return CreateVisiblePosition(PositionInFlatTree(&anchor, offset), affinity);
  }
};

TEST_F(VisibleUnitsParagraphTest, endOfParagraphFirstLetter) {
  SetBodyContent(
      "<style>div::first-letter { color: red }</style><div "
      "id=sample>1ab\nde</div>");

  Node* sample = GetDocument().getElementById("sample");
  Node* text = sample->firstChild();

  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 0))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 1))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 2))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 3))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 4))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 5))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 6))
                .DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, endOfParagraphFirstLetterPre) {
  SetBodyContent(
      "<style>pre::first-letter { color: red }</style><pre "
      "id=sample>1ab\nde</pre>");

  Node* sample = GetDocument().getElementById("sample");
  Node* text = sample->firstChild();

  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 0))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 1))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 2))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 3))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 4))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 5))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 6))
                .DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, endOfParagraphShadow) {
  const char* body_content =
      "<span id=host><b slot='#one' id=one>1</b><b slot='#two' "
      "id=two>22</b></span><b id=three>333</b>";
  const char* shadow_content =
      "<p><slot name=#two></slot></p><p><slot name=#one></slot></p>";
  SetBodyContent(body_content);
  SetShadowContent(shadow_content, "host");

  Element* one = GetDocument().getElementById("one");
  Element* two = GetDocument().getElementById("two");
  Element* three = GetDocument().getElementById("three");

  EXPECT_EQ(
      Position(three->firstChild(), 3),
      EndOfParagraph(CreateVisiblePositionInDOMTree(*one->firstChild(), 1))
          .DeepEquivalent());
  EXPECT_EQ(
      PositionInFlatTree(one->firstChild(), 1),
      EndOfParagraph(CreateVisiblePositionInFlatTree(*one->firstChild(), 1))
          .DeepEquivalent());

  EXPECT_EQ(
      Position(three->firstChild(), 3),
      EndOfParagraph(CreateVisiblePositionInDOMTree(*two->firstChild(), 2))
          .DeepEquivalent());
  EXPECT_EQ(
      PositionInFlatTree(two->firstChild(), 2),
      EndOfParagraph(CreateVisiblePositionInFlatTree(*two->firstChild(), 2))
          .DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, endOfParagraphSimple) {
  SetBodyContent("<div id=sample>1ab\nde</div>");

  Node* sample = GetDocument().getElementById("sample");
  Node* text = sample->firstChild();

  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 0))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 1))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 2))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 3))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 4))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 5))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 6))
                .DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, endOfParagraphSimplePre) {
  SetBodyContent("<pre id=sample>1ab\nde</pre>");

  Node* sample = GetDocument().getElementById("sample");
  Node* text = sample->firstChild();

  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 0))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 1))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 2))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 3),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 3))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 4))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 5))
                .DeepEquivalent());
  EXPECT_EQ(Position(text, 6),
            EndOfParagraph(CreateVisiblePositionInDOMTree(*text, 6))
                .DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, isEndOfParagraph) {
  const char* body_content =
      "<span id=host><b slot='#one' id=one>1</b><b slot='#two' "
      "id=two>22</b></span><b id=three>333</b>";
  const char* shadow_content =
      "<p><slot name=#two></slot></p><p><slot name=#one></slot></p>";
  SetBodyContent(body_content);
  SetShadowContent(shadow_content, "host");

  Node* one = GetDocument().getElementById("one")->firstChild();
  Node* two = GetDocument().getElementById("two")->firstChild();
  Node* three = GetDocument().getElementById("three")->firstChild();

  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInDOMTree(*one, 0)));
  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInFlatTree(*one, 0)));

  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInDOMTree(*one, 1)));
  EXPECT_TRUE(IsEndOfParagraph(CreateVisiblePositionInFlatTree(*one, 1)));

  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInDOMTree(*two, 2)));
  EXPECT_TRUE(IsEndOfParagraph(CreateVisiblePositionInFlatTree(*two, 2)));

  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInDOMTree(*three, 0)));
  EXPECT_FALSE(IsEndOfParagraph(CreateVisiblePositionInFlatTree(*three, 0)));

  EXPECT_TRUE(IsEndOfParagraph(CreateVisiblePositionInDOMTree(*three, 3)));
  EXPECT_TRUE(IsEndOfParagraph(CreateVisiblePositionInFlatTree(*three, 3)));
}

TEST_F(VisibleUnitsParagraphTest, isStartOfParagraph) {
  const char* body_content =
      "<b id=zero>0</b><span id=host><b slot='#one' id=one>1</b><b slot='#two' "
      "id=two>22</b></span><b id=three>333</b>";
  const char* shadow_content =
      "<p><slot name=#two></slot></p><p><slot name=#one></slot></p>";
  SetBodyContent(body_content);
  SetShadowContent(shadow_content, "host");

  Node* zero = GetDocument().getElementById("zero")->firstChild();
  Node* one = GetDocument().getElementById("one")->firstChild();
  Node* two = GetDocument().getElementById("two")->firstChild();
  Node* three = GetDocument().getElementById("three")->firstChild();

  EXPECT_TRUE(IsStartOfParagraph(CreateVisiblePositionInDOMTree(*zero, 0)));
  EXPECT_TRUE(IsStartOfParagraph(CreateVisiblePositionInFlatTree(*zero, 0)));

  EXPECT_FALSE(IsStartOfParagraph(CreateVisiblePositionInDOMTree(*one, 0)));
  EXPECT_TRUE(IsStartOfParagraph(CreateVisiblePositionInFlatTree(*one, 0)));

  EXPECT_FALSE(IsStartOfParagraph(CreateVisiblePositionInDOMTree(*one, 1)));
  EXPECT_FALSE(IsStartOfParagraph(CreateVisiblePositionInFlatTree(*one, 1)));

  EXPECT_FALSE(IsStartOfParagraph(CreateVisiblePositionInDOMTree(*two, 0)));
  EXPECT_TRUE(IsStartOfParagraph(CreateVisiblePositionInFlatTree(*two, 0)));

  EXPECT_FALSE(IsStartOfParagraph(CreateVisiblePositionInDOMTree(*three, 0)));
  EXPECT_TRUE(IsStartOfParagraph(CreateVisiblePositionInFlatTree(*three, 0)));
}

TEST_F(VisibleUnitsParagraphTest,
       endOfParagraphWithDifferentUpAndDownVisiblePositions) {
  InsertStyleElement("span, div { display: inline-block; width: 50vw; }");
  SetBodyContent("x<span></span><div></div>");

  const Position& text_end =
      Position::LastPositionInNode(*GetDocument().body()->firstChild());
  const Position& before_div =
      Position::BeforeNode(*GetDocument().QuerySelector("div"));
  const VisiblePosition& upstream =
      CreateVisiblePosition(before_div, TextAffinity::kUpstream);
  const VisiblePosition& downstream =
      CreateVisiblePosition(before_div, TextAffinity::kDownstream);
  EXPECT_LT(upstream.DeepEquivalent(), downstream.DeepEquivalent());
  EXPECT_EQ(text_end, upstream.DeepEquivalent());
  EXPECT_EQ(before_div, downstream.DeepEquivalent());

  // The end of paragraph of a position shouldn't precede it (bug 1179113).
  const VisiblePosition& end_of_paragraph = EndOfParagraph(downstream);
  EXPECT_LE(downstream.DeepEquivalent(), end_of_paragraph.DeepEquivalent());

  // In in this case they are equal.
  EXPECT_EQ(downstream.DeepEquivalent(), end_of_paragraph.DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, endOfParagraphCannotBeBeforePosition) {
  SetBodyContent(
      "<span contenteditable>x<br contenteditable=false>"
      "<br contenteditable=false></span>");
  Element* span = GetDocument().QuerySelector("span");
  const Position& p1 = Position(span, 2);
  const Position& p2 = Position::LastPositionInNode(*span);
  const Position& p3 = Position::AfterNode(*span);
  const VisiblePosition& vp1 = CreateVisiblePosition(p1);
  const VisiblePosition& vp2 = CreateVisiblePosition(p2);
  const VisiblePosition& vp3 = CreateVisiblePosition(p3);

  // The anchor should still be the span after the VisiblePosition
  // normalization, or the test would become useless.
  EXPECT_EQ(p1, vp1.DeepEquivalent());
  EXPECT_EQ(p2, vp2.DeepEquivalent());
  EXPECT_EQ(vp2.DeepEquivalent(), vp3.DeepEquivalent());

  // No need to test vp3 since it's equal to vp2.
  const VisiblePosition& end1 = EndOfParagraph(vp1);
  const VisiblePosition& end2 = EndOfParagraph(vp2);

  // EndOfParagraph() iterates nodes starting from the span, and "x"@1 would be
  // a suitable candidate. But it's skipped because it precedes the positions.
  EXPECT_LE(vp1.DeepEquivalent(), end1.DeepEquivalent());
  EXPECT_LE(vp2.DeepEquivalent(), end2.DeepEquivalent());

  // Test the actual values.
  EXPECT_EQ(p1, end1.DeepEquivalent());
  EXPECT_EQ(p2, end2.DeepEquivalent());
}

TEST_F(VisibleUnitsParagraphTest, startOfParagraphCannotBeAfterPosition) {
  SetBodyContent(
      "<span contenteditable><br contenteditable=false>"
      "<br contenteditable=false>x</span>");
  Element* span = GetDocument().QuerySelector("span");
  const Position& p1 = Position(span, 1);
  const Position& p2 = Position::FirstPositionInNode(*span);
  const Position& p3 = Position::BeforeNode(*span);
  const VisiblePosition& vp1 = CreateVisiblePosition(p1);
  const VisiblePosition& vp2 = CreateVisiblePosition(p2);
  const VisiblePosition& vp3 = CreateVisiblePosition(p3);

  // The anchor should still be the span after the VisiblePosition
  // normalization, or the test would become useless.
  EXPECT_EQ(p1, vp1.DeepEquivalent());
  EXPECT_EQ(p2, vp2.DeepEquivalent());
  EXPECT_EQ(vp2.DeepEquivalent(), vp3.DeepEquivalent());

  // No need to test vp3 since it's equal to vp2.
  const VisiblePosition& start1 = StartOfParagraph(vp1);
  const VisiblePosition& start2 = StartOfParagraph(vp2);

  // StartOfParagraph() iterates nodes in post order starting from the span, and
  // "x"@0 would be a suitable candidate. But it's skipped because it's after
  // the positions.
  EXPECT_LE(start1.DeepEquivalent(), vp1.DeepEquivalent());
  EXPECT_LE(start2.DeepEquivalent(), vp2.DeepEquivalent());

  // Test the actual values.
  EXPECT_EQ(p1, start1.DeepEquivalent());
  EXPECT_EQ(p2, start2.DeepEquivalent());
}

}  // namespace blink
