@@ -335,6 +335,166 @@ describe('SlotController', () => {
335335 } ) ;
336336 } ) ;
337337
338+ describe ( 'data-slot-ignore attribute' , ( ) => {
339+ let defaultNode ;
340+
341+ describe ( 'single slot with observe enabled' , ( ) => {
342+ beforeEach ( async ( ) => {
343+ element = fixtureSync ( `<${ tag } ></${ tag } >` ) ;
344+ controller = new SlotController ( element , 'foo' , 'div' , {
345+ initializer : ( node ) => {
346+ node . textContent = 'default content' ;
347+ } ,
348+ } ) ;
349+ element . addController ( controller ) ;
350+ defaultNode = element . querySelector ( '[slot="foo"]' ) ;
351+ // Wait for initial slotchange event
352+ await nextFrame ( ) ;
353+ } ) ;
354+
355+ it ( 'should ignore element with data-slot-ignore when checking slot children' , ( ) => {
356+ const ignored = document . createElement ( 'div' ) ;
357+ ignored . setAttribute ( 'slot' , 'foo' ) ;
358+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
359+ ignored . textContent = 'ignored' ;
360+ element . appendChild ( ignored ) ;
361+
362+ const slotChildren = controller . getSlotChildren ( ) ;
363+ expect ( slotChildren ) . to . not . include ( ignored ) ;
364+ expect ( slotChildren ) . to . include ( defaultNode ) ;
365+ } ) ;
366+
367+ it ( 'should not remove default node when element with data-slot-ignore is added' , async ( ) => {
368+ const ignored = document . createElement ( 'div' ) ;
369+ ignored . setAttribute ( 'slot' , 'foo' ) ;
370+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
371+ ignored . textContent = 'ignored' ;
372+ element . appendChild ( ignored ) ;
373+
374+ await nextFrame ( ) ;
375+ expect ( defaultNode . isConnected ) . to . be . true ;
376+ expect ( defaultNode . textContent ) . to . equal ( 'default content' ) ;
377+ } ) ;
378+
379+ it ( 'should remove default node when non-ignored element is added' , async ( ) => {
380+ const ignored = document . createElement ( 'div' ) ;
381+ ignored . setAttribute ( 'slot' , 'foo' ) ;
382+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
383+ ignored . textContent = 'ignored' ;
384+ element . appendChild ( ignored ) ;
385+
386+ await nextFrame ( ) ;
387+ expect ( defaultNode . isConnected ) . to . be . true ;
388+
389+ const custom = document . createElement ( 'div' ) ;
390+ custom . setAttribute ( 'slot' , 'foo' ) ;
391+ custom . textContent = 'custom' ;
392+ element . appendChild ( custom ) ;
393+
394+ await nextFrame ( ) ;
395+ expect ( defaultNode . isConnected ) . to . be . false ;
396+ expect ( controller . node ) . to . equal ( custom ) ;
397+ } ) ;
398+
399+ it ( 'should not call initCustomNode for element with data-slot-ignore' , async ( ) => {
400+ const initSpy = sinon . spy ( controller , 'initCustomNode' ) ;
401+
402+ const ignored = document . createElement ( 'div' ) ;
403+ ignored . setAttribute ( 'slot' , 'foo' ) ;
404+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
405+ ignored . textContent = 'ignored' ;
406+ element . appendChild ( ignored ) ;
407+
408+ await nextFrame ( ) ;
409+ expect ( initSpy . called ) . to . be . false ;
410+ } ) ;
411+ } ) ;
412+
413+ describe ( 'multiple slot with observe enabled' , ( ) => {
414+ let defaultNode ;
415+
416+ beforeEach ( async ( ) => {
417+ element = fixtureSync ( `<${ tag } ></${ tag } >` ) ;
418+ controller = new SlotController ( element , '' , 'div' , {
419+ initializer : ( node ) => {
420+ node . textContent = 'default content' ;
421+ } ,
422+ multiple : true ,
423+ } ) ;
424+ element . addController ( controller ) ;
425+ defaultNode = element . querySelector ( ':not([slot])' ) ;
426+ // Wait for initial slotchange event
427+ await nextFrame ( ) ;
428+ } ) ;
429+
430+ it ( 'should ignore element with data-slot-ignore in multiple mode' , ( ) => {
431+ const ignored = document . createElement ( 'div' ) ;
432+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
433+ ignored . textContent = 'ignored' ;
434+ element . appendChild ( ignored ) ;
435+
436+ const slotChildren = controller . getSlotChildren ( ) ;
437+ expect ( slotChildren ) . to . not . include ( ignored ) ;
438+ expect ( slotChildren ) . to . include ( defaultNode ) ;
439+ } ) ;
440+
441+ it ( 'should not remove default node when element with data-slot-ignore is added in multiple mode' , async ( ) => {
442+ const ignored = document . createElement ( 'div' ) ;
443+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
444+ ignored . textContent = 'ignored' ;
445+ element . appendChild ( ignored ) ;
446+
447+ await nextFrame ( ) ;
448+ expect ( defaultNode . isConnected ) . to . be . true ;
449+ expect ( controller . nodes ) . to . include ( defaultNode ) ;
450+ expect ( controller . nodes ) . to . not . include ( ignored ) ;
451+ } ) ;
452+
453+ it ( 'should remove default node when non-ignored element is added in multiple mode' , async ( ) => {
454+ const ignored = document . createElement ( 'div' ) ;
455+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
456+ ignored . textContent = 'ignored' ;
457+ element . appendChild ( ignored ) ;
458+
459+ await nextFrame ( ) ;
460+ expect ( defaultNode . isConnected ) . to . be . true ;
461+
462+ const custom = document . createElement ( 'div' ) ;
463+ custom . textContent = 'custom' ;
464+ element . appendChild ( custom ) ;
465+
466+ await nextFrame ( ) ;
467+ expect ( defaultNode . isConnected ) . to . be . false ;
468+ expect ( controller . nodes ) . to . include ( custom ) ;
469+ expect ( controller . nodes ) . to . not . include ( defaultNode ) ;
470+ expect ( controller . nodes ) . to . not . include ( ignored ) ;
471+ } ) ;
472+
473+ it ( 'should allow multiple custom elements alongside ignored elements' , async ( ) => {
474+ const custom1 = document . createElement ( 'div' ) ;
475+ custom1 . textContent = 'custom1' ;
476+ element . appendChild ( custom1 ) ;
477+
478+ const ignored = document . createElement ( 'div' ) ;
479+ ignored . setAttribute ( 'data-slot-ignore' , '' ) ;
480+ ignored . textContent = 'ignored' ;
481+ element . appendChild ( ignored ) ;
482+
483+ const custom2 = document . createElement ( 'div' ) ;
484+ custom2 . textContent = 'custom2' ;
485+ element . appendChild ( custom2 ) ;
486+
487+ await nextFrame ( ) ;
488+
489+ expect ( defaultNode . isConnected ) . to . be . false ;
490+ expect ( controller . nodes ) . to . have . lengthOf ( 2 ) ;
491+ expect ( controller . nodes ) . to . include ( custom1 ) ;
492+ expect ( controller . nodes ) . to . include ( custom2 ) ;
493+ expect ( controller . nodes ) . to . not . include ( ignored ) ;
494+ } ) ;
495+ } ) ;
496+ } ) ;
497+
338498 describe ( 'multiple nodes' , ( ) => {
339499 let children , initializeSpy ;
340500
0 commit comments