blob: 71cb1338c28b380cf36c42a7601c48dd133d96c9 [file] [log] [blame]
// Copyright 2018 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/finder/find_buffer.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
namespace blink {
class FindBufferTest : public EditingTestBase {
protected:
PositionInFlatTree FirstPosition() {
return PositionInFlatTree::FirstPositionInNode(
*GetDocument().documentElement());
}
PositionInFlatTree PositionFromParentId(const char* id, unsigned offset) {
return PositionInFlatTree(GetElementById(id)->firstChild(), offset);
}
std::string SerializeRange(const EphemeralRangeInFlatTree& range) {
return GetSelectionTextInFlatTreeFromBody(
SelectionInFlatTree::Builder().SetAsForwardSelection(range).Build());
}
};
TEST_F(FindBufferTest, FindInline) {
SetBodyContent(
"<div id='container'>a<span id='span'>b</span><b id='b'>c</b><div "
"id='none' style='display:none'>d</div><div id='inline-div' "
"style='display: inline;'>e</div></div>");
FindBuffer buffer(FirstPosition());
EXPECT_TRUE(buffer.PositionAfterBlock().IsNull());
std::unique_ptr<FindBuffer::Results> results =
buffer.FindMatches("abce", *mojom::blink::FindOptions::New());
EXPECT_EQ(1u, results->CountForTesting());
FindBuffer::BufferMatchResult match = *results->begin();
EXPECT_EQ(0u, match.start);
EXPECT_EQ(4u, match.length);
EXPECT_EQ(
EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("inline-div", 1)),
buffer.RangeFromBufferIndex(match.start, match.start + match.length));
}
TEST_F(FindBufferTest, RangeFromBufferIndex) {
SetBodyContent(
"<div id='container'>a <span id='span'> b</span><b id='b'>cc</b><div "
"id='none' style='display:none'>d</div><div id='inline-div' "
"style='display: inline;'>e</div></div>");
FindBuffer buffer(FirstPosition());
// Range for "a"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("container", 1)),
buffer.RangeFromBufferIndex(0, 1));
EXPECT_EQ(
"<div id=\"container\">^a| <span id=\"span\"> b</span><b "
"id=\"b\">cc</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 1)));
// Range for "a "
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("container", 2)),
buffer.RangeFromBufferIndex(0, 2));
EXPECT_EQ(
"<div id=\"container\">^a |<span id=\"span\"> b</span><b "
"id=\"b\">cc</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 2)));
// Range for "a b"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("span", 2)),
buffer.RangeFromBufferIndex(0, 3));
EXPECT_EQ(
"<div id=\"container\">^a <span id=\"span\"> b|</span><b "
"id=\"b\">cc</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 3)));
// Range for "a bc"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("b", 1)),
buffer.RangeFromBufferIndex(0, 4));
EXPECT_EQ(
"<div id=\"container\">^a <span id=\"span\"> b</span><b "
"id=\"b\">c|c</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 4)));
// Range for "a bcc"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("b", 2)),
buffer.RangeFromBufferIndex(0, 5));
EXPECT_EQ(
"<div id=\"container\">^a <span id=\"span\"> b</span><b "
"id=\"b\">cc|</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 5)));
// Range for "a bcce"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("inline-div", 1)),
buffer.RangeFromBufferIndex(0, 6));
EXPECT_EQ(
"<div id=\"container\">^a <span id=\"span\"> b</span><b "
"id=\"b\">cc</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e|</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(0, 6)));
// Range for " b"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 1),
PositionFromParentId("span", 2)),
buffer.RangeFromBufferIndex(1, 3));
EXPECT_EQ(
"<div id=\"container\">a^ <span id=\"span\"> b|</span><b "
"id=\"b\">cc</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(1, 3)));
// Range for " bc"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 1),
PositionFromParentId("b", 1)),
buffer.RangeFromBufferIndex(1, 4));
EXPECT_EQ(
"<div id=\"container\">a^ <span id=\"span\"> b</span><b "
"id=\"b\">c|c</b><div id=\"none\" style=\"display:none\">d</div><div "
"id=\"inline-div\" style=\"display: inline;\">e</div></div>",
SerializeRange(buffer.RangeFromBufferIndex(1, 4)));
}
class FindBufferBlockTest : public FindBufferTest,
public testing::WithParamInterface<std::string> {};
INSTANTIATE_TEST_CASE_P(Blocks,
FindBufferBlockTest,
testing::Values("block",
"table",
"flow-root",
"grid",
"flex",
"list-item"));
TEST_P(FindBufferBlockTest, FindBlock) {
SetBodyContent("text<div id='block' style='display: " + GetParam() +
";'>block</div><span id='span'>span</span>");
FindBuffer text_buffer(FirstPosition());
EXPECT_EQ(GetElementById("block"),
*text_buffer.PositionAfterBlock().ComputeContainerNode());
EXPECT_EQ(1u,
text_buffer.FindMatches("text", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, text_buffer
.FindMatches("textblock", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(
0u,
text_buffer.FindMatches("text block", *mojom::blink::FindOptions::New())
->CountForTesting());
FindBuffer block_buffer(text_buffer.PositionAfterBlock());
EXPECT_EQ(GetElementById("span"),
*block_buffer.PositionAfterBlock().ComputeContainerNode());
EXPECT_EQ(
1u, block_buffer.FindMatches("block", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, block_buffer
.FindMatches("textblock", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(
0u,
block_buffer.FindMatches("text block", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, block_buffer
.FindMatches("blockspan", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(
0u,
block_buffer.FindMatches("block span", *mojom::blink::FindOptions::New())
->CountForTesting());
FindBuffer span_buffer(block_buffer.PositionAfterBlock());
EXPECT_TRUE(span_buffer.PositionAfterBlock().IsNull());
EXPECT_EQ(1u,
span_buffer.FindMatches("span", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, span_buffer
.FindMatches("blockspan", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(
0u,
span_buffer.FindMatches("block span", *mojom::blink::FindOptions::New())
->CountForTesting());
}
class FindBufferSeparatorTest
: public FindBufferTest,
public testing::WithParamInterface<std::string> {};
INSTANTIATE_TEST_CASE_P(Separators,
FindBufferSeparatorTest,
testing::Values("br",
"hr",
"legend",
"meter",
"object",
"progress",
"select",
"video"));
TEST_P(FindBufferSeparatorTest, FindSeparatedElements) {
SetBodyContent("a<" + GetParam() + ">a</" + GetParam() + ">a");
FindBuffer buffer(FirstPosition());
EXPECT_EQ(0u, buffer.FindMatches("aa", *mojom::blink::FindOptions::New())
->CountForTesting());
}
TEST_F(FindBufferTest, WhiteSpaceCollapsingPreWrap) {
SetBodyContent(
" a \n b <b> c </b> d <span style='white-space: pre-wrap'> e "
"</span>");
FindBuffer buffer(FirstPosition());
EXPECT_EQ(
1u, buffer.FindMatches("a b c d e ", *mojom::blink::FindOptions::New())
->CountForTesting());
};
TEST_F(FindBufferTest, WhiteSpaceCollapsingPre) {
SetBodyContent("<div style='white-space: pre;'>a \n b</div>");
FindBuffer buffer(FirstPosition());
EXPECT_EQ(1u, buffer.FindMatches("a", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(1u, buffer.FindMatches("b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("ab", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a\n b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a \nb", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a \n b", *mojom::blink::FindOptions::New())
->CountForTesting());
}
TEST_F(FindBufferTest, WhiteSpaceCollapsingPreLine) {
SetBodyContent("<div style='white-space: pre-line;'>a \n b</div>");
FindBuffer buffer(FirstPosition());
EXPECT_EQ(1u, buffer.FindMatches("a", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(1u, buffer.FindMatches("b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("ab", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a \n b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a\n b", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a \nb", *mojom::blink::FindOptions::New())
->CountForTesting());
EXPECT_EQ(0u, buffer.FindMatches("a\nb", *mojom::blink::FindOptions::New())
->CountForTesting());
}
TEST_F(FindBufferTest, BidiTest) {
SetBodyContent("<bdo dir=rtl id=bdo>foo<span>bar</span></bdo>");
FindBuffer buffer(FirstPosition());
EXPECT_EQ(1u, buffer.FindMatches("foobar", *mojom::blink::FindOptions::New())
->CountForTesting());
}
} // namespace blink