TEST_F(EditingUtilitiesTest, isFirstPositionAfterTable)
{
    const char* bodyContent = "<div contenteditable id=host><table id=table><tr><td>1</td></tr></table><b id=two>22</b></div>";
    const char* shadowContent = "<content select=#two></content><content select=#table></content>";
    setBodyContent(bodyContent);
    setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Node* host = document().getElementById("host");
    Node* table = document().getElementById("table");

    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(Position::afterNode(table))));
    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(PositionInComposedTree::afterNode(table))));

    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(Position::lastPositionInNode(table))));
    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(PositionInComposedTree::lastPositionInNode(table))));

    EXPECT_EQ(nullptr, isFirstPositionAfterTable(createVisiblePosition(Position(host, 2))));
    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(PositionInComposedTree(host, 2))));

    EXPECT_EQ(nullptr, isFirstPositionAfterTable(createVisiblePosition(Position::afterNode(host))));
    EXPECT_EQ(nullptr, isFirstPositionAfterTable(createVisiblePosition(PositionInComposedTree::afterNode(host))));

    EXPECT_EQ(nullptr, isFirstPositionAfterTable(createVisiblePosition(Position::lastPositionInNode(host))));
    EXPECT_EQ(table, isFirstPositionAfterTable(createVisiblePosition(PositionInComposedTree::lastPositionInNode(host))));
}
TEST_F(SpellCheckerTest, AdvanceToNextMisspellingWithEmptyInputNoCrash)
{
    setBodyContent("<input placeholder='placeholder'>abc");
    updateLayoutAndStyleForPainting();
    RawPtr<Element> input = document().querySelector("input", ASSERT_NO_EXCEPTION);
    input->focus();
    document().settings()->setUnifiedTextCheckerEnabled(true);
    // Do not crash in AdvanceToNextMisspelling command.
    EXPECT_TRUE(document().frame()->editor().executeCommand("AdvanceToNextMisspelling"));
    document().settings()->setUnifiedTextCheckerEnabled(false);
}
TEST_F(EditingUtilitiesTest, directionOfEnclosingBlock)
{
    const char* bodyContent = "<p id='host'><b id='one'></b><b id='two'>22</b></p>";
    const char* shadowContent = "<content select=#two></content><p dir=rtl><content select=#one></content><p>";
    setBodyContent(bodyContent);
    setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Node* one = document().getElementById("one");

    EXPECT_EQ(LTR, directionOfEnclosingBlock(Position(one, 0)));
    EXPECT_EQ(RTL, directionOfEnclosingBlock(PositionInComposedTree(one, 0)));
}
TEST_F(NodeTest, canStartSelectionWithShadowDOM)
{
    const char* bodyContent = "<div id=host><span id=one>one</span></div>";
    const char* shadowContent = "<a href='http://www.msn.com'><content></content></a>";
    setBodyContent(bodyContent);
    setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Node* one = document().getElementById("one");

    EXPECT_FALSE(one->canStartSelection());
    EXPECT_FALSE(one->firstChild()->canStartSelection());
}
TEST_F(NodeTest, canStartSelection)
{
    const char* bodyContent = "<a id=one href='http://www.msn.com'>one</a><b id=two>two</b>";
    setBodyContent(bodyContent);
    updateLayoutAndStyleForPainting();
    Node* one = document().getElementById("one");
    Node* two = document().getElementById("two");

    EXPECT_FALSE(one->canStartSelection());
    EXPECT_FALSE(one->firstChild()->canStartSelection());
    EXPECT_TRUE(two->canStartSelection());
    EXPECT_TRUE(two->firstChild()->canStartSelection());
}
TEST_F(EditingUtilitiesTest, enclosingNodeOfType)
{
    const char* bodyContent = "<p id='host'><b id='one'>11</b></p>";
    const char* shadowContent = "<content select=#two></content><div id='three'><content select=#one></div></content>";
    setBodyContent(bodyContent);
    RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Node* host = document().getElementById("host");
    Node* one = document().getElementById("one");
    Node* three = shadowRoot->getElementById("three");

    EXPECT_EQ(host, enclosingNodeOfType(Position(one, 0), isEnclosingBlock));
    EXPECT_EQ(three, enclosingNodeOfType(PositionInComposedTree(one, 0), isEnclosingBlock));
}
TEST_F(EditingUtilitiesTest, NextVisuallyDistinctCandidate)
{
    const char* bodyContent = "<p id='host'>00<b id='one'>11</b><b id='two'>22</b><b id='three'>33</b></p>";
    const char* shadowContent = "<content select=#two></content><content select=#one></content><content select=#three></content>";
    setBodyContent(bodyContent);
    setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Node* one = document().getElementById("one");
    Node* two = document().getElementById("two");
    Node* three = document().getElementById("three");

    EXPECT_EQ(Position(two->firstChild(), 1), nextVisuallyDistinctCandidate(Position(one, 1)));
    EXPECT_EQ(PositionInComposedTree(three->firstChild(), 1), nextVisuallyDistinctCandidate(PositionInComposedTree(one, 1)));
}
TEST_F(SimplifiedBackwardsTextIteratorTest, SubrangeWithReplacedElements)
{
    static const char* bodyContent = "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>";
    const char* shadowContent = "three <content select=#two></content> <content select=#one></content> zero";
    setBodyContent(bodyContent);
    setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();

    Element* host = document().getElementById("host");

    // We should not apply DOM tree version to containing shadow tree in
    // general. To record current behavior, we have this test. even if it
    // isn't intuitive.
    EXPECT_EQ("onetwo", extractString<EditingStrategy>(*host));
    EXPECT_EQ("three two one zero", extractString<EditingInComposedTreeStrategy>(*host));
}
TEST_F(EditingUtilitiesTest, firstEditablePositionAfterPositionInRoot)
{
    const char* bodyContent = "<p id='host' contenteditable><b id='one'>1</b><b id='two'>22</b></p>";
    const char* shadowContent = "<content select=#two></content><content select=#one></content><b id='three'>333</b>";
    setBodyContent(bodyContent);
    RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = setShadowContent(shadowContent, "host");
    updateLayoutAndStyleForPainting();
    Element* host = document().getElementById("host");
    Node* one = document().getElementById("one");
    Node* two = document().getElementById("two");
    Node* three = shadowRoot->getElementById("three");

    EXPECT_EQ(Position(one, 0), firstEditablePositionAfterPositionInRoot(Position(one, 0), *host));
    EXPECT_EQ(Position(one->firstChild(), 0), firstEditableVisiblePositionAfterPositionInRoot(Position(one, 0), *host).deepEquivalent());

    EXPECT_EQ(PositionInComposedTree(one, 0), firstEditablePositionAfterPositionInRoot(PositionInComposedTree(one, 0), *host));
    EXPECT_EQ(PositionInComposedTree(two->firstChild(), 2), firstEditableVisiblePositionAfterPositionInRoot(PositionInComposedTree(one, 0), *host).deepEquivalent());

    EXPECT_EQ(Position::firstPositionInNode(host), firstEditablePositionAfterPositionInRoot(Position(three, 0), *host));
    EXPECT_EQ(Position(one->firstChild(), 0), firstEditableVisiblePositionAfterPositionInRoot(Position(three, 0), *host).deepEquivalent());
    EXPECT_EQ(PositionInComposedTree::afterNode(host), firstEditablePositionAfterPositionInRoot(PositionInComposedTree(three, 0), *host));
    EXPECT_EQ(PositionInComposedTree::lastPositionInNode(host), firstEditableVisiblePositionAfterPositionInRoot(PositionInComposedTree(three, 0), *host).deepEquivalent());
}
TEST_F(VisibleUnitsTest, inSameLine)
{
    const char* bodyContent = "<p id='host'>00<b id='one'>11</b><b id='two'>22</b>33</p>";
    const char* shadowContent = "<div><span id='s4'>44</span><content select=#two></content><br><span id='s5'>55</span><br><content select=#one></content><span id='s6'>66</span></div>";
    setBodyContent(bodyContent);
    RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = setShadowContent(shadowContent);
    updateLayoutAndStyleForPainting();

    RefPtrWillBeRawPtr<Element> body = document().body();
    RefPtrWillBeRawPtr<Element> one = body->querySelector("#one", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> two = body->querySelector("#two", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> four = shadowRoot->querySelector("#s4", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> five = shadowRoot->querySelector("#s5", ASSERT_NO_EXCEPTION);

    EXPECT_TRUE(inSameLine(positionWithAffinityInDOMTree(*one, 0), positionWithAffinityInDOMTree(*two, 0)));
    EXPECT_TRUE(inSameLine(positionWithAffinityInDOMTree(*one->firstChild(), 0), positionWithAffinityInDOMTree(*two->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInDOMTree(*one->firstChild(), 0), positionWithAffinityInDOMTree(*five->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInDOMTree(*two->firstChild(), 0), positionWithAffinityInDOMTree(*four->firstChild(), 0)));

    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one, 0), positionWithAffinityInComposedTree(*two, 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one->firstChild(), 0), positionWithAffinityInComposedTree(*two->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one->firstChild(), 0), positionWithAffinityInComposedTree(*five->firstChild(), 0)));
    EXPECT_TRUE(inSameLine(positionWithAffinityInComposedTree(*two->firstChild(), 0), positionWithAffinityInComposedTree(*four->firstChild(), 0)));
}