slots.html (15806B)
1 <!DOCTYPE html> 2 <title>Shadow DOM: Slots and assignments</title> 3 <meta name="author" title="Hayato Ito" href="mailto:hayato@google.com"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="resources/shadow-dom.js"></script> 7 8 <div id="test_basic"> 9 <div id="host"> 10 <template data-mode="open"> 11 <slot id="s1" name="slot1"></slot> 12 </template> 13 <div id="c1" slot="slot1"></div> 14 </div> 15 </div> 16 17 <script> 18 test(() => { 19 let n = createTestTree(test_basic); 20 removeWhiteSpaceOnlyTextNodes(n.test_basic); 21 22 assert_equals(n.c1.assignedSlot, n.s1); 23 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 24 }, 'Slots: Basic.'); 25 26 test(() => { 27 let n = createTestTree(test_basic); 28 29 assert_array_equals(n.s1.assignedElements(), [n.c1]); 30 }, 'Slots: Basic, elements only.'); 31 </script> 32 33 <div id="test_basic_closed"> 34 <div id="host"> 35 <template data-mode="closed"> 36 <slot id="s1" name="slot1"></slot> 37 </template> 38 <div id="c1" slot="slot1"></div> 39 </div> 40 </div> 41 42 <script> 43 test(() => { 44 let n = createTestTree(test_basic_closed); 45 removeWhiteSpaceOnlyTextNodes(n.test_basic_closed); 46 47 assert_equals(n.c1.assignedSlot, null); 48 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 49 }, 'Slots: Slots in closed.'); 50 51 test(() => { 52 let n = createTestTree(test_basic_closed); 53 54 assert_array_equals(n.s1.assignedElements(), [n.c1]); 55 }, 'Slots: Slots in closed, elements only.'); 56 </script> 57 58 <div id="test_slot_not_in_shadow"> 59 <slot id="s1"></slot> 60 </div> 61 62 <script> 63 test(() => { 64 let n = createTestTree(test_slot_not_in_shadow); 65 removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow); 66 67 assert_array_equals(n.s1.assignedNodes(), []); 68 }, 'Slots: Slots not in a shadow tree.'); 69 70 test(() => { 71 let n = createTestTree(test_slot_not_in_shadow); 72 73 assert_array_equals(n.s1.assignedElements(), []); 74 }, 'Slots: Slots not in a shadow tree, elements only.'); 75 </script> 76 77 <div id="test_slot_not_in_shadow_2"> 78 <slot id="s1"> 79 <div id="c1"></div> 80 </slot> 81 <slot id="s2"> 82 <div id="c2"></div> 83 <slot id="s3"> 84 <div id="c3_1"></div> 85 <div id="c3_2"></div> 86 </slot> 87 </slot> 88 </div> 89 90 <script> 91 test(() => { 92 let n = createTestTree(test_slot_not_in_shadow_2); 93 removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow_2); 94 95 assert_equals(n.c1.assignedSlot, null); 96 assert_equals(n.c2.assignedSlot, null); 97 assert_equals(n.c3_1.assignedSlot, null); 98 assert_equals(n.c3_2.assignedSlot, null); 99 100 assert_array_equals(n.s1.assignedNodes(), []); 101 assert_array_equals(n.s2.assignedNodes(), []); 102 assert_array_equals(n.s3.assignedNodes(), []); 103 104 assert_array_equals(n.s1.assignedNodes({ flatten: true }), []); 105 assert_array_equals(n.s2.assignedNodes({ flatten: true }), []); 106 assert_array_equals(n.s3.assignedNodes({ flatten: true }), []); 107 }, 'Slots: Distributed nodes for Slots not in a shadow tree.'); 108 </script> 109 110 <div id="test_slot_name_matching"> 111 <div id="host"> 112 <template data-mode="open"> 113 <slot id="s1" name="slot1"></slot> 114 <slot id="s2" name="slot2"></slot> 115 <slot id="s3" name="xxx"></slot> 116 </template> 117 <div id="c1" slot="slot1"></div> 118 <div id="c2" slot="slot2"></div> 119 <div id="c3" slot="yyy"></div> 120 </div> 121 </div> 122 123 <script> 124 test(() => { 125 let n = createTestTree(test_slot_name_matching); 126 removeWhiteSpaceOnlyTextNodes(n.test_slot_name_matching); 127 128 assert_equals(n.c1.assignedSlot, n.s1); 129 assert_equals(n.c2.assignedSlot, n.s2); 130 assert_equals(n.c3.assignedSlot, null); 131 }, 'Slots: Name matching'); 132 </script> 133 134 <div id="test_no_direct_host_child"> 135 <div id="host"> 136 <template data-mode="open"> 137 <slot id="s1" name="slot1"></slot> 138 <slot id="s2" name="slot1"></slot> 139 </template> 140 <div id="c1" slot="slot1"></div> 141 <div id="c2" slot="slot1"></div> 142 <div> 143 <div id="c3" slot="slot1"></div> 144 </div> 145 </div> 146 </div> 147 148 <script> 149 test(() => { 150 let n = createTestTree(test_no_direct_host_child); 151 removeWhiteSpaceOnlyTextNodes(n.test_no_direct_host_child); 152 153 assert_equals(n.c1.assignedSlot, n.s1); 154 assert_equals(n.c2.assignedSlot, n.s1); 155 assert_equals(n.c3.assignedSlot, null); 156 157 assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c2]); 158 }, 'Slots: No direct host child.'); 159 </script> 160 161 <div id="test_default_slot"> 162 <div id="host"> 163 <template data-mode="open"> 164 <slot id="s1" name="slot1"></slot> 165 <slot id="s2"></slot> 166 <slot id="s3"></slot> 167 </template> 168 <div id="c1"></div> 169 <div id="c2" slot=""></div> 170 <div id="c3" slot="foo"></div> 171 </div> 172 </div> 173 174 <script> 175 test(() => { 176 let n = createTestTree(test_default_slot); 177 removeWhiteSpaceOnlyTextNodes(n.test_default_slot); 178 179 assert_equals(n.c1.assignedSlot, n.s2); 180 assert_equals(n.c2.assignedSlot, n.s2); 181 assert_equals(n.c3.assignedSlot, null); 182 }, 'Slots: Default Slot.'); 183 </script> 184 185 <div id="test_slot_in_slot"> 186 <div id="host"> 187 <template data-mode="open"> 188 <slot id="s1" name="slot1"> 189 <slot id="s2" name="slot2"></slot> 190 </slot> 191 </template> 192 <div id="c1" slot="slot2"></div> 193 <div id="c2" slot="slot1"></div> 194 </div> 195 </div> 196 197 <script> 198 test(() => { 199 let n = createTestTree(test_slot_in_slot); 200 removeWhiteSpaceOnlyTextNodes(n.test_slot_in_slot); 201 202 assert_equals(n.c1.assignedSlot, n.s2); 203 assert_equals(n.c2.assignedSlot, n.s1); 204 }, 'Slots: Slot in Slot does not matter in assignment.'); 205 </script> 206 207 <div id="test_slot_is_assigned_to_slot"> 208 <div id="host1"> 209 <template data-mode="open"> 210 <div id="host2"> 211 <template data-mode="open"> 212 <slot id="s2" name="slot2"></slot> 213 </template> 214 <slot id="s1" name="slot1" slot="slot2"></slot> 215 </div> 216 </template> 217 <div id="c1" slot="slot1"></div> 218 </div> 219 </div> 220 221 <script> 222 test(() => { 223 let n = createTestTree(test_slot_is_assigned_to_slot); 224 removeWhiteSpaceOnlyTextNodes(n.test_slot_is_assigned_to_slot); 225 226 assert_equals(n.c1.assignedSlot, n.s1); 227 assert_equals(n.s1.assignedSlot, n.s2); 228 229 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 230 assert_array_equals(n.s2.assignedNodes(), [n.s1]); 231 232 assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]); 233 assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]); 234 }, 'Slots: Slot is assigned to another slot'); 235 </script> 236 237 <div id="test_open_closed"> 238 <div id="host1"> 239 <template data-mode="open"> 240 <div id="host2"> 241 <template data-mode="closed"> 242 <slot id="s2" name="slot2"></slot> 243 </template> 244 <slot id="s1" name="slot1" slot="slot2"></slot> 245 </div> 246 </template> 247 <div id="c1" slot="slot1"></div> 248 </div> 249 </div> 250 251 <script> 252 test(() => { 253 let n = createTestTree(test_open_closed); 254 removeWhiteSpaceOnlyTextNodes(n.test_open_closed); 255 256 assert_equals(n.c1.assignedSlot, n.s1); 257 assert_equals(n.s1.assignedSlot, null, 258 'A slot in a closed shadow tree should not be accessed via assignedSlot'); 259 260 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 261 assert_array_equals(n.s2.assignedNodes(), [n.s1]); 262 263 assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]); 264 assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]); 265 }, 'Slots: Open > Closed.'); 266 </script> 267 268 <div id="test_closed_closed"> 269 <div id="host1"> 270 <template data-mode="closed"> 271 <div id="host2"> 272 <template data-mode="closed"> 273 <slot id="s2" name="slot2"></slot> 274 </template> 275 <slot id="s1" name="slot1" slot="slot2"></slot> 276 </div> 277 </template> 278 <div id="c1" slot="slot1"></div> 279 </div> 280 </div> 281 282 <script> 283 test(() => { 284 let n = createTestTree(test_closed_closed); 285 removeWhiteSpaceOnlyTextNodes(n.test_closed_closed); 286 287 assert_equals(n.c1.assignedSlot, null, 288 'A slot in a closed shadow tree should not be accessed via assignedSlot'); 289 assert_equals(n.s1.assignedSlot, null, 290 'A slot in a closed shadow tree should not be accessed via assignedSlot'); 291 292 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 293 assert_array_equals(n.s2.assignedNodes(), [n.s1]); 294 295 assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]); 296 assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]); 297 }, 'Slots: Closed > Closed.'); 298 </script> 299 300 <div id="test_closed_open"> 301 <div id="host1"> 302 <template data-mode="closed"> 303 <div id="host2"> 304 <template data-mode="open"> 305 <slot id="s2" name="slot2"></slot> 306 </template> 307 <slot id="s1" name="slot1" slot="slot2"></slot> 308 </div> 309 </template> 310 <div id="c1" slot="slot1"></div> 311 </div> 312 </div> 313 314 <script> 315 test(() => { 316 let n = createTestTree(test_closed_open); 317 removeWhiteSpaceOnlyTextNodes(n.test_closed_open); 318 319 assert_equals(n.c1.assignedSlot, null, 320 'A slot in a closed shadow tree should not be accessed via assignedSlot'); 321 assert_equals(n.s1.assignedSlot, n.s2); 322 323 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 324 assert_array_equals(n.s2.assignedNodes(), [n.s1]); 325 326 assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]); 327 assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]); 328 }, 'Slots: Closed > Open.'); 329 </script> 330 331 <div id="test_complex"> 332 <div id="host1"> 333 <template data-mode="open"> 334 <div id="host2"> 335 <template data-mode="open"> 336 <slot id="s5" name="slot5"></slot> 337 <slot id="s6" name="slot6"></slot> 338 <slot id="s7"></slot> 339 <slot id="s8" name="slot8"></slot> 340 </template> 341 <slot id="s1" name="slot1" slot="slot5"></slot> 342 <slot id="s2" name="slot2" slot="slot6"></slot> 343 <slot id="s3"></slot> 344 <slot id="s4" name="slot4" slot="slot-none"></slot> 345 <div id="c5" slot="slot5"></div> 346 <div id="c6" slot="slot6"></div> 347 <div id="c7"></div> 348 <div id="c8" slot="slot-none"></div> 349 </div> 350 </template> 351 <div id="c1" slot="slot1"></div> 352 <div id="c2" slot="slot2"></div> 353 <div id="c3"></div> 354 <div id="c4" slot="slot-none"></div> 355 </div> 356 </div> 357 358 <script> 359 test(() => { 360 let n = createTestTree(test_complex); 361 removeWhiteSpaceOnlyTextNodes(n.test_complex); 362 363 assert_equals(n.c1.assignedSlot, n.s1); 364 assert_equals(n.c2.assignedSlot, n.s2); 365 assert_equals(n.c3.assignedSlot, n.s3); 366 assert_equals(n.c4.assignedSlot, null); 367 368 assert_equals(n.s1.assignedSlot, n.s5); 369 assert_equals(n.s2.assignedSlot, n.s6); 370 assert_equals(n.s3.assignedSlot, n.s7); 371 assert_equals(n.s4.assignedSlot, null); 372 373 assert_equals(n.c5.assignedSlot, n.s5); 374 assert_equals(n.c6.assignedSlot, n.s6); 375 assert_equals(n.c7.assignedSlot, n.s7); 376 assert_equals(n.c8.assignedSlot, null); 377 378 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 379 assert_array_equals(n.s2.assignedNodes(), [n.c2]); 380 assert_array_equals(n.s3.assignedNodes(), [n.c3]); 381 assert_array_equals(n.s4.assignedNodes(), []); 382 assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]); 383 assert_array_equals(n.s6.assignedNodes(), [n.s2, n.c6]); 384 assert_array_equals(n.s7.assignedNodes(), [n.s3, n.c7]); 385 assert_array_equals(n.s8.assignedNodes(), []); 386 387 assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]); 388 assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c2]); 389 assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c3]); 390 assert_array_equals(n.s4.assignedNodes({ flatten: true }), []); 391 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c5]); 392 assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c2, n.c6]); 393 assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c3, n.c7]); 394 assert_array_equals(n.s8.assignedNodes({ flatten: true }), []); 395 }, 'Slots: Complex case: Basi line.'); 396 397 test(() => { 398 let n = createTestTree(test_complex); 399 removeWhiteSpaceOnlyTextNodes(n.test_complex); 400 401 let d1 = document.createElement('div'); 402 d1.setAttribute('slot', 'slot1'); 403 n.host1.appendChild(d1); 404 405 assert_array_equals(n.s1.assignedNodes(), [n.c1, d1]); 406 assert_equals(d1.assignedSlot, n.s1); 407 408 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, d1, n.c5]); 409 }, 'Slots: Mutation: appendChild.'); 410 411 test(() => { 412 let n = createTestTree(test_complex); 413 removeWhiteSpaceOnlyTextNodes(n.test_complex); 414 415 n.c1.setAttribute('slot', 'slot-none'); 416 417 assert_array_equals(n.s1.assignedNodes(), []); 418 assert_equals(n.c1.assignedSlot, null); 419 420 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]); 421 }, 'Slots: Mutation: Change slot= attribute 1.'); 422 423 test(() => { 424 let n = createTestTree(test_complex); 425 removeWhiteSpaceOnlyTextNodes(n.test_complex); 426 427 n.c1.setAttribute('slot', 'slot2'); 428 429 assert_array_equals(n.s1.assignedNodes(), []); 430 assert_array_equals(n.s2.assignedNodes(), [n.c1, n.c2]); 431 assert_equals(n.c1.assignedSlot, n.s2); 432 433 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]); 434 assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]); 435 }, 'Slots: Mutation: Change slot= attribute 2.'); 436 437 test(() => { 438 let n = createTestTree(test_complex); 439 removeWhiteSpaceOnlyTextNodes(n.test_complex); 440 441 n.c4.setAttribute('slot', 'slot1'); 442 443 assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c4]); 444 assert_equals(n.c4.assignedSlot, n.s1); 445 446 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c4, n.c5]); 447 }, 'Slots: Mutation: Change slot= attribute 3.'); 448 449 test(() => { 450 let n = createTestTree(test_complex); 451 removeWhiteSpaceOnlyTextNodes(n.test_complex); 452 453 n.c1.remove(); 454 455 assert_array_equals(n.s1.assignedNodes(), []); 456 assert_equals(n.c1.assignedSlot, null); 457 458 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]); 459 }, 'Slots: Mutation: Remove a child.'); 460 461 test(() => { 462 let n = createTestTree(test_complex); 463 removeWhiteSpaceOnlyTextNodes(n.test_complex); 464 465 let slot = document.createElement('slot'); 466 slot.setAttribute('name', 'slot1'); 467 n.host2.appendChild(slot); 468 469 assert_array_equals(slot.assignedNodes(), []); 470 }, 'Slots: Mutation: Add a slot: after.'); 471 472 test(() => { 473 let n = createTestTree(test_complex); 474 removeWhiteSpaceOnlyTextNodes(n.test_complex); 475 476 let slot = document.createElement('slot'); 477 slot.setAttribute('name', 'slot1'); 478 n.host2.insertBefore(slot, n.s1); 479 480 assert_array_equals(slot.assignedNodes(), [n.c1]); 481 assert_equals(n.c1.assignedSlot, slot); 482 483 assert_array_equals(n.s7.assignedNodes(), [slot, n.s3, n.c7]); 484 assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c1, n.c3, n.c7]); 485 }, 'Slots: Mutation: Add a slot: before.'); 486 487 test(() => { 488 let n = createTestTree(test_complex); 489 removeWhiteSpaceOnlyTextNodes(n.test_complex); 490 491 n.s1.remove(); 492 493 assert_array_equals(n.s1.assignedNodes(), []); 494 assert_equals(n.c1.assignedSlot, null); 495 496 assert_array_equals(n.s5.assignedNodes(), [n.c5]); 497 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]); 498 }, 'Slots: Mutation: Remove a slot.'); 499 500 test(() => { 501 let n = createTestTree(test_complex); 502 removeWhiteSpaceOnlyTextNodes(n.test_complex); 503 504 n.s1.setAttribute('name', 'slot2'); 505 506 assert_array_equals(n.s1.assignedNodes(), [n.c2]); 507 assert_equals(n.c1.assignedSlot, null); 508 assert_equals(n.c2.assignedSlot, n.s1); 509 510 assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]); 511 assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c2, n.c5]); 512 }, 'Slots: Mutation: Change slot name= attribute.'); 513 514 test(() => { 515 let n = createTestTree(test_complex); 516 removeWhiteSpaceOnlyTextNodes(n.test_complex); 517 518 n.s1.setAttribute('slot', 'slot6'); 519 520 assert_array_equals(n.s1.assignedNodes(), [n.c1]); 521 522 assert_array_equals(n.s5.assignedNodes(), [n.c5]); 523 assert_array_equals(n.s6.assignedNodes(), [n.s1, n.s2, n.c6]); 524 assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]); 525 }, 'Slots: Mutation: Change slot slot= attribute.'); 526 </script>