{"version":3,"sources":["components/ads-masthead/ads-masthead.tsx","components/ads-masthead/ads-masthead.scss?tag=ads-masthead&encapsulation=shadow","components/core/global/pipeline.ts","components/core/utils/pipeline.ts","components/core/utils/components.ts","utils/breakpointHelper.ts","utils/resizeHelper.ts","utils/DOMHelper.ts"],"names":["AdsMasthead","this","el","setAttribute","identifier","component","newValue","Pipeline.addComponent","Pipeline.removeComponent","$breadcrumbsEl","$breadcrumbs","class","name","$headingEl","$heading","add","window","pipeline","set","id","tagName","toLowerCase","config","getBoolean","trackEvent","COMPONENT_REGISTER","componentId","environment","version","host","location","err","console","log","sendCustomEvent","addComponent","Pipeline.add","removeComponent","delete","Pipeline.remove","generateId","namespace","generateRandomString","Math","random","toString","substr","getClassFromSize","size","MEDIUM","SMALL","getClassFromLevel","level","PRIMARY","SECONDARY","TERTIARY","getMediaQueryBreakpointClassUp","bp","getMediaQueryBreakpointClassDown","showErrorMessage","message","ADS_CONSOLE_ERROR","warn","MediaTypes","getBreakpointInPixels","breakpoint","parseInt","breakpoints","mediaQueryLists","addMatchMedia","mediaType","listenerFunction","foundMatchMedia","find","m","media","newMatchMedia","matchMedia","push","addEventListener","removeMatchMedia","removeEventListener","callbacks","onresize","map","cb","timeout","callback","setTimeout","duration","subscribeToWindowResize","timeoutDuration","unSubscribeToWindowResize","index","findIndex","clearTimeout","splice","getContentFromSlotElementsRecursively","slotElements","reduce","acc","currentValue","assignedElements","isElementChildOfComponent","componentEl","element","maxIterations","tmpElement","parentElement","getAttribute","getSlottedElements","slotName","selector","Array","from","shadowRoot","querySelectorAll","slotElement","assignedNodes","flat","getAllElementsWithSlotAttribute","filter","getIsElementDescendantOfElement","el1","el2","getParentInDom","assignedSlot","getRootNode","currentIteration","currentParent","getIsElementRTL","elem","RTL","document","documentElement","LTR","getHtmlDirObserver","onDirMutationCallback","obs","MutationObserver","mutationList","htmlDirMutation","ml","target","nodeName","attributeName","observe","attributes","childList","subtree"],"mappings":"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","file":"static/js/21.e247f3ca.chunk.js","sourcesContent":["import { Component, Element, Prop, VNode, Watch, h } from '@stencil/core';\n\nimport * as Pipeline from '../core/utils/pipeline';\nimport { BaseComponent } from '../core/interfaces/BaseComponent';\nimport { Theme } from '../core/types/globalTypes';\nimport { generateId } from '../core/utils/components';\nimport { getAllElementsWithSlotAttribute, isNullOrUndefined } from 'utils/index';\n\n/**\n * The masthead is a customisable site-wide header that contains main navigation breadcrumbs (see ads-breadcrumb component) and the page title.\n * The masthead is displayed full width at the top of the page. The background can be configured to use colours or images by using utility classes.\n * @tag `<ads-masthead>`\n * @slot breadcrumbs - The breadcrumbs that will be displayed inside the component\n * @slot heading - The heading that will be displayed inside the component\n * @slot - Content rendered as rich text inside the component\n * @example\n * <ads-masthead>\n * <ads-breadcrumbs theme=\"dark\" slot=\"breadcrumbs\" sr-label=\"Breadcrumbs\">\n * <ads-breadcrumb slot=\"breadcrumb\" link=\"#\" sr-label=\"Link to Text1\">Text1</ads-breadcrumb>\n * <ads-breadcrumb slot=\"breadcrumb\" link=\"#\" sr-label=\"Link to Text2\">Text2</ads-breadcrumb>\n * <ads-breadcrumb slot=\"breadcrumb\" link=\"#\" sr-label=\"Link to Text3\">Text3</ads-breadcrumb>\n * <ads-breadcrumb slot=\"breadcrumb\" link=\"#\" sr-label=\"Link to Text4\" aria-current=\"true\">Text4</ads-breadcrumb>\n * </ads-breadcrumbs>\n * <h1 slot=\"heading\"><span>Lorem ipsum dolor sit amet</span></h1>\n * </ads-masthead>\n */\n@Component({\n tag: 'ads-masthead',\n styleUrl: 'ads-masthead.scss',\n shadow: true,\n})\nexport class AdsMasthead implements BaseComponent {\n /**\n * @hidden\n */\n public component: string;\n\n constructor() {\n this.el.setAttribute('id', this.identifier || generateId('ads-masthead'));\n this.component = 'ads-masthead';\n }\n\n @Element() private el: HTMLAdsMastheadElement;\n\n /**\n * The unique identifier (optional)\n */\n @Prop({ attribute: 'id' }) identifier?: string;\n\n /**\n * The theme for this component instance (optional)\n * Values: \"default\", \"dark\"\n */\n @Prop({ reflect: true }) theme?: Theme;\n\n /**\n * Handle identifier property changes\n * @param {string} newValue The new value for \"identifier\"\n * @hidden\n */\n @Watch('identifier')\n handleIdentifierChange(newValue: string): void {\n this.el.setAttribute('id', newValue || generateId('ads-masthead'));\n }\n\n protected componentDidLoad(): void {\n Pipeline.addComponent(this.el);\n }\n\n protected disconnectedCallback(): void {\n Pipeline.removeComponent(this.el);\n }\n\n protected render(): VNode {\n const $breadcrumbsEl = getAllElementsWithSlotAttribute(this.el, 'breadcrumbs')[0];\n const $breadcrumbs = !isNullOrUndefined($breadcrumbsEl)\n ? ((\n <div class=\"c-masthead__breadcrumbs\">\n <slot name=\"breadcrumbs\"></slot>\n </div>\n ) as HTMLElement)\n : null;\n\n const $headingEl = getAllElementsWithSlotAttribute(this.el, 'heading')[0];\n const $heading = !isNullOrUndefined($headingEl)\n ? ((\n <div class=\"c-masthead__heading\">\n <slot name=\"heading\"></slot>\n </div>\n ) as HTMLElement)\n : null;\n\n return (\n <div class=\"c-masthead\">\n <div class=\"c-masthead__top\">{$breadcrumbs}</div>\n {$heading}\n <slot />\n </div>\n ) as VNode;\n }\n}\n","@import 'core';\n\n/**\n * @prop --ads-masthead-background-color: Background color\n * @prop --ads-masthead-border-bottom-color: Border bottom color\n * @prop --ads-masthead-color: Text color\n * @prop --ads-masthead-horizontal-padding: Horizontal padding\n * @prop --ads-masthead-text-align: Text alignment\n */\n\n::slotted(*) {\n box-sizing: border-box;\n display: block !important;\n margin: 0 !important;\n padding: 0 !important;\n}\n\n::slotted([slot='heading']) {\n color: var(--ads-masthead-color, $ads-masthead-color) !important;\n justify-content: inherit;\n line-height: 1.25em !important;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n:host {\n background-color: var(--ads-masthead-background-color, $ads-masthead-background-color);\n background-position: center center;\n background-repeat: no-repeat;\n background-size: cover;\n display: block;\n position: relative;\n width: 100%;\n}\n\n:host([theme='default']) {\n @include ads-vars-component-masthead-default;\n}\n\n:host([theme='dark']) {\n @include ads-vars-component-masthead-dark;\n}\n\n:host([theme='light']) {\n @include ads-vars-component-masthead-light;\n}\n\n:host([dir='ltr']) {\n @include ads-vars-component-masthead-ltr;\n}\n\n:host([dir='rtl']) {\n @include ads-vars-component-masthead-rtl;\n}\n\n.c-masthead {\n align-items: flex-start;\n border: 0;\n border-bottom: 1px solid var(--ads-masthead-border-bottom-color, $ads-masthead-border-bottom-color);\n box-sizing: border-box;\n display: flex !important;\n flex-direction: column;\n font-family: var(--ads-font-family);\n justify-content: center;\n min-height: 90px;\n padding: 0 var(--ads-masthead-horizontal-padding, $ads-masthead-horizontal-padding);\n position: relative;\n\n @include media-query(md-up) {\n justify-content: flex-start;\n min-height: 105px;\n padding: 0 calc(var(--ads-masthead-horizontal-padding, $ads-masthead-horizontal-padding) * 2);\n }\n\n &__top {\n display: flex !important;\n margin: 0;\n max-height: 30px;\n\n @include media-query(md-up) {\n flex-direction: row;\n position: absolute;\n top: 10px;\n width: calc(100% - 32px);\n }\n }\n\n &__heading {\n margin: 0;\n width: calc(100% - 32px);\n\n @include media-query(md-up) {\n padding-top: 4px;\n position: absolute;\n text-align: var(--ads-masthead-text-align, $ads-masthead-text-align-ltr);\n top: 30px;\n }\n }\n}\n","import { EventTypes, environment, version } from './AppInsights/constants';\nimport { WindowGlobal } from '../types/globalTypes';\n\n/**\n * Send custom event to AppInsights\n * @param {string} component The reference to the component\n * @returns {void}\n * @hidden\n */\nconst sendCustomEvent = (component: HTMLElement): void => {\n try {\n (window as WindowGlobal)['AppInsights'].trackEvent(\n {\n name: EventTypes.COMPONENT_REGISTER,\n },\n {\n component: component.tagName.toLowerCase(),\n componentId: component.id,\n environment,\n version,\n host: window.location.host,\n }\n );\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('[APP INSIGHTS] Could not send event', err);\n }\n};\n\n/**\n * Add the component to the pipeline and send component events to AppInsights\n * @param {HTMLElement} component The component element\n * @returns {void}\n * @hidden\n */\nexport function add(component: HTMLElement): void {\n (window as WindowGlobal)['ArmDesignSystem'].pipeline.set(component.id, component.tagName.toLowerCase());\n\n // Disable sending events to AppInsights during unit tests\n if (!(window as WindowGlobal)['ArmDesignSystem'].config.getBoolean('_isTesting')) {\n sendCustomEvent(component);\n }\n}\n\n/**\n * Remove the component from the pipeline\n * @param {HTMLElement} component The component element\n * @returns {void}\n * @hidden\n */\nexport function remove(component: HTMLElement): void {\n (window as WindowGlobal)['ArmDesignSystem'].pipeline.delete(component.id);\n}\n","import * as Pipeline from '../global/pipeline';\n\n/**\n * Add a component to the ADS pipeline\n * @param {HTMLElement} component The component element\n * @return {void}\n */\nexport const addComponent = (component: HTMLElement): void => {\n Pipeline.add(component);\n};\n\n/**\n * Remove a component from the ADS pipeline\n * @param {HTMLElement} component The component element\n * @return {void}\n */\nexport const removeComponent = (component: HTMLElement): void => {\n Pipeline.remove(component);\n};\n","import { Breakpoint, ButtonLevel, ButtonLevels, ButtonSize, ButtonSizes, WindowGlobal } from '../types/globalTypes';\nimport { EventTypes, environment, version } from '../global/AppInsights/constants';\n\nexport type ShadowRootLegacy = ShadowRoot & { tagName: string };\n\n/**\n * Generates a unique component ID\n * @param {string} namespace The unique id's namespace (e.g. ads)\n * @returns {string} A generated random id (e.g. ads-1234)\n */\nexport const generateId = (namespace = 'ads'): string => {\n return `${namespace}-${generateRandomString()}`;\n};\n\n/**\n * Generates a randon string\n * @returns {string} A generated random string\n */\nexport const generateRandomString = (): string => {\n return Math.random().toString(36).substr(2, 16);\n};\n\n/**\n * Generates a size class based on a button size\n * @param {ButtonSize} size The size of the button (e.g. ButtonSizes.SMALL)\n * @returns {string} The button size class (e.g. 'is-small')\n */\nexport const getClassFromSize = (size: ButtonSize): string => {\n switch (size) {\n case ButtonSizes.MEDIUM:\n return 'is-medium';\n case ButtonSizes.SMALL:\n return 'is-small';\n default:\n return '';\n }\n};\n\n/**\n * Generates a level class based on button a level\n * @param {ButtonLevel} level The level of the button (e.g. ButtonLevels.PRIMARY)\n * @returns {string} The button level class (e.g. 'is-primary')\n */\nexport const getClassFromLevel = (level: ButtonLevel): string => {\n switch (level) {\n case ButtonLevels.PRIMARY:\n return 'is-primary';\n case ButtonLevels.SECONDARY:\n return 'is-secondary';\n case ButtonLevels.TERTIARY:\n return 'is-tertiary';\n default:\n return '';\n }\n};\n\n/**\n * Given a breakpoint it will return the appropriate class for the media-queries (breakpoints-up).\n * @param {Breakpoint} bp The breakpoint.\n * @returns {string} The class.\n */\nexport const getMediaQueryBreakpointClassUp = (bp: Breakpoint): string => `${bp.toString()}-up`;\n\n/**\n * Given a breakpoint it will return the appropriate class for the media-queries (breakpoints-down).\n * @param {Breakpoint} bp The breakpoint.\n * @returns {string} The class.\n */\nexport const getMediaQueryBreakpointClassDown = (bp: Breakpoint): string => `${bp.toString()}-down`;\n\n/**\n * Display an ADS warning with the given message\n * @param {string} message The error message to show\n * @param {string} component The reference to the component\n * @returns {void}\n */\nexport const showErrorMessage = (message: string, component: HTMLElement): void => {\n try {\n (window as WindowGlobal)['AppInsights'].trackEvent(\n {\n name: EventTypes.ADS_CONSOLE_ERROR as string,\n },\n {\n component: component.tagName.toLowerCase(),\n componentId: component.id,\n message: message,\n environment,\n version,\n host: window.location.host,\n }\n );\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('[APP INSIGHTS] Could not send console error', err);\n }\n // eslint-disable-next-line no-console\n console.warn(`ADS-Warning: ${message}`);\n};\n","import { Breakpoint } from '../components/core/types/globalTypes';\nimport { isNullOrUndefined } from './collection';\nimport config from './../styles/settings/configs/breakpoints-config.json';\n\n/**\n * Match media types\n */\nexport enum MediaTypes {\n minWidth = 'min-width',\n maxWidth = 'max-width',\n}\n\n/**\n * Returns the list all of breakpoint keys\n * @returns {Breakpoint[]} The list of breakpoints\n */\nexport const getBreakpoints = (): Breakpoint[] => Object.keys(config.breakpoints) as Breakpoint[];\n\n/**\n * Returns the breakpoint in pixels\n * @param {Breakpoint} breakpoint The breakpoint\n * @returns {number} The breakpoint value in pixels\n */\nexport const getBreakpointInPixels = (breakpoint: Breakpoint): number => parseInt(config.breakpoints[breakpoint], 10);\n\n/**\n * Returns the breakpoint key for given pixels\n * @param {number} pixels The pixels of the breakpoint\n * @returns {Breakpoint} The breakpoint key\n */\nexport const getBreakpointFromPixels = (pixels: number): Breakpoint =>\n Object.keys(config.breakpoints)[\n Object.values(config.breakpoints)\n .map((bp) => parseInt(bp, 10))\n .findIndex((bpPixels) => bpPixels === pixels)\n ] as Breakpoint;\n\nconst mediaQueryLists: MediaQueryList[] = [];\n\n/**\n * Adds matchMedia to window with the given properties.\n * @param {MediaTypes} mediaType The type of media\n * @param {Sizes} breakpoint The media size\n * @param {Function} listenerFunction Callback function for the listener\n */\nexport const addMatchMedia = (\n mediaType: MediaTypes,\n breakpoint: Breakpoint,\n listenerFunction: (this: MediaQueryList, ev: MediaQueryListEvent) => unknown\n): void => {\n const foundMatchMedia = mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`);\n if (!isNullOrUndefined(foundMatchMedia)) {\n foundMatchMedia.addEventListener('change', listenerFunction);\n } else {\n const newMatchMedia = window.matchMedia(`(${mediaType}: ${config.breakpoints[breakpoint]})`);\n mediaQueryLists.push(newMatchMedia);\n newMatchMedia.addEventListener('change', listenerFunction);\n }\n};\n\n/**\n * Removes matchMedia from window with the given properties.\n * @param {MediaTypes} mediaType The type of media\n * @param {Sizes} breakpoint The media size\n * @param {Function} listenerFunction Callback function to be removed from the listener\n */\nexport const removeMatchMedia = (\n mediaType: MediaTypes,\n breakpoint: Breakpoint,\n listenerFunction: (this: MediaQueryList, ev: MediaQueryListEvent) => unknown\n): void => {\n mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`)?.removeEventListener('change', listenerFunction);\n};\n\n/**\n * Matches the current window with the given media type and breakpoint\n * @param {MediaTypes} mediaType The media type\n * @param {Breakpoint} breakpoint The breakpoint\n * @returns {boolean} True if it matches, false otherwise\n */\nexport const mediaMatchingBreakpoint = (mediaType: MediaTypes, breakpoint: Breakpoint): boolean => {\n const foundMatchMedia = mediaQueryLists.find((m) => m.media === `(${mediaType}: ${config.breakpoints[breakpoint]})`);\n if (!isNullOrUndefined(foundMatchMedia)) {\n return foundMatchMedia.matches;\n }\n const newMatchMedia = window.matchMedia(`(${mediaType}: ${config.breakpoints[breakpoint]})`);\n mediaQueryLists.push(newMatchMedia);\n return newMatchMedia.matches;\n};\n","import { isNullOrUndefined } from './collection';\n\ninterface ResizeCallback {\n callback: () => void;\n duration: number;\n timeout?: NodeJS.Timeout;\n}\n\nconst defaultTimeout = 50;\n\nconst callbacks: ResizeCallback[] = [];\n\nwindow.onresize = () => {\n callbacks.map((cb: ResizeCallback) => {\n if (isNullOrUndefined(cb.timeout)) {\n cb.callback();\n cb.timeout = setTimeout(() => {\n cb.timeout = null;\n }, cb.duration);\n }\n });\n};\n\n/**\n * Subscribe to the resize listener\n * @param {function} callback The callback function to run on resize\n * @param {number} timeoutDuration The throttle timeout duration\n */\nexport const subscribeToWindowResize = (callback: () => void, timeoutDuration: number = defaultTimeout): void => {\n callbacks.push({ callback, duration: timeoutDuration });\n};\n\n/**\n * Unsubscribe to the resize listener\n * @param {function} callback The callback function to unsubscribe\n */\nexport const unSubscribeToWindowResize = (callback: () => void): void => {\n const index = callbacks.findIndex((cb: ResizeCallback) => cb.callback === callback);\n if (index >= 0) {\n if (!isNullOrUndefined(callbacks[index].timeout)) {\n clearTimeout(callbacks[index].timeout);\n }\n callbacks.splice(index, 1);\n }\n};\n","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"],"sourceRoot":""}