Hello! I am Redis Copilot, I can provide answers about Redis products and solutions.

How can I help you?


Redis Copilot is powered by OpenAI API and is for general info only; avoid inputting confidential or personal data. By using it, you agree to its Terms and Privacy Policy.
Verify any information from Redis Copilot before using
restart the conversation
` : ''} ${key.replace(new RegExp(`(^|)(${searchTerm})(|$)`, 'ig'), '$1$2$3')} ` ) }) if (!resultsContainer.querySelector('[aria-selected]')) resultsContainer.querySelector('.search-item').setAttribute('aria-selected', '') }) } return } function displayError(error) { console.log(error) } search(`https://redis.io/convai/api/search-service?q=${searchTerm}*&p=${searchProduct}&site=${searchSite}`) .then(displayData) .catch(displayError) } function loadHandler(event) { style.innerHTML = ` [data-scroll-disabled="on"], [data-scroll-disabled="on"] body { touch-action: none; overscroll-behavior: none; -webkit-overflow-scrolling: auto; overflow: hidden; } [data-scroll-disabled="on"] .sticky { position: fixed; } ` document.head.appendChild(style) document.documentElement.dataset.searchState = 'off' } function getNextSibling(elem, selector, direction) { let sibling = direction === 'down' ? elem.nextElementSibling : elem.previousElementSibling while (sibling) { if (sibling.matches(selector)) return sibling sibling = direction === 'down' ? sibling.nextElementSibling : sibling.previousElementSibling } } function tabSelection(direction) { const currentSelection = resultsContainer.querySelector('[aria-selected]') if (!currentSelection || direction === 'down' && !currentSelection.nextElementSibling || direction === 'up' && !currentSelection.previousElementSibling) return false const nextSelection = getNextSibling(currentSelection, '.search-item', direction) if (!nextSelection) return false nextSelection.setAttribute('aria-selected', '') currentSelection.removeAttribute('aria-selected') resultsContainer.scrollTop = nextSelection.offsetTop - resultsContainer.offsetTop } function keyDownHandler(event) { switch (event.key) { // Arrow keys case 'ArrowDown': if (document.documentElement.dataset.searchState === 'off' || !document.querySelector('.search-item')) return false event.preventDefault() tabSelection('down') break case 'ArrowUp': if (document.documentElement.dataset.searchState === 'off' || !document.querySelector('.search-item')) return false event.preventDefault() tabSelection('up') break // Tab case 'Tab': if (document.documentElement.dataset.searchState === 'off') return false if (focusable.length === 1) { event.preventDefault() break } // If shift is fired, tab backward if (event.shiftKey) { if (document.activeElement === firstFocusable) { event.preventDefault() lastFocusable.focus() } // Otherwise tab forward } else { if (document.activeElement === lastFocusable) { event.preventDefault() firstFocusable.focus() } } break // Esc case 'Escape': if (document.documentElement.dataset.searchState === 'off') return false stopSearch() break // Enter case 'Enter': if (!document.querySelector('.search-item:focus-within') && document.querySelector('.search-item[aria-selected]')) { event.preventDefault() document.querySelector('.search-item[aria-selected] a').click() } break // Forward slash case '/': if (document.documentElement.dataset.searchState === 'on') return false event.preventDefault() startSearch() break // Default default: return false break } } function changeHandler(event) { searchSubmit(document.activeElement.closest('form')) } function keyUpHandler(event) { if (document.documentElement.dataset.searchState === 'off' || !document.activeElement.matches('.search-input')) return false switch (event.key) { case 'Meta': return false break case 'ArrowDown': return false break case 'ArrowUp': return false break case 'ArrowLeft': return false break case 'ArrowRight': return false break case 'Tab': return false break case 'Escape': return false break case 'Enter': return false break case '/': return false break default: searchSubmit(document.activeElement.closest('form')) break } } function multiKeyHandler(event) { if (document.documentElement.dataset.searchState === 'on') return false let { key, type } = event let isKeyDown = (type == 'keydown') keys[key] = isKeyDown // Both (cmd || cntrl) & k pressed if (isKeyDown && (keys.Control || keys.Meta) && keys.k) { event.preventDefault() startSearch() } } // Click handler function function clickHandler(event) { if (event.target.closest('#search-button') || event.target.closest('#search-button-mobile')) { startSearch() } else if (event.target.closest('#search-cancel') || event.target.matches('#search-container')) { stopSearch() } } function startSearch() { sessionStorage.setItem('scroll-position', document.documentElement.scrollTop) document.documentElement.dataset.scrollDisabled = 'on' document.documentElement.dataset.searchState = 'on' allowFocus(searchContainer, true) trapFocus(searchContainer) searchInput.focus() } function stopSearch() { document.documentElement.dataset.searchState = 'off' document.documentElement.dataset.scrollDisabled = 'off' document.documentElement.scrollTop = sessionStorage.getItem('scroll-position') allowFocus(searchContainer, false) document.activeElement.blur() resultsContainer.innerHTML = '' searchInput.value = '' keys = {} } function submitHandler(event) { if (event.target.id === 'search-form') { event.preventDefault() return false } } function allowFocus(selector, state) { const focusable = selector.querySelectorAll('button, [href], input, select, textarea') focusable.forEach(el => el.setAttribute('tabindex', state ? '' : '-1')) selector.classList.toggle('sr-only') } function trapFocus(selector) { focusable = selector.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]') firstFocusable = focusable[0] lastFocusable = focusable[focusable.length - 1] } // Attach event listeners document.addEventListener('DOMContentLoaded', loadHandler) document.addEventListener('click', clickHandler) document.addEventListener('keydown', event => debounce(keyDownHandler(event), 100)) document.addEventListener('keyup', event => debounce(keyUpHandler(event), 100)) searchSelect.addEventListener('change', event => debounce(changeHandler(event), 100)) document.addEventListener('keydown', multiKeyHandler) document.addEventListener('keyup', multiKeyHandler) document.addEventListener('submit', submitHandler) })()