{"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"}