forked from denis-taran/autocomplete
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautocomplete.min.js.map
1 lines (1 loc) · 23.2 KB
/
autocomplete.min.js.map
1
{"version":3,"file":"autocomplete.min.js","sources":["autocomplete.ts"],"sourcesContent":[" /*\r\n * https://github.com/kraaden/autocomplete\r\n * Copyright (c) 2016 Denys Krasnoshchok\r\n * MIT License\r\n */\r\n\r\nexport const enum EventTrigger {\r\n Keyboard = 0,\r\n Focus = 1\r\n}\r\n\r\nexport interface AutocompleteItem {\r\n label?: string;\r\n group?: string;\r\n}\r\n\r\nexport interface AutocompleteSettings<T extends AutocompleteItem> {\r\n input: HTMLInputElement;\r\n render?: (item: T, currentValue: string) => HTMLDivElement | undefined;\r\n renderGroup?: (name: string, currentValue: string) => HTMLDivElement | undefined;\r\n className?: string;\r\n minLength?: number;\r\n emptyMsg?: string;\r\n onSelect: (item: T, input: HTMLInputElement) => void;\r\n /**\r\n * Show autocomplete on focus event. Focus event will ignore the `minLength` property and will always call `fetch`.\r\n */\r\n showOnFocus?: boolean;\r\n fetch: (text: string, update: (items: T[] | false) => void, trigger: EventTrigger) => void;\r\n debounceWaitMs?: number;\r\n /**\r\n * Callback for additional autocomplete customization\r\n * @param {HTMLInputElement} input - input box associated with autocomplete\r\n * @param {ClientRect | DOMRect} inputRect - size of the input box and its position relative to the viewport\r\n * @param {HTMLDivElement} container - container with suggestions\r\n * @param {number} maxHeight - max height that can be used by autocomplete\r\n */\r\n customize?: (input: HTMLInputElement, inputRect: ClientRect | DOMRect, container: HTMLDivElement, maxHeight: number) => void;\r\n /**\r\n * Prevents automatic form submit when ENTER is pressed\r\n */\r\n preventSubmit?: boolean;\r\n allowSubmitOnTab?: boolean;\r\n}\r\n\r\nexport interface AutocompleteResult {\r\n destroy: () => void;\r\n}\r\n\r\nconst enum Keys {\r\n Enter = 13,\r\n Esc = 27,\r\n Up = 38,\r\n Down = 40,\r\n Left = 37,\r\n Right = 39,\r\n Shift = 16,\r\n Ctrl = 17,\r\n Alt = 18,\r\n CapsLock = 20,\r\n WindowsKey = 91,\r\n Tab = 9,\r\n F1 = 112,\r\n F12 = 123\r\n}\r\n\r\nexport default function autocomplete<T extends AutocompleteItem>(settings: AutocompleteSettings<T>): AutocompleteResult {\r\n\r\n // just an alias to minimize JS file size\r\n const doc = document;\r\n\r\n const container: HTMLDivElement = doc.createElement(\"div\");\r\n const containerStyle = container.style;\r\n const userAgent = navigator.userAgent;\r\n const mobileFirefox = userAgent.indexOf(\"Firefox\") !== -1 && userAgent.indexOf(\"Mobile\") !== -1;\r\n const debounceWaitMs = settings.debounceWaitMs || 0;\r\n const preventSubmit = settings.preventSubmit || false;\r\n const allowSubmitOnTab = settings.allowSubmitOnTab || false;\r\n\r\n // 'keyup' event will not be fired on Mobile Firefox, so we have to use 'input' event instead\r\n const keyUpEventName = mobileFirefox ? \"input\" : \"keyup\";\r\n\r\n let items: T[] = [];\r\n let inputValue = \"\";\r\n let minLen = 2;\r\n const showOnFocus = settings.showOnFocus;\r\n let selected: T | undefined;\r\n let keypressCounter = 0;\r\n let debounceTimer : number | undefined;\r\n\r\n if (settings.minLength !== undefined) {\r\n minLen = settings.minLength;\r\n }\r\n\r\n if (!settings.input) {\r\n throw new Error(\"input undefined\");\r\n }\r\n\r\n const input: HTMLInputElement = settings.input;\r\n\r\n container.className = \"autocomplete \" + (settings.className || \"\");\r\n\r\n // IOS implementation for fixed positioning has many bugs, so we will use absolute positioning\r\n containerStyle.position = \"absolute\";\r\n\r\n /**\r\n * Detach the container from DOM\r\n */\r\n function detach(): void {\r\n const parent = container.parentNode;\r\n if (parent) {\r\n parent.removeChild(container);\r\n }\r\n }\r\n\r\n /**\r\n * Clear debouncing timer if assigned\r\n */\r\n function clearDebounceTimer(): void {\r\n if (debounceTimer) {\r\n window.clearTimeout(debounceTimer);\r\n }\r\n }\r\n\r\n /**\r\n * Attach the container to DOM\r\n */\r\n function attach(): void {\r\n if (!container.parentNode) {\r\n doc.body.appendChild(container);\r\n }\r\n }\r\n\r\n /**\r\n * Check if container for autocomplete is displayed\r\n */\r\n function containerDisplayed(): boolean {\r\n return !!container.parentNode;\r\n }\r\n\r\n /**\r\n * Clear autocomplete state and hide container\r\n */\r\n function clear(): void {\r\n // prevent the update call if there are pending AJAX requests\r\n keypressCounter++;\r\n\r\n items = [];\r\n inputValue = \"\";\r\n selected = undefined;\r\n detach();\r\n }\r\n\r\n /**\r\n * Update autocomplete position\r\n */\r\n function updatePosition(): void {\r\n if (!containerDisplayed()) {\r\n return;\r\n }\r\n\r\n containerStyle.height = \"auto\";\r\n containerStyle.width = input.offsetWidth + \"px\";\r\n\r\n let maxHeight = 0;\r\n let inputRect: ClientRect | DOMRect | undefined;\r\n\r\n function calc() {\r\n const docEl = doc.documentElement as HTMLElement;\r\n const clientTop = docEl.clientTop || doc.body.clientTop || 0;\r\n const clientLeft = docEl.clientLeft || doc.body.clientLeft || 0;\r\n const scrollTop = window.pageYOffset || docEl.scrollTop;\r\n const scrollLeft = window.pageXOffset || docEl.scrollLeft;\r\n\r\n inputRect = input.getBoundingClientRect();\r\n\r\n const top = inputRect.top + input.offsetHeight + scrollTop - clientTop;\r\n const left = inputRect.left + scrollLeft - clientLeft;\r\n\r\n containerStyle.top = top + \"px\";\r\n containerStyle.left = left + \"px\";\r\n\r\n maxHeight = window.innerHeight - (inputRect.top + input.offsetHeight);\r\n\r\n if (maxHeight < 0) {\r\n maxHeight = 0;\r\n }\r\n\r\n containerStyle.top = top + \"px\";\r\n containerStyle.bottom = \"\";\r\n containerStyle.left = left + \"px\";\r\n containerStyle.maxHeight = maxHeight + \"px\";\r\n }\r\n\r\n // the calc method must be called twice, otherwise the calculation may be wrong on resize event (chrome browser)\r\n calc();\r\n calc();\r\n\r\n if (settings.customize && inputRect) {\r\n settings.customize(input, inputRect, container, maxHeight);\r\n }\r\n }\r\n\r\n /**\r\n * Redraw the autocomplete div element with suggestions\r\n */\r\n function update(): void {\r\n\r\n // delete all children from autocomplete DOM container\r\n while (container.firstChild) {\r\n container.removeChild(container.firstChild);\r\n }\r\n\r\n // function for rendering autocomplete suggestions\r\n let render = function(item: T, currentValue: string): HTMLDivElement | undefined {\r\n const itemElement = doc.createElement(\"div\");\r\n itemElement.textContent = item.label || \"\";\r\n return itemElement;\r\n };\r\n if (settings.render) {\r\n render = settings.render;\r\n }\r\n\r\n // function to render autocomplete groups\r\n let renderGroup = function(groupName: string, currentValue: string): HTMLDivElement | undefined {\r\n const groupDiv = doc.createElement(\"div\");\r\n groupDiv.textContent = groupName;\r\n return groupDiv;\r\n };\r\n if (settings.renderGroup) {\r\n renderGroup = settings.renderGroup;\r\n }\r\n\r\n const fragment = doc.createDocumentFragment();\r\n let prevGroup = \"#9?$\";\r\n\r\n items.forEach(function(item: T): void {\r\n if (item.group && item.group !== prevGroup) {\r\n prevGroup = item.group;\r\n const groupDiv = renderGroup(item.group, inputValue);\r\n if (groupDiv) {\r\n groupDiv.className += \" group\";\r\n fragment.appendChild(groupDiv);\r\n }\r\n }\r\n const div = render(item, inputValue);\r\n if (div) {\r\n div.addEventListener(\"click\", function(ev: MouseEvent): void {\r\n settings.onSelect(item, input);\r\n clear();\r\n ev.preventDefault();\r\n ev.stopPropagation();\r\n });\r\n if (item === selected) {\r\n div.className += \" selected\";\r\n }\r\n fragment.appendChild(div);\r\n }\r\n });\r\n container.appendChild(fragment);\r\n if (items.length < 1) {\r\n if (settings.emptyMsg) {\r\n const empty = doc.createElement(\"div\");\r\n empty.className = \"empty\";\r\n empty.textContent = settings.emptyMsg;\r\n container.appendChild(empty);\r\n } else {\r\n clear();\r\n return;\r\n }\r\n }\r\n\r\n attach();\r\n updatePosition();\r\n\r\n updateScroll();\r\n }\r\n\r\n function updateIfDisplayed(): void {\r\n if (containerDisplayed()) {\r\n update();\r\n }\r\n }\r\n\r\n function resizeEventHandler(): void {\r\n updateIfDisplayed();\r\n }\r\n\r\n function scrollEventHandler(e: Event): void {\r\n if (e.target !== container) {\r\n updateIfDisplayed();\r\n } else {\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n function keyupEventHandler(ev: KeyboardEvent): void {\r\n const keyCode = ev.which || ev.keyCode || 0;\r\n\r\n const ignore = [Keys.Up, Keys.Enter, Keys.Esc, Keys.Right, Keys.Left, Keys.Shift, Keys.Ctrl, Keys.Alt, Keys.CapsLock, Keys.WindowsKey, Keys.Tab];\r\n for (const key of ignore) {\r\n if (keyCode === key) {\r\n return;\r\n }\r\n }\r\n\r\n if (keyCode >= Keys.F1 && keyCode <= Keys.F12) {\r\n return;\r\n }\r\n\r\n // the down key is used to open autocomplete\r\n if (keyCode === Keys.Down && containerDisplayed()) {\r\n return;\r\n }\r\n\r\n startFetch(EventTrigger.Keyboard);\r\n }\r\n\r\n /**\r\n * Automatically move scroll bar if selected item is not visible\r\n */\r\n function updateScroll(): void {\r\n const elements = container.getElementsByClassName(\"selected\");\r\n if (elements.length > 0) {\r\n let element = elements[0] as HTMLDivElement;\r\n\r\n // make group visible\r\n const previous = element.previousElementSibling as HTMLDivElement;\r\n if (previous && previous.className.indexOf(\"group\") !== -1 && !previous.previousElementSibling) {\r\n element = previous;\r\n }\r\n\r\n if (element.offsetTop < container.scrollTop) {\r\n container.scrollTop = element.offsetTop;\r\n } else {\r\n const selectBottom = element.offsetTop + element.offsetHeight;\r\n const containerBottom = container.scrollTop + container.offsetHeight;\r\n if (selectBottom > containerBottom) {\r\n container.scrollTop += selectBottom - containerBottom;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Select the previous item in suggestions\r\n */\r\n function selectPrev(): void {\r\n if (items.length < 1) {\r\n selected = undefined;\r\n } else {\r\n if (selected === items[0]) {\r\n selected = items[items.length - 1];\r\n } else {\r\n for (let i = items.length - 1; i > 0; i--) {\r\n if (selected === items[i] || i === 1) {\r\n selected = items[i - 1];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Select the next item in suggestions\r\n */\r\n function selectNext(): void {\r\n if (items.length < 1) {\r\n selected = undefined;\r\n }\r\n if (!selected || selected === items[items.length - 1]) {\r\n selected = items[0];\r\n return;\r\n }\r\n for (let i = 0; i < (items.length - 1); i++) {\r\n if (selected === items[i]) {\r\n selected = items[i + 1];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function keydownEventHandler(ev: KeyboardEvent): void {\r\n const keyCode = ev.which || ev.keyCode || 0;\r\n\r\n if (keyCode === Keys.Up || keyCode === Keys.Down || keyCode === Keys.Esc) {\r\n const containerIsDisplayed = containerDisplayed();\r\n\r\n if (keyCode === Keys.Esc) {\r\n clear();\r\n } else {\r\n if (!containerDisplayed || items.length < 1) {\r\n return;\r\n }\r\n keyCode === Keys.Up\r\n ? selectPrev()\r\n : selectNext();\r\n update();\r\n }\r\n\r\n ev.preventDefault();\r\n if (containerIsDisplayed) {\r\n ev.stopPropagation();\r\n }\r\n\r\n return;\r\n }\r\n\r\n if (keyCode === Keys.Enter || (keyCode === Keys.Tab && allowSubmitOnTab)) {\r\n if (selected) {\r\n settings.onSelect(selected, input);\r\n clear();\r\n }\r\n\r\n if (preventSubmit) {\r\n ev.preventDefault();\r\n }\r\n }\r\n }\r\n\r\n function focusEventHandler(): void {\r\n if (showOnFocus) {\r\n startFetch(EventTrigger.Focus);\r\n }\r\n }\r\n\r\n function startFetch(trigger: EventTrigger) {\r\n // if multiple keys were pressed, before we get update from server,\r\n // this may cause redrawing our autocomplete multiple times after the last key press.\r\n // to avoid this, the number of times keyboard was pressed will be\r\n // saved and checked before redraw our autocomplete box.\r\n const savedKeypressCounter = ++keypressCounter;\r\n\r\n const val = input.value;\r\n if (val.length >= minLen || trigger === EventTrigger.Focus) {\r\n clearDebounceTimer();\r\n debounceTimer = window.setTimeout(function(): void {\r\n settings.fetch(val, function(elements: T[] | false): void {\r\n if (keypressCounter === savedKeypressCounter && elements) {\r\n items = elements;\r\n inputValue = val;\r\n selected = items.length > 0 ? items[0] : undefined;\r\n update();\r\n }\r\n }, EventTrigger.Keyboard);\r\n }, trigger === EventTrigger.Keyboard ? debounceWaitMs : 0);\r\n } else {\r\n clear();\r\n }\r\n }\r\n\r\n function blurEventHandler(): void {\r\n // we need to delay clear, because when we click on an item, blur will be called before click and remove items from DOM\r\n setTimeout(() => {\r\n if (doc.activeElement !== input) {\r\n clear();\r\n }\r\n }, 200);\r\n }\r\n\r\n /**\r\n * Fixes #26: on long clicks focus will be lost and onSelect method will not be called\r\n */\r\n container.addEventListener(\"mousedown\", function(evt: Event) {\r\n evt.stopPropagation();\r\n evt.preventDefault();\r\n });\r\n\r\n /**\r\n * Fixes #30: autocomplete closes when scrollbar is clicked in IE\r\n * See: https://stackoverflow.com/a/9210267/13172349\r\n */\r\n container.addEventListener(\"focus\", () => input.focus());\r\n\r\n /**\r\n * This function will remove DOM elements and clear event handlers\r\n */\r\n function destroy(): void {\r\n input.removeEventListener(\"focus\", focusEventHandler);\r\n input.removeEventListener(\"keydown\", keydownEventHandler);\r\n input.removeEventListener(keyUpEventName, keyupEventHandler as EventListenerOrEventListenerObject);\r\n input.removeEventListener(\"blur\", blurEventHandler);\r\n window.removeEventListener(\"resize\", resizeEventHandler);\r\n doc.removeEventListener(\"scroll\", scrollEventHandler, true);\r\n clearDebounceTimer();\r\n clear();\r\n }\r\n\r\n // setup event handlers\r\n input.addEventListener(\"keydown\", keydownEventHandler);\r\n input.addEventListener(keyUpEventName, keyupEventHandler as EventListenerOrEventListenerObject);\r\n input.addEventListener(\"blur\", blurEventHandler);\r\n input.addEventListener(\"focus\", focusEventHandler);\r\n window.addEventListener(\"resize\", resizeEventHandler);\r\n doc.addEventListener(\"scroll\", scrollEventHandler, true);\r\n\r\n return {\r\n destroy\r\n };\r\n}\r\n"],"names":["settings","selected","debounceTimer","doc","document","container","createElement","containerStyle","style","userAgent","navigator","mobileFirefox","indexOf","debounceWaitMs","preventSubmit","allowSubmitOnTab","keyUpEventName","items","inputValue","minLen","showOnFocus","keypressCounter","undefined","minLength","input","Error","clearDebounceTimer","window","clearTimeout","containerDisplayed","parentNode","clear","parent","removeChild","update","firstChild","render","item","currentValue","itemElement","textContent","label","renderGroup","groupName","groupDiv","fragment","createDocumentFragment","prevGroup","forEach","group","className","appendChild","div","addEventListener","ev","onSelect","preventDefault","stopPropagation","length","emptyMsg","empty","body","height","width","offsetWidth","inputRect","maxHeight","calc","customize","docEl","documentElement","clientTop","clientLeft","scrollTop","pageYOffset","scrollLeft","pageXOffset","top","getBoundingClientRect","offsetHeight","left","innerHeight","bottom","updatePosition","elements","getElementsByClassName","element","previous","previousElementSibling","offsetTop","selectBottom","containerBottom","updateScroll","updateIfDisplayed","resizeEventHandler","scrollEventHandler","e","target","keyupEventHandler","keyCode","which","ignore_1","_i","startFetch","keydownEventHandler","containerIsDisplayed","i","selectPrev","selectNext","focusEventHandler","trigger","savedKeypressCounter","val","value","setTimeout","fetch","blurEventHandler","activeElement","position","evt","focus","destroy","removeEventListener"],"mappings":"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"}