1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "core/dom/Range.h"
8 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
9 #include "core/dom/Element.h"
10 #include "core/dom/NodeList.h"
11 #include "core/dom/Text.h"
12 #include "core/html/HTMLBodyElement.h"
13 #include "core/html/HTMLDocument.h"
14 #include "core/html/HTMLElement.h"
15 #include "core/html/HTMLHtmlElement.h"
16 #include "platform/heap/Handle.h"
17 #include "wtf/Compiler.h"
18 #include "wtf/RefPtr.h"
19 #include "wtf/text/AtomicString.h"
20 #include <gtest/gtest.h>
24 class RangeTest
: public ::testing::Test
{
26 void SetUp() override
;
28 HTMLDocument
& document() const;
31 RefPtrWillBePersistent
<HTMLDocument
> m_document
;
34 void RangeTest::SetUp()
36 m_document
= HTMLDocument::create();
37 RefPtrWillBeRawPtr
<HTMLHtmlElement
> html
= HTMLHtmlElement::create(*m_document
);
38 html
->appendChild(HTMLBodyElement::create(*m_document
));
39 m_document
->appendChild(html
.release());
42 HTMLDocument
& RangeTest::document() const
47 TEST_F(RangeTest
, SplitTextNodeRangeWithinText
)
49 document().body()->setInnerHTML("1234", ASSERT_NO_EXCEPTION
);
50 Text
* oldText
= toText(document().body()->firstChild());
52 RefPtrWillBeRawPtr
<Range
> range04
= Range::create(document(), oldText
, 0, oldText
, 4);
53 RefPtrWillBeRawPtr
<Range
> range02
= Range::create(document(), oldText
, 0, oldText
, 2);
54 RefPtrWillBeRawPtr
<Range
> range22
= Range::create(document(), oldText
, 2, oldText
, 2);
55 RefPtrWillBeRawPtr
<Range
> range24
= Range::create(document(), oldText
, 2, oldText
, 4);
57 oldText
->splitText(2, ASSERT_NO_EXCEPTION
);
58 Text
* newText
= toText(oldText
->nextSibling());
60 EXPECT_TRUE(range04
->boundaryPointsValid());
61 EXPECT_EQ(oldText
, range04
->startContainer());
62 EXPECT_EQ(0, range04
->startOffset());
63 EXPECT_EQ(newText
, range04
->endContainer());
64 EXPECT_EQ(2, range04
->endOffset());
66 EXPECT_TRUE(range02
->boundaryPointsValid());
67 EXPECT_EQ(oldText
, range02
->startContainer());
68 EXPECT_EQ(0, range02
->startOffset());
69 EXPECT_EQ(oldText
, range02
->endContainer());
70 EXPECT_EQ(2, range02
->endOffset());
72 // Our implementation always moves the boundary point at the separation point to the end of the original text node.
73 EXPECT_TRUE(range22
->boundaryPointsValid());
74 EXPECT_EQ(oldText
, range22
->startContainer());
75 EXPECT_EQ(2, range22
->startOffset());
76 EXPECT_EQ(oldText
, range22
->endContainer());
77 EXPECT_EQ(2, range22
->endOffset());
79 EXPECT_TRUE(range24
->boundaryPointsValid());
80 EXPECT_EQ(oldText
, range24
->startContainer());
81 EXPECT_EQ(2, range24
->startOffset());
82 EXPECT_EQ(newText
, range24
->endContainer());
83 EXPECT_EQ(2, range24
->endOffset());
86 TEST_F(RangeTest
, SplitTextNodeRangeOutsideText
)
88 document().body()->setInnerHTML("<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span id=\"inner-right\">2</span>3</span>", ASSERT_NO_EXCEPTION
);
90 Element
* outer
= document().getElementById(AtomicString::fromUTF8("outer"));
91 Element
* innerLeft
= document().getElementById(AtomicString::fromUTF8("inner-left"));
92 Element
* innerRight
= document().getElementById(AtomicString::fromUTF8("inner-right"));
93 Text
* oldText
= toText(outer
->childNodes()->item(2));
95 RefPtrWillBeRawPtr
<Range
> rangeOuterOutside
= Range::create(document(), outer
, 0, outer
, 5);
96 RefPtrWillBeRawPtr
<Range
> rangeOuterInside
= Range::create(document(), outer
, 1, outer
, 4);
97 RefPtrWillBeRawPtr
<Range
> rangeOuterSurroundingText
= Range::create(document(), outer
, 2, outer
, 3);
98 RefPtrWillBeRawPtr
<Range
> rangeInnerLeft
= Range::create(document(), innerLeft
, 0, innerLeft
, 1);
99 RefPtrWillBeRawPtr
<Range
> rangeInnerRight
= Range::create(document(), innerRight
, 0, innerRight
, 1);
100 RefPtrWillBeRawPtr
<Range
> rangeFromTextToMiddleOfElement
= Range::create(document(), oldText
, 6, outer
, 3);
102 oldText
->splitText(3, ASSERT_NO_EXCEPTION
);
103 Text
* newText
= toText(oldText
->nextSibling());
105 EXPECT_TRUE(rangeOuterOutside
->boundaryPointsValid());
106 EXPECT_EQ(outer
, rangeOuterOutside
->startContainer());
107 EXPECT_EQ(0, rangeOuterOutside
->startOffset());
108 EXPECT_EQ(outer
, rangeOuterOutside
->endContainer());
109 EXPECT_EQ(6, rangeOuterOutside
->endOffset()); // Increased by 1 since a new node is inserted.
111 EXPECT_TRUE(rangeOuterInside
->boundaryPointsValid());
112 EXPECT_EQ(outer
, rangeOuterInside
->startContainer());
113 EXPECT_EQ(1, rangeOuterInside
->startOffset());
114 EXPECT_EQ(outer
, rangeOuterInside
->endContainer());
115 EXPECT_EQ(5, rangeOuterInside
->endOffset());
117 EXPECT_TRUE(rangeOuterSurroundingText
->boundaryPointsValid());
118 EXPECT_EQ(outer
, rangeOuterSurroundingText
->startContainer());
119 EXPECT_EQ(2, rangeOuterSurroundingText
->startOffset());
120 EXPECT_EQ(outer
, rangeOuterSurroundingText
->endContainer());
121 EXPECT_EQ(4, rangeOuterSurroundingText
->endOffset());
123 EXPECT_TRUE(rangeInnerLeft
->boundaryPointsValid());
124 EXPECT_EQ(innerLeft
, rangeInnerLeft
->startContainer());
125 EXPECT_EQ(0, rangeInnerLeft
->startOffset());
126 EXPECT_EQ(innerLeft
, rangeInnerLeft
->endContainer());
127 EXPECT_EQ(1, rangeInnerLeft
->endOffset());
129 EXPECT_TRUE(rangeInnerRight
->boundaryPointsValid());
130 EXPECT_EQ(innerRight
, rangeInnerRight
->startContainer());
131 EXPECT_EQ(0, rangeInnerRight
->startOffset());
132 EXPECT_EQ(innerRight
, rangeInnerRight
->endContainer());
133 EXPECT_EQ(1, rangeInnerRight
->endOffset());
135 EXPECT_TRUE(rangeFromTextToMiddleOfElement
->boundaryPointsValid());
136 EXPECT_EQ(newText
, rangeFromTextToMiddleOfElement
->startContainer());
137 EXPECT_EQ(3, rangeFromTextToMiddleOfElement
->startOffset());
138 EXPECT_EQ(outer
, rangeFromTextToMiddleOfElement
->endContainer());
139 EXPECT_EQ(4, rangeFromTextToMiddleOfElement
->endOffset());