| 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 |