{"version":3,"names":["getContentFromSlotElementsRecursively","slotElements","reduce","acc","currentValue","tagName","toLowerCase","tmpSlotElement","assignedElements","push","isElementChildOfComponent","componentEl","element","maxIterations","tmpElement","index","parentElement","getAttribute","getSlottedElements","slotName","selector","Array","from","shadowRoot","querySelectorAll","map","slotElement","assignedNodes","flat","getAllElementsWithSlotAttribute","filter","el","getFirstParentWithAttribute","attribute","attributeValue","currentEl","currentIteration","parentAttr","toString","getIsElementDescendantOfElement","el1","el2","getParentInDom","assignedSlot","getRootNode","rootNode","host","currentParent","getIsElementRTL","elem","Directions","RTL","document","documentElement","LTR","getHtmlDirObserver","onDirMutationCallback","config","attributes","childList","subtree","obs","MutationObserver","mutationList","htmlDirMutation","find","ml","target","nodeName","attributeName","isNullOrUndefined","observe"],"sources":["src/utils/DOMHelper.ts"],"sourcesContent":["import { Directions } from '../components/core/types/globalTypes';\nimport { isNullOrUndefined } from './collection';\n\n/**\n * Goes through the provided list of elements recursively and returns the underlying content from slot elements\n * @param {HTMLElement[]} slotElements  A list of elements to go through\n * @returns {HTMLElement[]}             The underlying content\n */\nexport const getContentFromSlotElementsRecursively = (slotElements: HTMLElement[]): HTMLElement[] => {\n  return slotElements.reduce((acc: HTMLElement[], currentValue) => {\n    if (currentValue.tagName && currentValue.tagName.toLowerCase() === 'slot') {\n      const tmpSlotElement = currentValue as HTMLSlotElement;\n      return getContentFromSlotElementsRecursively(tmpSlotElement.assignedElements() as HTMLElement[]);\n    }\n    acc.push(currentValue);\n    return acc;\n  }, []);\n};\n\n/**\n * Going up the chain of elements, it will return true if the given element is a child of the root node and false if it sits under an other (slotted) element\n * @param {HTMLElement} componentEl     The root element (parent)\n * @param {HTMLElement} element         The element in question\n * @param {number} maxIterations        Optional. Number of steps to find the parent. Default: 10\n * @returns {boolean}                   Whether or not the given element is a child of the root node\n */\nconst isElementChildOfComponent = (componentEl: HTMLElement, element: HTMLElement, maxIterations = 10): boolean => {\n  {\n    let tmpElement = element;\n    for (let index = 0; index < maxIterations; index++) {\n      if (tmpElement.parentElement === componentEl) {\n        return true;\n      }\n      if (!tmpElement.parentElement || tmpElement.parentElement.getAttribute('slot')) {\n        return false;\n      }\n\n      tmpElement = tmpElement.parentElement;\n    }\n  }\n};\n\n/**\n * Returns the content elements of the slots within a component\n * If browser doesn't support slots, it will return all the elements that are assigned to the space where the slot should be\n * @param {HTMLElement} element         The parent element\n * @param {string} slotName             Optional slot name for filtering results\n * @returns {Element[]}                 The content elements of the slots within a component\n */\nexport const getSlottedElements = (element: HTMLElement, slotName = ''): Element[] => {\n  const selector = slotName ? `slot[name=${slotName}]` : 'slot';\n\n  return getContentFromSlotElementsRecursively(\n    Array.from(element.shadowRoot.querySelectorAll(selector))\n      .map((slotElement: HTMLSlotElement) => slotElement.assignedNodes() as HTMLElement[])\n      .flat()\n  );\n};\n\n/**\n * Returns all the child elements within a slot property, regardless of them being in an actual slot or not\n * @param {HTMLElement} element         The parent element\n * @param {string} slotName             Optional slot name for filtering results\n * @returns {Element[]}                 The child elements within a slot\n */\nexport const getAllElementsWithSlotAttribute = (element: HTMLElement, slotName = ''): Element[] => {\n  const selector = slotName ? `[slot=${slotName}]` : '[slot]';\n  return Array.from(element.querySelectorAll(selector)).filter((el: HTMLElement) => isElementChildOfComponent(element, el));\n};\n\n/**\n * Going up the chain of elements, it returns the first element with the given attribute\n * @param {HTMLElement} el              The src element\n * @param {string} attribute            The attribute to look for\n * @param {string} attributeValue       The attribute value to look for\n * @param {number} maxIterations        Max iterations. Default 10\n * @returns {HTMLElement}               The first element with the given attribute\n */\nexport const getFirstParentWithAttribute = (el: HTMLElement, attribute: string, attributeValue: string, maxIterations = 10): HTMLElement => {\n  if (el.getAttribute(attribute) === attributeValue) {\n    return el;\n  }\n  let currentEl = el;\n  let currentIteration = 0;\n  while (currentEl && currentEl.parentElement && currentIteration <= maxIterations) {\n    const parentAttr = currentEl.parentElement.getAttribute(attribute);\n    if (parentAttr && parentAttr.toString().toLowerCase() === attributeValue.toString().toLowerCase()) {\n      return currentEl.parentElement;\n    }\n    currentEl = currentEl.parentElement;\n    currentIteration++;\n  }\n  return null;\n};\n\n/**\n * Starting from the given element, goes upwards in the dom accounting for slots and shadowRoot, it will return if the given element sits under an other element\n * @param {Element} el1 The descendant element\n * @param {Element} el2 The parent element\n * @param {number} maxIterations max iterations. Default = 20\n * @returns {boolean} True if element one is a descendant (in the DOM) of element two\n */\nexport const getIsElementDescendantOfElement = (el1: Element, el2: Element, maxIterations = 20): boolean => {\n  const getParentInDom = (el: Element): Element => {\n    // if it's under a slot, go to the slot\n    if (el.assignedSlot) {\n      return el.assignedSlot;\n      // if not under slot get the normal parent\n    } else if (el.parentElement) {\n      return el.parentElement;\n      // if there is no parent try and find the shadowroot host that contains the element\n    } else if (el.getRootNode()) {\n      const rootNode = el.getRootNode() as ShadowRoot;\n      return rootNode.host;\n    }\n  };\n\n  let currentIteration = 0;\n  let currentParent: Element = getParentInDom(el1);\n\n  while (currentParent && currentIteration <= maxIterations) {\n    if (currentParent === el2) {\n      return true;\n    }\n    currentParent = getParentInDom(currentParent);\n    currentIteration++;\n  }\n  return false;\n};\n\n/**\n * Given an element, calculate whether it should render in RTL mode\n * @param {Element} elem The element in question\n * @returns {boolean} Whether the element should render in RTL mode\n */\nexport const getIsElementRTL = (elem: Element): boolean => {\n  return (\n    elem.getAttribute('dir') === Directions.RTL ||\n    (document.documentElement.getAttribute('dir') === Directions.RTL && elem.getAttribute('dir') !== Directions.LTR)\n  );\n};\n\n/**\n * Sets a MutationObserver to detect dir change on the HTML element\n * @param {Function} onDirMutationCallback Callback to be executed when dir changes\n * @returns {MutationObserver} The mutation observer obj\n */\nexport const getHtmlDirObserver = (onDirMutationCallback: (htmlDirMutation?: MutationRecord) => void): MutationObserver => {\n  const config = { attributes: true, childList: false, subtree: false };\n  const obs = new MutationObserver((mutationList) => {\n    const htmlDirMutation = mutationList.find((ml) => ml.target.nodeName.toLowerCase() === 'html' && ml.attributeName === 'dir');\n    if (!isNullOrUndefined(htmlDirMutation)) {\n      onDirMutationCallback(htmlDirMutation);\n    }\n  });\n  obs.observe(document.documentElement, config);\n  return obs;\n};\n"],"mappings":"8EAQaA,EAAyCC,GAC7CA,EAAaC,QAAO,CAACC,EAAoBC,KAC9C,GAAIA,EAAaC,SAAWD,EAAaC,QAAQC,gBAAkB,OAAQ,CACzE,MAAMC,EAAiBH,EACvB,OAAOJ,EAAsCO,EAAeC,mB,CAE9DL,EAAIM,KAAKL,GACT,OAAOD,CAAG,GACT,IAUL,MAAMO,EAA4B,CAACC,EAA0BC,EAAsBC,EAAgB,MACjG,CACE,IAAIC,EAAaF,EACjB,IAAK,IAAIG,EAAQ,EAAGA,EAAQF,EAAeE,IAAS,CAClD,GAAID,EAAWE,gBAAkBL,EAAa,CAC5C,OAAO,I,CAET,IAAKG,EAAWE,eAAiBF,EAAWE,cAAcC,aAAa,QAAS,CAC9E,OAAO,K,CAGTH,EAAaA,EAAWE,a,UAYjBE,EAAqB,CAACN,EAAsBO,EAAW,MAClE,MAAMC,EAAWD,EAAW,aAAaA,KAAc,OAEvD,OAAOnB,EACLqB,MAAMC,KAAKV,EAAQW,WAAWC,iBAAiBJ,IAC5CK,KAAKC,GAAiCA,EAAYC,kBAClDC,OACJ,E,MASUC,EAAkC,CAACjB,EAAsBO,EAAW,MAC/E,MAAMC,EAAWD,EAAW,SAASA,KAAc,SACnD,OAAOE,MAAMC,KAAKV,EAAQY,iBAAiBJ,IAAWU,QAAQC,GAAoBrB,EAA0BE,EAASmB,IAAI,E,MAW9GC,EAA8B,CAACD,EAAiBE,EAAmBC,EAAwBrB,EAAgB,MACtH,GAAIkB,EAAGd,aAAagB,KAAeC,EAAgB,CACjD,OAAOH,C,CAET,IAAII,EAAYJ,EAChB,IAAIK,EAAmB,EACvB,MAAOD,GAAaA,EAAUnB,eAAiBoB,GAAoBvB,EAAe,CAChF,MAAMwB,EAAaF,EAAUnB,cAAcC,aAAagB,GACxD,GAAII,GAAcA,EAAWC,WAAWhC,gBAAkB4B,EAAeI,WAAWhC,cAAe,CACjG,OAAO6B,EAAUnB,a,CAEnBmB,EAAYA,EAAUnB,cACtBoB,G,CAEF,OAAO,IAAI,E,MAUAG,EAAkC,CAACC,EAAcC,EAAc5B,EAAgB,MAC1F,MAAM6B,EAAkBX,IAEtB,GAAIA,EAAGY,aAAc,CACnB,OAAOZ,EAAGY,Y,MAEL,GAAIZ,EAAGf,cAAe,CAC3B,OAAOe,EAAGf,a,MAEL,GAAIe,EAAGa,cAAe,CAC3B,MAAMC,EAAWd,EAAGa,cACpB,OAAOC,EAASC,I,GAIpB,IAAIV,EAAmB,EACvB,IAAIW,EAAyBL,EAAeF,GAE5C,MAAOO,GAAiBX,GAAoBvB,EAAe,CACzD,GAAIkC,IAAkBN,EAAK,CACzB,OAAO,I,CAETM,EAAgBL,EAAeK,GAC/BX,G,CAEF,OAAO,KAAK,E,MAQDY,EAAmBC,GAE5BA,EAAKhC,aAAa,SAAWiC,EAAWC,KACvCC,SAASC,gBAAgBpC,aAAa,SAAWiC,EAAWC,KAAOF,EAAKhC,aAAa,SAAWiC,EAAWI,I,MASnGC,EAAsBC,IACjC,MAAMC,EAAS,CAAEC,WAAY,KAAMC,UAAW,MAAOC,QAAS,OAC9D,MAAMC,EAAM,IAAIC,kBAAkBC,IAChC,MAAMC,EAAkBD,EAAaE,MAAMC,GAAOA,EAAGC,OAAOC,SAAS9D,gBAAkB,QAAU4D,EAAGG,gBAAkB,QACtH,IAAKC,EAAkBN,GAAkB,CACvCR,EAAsBQ,E,KAG1BH,EAAIU,QAAQnB,SAASC,gBAAiBI,GACtC,OAAOI,CAAG,E"}