-
Notifications
You must be signed in to change notification settings - Fork 85
/
autocomplete.min.js.map
1 lines (1 loc) · 30.6 KB
/
autocomplete.min.js.map
1
{"version":3,"file":"autocomplete.min.js","sources":["autocomplete.ts"],"sourcesContent":["/**\n * Copyright (c) 2016 Denis Taran\n * \n * Homepage: https://smartscheduling.com/en/documentation/autocomplete\n * Source: https://github.com/denis-taran/autocomplete\n * \n * MIT License\n */\n\nexport const enum EventTrigger {\n Keyboard = 0,\n Focus = 1,\n Mouse = 2,\n /**\n * Fetch is triggered manually by calling `fetch` function returned in `AutocompleteResult`\n */\n Manual = 3\n}\n\n/**\n * Enum for controlling form submission when `ENTER` key is pressed in the autocomplete input field.\n */\nexport const enum PreventSubmit {\n Never = 0,\n Always = 1,\n /**\n * Form submission is prevented only when an item is selected from the autocomplete list.\n */\n OnSelect = 2\n}\n\nexport interface AutocompleteItem {\n label?: string;\n group?: string;\n}\n\nexport interface AutocompleteEvent<T extends Event> {\n /**\n * Native event object passed by browser to the event handler\n */\n event: T;\n\n /**\n * Fetch data and display autocomplete\n */\n fetch: () => void;\n}\n\nexport interface AutocompleteSettings<T extends AutocompleteItem> {\n /**\n * Autocomplete will be attached to this element.\n */\n input: HTMLInputElement | HTMLTextAreaElement;\n\n /**\n * Provide your own container for the widget.\n * If not specified, a new DIV element will be created.\n */\n container?: HTMLDivElement;\n\n /**\n * This method allows you to override the default rendering function for items.\n * It must return a DIV element or undefined to skip rendering.\n */\n render?: (item: T, currentValue: string, index: number) => HTMLDivElement | undefined;\n\n /**\n * This method allows you to override the default rendering function for item groups.\n * It must return a DIV element or undefined to skip rendering.\n */\n renderGroup?: (name: string, currentValue: string) => HTMLDivElement | undefined;\n\n /**\n * If specified, the autocomplete DOM element will have this class assigned to it.\n */\n className?: string;\n\n /**\n * Specify the minimum text length required to show autocomplete.\n */\n minLength?: number;\n\n /**\n * The message that will be showed when there are no suggestions that match the entered value.\n */\n emptyMsg?: string;\n\n /**\n * This method will be called when user choose an item in autocomplete. The selected item will be passed as the first parameter.\n */\n onSelect: (item: T, input: HTMLInputElement | HTMLTextAreaElement) => void;\n\n /**\n * Show autocomplete on focus event. Focus event will ignore the `minLength` property and will always call `fetch`.\n */\n showOnFocus?: boolean;\n\n /**\n * This method will be called to prepare suggestions and then pass them to autocomplete.\n * @param {string} text - text in the input field\n * @param {(items: T[] | false) => void} update - a callback function that must be called after suggestions are prepared\n * @param {EventTrigger} trigger - type of the event that triggered the fetch\n * @param {number} cursorPos - position of the cursor in the input field\n */\n fetch: (text: string, update: (items: T[] | false) => void, trigger: EventTrigger, cursorPos: number) => void;\n\n /**\n * Enforces that the fetch function will only be called once within the specified time frame (in milliseconds) and\n * delays execution. This prevents flooding your server with AJAX requests.\n */\n debounceWaitMs?: number;\n\n /**\n * Callback for additional autocomplete customization\n * @param {HTMLInputElement | HTMLTextAreaElement} 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 | HTMLTextAreaElement, inputRect: ClientRect | DOMRect, container: HTMLDivElement, maxHeight: number) => void;\n\n /**\n * Controls form submission when the ENTER key is pressed in a input field.\n */\n preventSubmit?: PreventSubmit;\n\n /**\n * Prevents the first item in the list from being selected automatically. This option allows you\n * to submit a custom text by pressing ENTER even when autocomplete is displayed.\n */\n disableAutoSelect?: boolean;\n\n /**\n * Provide your keyup event handler to display autocomplete when a key is pressed that doesn't modify the content. You can also perform some additional actions.\n */\n keyup?: (e: AutocompleteEvent<KeyboardEvent>) => void;\n\n /**\n * Allows to display autocomplete on mouse clicks or perform some additional actions.\n */\n click?: (e: AutocompleteEvent<MouseEvent>) => void;\n}\n\nexport interface AutocompleteResult {\n /**\n * Remove event handlers, DOM elements and ARIA/accessibility attributes created by the widget.\n */\n destroy: () => void;\n\n /**\n * This function allows to manually start data fetching and display autocomplete. Note that\n * it does not automatically place focus on the input field, so you may need to do so manually\n * in certain situations.\n */\n fetch: () => void;\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 = settings.container || doc.createElement('div');\n const preventSubmit: PreventSubmit = settings.preventSubmit || PreventSubmit.Never;\n\n container.id = container.id || 'autocomplete-' + uid();\n const containerStyle = container.style;\n const debounceWaitMs = settings.debounceWaitMs || 0;\n const disableAutoSelect = settings.disableAutoSelect || false;\n const customContainerParent = container.parentElement;\n\n let items: T[] = [];\n let inputValue = '';\n let minLen = 2;\n const showOnFocus = settings.showOnFocus;\n let selected: T | undefined;\n let fetchCounter = 0;\n let debounceTimer: number | undefined;\n let destroyed = false;\n\n // Fixes #104: autocomplete selection is broken on Firefox for Android\n let suppressAutocomplete = false;\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 | HTMLTextAreaElement = settings.input;\n\n container.className = [container.className, 'autocomplete', settings.className || ''].join(' ').trim();\n container.setAttribute('role', 'listbox');\n\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-controls', container.id);\n input.setAttribute('aria-owns', container.id);\n input.setAttribute('aria-activedescendant', '');\n input.setAttribute('aria-haspopup', 'listbox');\n\n // IOS implementation for fixed positioning has many bugs, so we will use absolute positioning\n containerStyle.position = 'absolute';\n\n /**\n * Generate a very complex textual ID that greatly reduces the chance of a collision with another ID or text.\n */\n function uid(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n }\n\n /**\n * Detach the container from DOM\n */\n function detach() {\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() {\n if (debounceTimer) {\n window.clearTimeout(debounceTimer);\n }\n }\n\n /**\n * Attach the container to DOM\n */\n function attach() {\n if (!container.parentNode) {\n (customContainerParent || 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() {\n // prevent the update call if there are pending AJAX requests\n fetchCounter++;\n\n items = [];\n inputValue = '';\n selected = undefined;\n input.setAttribute('aria-activedescendant', '');\n input.setAttribute('aria-expanded', 'false');\n detach();\n }\n\n /**\n * Update autocomplete position\n */\n function updatePosition() {\n if (!containerDisplayed()) {\n return;\n }\n\n input.setAttribute('aria-expanded', 'true');\n\n containerStyle.height = 'auto';\n containerStyle.width = input.offsetWidth + 'px';\n\n let maxHeight = 0;\n let inputRect: 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() {\n\n container.textContent = '';\n input.setAttribute('aria-activedescendant', '');\n\n // function for rendering autocomplete suggestions\n let render = function (item: T, _: string, __: number): HTMLDivElement | undefined {\n const itemElement = doc.createElement('div');\n itemElement.textContent = 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, _: 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 = uid();\n\n items.forEach(function (item: T, index: number): 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, index);\n if (div) {\n div.id = `${container.id}_${index}`;\n div.setAttribute('role', 'option');\n div.addEventListener('click', function (ev: MouseEvent): void {\n suppressAutocomplete = true;\n try {\n settings.onSelect(item, input);\n } finally {\n suppressAutocomplete = false;\n }\n clear();\n ev.preventDefault();\n ev.stopPropagation();\n });\n if (item === selected) {\n div.className += ' selected';\n div.setAttribute('aria-selected', 'true');\n input.setAttribute('aria-activedescendant', div.id);\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.id = `${container.id}_${uid()}`;\n empty.className = 'empty';\n empty.textContent = settings.emptyMsg;\n container.appendChild(empty);\n input.setAttribute('aria-activedescendant', empty.id);\n } else {\n clear();\n return;\n }\n }\n\n attach();\n updatePosition();\n\n updateScroll();\n }\n\n function updateIfDisplayed() {\n if (containerDisplayed()) {\n update();\n }\n }\n\n function resizeEventHandler() {\n updateIfDisplayed();\n }\n\n function scrollEventHandler(e: Event) {\n if (e.target !== container) {\n updateIfDisplayed();\n } else {\n e.preventDefault();\n }\n }\n\n function inputEventHandler() {\n if (!suppressAutocomplete) {\n fetch(EventTrigger.Keyboard);\n }\n }\n\n /**\n * Automatically move scroll bar if selected item is not visible\n */\n function updateScroll() {\n const elements = container.getElementsByClassName('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 function selectPreviousSuggestion() {\n const index = items.indexOf(selected!);\n\n selected = index === -1\n ? undefined\n : items[(index + items.length - 1) % items.length];\n\n updateSelectedSuggestion(index);\n }\n\n function selectNextSuggestion() {\n const index = items.indexOf(selected!);\n\n selected = items.length < 1\n ? undefined\n : index === -1\n ? items[0]\n : items[(index + 1) % items.length];\n\n updateSelectedSuggestion(index);\n }\n\n function updateSelectedSuggestion(index: number) {\n if (items.length > 0) {\n unselectSuggestion(index);\n selectSuggestion(items.indexOf(selected!));\n updateScroll();\n }\n }\n\n function selectSuggestion(index: number) {\n var element = doc.getElementById(container.id + \"_\" + index);\n if (element) {\n element.classList.add('selected');\n element.setAttribute('aria-selected', 'true');\n input.setAttribute('aria-activedescendant', element.id);\n }\n }\n\n function unselectSuggestion(index: number) {\n var element = doc.getElementById(container.id + \"_\" + index);\n if (element) {\n element.classList.remove('selected');\n element.removeAttribute('aria-selected');\n input.removeAttribute('aria-activedescendant');\n }\n }\n\n function handleArrowAndEscapeKeys(ev: KeyboardEvent, key: 'ArrowUp' | 'ArrowDown' | 'Escape') {\n const containerIsDisplayed = containerDisplayed();\n\n if (key === 'Escape') {\n clear();\n } else {\n if (!containerIsDisplayed || items.length < 1) {\n return;\n }\n key === 'ArrowUp'\n ? selectPreviousSuggestion()\n : selectNextSuggestion();\n }\n\n ev.preventDefault();\n\n if (containerIsDisplayed) {\n ev.stopPropagation();\n }\n }\n\n function handleEnterKey(ev: KeyboardEvent) {\n if (selected) {\n if (preventSubmit === PreventSubmit.OnSelect) {\n ev.preventDefault();\n }\n suppressAutocomplete = true;\n try {\n settings.onSelect(selected, input);\n } finally {\n suppressAutocomplete = false;\n }\n clear();\n }\n\n if (preventSubmit === PreventSubmit.Always) {\n ev.preventDefault();\n }\n }\n\n function keydownEventHandler(ev: KeyboardEvent) {\n const key = ev.key;\n\n switch (key) {\n case 'ArrowUp':\n case 'ArrowDown':\n case 'Escape':\n handleArrowAndEscapeKeys(ev, key);\n break;\n case 'Enter':\n handleEnterKey(ev);\n break;\n default:\n break;\n }\n }\n\n function focusEventHandler() {\n if (showOnFocus) {\n fetch(EventTrigger.Focus);\n }\n }\n\n function fetch(trigger: EventTrigger) {\n if (input.value.length >= minLen || trigger === EventTrigger.Focus) {\n clearDebounceTimer();\n debounceTimer = window.setTimeout(\n () => startFetch(input.value, trigger, input.selectionStart || 0),\n trigger === EventTrigger.Keyboard || trigger === EventTrigger.Mouse ? debounceWaitMs : 0);\n } else {\n clear();\n }\n }\n\n function startFetch(inputText: string, trigger: EventTrigger, cursorPos: number) {\n if (destroyed) return;\n const savedFetchCounter = ++fetchCounter;\n settings.fetch(inputText, function (elements: T[] | false): void {\n if (fetchCounter === savedFetchCounter && elements) {\n items = elements;\n inputValue = inputText;\n selected = (items.length < 1 || disableAutoSelect) ? undefined : items[0];\n update();\n }\n }, trigger, cursorPos);\n }\n\n function keyupEventHandler(e: KeyboardEvent) {\n if (settings.keyup) {\n settings.keyup({\n event: e,\n fetch: () => fetch(EventTrigger.Keyboard)\n });\n return;\n }\n\n if (!containerDisplayed() && e.key === 'ArrowDown') {\n fetch(EventTrigger.Keyboard);\n }\n }\n\n function clickEventHandler(e: MouseEvent) {\n settings.click && settings.click({\n event: e,\n fetch: () => fetch(EventTrigger.Mouse)\n });\n }\n\n function blurEventHandler() {\n // when an item is selected by mouse click, the blur event will be initiated before the click event and remove DOM elements,\n // so that the click event will never be triggered. In order to avoid this issue, DOM removal should be delayed.\n setTimeout(() => {\n if (doc.activeElement !== input) {\n clear();\n }\n }, 200);\n }\n\n function manualFetch() {\n startFetch(input.value, EventTrigger.Manual, input.selectionStart || 0);\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 // If the custom autocomplete container is already appended to the DOM during widget initialization, detach it.\n detach();\n\n /**\n * This function will remove DOM elements and clear event handlers\n */\n function destroy() {\n input.removeEventListener('focus', focusEventHandler);\n input.removeEventListener('keyup', keyupEventHandler as EventListenerOrEventListenerObject)\n input.removeEventListener('click', clickEventHandler as EventListenerOrEventListenerObject)\n input.removeEventListener('keydown', keydownEventHandler as EventListenerOrEventListenerObject);\n input.removeEventListener('input', inputEventHandler as EventListenerOrEventListenerObject);\n input.removeEventListener('blur', blurEventHandler);\n window.removeEventListener('resize', resizeEventHandler);\n doc.removeEventListener('scroll', scrollEventHandler, true);\n input.removeAttribute('role');\n input.removeAttribute('aria-expanded');\n input.removeAttribute('aria-autocomplete');\n input.removeAttribute('aria-controls');\n input.removeAttribute('aria-activedescendant');\n input.removeAttribute('aria-owns');\n input.removeAttribute('aria-haspopup');\n clearDebounceTimer();\n clear();\n destroyed = true;\n }\n\n // setup event handlers\n input.addEventListener('keyup', keyupEventHandler as EventListenerOrEventListenerObject);\n input.addEventListener('click', clickEventHandler as EventListenerOrEventListenerObject);\n input.addEventListener('keydown', keydownEventHandler as EventListenerOrEventListenerObject);\n input.addEventListener('input', inputEventHandler as EventListenerOrEventListenerObject);\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 fetch: manualFetch\n };\n}\n"],"names":["settings","doc","document","container","createElement","preventSubmit","id","uid","selected","debounceTimer","containerStyle","style","debounceWaitMs","disableAutoSelect","customContainerParent","parentElement","items","inputValue","minLen","showOnFocus","fetchCounter","destroyed","suppressAutocomplete","undefined","minLength","input","Error","Date","now","toString","Math","random","substring","detach","parent","parentNode","removeChild","clearDebounceTimer","window","clearTimeout","containerDisplayed","clear","setAttribute","update","textContent","render","item","_","__","itemElement","label","renderGroup","groupName","groupDiv","fragment","createDocumentFragment","prevGroup","forEach","index","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","updateScroll","updateIfDisplayed","resizeEventHandler","scrollEventHandler","e","target","inputEventHandler","fetch","elements","getElementsByClassName","element","previous","previousElementSibling","indexOf","offsetTop","selectBottom","containerBottom","updateSelectedSuggestion","getElementById","classList","remove","removeAttribute","unselectSuggestion","add","selectSuggestion","handleArrowAndEscapeKeys","key","containerIsDisplayed","selectNextSuggestion","keydownEventHandler","handleEnterKey","focusEventHandler","trigger","value","setTimeout","startFetch","selectionStart","inputText","cursorPos","savedFetchCounter","keyupEventHandler","keyup","event","clickEventHandler","click","blurEventHandler","activeElement","join","trim","position","evt","focus","destroy","removeEventListener"],"mappings":"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"}