| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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. | |
| 4 | |
| 5 #include "core/dom/shadow/ComposedTreeTraversal.h" | |
| 6 | |
| 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | |
| 8 #include "core/dom/Document.h" | |
| 9 #include "core/dom/Element.h" | |
| 10 #include "core/dom/Node.h" | |
| 11 #include "core/dom/NodeTraversal.h" | |
| 12 #include "core/dom/shadow/ShadowRoot.h" | |
| 13 #include "core/frame/FrameView.h" | |
| 14 #include "core/html/HTMLDocument.h" | |
| 15 #include "core/html/HTMLElement.h" | |
| 16 #include "core/testing/DummyPageHolder.h" | |
| 17 #include "platform/geometry/IntSize.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | |
| 19 #include "wtf/Compiler.h" | |
| 20 #include "wtf/OwnPtr.h" | |
| 21 #include "wtf/PassRefPtr.h" | |
| 22 #include "wtf/RefPtr.h" | |
| 23 #include "wtf/StdLibExtras.h" | |
| 24 #include "wtf/Vector.h" | |
| 25 | |
| 26 namespace blink { | |
| 27 | |
| 28 class ComposedTreeTraversalTest : public ::testing::Test { | |
| 29 protected: | |
| 30 HTMLDocument& document() const; | |
| 31 | |
| 32 // Sets |mainHTML| to BODY element with |innerHTML| property and attaches | |
| 33 // shadow root to child with |shadowHTML|, then update distribution for | |
| 34 // calling member functions in |ComposedTreeTraversal|. | |
| 35 void setupSampleHTML(const char* mainHTML, const char* shadowHTML, unsigned)
; | |
| 36 | |
| 37 void setupDocumentTree(const char* mainHTML); | |
| 38 | |
| 39 void attachV0ShadowRoot(Element& shadowHost, const char* shadowInnerHTML); | |
| 40 void attachOpenShadowRoot(Element& shadowHost, const char* shadowInnerHTML); | |
| 41 | |
| 42 private: | |
| 43 void SetUp() override; | |
| 44 | |
| 45 RefPtrWillBePersistent<HTMLDocument> m_document; | |
| 46 OwnPtr<DummyPageHolder> m_dummyPageHolder; | |
| 47 }; | |
| 48 | |
| 49 void ComposedTreeTraversalTest::SetUp() | |
| 50 { | |
| 51 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); | |
| 52 m_document = toHTMLDocument(&m_dummyPageHolder->document()); | |
| 53 ASSERT(m_document); | |
| 54 } | |
| 55 | |
| 56 HTMLDocument& ComposedTreeTraversalTest::document() const | |
| 57 { | |
| 58 return *m_document; | |
| 59 } | |
| 60 | |
| 61 void ComposedTreeTraversalTest::setupSampleHTML(const char* mainHTML, const char
* shadowHTML, unsigned index) | |
| 62 { | |
| 63 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 64 body->setInnerHTML(String::fromUTF8(mainHTML), ASSERT_NO_EXCEPTION); | |
| 65 RefPtrWillBeRawPtr<Element> shadowHost = toElement(NodeTraversal::childAt(*b
ody, index)); | |
| 66 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = shadowHost->createShadowRootInte
rnal(ShadowRootType::V0, ASSERT_NO_EXCEPTION); | |
| 67 shadowRoot->setInnerHTML(String::fromUTF8(shadowHTML), ASSERT_NO_EXCEPTION); | |
| 68 body->updateDistribution(); | |
| 69 } | |
| 70 | |
| 71 void ComposedTreeTraversalTest::setupDocumentTree(const char* mainHTML) | |
| 72 { | |
| 73 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 74 body->setInnerHTML(String::fromUTF8(mainHTML), ASSERT_NO_EXCEPTION); | |
| 75 } | |
| 76 | |
| 77 void ComposedTreeTraversalTest::attachV0ShadowRoot(Element& shadowHost, const ch
ar* shadowInnerHTML) | |
| 78 { | |
| 79 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = shadowHost.createShadowRootInter
nal(ShadowRootType::V0, ASSERT_NO_EXCEPTION); | |
| 80 shadowRoot->setInnerHTML(String::fromUTF8(shadowInnerHTML), ASSERT_NO_EXCEPT
ION); | |
| 81 document().body()->updateDistribution(); | |
| 82 } | |
| 83 | |
| 84 void ComposedTreeTraversalTest::attachOpenShadowRoot(Element& shadowHost, const
char* shadowInnerHTML) | |
| 85 { | |
| 86 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = shadowHost.createShadowRootInter
nal(ShadowRootType::Open, ASSERT_NO_EXCEPTION); | |
| 87 shadowRoot->setInnerHTML(String::fromUTF8(shadowInnerHTML), ASSERT_NO_EXCEPT
ION); | |
| 88 document().body()->updateDistribution(); | |
| 89 } | |
| 90 | |
| 91 void testCommonAncestor(Node* expectedResult, const Node& nodeA, const Node& nod
eB) | |
| 92 { | |
| 93 Node* result1 = ComposedTreeTraversal::commonAncestor(nodeA, nodeB); | |
| 94 EXPECT_EQ(expectedResult, result1) << "commonAncestor(" << nodeA.textContent
() << "," << nodeB.textContent() << ")"; | |
| 95 Node* result2 = ComposedTreeTraversal::commonAncestor(nodeB, nodeA); | |
| 96 EXPECT_EQ(expectedResult, result2) << "commonAncestor(" << nodeB.textContent
() << "," << nodeA.textContent() << ")"; | |
| 97 } | |
| 98 | |
| 99 // Test case for | |
| 100 // - childAt | |
| 101 // - countChildren | |
| 102 // - hasChildren | |
| 103 // - index | |
| 104 // - isDescendantOf | |
| 105 TEST_F(ComposedTreeTraversalTest, childAt) | |
| 106 { | |
| 107 const char* mainHTML = | |
| 108 "<div id='m0'>" | |
| 109 "<span id='m00'>m00</span>" | |
| 110 "<span id='m01'>m01</span>" | |
| 111 "</div>"; | |
| 112 const char* shadowHTML = | |
| 113 "<a id='s00'>s00</a>" | |
| 114 "<content select='#m01'></content>" | |
| 115 "<a id='s02'>s02</a>" | |
| 116 "<a id='s03'><content select='#m00'></content></a>" | |
| 117 "<a id='s04'>s04</a>"; | |
| 118 setupSampleHTML(mainHTML, shadowHTML, 0); | |
| 119 | |
| 120 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 121 RefPtrWillBeRawPtr<Element> m0 = body->querySelector("#m0", ASSERT_NO_EXCEPT
ION); | |
| 122 RefPtrWillBeRawPtr<Element> m00 = m0->querySelector("#m00", ASSERT_NO_EXCEPT
ION); | |
| 123 RefPtrWillBeRawPtr<Element> m01 = m0->querySelector("#m01", ASSERT_NO_EXCEPT
ION); | |
| 124 | |
| 125 RefPtrWillBeRawPtr<Element> shadowHost = m0; | |
| 126 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = shadowHost->openShadowRoot(); | |
| 127 RefPtrWillBeRawPtr<Element> s00 = shadowRoot->querySelector("#s00", ASSERT_N
O_EXCEPTION); | |
| 128 RefPtrWillBeRawPtr<Element> s02 = shadowRoot->querySelector("#s02", ASSERT_N
O_EXCEPTION); | |
| 129 RefPtrWillBeRawPtr<Element> s03 = shadowRoot->querySelector("#s03", ASSERT_N
O_EXCEPTION); | |
| 130 RefPtrWillBeRawPtr<Element> s04 = shadowRoot->querySelector("#s04", ASSERT_N
O_EXCEPTION); | |
| 131 | |
| 132 const unsigned numberOfChildNodes = 5; | |
| 133 Node* expectedChildNodes[5] = { s00.get(), m01.get(), s02.get(), s03.get(),
s04.get() }; | |
| 134 | |
| 135 ASSERT_EQ(numberOfChildNodes, ComposedTreeTraversal::countChildren(*shadowHo
st)); | |
| 136 EXPECT_TRUE(ComposedTreeTraversal::hasChildren(*shadowHost)); | |
| 137 | |
| 138 for (unsigned index = 0; index < numberOfChildNodes; ++index) { | |
| 139 Node* child = ComposedTreeTraversal::childAt(*shadowHost, index); | |
| 140 EXPECT_EQ(expectedChildNodes[index], child) | |
| 141 << "ComposedTreeTraversal::childAt(*shadowHost, " << index << ")"; | |
| 142 EXPECT_EQ(index, ComposedTreeTraversal::index(*child)) | |
| 143 << "ComposedTreeTraversal::index(ComposedTreeTraversal(*shadowHost,
" << index << "))"; | |
| 144 EXPECT_TRUE(ComposedTreeTraversal::isDescendantOf(*child, *shadowHost)) | |
| 145 << "ComposedTreeTraversal::isDescendantOf(*ComposedTreeTraversal(*sh
adowHost, " << index << "), *shadowHost)"; | |
| 146 } | |
| 147 EXPECT_EQ(nullptr, ComposedTreeTraversal::childAt(*shadowHost, numberOfChild
Nodes + 1)) | |
| 148 << "Out of bounds childAt() returns nullptr."; | |
| 149 | |
| 150 // Distribute node |m00| is child of node in shadow tree |s03|. | |
| 151 EXPECT_EQ(m00.get(), ComposedTreeTraversal::childAt(*s03, 0)); | |
| 152 } | |
| 153 | |
| 154 // Test case for | |
| 155 // - commonAncestor | |
| 156 // - isDescendantOf | |
| 157 TEST_F(ComposedTreeTraversalTest, commonAncestor) | |
| 158 { | |
| 159 // We build following composed tree: | |
| 160 // ____BODY___ | |
| 161 // | | | | |
| 162 // m0 m1 m2 m1 is shadow host having m10, m11, m12. | |
| 163 // _|_ | __|__ | |
| 164 // | | | | | | |
| 165 // m00 m01 | m20 m21 | |
| 166 // _____|_____________ | |
| 167 // | | | | | | |
| 168 // s10 s11 s12 s13 s14 | |
| 169 // | | |
| 170 // __|__ | |
| 171 // | | | | |
| 172 // m12 m10 m11 <-- distributed | |
| 173 // where: each symbol consists with prefix, child index, child-child index. | |
| 174 // prefix "m" means node in main tree, | |
| 175 // prefix "d" means node in main tree and distributed | |
| 176 // prefix "s" means node in shadow tree | |
| 177 const char* mainHTML = | |
| 178 "<a id='m0'><b id='m00'>m00</b><b id='m01'>m01</b></a>" | |
| 179 "<a id='m1'>" | |
| 180 "<b id='m10'>m10</b>" | |
| 181 "<b id='m11'>m11</b>" | |
| 182 "<b id='m12'>m12</b>" | |
| 183 "</a>" | |
| 184 "<a id='m2'><b id='m20'>m20</b><b id='m21'>m21</b></a>"; | |
| 185 const char* shadowHTML = | |
| 186 "<a id='s10'>s10</a>" | |
| 187 "<a id='s11'><content select='#m12'></content></a>" | |
| 188 "<a id='s12'>s12</a>" | |
| 189 "<a id='s13'>" | |
| 190 "<content select='#m10'></content>" | |
| 191 "<content select='#m11'></content>" | |
| 192 "</a>" | |
| 193 "<a id='s14'>s14</a>"; | |
| 194 setupSampleHTML(mainHTML, shadowHTML, 1); | |
| 195 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 196 RefPtrWillBeRawPtr<Element> m0 = body->querySelector("#m0", ASSERT_NO_EXCEPT
ION); | |
| 197 RefPtrWillBeRawPtr<Element> m1 = body->querySelector("#m1", ASSERT_NO_EXCEPT
ION); | |
| 198 RefPtrWillBeRawPtr<Element> m2 = body->querySelector("#m2", ASSERT_NO_EXCEPT
ION); | |
| 199 | |
| 200 RefPtrWillBeRawPtr<Element> m00 = body->querySelector("#m00", ASSERT_NO_EXCE
PTION); | |
| 201 RefPtrWillBeRawPtr<Element> m01 = body->querySelector("#m01", ASSERT_NO_EXCE
PTION); | |
| 202 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 203 RefPtrWillBeRawPtr<Element> m11 = body->querySelector("#m11", ASSERT_NO_EXCE
PTION); | |
| 204 RefPtrWillBeRawPtr<Element> m12 = body->querySelector("#m12", ASSERT_NO_EXCE
PTION); | |
| 205 RefPtrWillBeRawPtr<Element> m20 = body->querySelector("#m20", ASSERT_NO_EXCE
PTION); | |
| 206 RefPtrWillBeRawPtr<Element> m21 = body->querySelector("#m21", ASSERT_NO_EXCE
PTION); | |
| 207 | |
| 208 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = m1->openShadowRoot(); | |
| 209 RefPtrWillBeRawPtr<Element> s10 = shadowRoot->querySelector("#s10", ASSERT_N
O_EXCEPTION); | |
| 210 RefPtrWillBeRawPtr<Element> s11 = shadowRoot->querySelector("#s11", ASSERT_N
O_EXCEPTION); | |
| 211 RefPtrWillBeRawPtr<Element> s12 = shadowRoot->querySelector("#s12", ASSERT_N
O_EXCEPTION); | |
| 212 RefPtrWillBeRawPtr<Element> s13 = shadowRoot->querySelector("#s13", ASSERT_N
O_EXCEPTION); | |
| 213 RefPtrWillBeRawPtr<Element> s14 = shadowRoot->querySelector("#s14", ASSERT_N
O_EXCEPTION); | |
| 214 | |
| 215 testCommonAncestor(body.get(), *m0, *m1); | |
| 216 testCommonAncestor(body.get(), *m1, *m2); | |
| 217 testCommonAncestor(body.get(), *m1, *m20); | |
| 218 testCommonAncestor(body.get(), *s14, *m21); | |
| 219 | |
| 220 testCommonAncestor(m0.get(), *m0, *m0); | |
| 221 testCommonAncestor(m0.get(), *m00, *m01); | |
| 222 | |
| 223 testCommonAncestor(m1.get(), *m1.get(), *m1); | |
| 224 testCommonAncestor(m1.get(), *s10, *s14); | |
| 225 testCommonAncestor(m1.get(), *s10, *m12); | |
| 226 testCommonAncestor(m1.get(), *s12, *m12); | |
| 227 testCommonAncestor(m1.get(), *m10, *m12); | |
| 228 | |
| 229 testCommonAncestor(m01.get(), *m01, *m01); | |
| 230 testCommonAncestor(s11.get(), *s11, *m12); | |
| 231 testCommonAncestor(s13.get(), *m10, *m11); | |
| 232 | |
| 233 s12->remove(ASSERT_NO_EXCEPTION); | |
| 234 testCommonAncestor(s12.get(), *s12, *s12); | |
| 235 testCommonAncestor(nullptr, *s12, *s11); | |
| 236 testCommonAncestor(nullptr, *s12, *m01); | |
| 237 testCommonAncestor(nullptr, *s12, *m20); | |
| 238 | |
| 239 m20->remove(ASSERT_NO_EXCEPTION); | |
| 240 testCommonAncestor(m20.get(), *m20, *m20); | |
| 241 testCommonAncestor(nullptr, *m20, *s12); | |
| 242 testCommonAncestor(nullptr, *m20, *m1); | |
| 243 } | |
| 244 | |
| 245 // Test case for | |
| 246 // - nextSkippingChildren | |
| 247 // - previousSkippingChildren | |
| 248 TEST_F(ComposedTreeTraversalTest, nextSkippingChildren) | |
| 249 { | |
| 250 const char* mainHTML = | |
| 251 "<div id='m0'>m0</div>" | |
| 252 "<div id='m1'>" | |
| 253 "<span id='m10'>m10</span>" | |
| 254 "<span id='m11'>m11</span>" | |
| 255 "</div>" | |
| 256 "<div id='m2'>m2</div>"; | |
| 257 const char* shadowHTML = | |
| 258 "<content select='#m11'></content>" | |
| 259 "<a id='s11'>s11</a>" | |
| 260 "<a id='s12'>" | |
| 261 "<b id='s120'>s120</b>" | |
| 262 "<content select='#m10'></content>" | |
| 263 "</a>"; | |
| 264 setupSampleHTML(mainHTML, shadowHTML, 1); | |
| 265 | |
| 266 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 267 RefPtrWillBeRawPtr<Element> m0 = body->querySelector("#m0", ASSERT_NO_EXCEPT
ION); | |
| 268 RefPtrWillBeRawPtr<Element> m1 = body->querySelector("#m1", ASSERT_NO_EXCEPT
ION); | |
| 269 RefPtrWillBeRawPtr<Element> m2 = body->querySelector("#m2", ASSERT_NO_EXCEPT
ION); | |
| 270 | |
| 271 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 272 RefPtrWillBeRawPtr<Element> m11 = body->querySelector("#m11", ASSERT_NO_EXCE
PTION); | |
| 273 | |
| 274 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = m1->openShadowRoot(); | |
| 275 RefPtrWillBeRawPtr<Element> s11 = shadowRoot->querySelector("#s11", ASSERT_N
O_EXCEPTION); | |
| 276 RefPtrWillBeRawPtr<Element> s12 = shadowRoot->querySelector("#s12", ASSERT_N
O_EXCEPTION); | |
| 277 RefPtrWillBeRawPtr<Element> s120 = shadowRoot->querySelector("#s120", ASSERT
_NO_EXCEPTION); | |
| 278 | |
| 279 // Main tree node to main tree node | |
| 280 EXPECT_EQ(*m1, ComposedTreeTraversal::nextSkippingChildren(*m0)); | |
| 281 EXPECT_EQ(*m0, ComposedTreeTraversal::previousSkippingChildren(*m1)); | |
| 282 | |
| 283 // Distribute node to main tree node | |
| 284 EXPECT_EQ(*m2, ComposedTreeTraversal::nextSkippingChildren(*m10)); | |
| 285 EXPECT_EQ(*m1, ComposedTreeTraversal::previousSkippingChildren(*m2)); | |
| 286 | |
| 287 // Distribute node to node in shadow tree | |
| 288 EXPECT_EQ(*s11, ComposedTreeTraversal::nextSkippingChildren(*m11)); | |
| 289 EXPECT_EQ(*m11, ComposedTreeTraversal::previousSkippingChildren(*s11)); | |
| 290 | |
| 291 // Node in shadow tree to distributed node | |
| 292 EXPECT_EQ(*s11, ComposedTreeTraversal::nextSkippingChildren(*m11)); | |
| 293 EXPECT_EQ(*m11, ComposedTreeTraversal::previousSkippingChildren(*s11)); | |
| 294 | |
| 295 EXPECT_EQ(*m10, ComposedTreeTraversal::nextSkippingChildren(*s120)); | |
| 296 EXPECT_EQ(*s120, ComposedTreeTraversal::previousSkippingChildren(*m10)); | |
| 297 | |
| 298 // Node in shadow tree to main tree | |
| 299 EXPECT_EQ(*m2, ComposedTreeTraversal::nextSkippingChildren(*s12)); | |
| 300 EXPECT_EQ(*m1, ComposedTreeTraversal::previousSkippingChildren(*m2)); | |
| 301 } | |
| 302 | |
| 303 // Test case for | |
| 304 // - lastWithin | |
| 305 // - lastWithinOrSelf | |
| 306 TEST_F(ComposedTreeTraversalTest, lastWithin) | |
| 307 { | |
| 308 const char* mainHTML = | |
| 309 "<div id='m0'>m0</div>" | |
| 310 "<div id='m1'>" | |
| 311 "<span id='m10'>m10</span>" | |
| 312 "<span id='m11'>m11</span>" | |
| 313 "<span id='m12'>m12</span>" // #m12 is not distributed. | |
| 314 "</div>" | |
| 315 "<div id='m2'></div>"; | |
| 316 const char* shadowHTML = | |
| 317 "<content select='#m11'></content>" | |
| 318 "<a id='s11'>s11</a>" | |
| 319 "<a id='s12'>" | |
| 320 "<content select='#m10'></content>" | |
| 321 "</a>"; | |
| 322 setupSampleHTML(mainHTML, shadowHTML, 1); | |
| 323 | |
| 324 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 325 RefPtrWillBeRawPtr<Element> m0 = body->querySelector("#m0", ASSERT_NO_EXCEPT
ION); | |
| 326 RefPtrWillBeRawPtr<Element> m1 = body->querySelector("#m1", ASSERT_NO_EXCEPT
ION); | |
| 327 RefPtrWillBeRawPtr<Element> m2 = body->querySelector("#m2", ASSERT_NO_EXCEPT
ION); | |
| 328 | |
| 329 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 330 | |
| 331 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = m1->openShadowRoot(); | |
| 332 RefPtrWillBeRawPtr<Element> s11 = shadowRoot->querySelector("#s11", ASSERT_N
O_EXCEPTION); | |
| 333 RefPtrWillBeRawPtr<Element> s12 = shadowRoot->querySelector("#s12", ASSERT_N
O_EXCEPTION); | |
| 334 | |
| 335 EXPECT_EQ(m0->firstChild(), ComposedTreeTraversal::lastWithin(*m0)); | |
| 336 EXPECT_EQ(*m0->firstChild(), ComposedTreeTraversal::lastWithinOrSelf(*m0)); | |
| 337 | |
| 338 EXPECT_EQ(m10->firstChild(), ComposedTreeTraversal::lastWithin(*m1)); | |
| 339 EXPECT_EQ(*m10->firstChild(), ComposedTreeTraversal::lastWithinOrSelf(*m1)); | |
| 340 | |
| 341 EXPECT_EQ(nullptr, ComposedTreeTraversal::lastWithin(*m2)); | |
| 342 EXPECT_EQ(*m2, ComposedTreeTraversal::lastWithinOrSelf(*m2)); | |
| 343 | |
| 344 EXPECT_EQ(s11->firstChild(), ComposedTreeTraversal::lastWithin(*s11)); | |
| 345 EXPECT_EQ(*s11->firstChild(), ComposedTreeTraversal::lastWithinOrSelf(*s11))
; | |
| 346 | |
| 347 EXPECT_EQ(m10->firstChild(), ComposedTreeTraversal::lastWithin(*s12)); | |
| 348 EXPECT_EQ(*m10->firstChild(), ComposedTreeTraversal::lastWithinOrSelf(*s12))
; | |
| 349 } | |
| 350 | |
| 351 TEST_F(ComposedTreeTraversalTest, previousPostOrder) | |
| 352 { | |
| 353 const char* mainHTML = | |
| 354 "<div id='m0'>m0</div>" | |
| 355 "<div id='m1'>" | |
| 356 "<span id='m10'>m10</span>" | |
| 357 "<span id='m11'>m11</span>" | |
| 358 "</div>" | |
| 359 "<div id='m2'>m2</div>"; | |
| 360 const char* shadowHTML = | |
| 361 "<content select='#m11'></content>" | |
| 362 "<a id='s11'>s11</a>" | |
| 363 "<a id='s12'>" | |
| 364 "<b id='s120'>s120</b>" | |
| 365 "<content select='#m10'></content>" | |
| 366 "</a>"; | |
| 367 setupSampleHTML(mainHTML, shadowHTML, 1); | |
| 368 | |
| 369 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 370 RefPtrWillBeRawPtr<Element> m0 = body->querySelector("#m0", ASSERT_NO_EXCEPT
ION); | |
| 371 RefPtrWillBeRawPtr<Element> m1 = body->querySelector("#m1", ASSERT_NO_EXCEPT
ION); | |
| 372 RefPtrWillBeRawPtr<Element> m2 = body->querySelector("#m2", ASSERT_NO_EXCEPT
ION); | |
| 373 | |
| 374 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 375 RefPtrWillBeRawPtr<Element> m11 = body->querySelector("#m11", ASSERT_NO_EXCE
PTION); | |
| 376 | |
| 377 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = m1->openShadowRoot(); | |
| 378 RefPtrWillBeRawPtr<Element> s11 = shadowRoot->querySelector("#s11", ASSERT_N
O_EXCEPTION); | |
| 379 RefPtrWillBeRawPtr<Element> s12 = shadowRoot->querySelector("#s12", ASSERT_N
O_EXCEPTION); | |
| 380 RefPtrWillBeRawPtr<Element> s120 = shadowRoot->querySelector("#s120", ASSERT
_NO_EXCEPTION); | |
| 381 | |
| 382 EXPECT_EQ(*m0->firstChild(), ComposedTreeTraversal::previousPostOrder(*m0)); | |
| 383 EXPECT_EQ(*s12, ComposedTreeTraversal::previousPostOrder(*m1)); | |
| 384 EXPECT_EQ(*m10->firstChild(), ComposedTreeTraversal::previousPostOrder(*m10)
); | |
| 385 EXPECT_EQ(*s120, ComposedTreeTraversal::previousPostOrder(*m10->firstChild()
)); | |
| 386 EXPECT_EQ(*s120, ComposedTreeTraversal::previousPostOrder(*m10->firstChild()
, s12.get())); | |
| 387 EXPECT_EQ(*m11->firstChild(), ComposedTreeTraversal::previousPostOrder(*m11)
); | |
| 388 EXPECT_EQ(*m0, ComposedTreeTraversal::previousPostOrder(*m11->firstChild()))
; | |
| 389 EXPECT_EQ(nullptr, ComposedTreeTraversal::previousPostOrder(*m11->firstChild
(), m11.get())); | |
| 390 EXPECT_EQ(*m2->firstChild(), ComposedTreeTraversal::previousPostOrder(*m2)); | |
| 391 | |
| 392 EXPECT_EQ(*s11->firstChild(), ComposedTreeTraversal::previousPostOrder(*s11)
); | |
| 393 EXPECT_EQ(*m10, ComposedTreeTraversal::previousPostOrder(*s12)); | |
| 394 EXPECT_EQ(*s120->firstChild(), ComposedTreeTraversal::previousPostOrder(*s12
0)); | |
| 395 EXPECT_EQ(*s11, ComposedTreeTraversal::previousPostOrder(*s120->firstChild()
)); | |
| 396 EXPECT_EQ(nullptr, ComposedTreeTraversal::previousPostOrder(*s120->firstChil
d(), s12.get())); | |
| 397 } | |
| 398 | |
| 399 TEST_F(ComposedTreeTraversalTest, nextSiblingNotInDocumentComposedTree) | |
| 400 { | |
| 401 const char* mainHTML = | |
| 402 "<div id='m0'>m0</div>" | |
| 403 "<div id='m1'>" | |
| 404 "<span id='m10'>m10</span>" | |
| 405 "<span id='m11'>m11</span>" | |
| 406 "</div>" | |
| 407 "<div id='m2'>m2</div>"; | |
| 408 const char* shadowHTML = | |
| 409 "<content select='#m11'></content>"; | |
| 410 setupSampleHTML(mainHTML, shadowHTML, 1); | |
| 411 | |
| 412 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 413 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 414 | |
| 415 EXPECT_EQ(nullptr, ComposedTreeTraversal::nextSibling(*m10)); | |
| 416 EXPECT_EQ(nullptr, ComposedTreeTraversal::previousSibling(*m10)); | |
| 417 } | |
| 418 | |
| 419 TEST_F(ComposedTreeTraversalTest, redistribution) | |
| 420 { | |
| 421 const char* mainHTML = | |
| 422 "<div id='m0'>m0</div>" | |
| 423 "<div id='m1'>" | |
| 424 "<span id='m10'>m10</span>" | |
| 425 "<span id='m11'>m11</span>" | |
| 426 "</div>" | |
| 427 "<div id='m2'>m2</div>"; | |
| 428 const char* shadowHTML1 = | |
| 429 "<div id='s1'>" | |
| 430 "<content></content>" | |
| 431 "</div>"; | |
| 432 | |
| 433 setupSampleHTML(mainHTML, shadowHTML1, 1); | |
| 434 | |
| 435 const char* shadowHTML2 = | |
| 436 "<div id='s2'>" | |
| 437 "<content select='#m10'></content>" | |
| 438 "<span id='s21'>s21</span>" | |
| 439 "</div>"; | |
| 440 | |
| 441 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 442 RefPtrWillBeRawPtr<Element> m1 = body->querySelector("#m1", ASSERT_NO_EXCEPT
ION); | |
| 443 RefPtrWillBeRawPtr<Element> m10 = body->querySelector("#m10", ASSERT_NO_EXCE
PTION); | |
| 444 | |
| 445 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = m1->openShadowRoot(); | |
| 446 RefPtrWillBeRawPtr<Element> s1 = shadowRoot1->querySelector("#s1", ASSERT_NO
_EXCEPTION); | |
| 447 | |
| 448 attachV0ShadowRoot(*s1, shadowHTML2); | |
| 449 | |
| 450 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot2 = s1->openShadowRoot(); | |
| 451 RefPtrWillBeRawPtr<Element> s21 = shadowRoot2->querySelector("#s21", ASSERT_
NO_EXCEPTION); | |
| 452 | |
| 453 EXPECT_EQ(s21.get(), ComposedTreeTraversal::nextSibling(*m10)); | |
| 454 EXPECT_EQ(m10.get(), ComposedTreeTraversal::previousSibling(*s21)); | |
| 455 | |
| 456 // ComposedTreeTraversal::traverseSiblings does not work for a node which is
not in a document composed tree. | |
| 457 // e.g. The following test fails. The result of ComposedTreeTraversal::previ
ousSibling(*m11)) will be #m10, instead of nullptr. | |
| 458 // RefPtrWillBeRawPtr<Element> m11 = body->querySelector("#m11", ASSERT_NO_E
XCEPTION); | |
| 459 // EXPECT_EQ(nullptr, ComposedTreeTraversal::previousSibling(*m11)); | |
| 460 } | |
| 461 | |
| 462 TEST_F(ComposedTreeTraversalTest, v1Simple) | |
| 463 { | |
| 464 const char* mainHTML = | |
| 465 "<div id='host'>" | |
| 466 "<div id='child1' slot='slot1'></div>" | |
| 467 "<div id='child2' slot='slot2'></div>" | |
| 468 "</div>"; | |
| 469 const char* shadowHTML = | |
| 470 "<div id='shadow-child1'></div>" | |
| 471 "<slot name='slot1'></slot>" | |
| 472 "<slot name='slot2'></slot>" | |
| 473 "<div id='shadow-child2'></div>"; | |
| 474 | |
| 475 setupDocumentTree(mainHTML); | |
| 476 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 477 RefPtrWillBeRawPtr<Element> host = body->querySelector("#host", ASSERT_NO_EX
CEPTION); | |
| 478 RefPtrWillBeRawPtr<Element> child1 = body->querySelector("#child1", ASSERT_N
O_EXCEPTION); | |
| 479 RefPtrWillBeRawPtr<Element> child2 = body->querySelector("#child2", ASSERT_N
O_EXCEPTION); | |
| 480 | |
| 481 attachOpenShadowRoot(*host, shadowHTML); | |
| 482 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = host->openShadowRoot(); | |
| 483 RefPtrWillBeRawPtr<Element> slot1 = shadowRoot->querySelector("[name=slot1]"
, ASSERT_NO_EXCEPTION); | |
| 484 RefPtrWillBeRawPtr<Element> slot2 = shadowRoot->querySelector("[name=slot2]"
, ASSERT_NO_EXCEPTION); | |
| 485 RefPtrWillBeRawPtr<Element> shadowChild1 = shadowRoot->querySelector("#shado
w-child1", ASSERT_NO_EXCEPTION); | |
| 486 RefPtrWillBeRawPtr<Element> shadowChild2 = shadowRoot->querySelector("#shado
w-child2", ASSERT_NO_EXCEPTION); | |
| 487 | |
| 488 EXPECT_TRUE(slot1); | |
| 489 EXPECT_TRUE(slot2); | |
| 490 EXPECT_EQ(shadowChild1.get(), ComposedTreeTraversal::firstChild(*host)); | |
| 491 EXPECT_EQ(child1.get(), ComposedTreeTraversal::nextSibling(*shadowChild1)); | |
| 492 EXPECT_EQ(child2.get(), ComposedTreeTraversal::nextSibling(*child1)); | |
| 493 EXPECT_EQ(shadowChild2.get(), ComposedTreeTraversal::nextSibling(*child2)); | |
| 494 } | |
| 495 | |
| 496 TEST_F(ComposedTreeTraversalTest, v1Redistribution) | |
| 497 { | |
| 498 const char* mainHTML = | |
| 499 "<div id='d1'>" | |
| 500 "<div id='d2' slot='d1-s1'></div>" | |
| 501 "<div id='d3' slot='d1-s2'></div>" | |
| 502 "<div id='d4' slot='nonexistent'></div>" | |
| 503 "<div id='d5'></div>" | |
| 504 "</div>" | |
| 505 "<div id='d6'></div>"; | |
| 506 const char* shadowHTML1 = | |
| 507 "<div id='d1-1'>" | |
| 508 "<div id='d1-2'></div>" | |
| 509 "<slot id='d1-s0'></slot>" | |
| 510 "<slot name='d1-s1' slot='d1-1-s1'></slot>" | |
| 511 "<slot name='d1-s2'></slot>" | |
| 512 "<div id='d1-3'></div>" | |
| 513 "<div id='d1-4' slot='d1-1-s1'></div>" | |
| 514 "</div>"; | |
| 515 const char* shadowHTML2 = | |
| 516 "<div id='d1-1-1'></div>" | |
| 517 "<slot name='d1-1-s1'></slot>" | |
| 518 "<slot name='d1-1-s2'></slot>" | |
| 519 "<div id='d1-1-2'></div>"; | |
| 520 | |
| 521 setupDocumentTree(mainHTML); | |
| 522 | |
| 523 RefPtrWillBeRawPtr<Element> body = document().body(); | |
| 524 RefPtrWillBeRawPtr<Element> d1 = body->querySelector("#d1", ASSERT_NO_EXCEPT
ION); | |
| 525 RefPtrWillBeRawPtr<Element> d2 = body->querySelector("#d2", ASSERT_NO_EXCEPT
ION); | |
| 526 RefPtrWillBeRawPtr<Element> d3 = body->querySelector("#d3", ASSERT_NO_EXCEPT
ION); | |
| 527 RefPtrWillBeRawPtr<Element> d4 = body->querySelector("#d4", ASSERT_NO_EXCEPT
ION); | |
| 528 RefPtrWillBeRawPtr<Element> d5 = body->querySelector("#d5", ASSERT_NO_EXCEPT
ION); | |
| 529 RefPtrWillBeRawPtr<Element> d6 = body->querySelector("#d6", ASSERT_NO_EXCEPT
ION); | |
| 530 | |
| 531 attachOpenShadowRoot(*d1, shadowHTML1); | |
| 532 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = d1->openShadowRoot(); | |
| 533 RefPtrWillBeRawPtr<Element> d11 = shadowRoot1->querySelector("#d1-1", ASSERT
_NO_EXCEPTION); | |
| 534 RefPtrWillBeRawPtr<Element> d12 = shadowRoot1->querySelector("#d1-2", ASSERT
_NO_EXCEPTION); | |
| 535 RefPtrWillBeRawPtr<Element> d13 = shadowRoot1->querySelector("#d1-3", ASSERT
_NO_EXCEPTION); | |
| 536 RefPtrWillBeRawPtr<Element> d14 = shadowRoot1->querySelector("#d1-4", ASSERT
_NO_EXCEPTION); | |
| 537 RefPtrWillBeRawPtr<Element> d1s0 = shadowRoot1->querySelector("#d1-s0", ASSE
RT_NO_EXCEPTION); | |
| 538 RefPtrWillBeRawPtr<Element> d1s1 = shadowRoot1->querySelector("[name=d1-s1]"
, ASSERT_NO_EXCEPTION); | |
| 539 RefPtrWillBeRawPtr<Element> d1s2 = shadowRoot1->querySelector("[name=d1-s2]"
, ASSERT_NO_EXCEPTION); | |
| 540 | |
| 541 attachOpenShadowRoot(*d11, shadowHTML2); | |
| 542 RefPtrWillBeRawPtr<ShadowRoot> shadowRoot2 = d11->openShadowRoot(); | |
| 543 RefPtrWillBeRawPtr<Element> d111 = shadowRoot2->querySelector("#d1-1-1", ASS
ERT_NO_EXCEPTION); | |
| 544 RefPtrWillBeRawPtr<Element> d112 = shadowRoot2->querySelector("#d1-1-2", ASS
ERT_NO_EXCEPTION); | |
| 545 RefPtrWillBeRawPtr<Element> d11s1 = shadowRoot2->querySelector("[name=d1-1-s
1]", ASSERT_NO_EXCEPTION); | |
| 546 RefPtrWillBeRawPtr<Element> d11s2 = shadowRoot2->querySelector("[name=d1-1-s
2]", ASSERT_NO_EXCEPTION); | |
| 547 | |
| 548 EXPECT_TRUE(d5); | |
| 549 EXPECT_TRUE(d12); | |
| 550 EXPECT_TRUE(d13); | |
| 551 EXPECT_TRUE(d1s0); | |
| 552 EXPECT_TRUE(d1s1); | |
| 553 EXPECT_TRUE(d1s2); | |
| 554 EXPECT_TRUE(d11s1); | |
| 555 EXPECT_TRUE(d11s2); | |
| 556 EXPECT_EQ(d11.get(), ComposedTreeTraversal::next(*d1)); | |
| 557 EXPECT_EQ(d111.get(), ComposedTreeTraversal::next(*d11)); | |
| 558 EXPECT_EQ(d2.get(), ComposedTreeTraversal::next(*d111)); | |
| 559 EXPECT_EQ(d14.get(), ComposedTreeTraversal::next(*d2)); | |
| 560 EXPECT_EQ(d112.get(), ComposedTreeTraversal::next(*d14)); | |
| 561 EXPECT_EQ(d6.get(), ComposedTreeTraversal::next(*d112)); | |
| 562 | |
| 563 EXPECT_EQ(d112.get(), ComposedTreeTraversal::previous(*d6)); | |
| 564 | |
| 565 EXPECT_EQ(d11.get(), ComposedTreeTraversal::parent(*d111)); | |
| 566 EXPECT_EQ(d11.get(), ComposedTreeTraversal::parent(*d112)); | |
| 567 EXPECT_EQ(d11.get(), ComposedTreeTraversal::parent(*d2)); | |
| 568 EXPECT_EQ(d11.get(), ComposedTreeTraversal::parent(*d14)); | |
| 569 EXPECT_EQ(nullptr, ComposedTreeTraversal::parent(*d3)); | |
| 570 EXPECT_EQ(nullptr, ComposedTreeTraversal::parent(*d4)); | |
| 571 } | |
| 572 | |
| 573 } // namespace blink | |
| OLD | NEW |