summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp148
1 files changed, 136 insertions, 12 deletions
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp b/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
index 0692414f080..63a7f403f98 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
@@ -62,11 +62,14 @@ protected:
HTMLDocument& document() const;
Vector<String> iterate(TextIteratorBehavior = TextIteratorDefaultBehavior);
+ Vector<String> iteratePartial(const Position& start, const Position& end, TextIteratorBehavior = TextIteratorDefaultBehavior);
void setBodyInnerHTML(const char*);
- PassRefPtr<Range> getBodyRange() const;
+ PassRefPtrWillBeRawPtr<Range> getBodyRange() const;
private:
+ Vector<String> iterateWithIterator(TextIterator&);
+
OwnPtr<DummyPageHolder> m_dummyPageHolder;
HTMLDocument* m_document;
@@ -82,13 +85,24 @@ void TextIteratorTest::SetUp()
Vector<String> TextIteratorTest::iterate(TextIteratorBehavior iteratorBehavior)
{
document().view()->updateLayoutAndStyleIfNeededRecursive(); // Force renderers to be created; TextIterator needs them.
+ RefPtrWillBeRawPtr<Range> range = getBodyRange();
+ TextIterator iterator(range.get(), iteratorBehavior);
+ return iterateWithIterator(iterator);
+}
+
+Vector<String> TextIteratorTest::iteratePartial(const Position& start, const Position& end, TextIteratorBehavior iteratorBehavior)
+{
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+ TextIterator iterator(start, end, iteratorBehavior);
+ return iterateWithIterator(iterator);
+}
- RefPtr<Range> range = getBodyRange();
- TextIterator textIterator(range.get(), iteratorBehavior);
+Vector<String> TextIteratorTest::iterateWithIterator(TextIterator& iterator)
+{
Vector<String> textChunks;
- while (!textIterator.atEnd()) {
- textChunks.append(textIterator.substring(0, textIterator.length()));
- textIterator.advance();
+ while (!iterator.atEnd()) {
+ textChunks.append(iterator.substring(0, iterator.length()));
+ iterator.advance();
}
return textChunks;
}
@@ -103,9 +117,9 @@ void TextIteratorTest::setBodyInnerHTML(const char* bodyContent)
document().body()->setInnerHTML(String::fromUTF8(bodyContent), ASSERT_NO_EXCEPTION);
}
-PassRefPtr<Range> TextIteratorTest::getBodyRange() const
+PassRefPtrWillBeRawPtr<Range> TextIteratorTest::getBodyRange() const
{
- RefPtr<Range> range(Range::create(document()));
+ RefPtrWillBeRawPtr<Range> range(Range::create(document()));
range->selectNode(document().body());
return range.release();
}
@@ -117,9 +131,9 @@ Vector<String> createVectorString(const char* const* rawStrings, size_t size)
return result;
}
-PassRefPtr<ShadowRoot> createShadowRootForElementWithIDAndSetInnerHTML(TreeScope& scope, const char* hostElementID, const char* shadowRootContent)
+PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRootForElementWithIDAndSetInnerHTML(TreeScope& scope, const char* hostElementID, const char* shadowRootContent)
{
- RefPtr<ShadowRoot> shadowRoot = scope.getElementById(AtomicString::fromUTF8(hostElementID))->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = scope.getElementById(AtomicString::fromUTF8(hostElementID))->createShadowRoot(ASSERT_NO_EXCEPTION);
shadowRoot->setInnerHTML(String::fromUTF8(shadowRootContent), ASSERT_NO_EXCEPTION);
return shadowRoot.release();
}
@@ -251,7 +265,7 @@ TEST_F(TextIteratorTest, NotEnteringShadowTreeWithNestedShadowTrees)
Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
setBodyInnerHTML(bodyContent);
- RefPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
createShadowRootForElementWithIDAndSetInnerHTML(*shadowRoot1, "host-in-shadow", shadowContent2);
EXPECT_EQ(expectedTextChunks, iterate());
@@ -324,7 +338,7 @@ TEST_F(TextIteratorTest, EnteringShadowTreeWithNestedShadowTreesWithOption)
Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
setBodyInnerHTML(bodyContent);
- RefPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
createShadowRootForElementWithIDAndSetInnerHTML(*shadowRoot1, "host-in-shadow", shadowContent2);
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
@@ -351,6 +365,47 @@ TEST_F(TextIteratorTest, EnteringShadowTreeWithContentInsertionPointWithOption)
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
}
+TEST_F(TextIteratorTest, StartingAtNodeInShadowRoot)
+{
+ static const char* bodyContent = "<div id=\"outer\">Hello, <span id=\"host\">text</span> iterator.</div>";
+ static const char* shadowContent = "<span><content>content</content> shadow</span>";
+ static const char* expectedTextChunksRawString[] = {
+ " shadow",
+ "text",
+ " iterator."
+ };
+ Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
+
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host", shadowContent);
+ Node* outerDiv = document().getElementById("outer");
+ Node* spanInShadow = shadowRoot->firstChild();
+ Position start(spanInShadow, Position::PositionIsBeforeChildren);
+ Position end(outerDiv, Position::PositionIsAfterChildren);
+
+ EXPECT_EQ(expectedTextChunks, iteratePartial(start, end, TextIteratorEntersAuthorShadowRoots));
+}
+
+TEST_F(TextIteratorTest, FinishingAtNodeInShadowRoot)
+{
+ static const char* bodyContent = "<div id=\"outer\">Hello, <span id=\"host\">text</span> iterator.</div>";
+ static const char* shadowContent = "<span><content>content</content> shadow</span>";
+ static const char* expectedTextChunksRawString[] = {
+ "Hello, ",
+ " shadow"
+ };
+ Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
+
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host", shadowContent);
+ Node* outerDiv = document().getElementById("outer");
+ Node* spanInShadow = shadowRoot->firstChild();
+ Position start(outerDiv, Position::PositionIsBeforeChildren);
+ Position end(spanInShadow, Position::PositionIsAfterChildren);
+
+ EXPECT_EQ(expectedTextChunks, iteratePartial(start, end, TextIteratorEntersAuthorShadowRoots));
+}
+
TEST_F(TextIteratorTest, FullyClipsContents)
{
static const char* bodyContent =
@@ -428,4 +483,73 @@ TEST_F(TextIteratorTest, IgnoresContainersClipDistributed)
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
}
+TEST_F(TextIteratorTest, FindPlainTextInvalidTarget)
+{
+ static const char* bodyContent = "<div>foo bar test</div>";
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<Range> range = getBodyRange();
+
+ RefPtrWillBeRawPtr<Range> expectedRange = range->cloneRange();
+ expectedRange->collapse(false);
+
+ // A lone lead surrogate (0xDA0A) example taken from fuzz-58.
+ static const UChar invalid1[] = {
+ 0x1461u, 0x2130u, 0x129bu, 0xd711u, 0xd6feu, 0xccadu, 0x7064u,
+ 0xd6a0u, 0x4e3bu, 0x03abu, 0x17dcu, 0xb8b7u, 0xbf55u, 0xfca0u,
+ 0x07fau, 0x0427u, 0xda0au, 0
+ };
+
+ // A lone trailing surrogate (U+DC01).
+ static const UChar invalid2[] = {
+ 0x1461u, 0x2130u, 0x129bu, 0xdc01u, 0xd6feu, 0xccadu, 0
+ };
+ // A trailing surrogate followed by a lead surrogate (U+DC03 U+D901).
+ static const UChar invalid3[] = {
+ 0xd800u, 0xdc00u, 0x0061u, 0xdc03u, 0xd901u, 0xccadu, 0
+ };
+
+ static const UChar* invalidUStrings[] = { invalid1, invalid2, invalid3 };
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(invalidUStrings); ++i) {
+ String invalidTarget(invalidUStrings[i]);
+ RefPtrWillBeRawPtr<Range> actualRange = findPlainText(range.get(), invalidTarget, 0);
+ EXPECT_TRUE(areRangesEqual(expectedRange.get(), actualRange.get()));
+ }
+}
+
+TEST_F(TextIteratorTest, EmitsReplacementCharForInput)
+{
+ static const char* bodyContent =
+ "<div contenteditable=\"true\">"
+ "Before"
+ "<img src=\"foo.png\">"
+ "After"
+ "</div>";
+ // "Before".
+ static const UChar expectedRawString1[] = { 0x42, 0x65, 0x66, 0x6F, 0x72, 0x65, 0 };
+ // Object replacement char.
+ static const UChar expectedRawString2[] = { 0xFFFC, 0 };
+ // "After".
+ static const UChar expectedRawString3[] = { 0x41, 0x66, 0x74, 0x65, 0x72, 0 };
+ static const UChar* expectedRawStrings[] = { expectedRawString1, expectedRawString2, expectedRawString3 };
+ Vector<String> expectedTextChunks;
+ expectedTextChunks.append(expectedRawStrings, WTF_ARRAY_LENGTH(expectedRawStrings));
+
+ setBodyInnerHTML(bodyContent);
+ EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEmitsObjectReplacementCharacter));
+}
+
+TEST_F(TextIteratorTest, RangeLengthWithReplacedElements)
+{
+ static const char* bodyContent =
+ "<div id=\"div\" contenteditable=\"true\">1<img src=\"foo.png\">3</div>";
+ setBodyInnerHTML(bodyContent);
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ Node* divNode = document().getElementById("div");
+ RefPtrWillBeRawPtr<Range> range = Range::create(document(), divNode, 0, divNode, 3);
+
+ EXPECT_EQ(3, TextIterator::rangeLength(range.get()));
+}
+
}