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 |