{"version":3,"sources":["utils.js"],"names":["debounce","func","timer","_this","this","timeout","arguments","length","undefined","_len","args","Array","_key","clearTimeout","setTimeout","apply","executeScripts","element","querySelectorAll","forEach","script","newScript","document","createElement","from","attributes","a","setAttribute","name","value","appendChild","createTextNode","innerHTML","parentNode","replaceChild","fetch","url","options","defaultOptions","headers","X-Requested-With","_objectSpread","window","concat","startsWith","config","urlPrefix","getData","prefix","propertyName","_data$propertyName","includeEmptyDataAttributes","data","dataset","hasOwnProperty","RegExp","test","toLowerCase","substr","getHeight","style","getComputedStyle","offsetHeight","parseInt","marginTop","marginBottom","getWidth","offsetWidth","marginLeft","marginRight","getName","fullName","firstName","trim","includes","substring","lastIndexOf","lastName","loadCss","head","getElementsByTagName","link","href","rel","content","parseErrors","defaultErrorMessage","errors","_typeof","values","Object","flat","i","push","readFileAsDataURL","file","Promise","resolve","reject","reader","FileReader","onload","result","onerror","readAsDataURL","setInnerHTML","html","dispatchEvent","Event","bubbles","cancelable"],"mappings":"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","file":"utils.js","sourcesContent":["/**\r\n * Delays the processing of the event until the user has stopped for a predetermined amount of time.\r\n * Reference: https://www.freecodecamp.org/news/javascript-debounce-example/\r\n */\r\nexport function debounce(func, timeout = 300) {\r\n let timer;\r\n\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => { func.apply(this, args); }, timeout);\r\n };\r\n}\r\n\r\n/**\r\n * Execute the scripts within an element.\r\n * Reference: https://stackoverflow.com/a/47614491/155899\r\n */\r\nexport function executeScripts(element) {\r\n element.querySelectorAll('script').forEach(script => {\r\n // Create the new script.\r\n const newScript = document.createElement('script');\r\n\r\n // Add the attributes.\r\n Array.from(script.attributes).forEach(a => newScript.setAttribute(a.name, a.value));\r\n\r\n // Set the inner HTML.\r\n newScript.appendChild(document.createTextNode(script.innerHTML));\r\n\r\n // Replace the old script with the new script tag.\r\n script.parentNode.replaceChild(newScript, script);\r\n });\r\n}\r\n\r\n/**\r\n * Overrides the default fetch method and feeds in some default options.\r\n */\r\nexport function fetch(url, options = {}) {\r\n const defaultOptions = {\r\n headers: {\r\n 'X-Requested-With': 'XMLHttpRequest' // This is needed as by default the fetch API doesn't pass it and therefore there is no way to detect on the server whether the request is an ajax request.\r\n }\r\n };\r\n\r\n // Merge the options with the default options. Make sure the default headers are not overridden.\r\n if ('headers' in options)\r\n options.headers = { ...defaultOptions.headers, ...options.headers };\r\n else\r\n options = { ...defaultOptions, ...options };\r\n\r\n // Note: Automatically prefixing any locale request with the url prefix (if not already prefixed) makes sure the correct locale is set.\r\n return window.fetch(`${url.startsWith('/') && config.urlPrefix != null && !url.startsWith(`/${config.urlPrefix}/`) ? `/${config.urlPrefix}` : ''}${url}`, options);\r\n}\r\n\r\n/**\r\n * Gets the data object of an element from the prefix.\r\n * \r\n * @param {bool} includeEmptyDataAttributes in razor when saying data-foo=\"null\" it still renders an empty data attribute (unlike regular attributes which wouldn't render an attribute) so we may wish to ignore these.\r\n */\r\nexport function getData(element, prefix, includeEmptyDataAttributes = true) {\r\n // Get the elements data.\r\n const data = element.dataset;\r\n\r\n // Allow properties to be accessed sans prefix.\r\n for (const propertyName in data) {\r\n if (data.hasOwnProperty(propertyName) && (includeEmptyDataAttributes || data[propertyName]?.length > 0) && new RegExp('^' + prefix + '[A-Z]+').test(propertyName)) {\r\n const shortName = propertyName[prefix.length].toLowerCase() + propertyName.substr(prefix.length + 1);\r\n data[shortName] = data[propertyName];\r\n }\r\n }\r\n\r\n return data;\r\n}\r\n\r\n/**\r\n * Get the full height of an element (outer height + top/bottom margins).\r\n */\r\nexport function getHeight(element) {\r\n const style = getComputedStyle(element);\r\n return element.offsetHeight + parseInt(style.marginTop) + parseInt(style.marginBottom);\r\n}\r\n\r\n/**\r\n * Get the full width of an element (outer width + left/right margins).\r\n */\r\nexport function getWidth(element) {\r\n const style = getComputedStyle(element);\r\n return element.offsetWidth + parseInt(style.marginLeft) + parseInt(style.marginRight);\r\n}\r\n\r\n/**\r\n * Get the first and last name from a full name.\r\n */\r\nexport function getName(fullName) {\r\n fullName = fullName.trim();\r\n\r\n const firstName = fullName.includes(' ') ? fullName.substring(0, fullName.lastIndexOf(' ')) : fullName;\r\n const lastName = fullName.includes(' ') ? fullName.substring(fullName.lastIndexOf(' ') + 1) : null;\r\n\r\n return { firstName, lastName };\r\n}\r\n\r\n/**\r\n * Programatically load CSS.\r\n */\r\nexport function loadCss(config) {\r\n const head = document.getElementsByTagName('head')[0];\r\n\r\n if (config.url) {\r\n const link = document.createElement('link');\r\n link.href = config.url;\r\n link.rel = 'stylesheet';\r\n head.appendChild(link);\r\n } else {\r\n const style = document.createElement('style');\r\n style.innerHTML = config.content;\r\n head.appendChild(style);\r\n }\r\n}\r\n\r\nexport function parseErrors(data, defaultErrorMessage = 'There was a problem processing your request.') {\r\n const errors = [];\r\n\r\n if (typeof data === 'object' && data !== null) {\r\n const values = Object.values(data).flat();\r\n\r\n for (var i = 0; i < values.length; i++) {\r\n errors.push(values[i]);\r\n }\r\n } else if (typeof data === 'string' && data != '')\r\n errors.push(data);\r\n else\r\n errors.push(defaultErrorMessage);\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Reference: https://simon-schraeder.de/posts/filereader-async/\r\n */\r\nexport function readFileAsDataURL(file) {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n\r\n reader.onload = () => {\r\n resolve(reader.result);\r\n };\r\n\r\n reader.onerror = reject;\r\n reader.readAsDataURL(file);\r\n });\r\n}\r\n\r\n/**\r\n * Inserts HTML to the element, execute scripts and fires the content updated event.\r\n */\r\nexport function setInnerHTML(element, html) {\r\n // Dispatch the \"DOMContentUpdating\" event against the element to update.\r\n const cancelled = !element.dispatchEvent(new Event('DOMContentUpdating', { bubbles: true, cancelable: true }));\r\n\r\n if (!cancelled) {\r\n // Set the inner HTML.\r\n element.innerHTML = html;\r\n\r\n // Execute the scripts.\r\n executeScripts(element);\r\n\r\n // Dispatch the \"DOMContentUpdated\" event against the updated element.\r\n element.dispatchEvent(new Event('DOMContentUpdated', { bubbles: true }));\r\n }\r\n}"]}