OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/editing/EphemeralRange.h" | 5 #include "core/editing/EphemeralRange.h" |
6 | 6 |
7 #include "core/dom/Range.h" | 7 #include "core/dom/Range.h" |
8 #include "core/editing/EditingTestBase.h" | 8 #include "core/editing/EditingTestBase.h" |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 Range* EphemeralRangeTest::getBodyRange() const { | 45 Range* EphemeralRangeTest::getBodyRange() const { |
46 Range* range = Range::create(document()); | 46 Range* range = Range::create(document()); |
47 range->selectNode(document().body()); | 47 range->selectNode(document().body()); |
48 return range; | 48 return range; |
49 } | 49 } |
50 | 50 |
51 // Tests that |EphemeralRange::nodes()| will traverse the whole range exactly as | 51 // Tests that |EphemeralRange::nodes()| will traverse the whole range exactly as |
52 // |for (Node* n = firstNode(); n != pastLastNode(); n = Traversal::next(*n))| | 52 // |for (Node* n = firstNode(); n != pastLastNode(); n = Traversal::next(*n))| |
53 // does. | 53 // does. |
54 TEST_F(EphemeralRangeTest, rangeTraversal) { | 54 TEST_F(EphemeralRangeTest, rangeTraversalDOM) { |
55 const char* bodyContent = | 55 const char* bodyContent = |
56 "<p id='host'><b id='one'></b><b id='two'>22</b></p>"; | 56 "<p id='host'>" |
| 57 "<b id='zero'>0</b>" |
| 58 "<b id='one'>1</b>" |
| 59 "<b id='two'>22</b>" |
| 60 "<span id='three'>333</span>" |
| 61 "</p>"; |
57 setBodyContent(bodyContent); | 62 setBodyContent(bodyContent); |
58 | 63 |
59 const std::string expectedNodes( | 64 const std::string expectedNodes( |
60 "[BODY][P id=\"host\"][B id=\"one\"][B id=\"two\"][#text \"22\"]"); | 65 "[BODY][P id=\"host\"][B id=\"zero\"][#text \"0\"][B id=\"one\"][#text " |
| 66 "\"1\"][B id=\"two\"][#text \"22\"][SPAN id=\"three\"][#text \"333\"]"); |
61 | 67 |
62 // Check two ways to traverse. | 68 // Check two ways to traverse. |
63 EXPECT_EQ(expectedNodes, traverseRange<>(getBodyRange())); | 69 EXPECT_EQ(expectedNodes, traverseRange<>(getBodyRange())); |
64 EXPECT_EQ(traverseRange<>(getBodyRange()), | 70 EXPECT_EQ(traverseRange<>(getBodyRange()), |
65 traverseRange(EphemeralRange(getBodyRange()))); | 71 traverseRange(EphemeralRange(getBodyRange()))); |
66 | 72 |
67 // The same with FlatTree traversing. | |
68 EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); | 73 EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); |
69 EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), | 74 EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), |
70 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); | 75 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); |
71 } | 76 } |
72 | 77 |
73 // Tests that |inRange| helper will traverse the whole range with shadow DOM. | 78 // Tests that |inRange| helper will traverse the whole range with shadow DOM. |
74 TEST_F(EphemeralRangeTest, rangeShadowTraversal) { | 79 TEST_F(EphemeralRangeTest, rangeShadowTraversal) { |
75 const char* bodyContent = | 80 const char* bodyContent = |
76 "<p id='host'><b id='one'></b><input type='text' value='some'></p>"; | 81 "<b id='zero'>0</b>" |
| 82 "<p id='host'>" |
| 83 "<b id='one'>1</b>" |
| 84 "<b id='two'>22</b>" |
| 85 "<b id='three'>333</b>" |
| 86 "</p>" |
| 87 "<b id='four'>4444</b>"; |
| 88 const char* shadowContent = |
| 89 "<p id='five'>55555</p>" |
| 90 "<content select=#two></content>" |
| 91 "<content select=#one></content>" |
| 92 "<span id='six'>666666</span>" |
| 93 "<p id='seven'>7777777</p>"; |
77 setBodyContent(bodyContent); | 94 setBodyContent(bodyContent); |
| 95 setShadowContent(shadowContent, "host"); |
78 | 96 |
79 EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"][INPUT]", | 97 const std::string expectedNodes( |
80 traverseRange<>(getBodyRange())); | 98 "[BODY][B id=\"zero\"][#text \"0\"][P id=\"host\"][P id=\"five\"][#text " |
81 EXPECT_EQ(traverseRange<>(getBodyRange()), | 99 "\"55555\"][B id=\"two\"][#text \"22\"][B id=\"one\"][#text \"1\"][SPAN " |
82 traverseRange(EphemeralRange(getBodyRange()))); | 100 "id=\"six\"][#text \"666666\"][P id=\"seven\"][#text \"7777777\"][B " |
| 101 "id=\"four\"][#text \"4444\"]"); |
83 | 102 |
84 // In this case FlatTree traverse should differs from DOM tree traverse. | 103 EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); |
85 EXPECT_EQ( | |
86 "[BODY][P id=\"host\"][B id=\"one\"][INPUT][DIV id=\"inner-editor\" " | |
87 "(editable)][#text \"some\"]", | |
88 traverseRange<FlatTreeTraversal>(getBodyRange())); | |
89 EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), | 104 EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), |
90 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); | 105 traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); |
| 106 // Node 'three' should not appear in FlatTreeTraversal. |
| 107 EXPECT_EQ(expectedNodes.find("three") == std::string::npos, true); |
91 } | 108 } |
92 | 109 |
93 // Limit a range and check that it will be traversed correctly. | 110 // Limit a range and check that it will be traversed correctly. |
94 TEST_F(EphemeralRangeTest, rangeTraversalLimited) { | 111 TEST_F(EphemeralRangeTest, rangeTraversalLimitedDOM) { |
95 const char* bodyContent = | 112 const char* bodyContent = |
96 "<p id='host'><b id='one'></b><input type='text' value='some'><span " | 113 "<p id='host'>" |
97 "id='two'></p>"; | 114 "<b id='zero'>0</b>" |
| 115 "<b id='one'>1</b>" |
| 116 "<b id='two'>22</b>" |
| 117 "<span id='three'>333</span>" |
| 118 "</p>"; |
98 setBodyContent(bodyContent); | 119 setBodyContent(bodyContent); |
99 | 120 |
100 // Get a limited range from <body> to <b> nodes. | |
101 Range* untilB = getBodyRange(); | 121 Range* untilB = getBodyRange(); |
102 untilB->setEnd(document().getElementById("one"), 0, | 122 untilB->setEnd(document().getElementById("one"), 0, |
103 IGNORE_EXCEPTION_FOR_TESTING); | 123 IGNORE_EXCEPTION_FOR_TESTING); |
104 EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"]", traverseRange<>(untilB)); | 124 EXPECT_EQ("[BODY][P id=\"host\"][B id=\"zero\"][#text \"0\"][B id=\"one\"]", |
105 | 125 traverseRange<>(untilB)); |
106 EXPECT_EQ(traverseRange<>(untilB), traverseRange(EphemeralRange(untilB))); | 126 EXPECT_EQ(traverseRange<>(untilB), traverseRange(EphemeralRange(untilB))); |
107 | 127 |
108 EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"]", | |
109 traverseRange<FlatTreeTraversal>(untilB)); | |
110 EXPECT_EQ(traverseRange<FlatTreeTraversal>(untilB), | |
111 traverseRange(EphemeralRangeInFlatTree(untilB))); | |
112 | |
113 // Get a limited range from <b> to <span> nodes. | |
114 Range* fromBToSpan = getBodyRange(); | 128 Range* fromBToSpan = getBodyRange(); |
115 fromBToSpan->setStart(document().getElementById("one"), 0, | 129 fromBToSpan->setStart(document().getElementById("one"), 0, |
116 IGNORE_EXCEPTION_FOR_TESTING); | 130 IGNORE_EXCEPTION_FOR_TESTING); |
117 fromBToSpan->setEnd(document().getElementById("two"), 0, | 131 fromBToSpan->setEnd(document().getElementById("three"), 0, |
118 IGNORE_EXCEPTION_FOR_TESTING); | 132 IGNORE_EXCEPTION_FOR_TESTING); |
119 | 133 EXPECT_EQ("[#text \"1\"][B id=\"two\"][#text \"22\"][SPAN id=\"three\"]", |
120 EXPECT_EQ("[B id=\"one\"][INPUT][SPAN id=\"two\"]", | |
121 traverseRange<>(fromBToSpan)); | 134 traverseRange<>(fromBToSpan)); |
122 EXPECT_EQ(traverseRange<>(fromBToSpan), | 135 EXPECT_EQ(traverseRange<>(fromBToSpan), |
123 traverseRange(EphemeralRange(fromBToSpan))); | 136 traverseRange(EphemeralRange(fromBToSpan))); |
| 137 } |
124 | 138 |
125 EXPECT_EQ( | 139 TEST_F(EphemeralRangeTest, rangeTraversalLimitedFlatTree) { |
126 "[B id=\"one\"][INPUT][DIV id=\"inner-editor\" (editable)][#text " | 140 const char* bodyContent = |
127 "\"some\"][SPAN id=\"two\"]", | 141 "<b id='zero'>0</b>" |
128 traverseRange<FlatTreeTraversal>(fromBToSpan)); | 142 "<p id='host'>" |
129 EXPECT_EQ(traverseRange<FlatTreeTraversal>(fromBToSpan), | 143 "<b id='one'>1</b>" |
130 traverseRange(EphemeralRangeInFlatTree(fromBToSpan))); | 144 "<b id='two'>22</b>" |
| 145 "</p>" |
| 146 "<b id='three'>333</b>"; |
| 147 const char* shadowContent = |
| 148 "<p id='four'>4444</p>" |
| 149 "<content select=#two></content>" |
| 150 "<content select=#one></content>" |
| 151 "<span id='five'>55555</span>" |
| 152 "<p id='six'>666666</p>"; |
| 153 setBodyContent(bodyContent); |
| 154 ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); |
| 155 |
| 156 const PositionInFlatTree startPosition(document().getElementById("one"), 0); |
| 157 const PositionInFlatTree limitPosition(shadowRoot->getElementById("five"), 0); |
| 158 const PositionInFlatTree endPosition(shadowRoot->getElementById("six"), 0); |
| 159 const EphemeralRangeInFlatTree fromBToSpan(startPosition, limitPosition); |
| 160 EXPECT_EQ("[#text \"1\"][SPAN id=\"five\"]", traverseRange(fromBToSpan)); |
| 161 |
| 162 const EphemeralRangeInFlatTree fromSpanToEnd(limitPosition, endPosition); |
| 163 EXPECT_EQ("[#text \"55555\"][P id=\"six\"]", traverseRange(fromSpanToEnd)); |
131 } | 164 } |
132 | 165 |
133 TEST_F(EphemeralRangeTest, traversalEmptyRanges) { | 166 TEST_F(EphemeralRangeTest, traversalEmptyRanges) { |
134 const char* bodyContent = "<p id='host'><b id='one'></b></p>"; | 167 const char* bodyContent = |
| 168 "<p id='host'>" |
| 169 "<b id='one'>1</b>" |
| 170 "</p>"; |
135 setBodyContent(bodyContent); | 171 setBodyContent(bodyContent); |
136 | 172 |
137 // Expect no iterations in loop for an empty EphemeralRange. | 173 // Expect no iterations in loop for an empty EphemeralRange. |
138 EXPECT_EQ(std::string(), traverseRange(EphemeralRange())); | 174 EXPECT_EQ(std::string(), traverseRange(EphemeralRange())); |
139 | 175 |
140 auto iterable = EphemeralRange().nodes(); | 176 auto iterable = EphemeralRange().nodes(); |
141 // Tree iterators have only |operator !=| ATM. | 177 // Tree iterators have only |operator !=| ATM. |
142 EXPECT_FALSE(iterable.begin() != iterable.end()); | 178 EXPECT_FALSE(iterable.begin() != iterable.end()); |
143 | 179 |
144 const EphemeralRange singlePositionRange(getBodyRange()->startPosition()); | 180 const EphemeralRange singlePositionRange(getBodyRange()->startPosition()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 setBodyContent(bodyContent); | 215 setBodyContent(bodyContent); |
180 ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); | 216 ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); |
181 | 217 |
182 const PositionInFlatTree startPosition(document().getElementById("one"), 0); | 218 const PositionInFlatTree startPosition(document().getElementById("one"), 0); |
183 const PositionInFlatTree endPosition(shadowRoot->getElementById("five"), 0); | 219 const PositionInFlatTree endPosition(shadowRoot->getElementById("five"), 0); |
184 const EphemeralRangeInFlatTree range(startPosition, endPosition); | 220 const EphemeralRangeInFlatTree range(startPosition, endPosition); |
185 EXPECT_EQ(document().getElementById("host"), range.commonAncestorContainer()); | 221 EXPECT_EQ(document().getElementById("host"), range.commonAncestorContainer()); |
186 } | 222 } |
187 | 223 |
188 } // namespace blink | 224 } // namespace blink |
OLD | NEW |