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