import { Build, getElement } from '@stencil/core';
function queryForSlot(el, slotName) {
  const query = slotName ? `slot[name="${slotName}"]` : 'slot:not([name])';
  return el.shadowRoot ? el.shadowRoot.querySelector(query) : el.querySelector(query);
}
export default function SlotChange(slotName = '', immediately = true) {
  return (proto, method) => {
    // the compiler optimizes lifecycle events out unless explicity declared in one of the components
    // this fixes the issue by telling the compiler to include it
    ;
    Build.cmpDidLoad = true;
    if (!('__slots' in proto)) {
      proto.__slots = {};
    }
    if (!('slot' in proto)) {
      proto.__slot = null;
    }
    const { componentDidLoad, disconnectedCallback } = proto;
    function registerSlotListener() {
      const host = getElement(this);
      const slot = queryForSlot(host, slotName);
      const handler = proto[method].bind(this, slot);
      const slotItem = {
        slot,
        host,
        slotName,
        handler,
      };
      // make sure the slot actually exists
      if (!slot) {
        console.error('The requested slot was not found');
        return;
      }
      // store the slot handler for later event removal
      if (slotName == '') {
        proto.__slot = slotItem;
      }
      else {
        proto.__slots[slotName] = slotItem;
      }
      // watch the slot for changes
      slot.addEventListener('slotChange', handler);
      if (immediately) {
        // do an initial trigger of the slot change handler
        handler();
      }
    }
    proto.componentDidLoad = function () {
      registerSlotListener.apply(this);
      return componentDidLoad && componentDidLoad.apply(this);
    };
    proto.disconnectedCallback = function () {
      // remove change event for the default slot
      if (proto.__slot) {
        proto.__slot.slot.removeEventListener('slotChange', proto.__slot.handler);
        proto.__slot = null;
      }
      // remove change event for named slots
      Object.values(proto.__slots).forEach(({ slotName, slot, handler }) => {
        slot.removeEventListener('slotChange', handler);
        delete proto.__slots[slotName];
      });
      return disconnectedCallback && disconnectedCallback.apply(this);
    };
  };
}
//# sourceMappingURL=slot-change.js.map
