¯\_(ツ)_/¯
  |   | 
  | 6 | 
   === 
  |   | 
  | | | 
  | | | 
   ^ ^ 

SlotchangeExplosion #1

We start viewing the situation from HTML.
  1. A portrait-frame with a bunch of pre children are declared in the top most lightDOM.
  2. The portrait-frame has a slot with a green-frame element that it chains its slot element to.
  3. The green-frame has a slot element.
  4. From the perspective of HTML, the declaration of the portrait-frame should trigger one relevant slotchange event as the pre elements are transposed from the topmost lightDOM to the slot inside green-frame.
In JS, you (most likely) see two slotchange events. Why?
  1. [slot#inner, document-fragment]
    [slot#outer]
    []
    The first slotchange event is caused by slot#outer being transposed into slot#inner. This slotchange event occurs on a temporary DOM branch construction. A this point in time, portrait-frame is still being created and no childNodes is yet connected to its host element. Therefore, the slot#inner.assignedElements({flatten: true}) returns an empty list. This slotchange event is not really redundant, a slotchange explosion, because we should be alerted about the slot#inner getting transposed content. The main problem with this slotchange event is that it is coming too early.
  2. [slot#outer, slot#inner, document-fragment, green-frame#frameOne, document-fragment]
    [pre, pre, pre, pre, pre, pre, pre]
    [pre, pre, pre, pre, pre, pre, pre]
    The second slotchange event is caused by all the pre elements being transposed into slot#outer. Important to note here is that this slotchange event is not dispatched on slot#inner, but bubbles *from* slot#outer *to* slot#inner. This is very strange, but it is because the flattened DOM looks like this:
    ...
      < portrait-frame >
        #shadowRoot
          ..
          < green-frame >
            #shadowRoot
              < slot#inner >
                < slot#outer >
                  < pre >¯\_(ツ)_/¯
                  < pre >  |   |
                  ...
        
    The second slotchange event is the one we want. The problem with this slotchange event is that it really dispatched on slot#outer, not the slot#inner. It would be natural to assume that when the pre-nodes become transposed all the way into slot#inner, a slotchange event would be dispatched directly from slot#inner. This is not so. The reason the slotchange event listener for slot#inner receives a slotchange event is that this event will bubble all the way up to #shadowRoot under portrait-frame.
  3. If your browser displays _more than_ two slotchange events, don't worry. I will explain why this happens in the next example.