Repository: eslint/eslint
File: docs/src/assets/js/search.js (JavaScript)

Code before:
    const { offsetHeight, offsetTop } = activeElement;
    const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;

    const isAbove = offsetTop < scrollTop;
    const isBelow = (offsetTop + offsetHeight) > (scrollTop + parentOffsetHeight);

    if (isAbove) {
        scrollParent.scrollTo(0, offsetTop);
    }
    else if (isBelow) {
        scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight);
    }

}

/**
 * Debounces the provided callback with a given delay.
 * @param {Function} callback The callback that needs to be debounced.
 * @param {Number} delay Time in ms that the timer shoud wait before the callback is executed.
 * @returns {Function}
 */
function debounce(callback, delay) {
    let timer;
    return (...args) => {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => callback(...args), delay)
    }
}

const debouncedFetchSearchResults = debounce((query, onsuccess, onerror) => {
    fetchSearchResults(query)
        .then(onsuccess)
        .catch(onerror);
}, 300);

//-----------------------------------------------------------------------------
// Event Handlers
//-----------------------------------------------------------------------------

// listen for input changes
if(searchInput)
    searchInput.addEventListener('keyup', function (e) {
        const query = searchInput.value;

        if(query === searchQuery) return;

        if(query.length) searchClearBtn.removeAttribute('hidden');
        else searchClearBtn.setAttribute('hidden', '');

        if (query.length > 2) {


Review comment (suggestion):
```suggestion
        timer = setTimeout(() => callback.apply(this, args), delay)
```
Use the apply method to bind the `this` & arguments to the called function


Code after:
    const isAbove = offsetTop < scrollTop;
    const isBelow = (offsetTop + offsetHeight) > (scrollTop + parentOffsetHeight);

    if (isAbove) {
        scrollParent.scrollTo(0, offsetTop);
    }
    else if (isBelow) {
        scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight);
    }

}

/**
 * Debounces the provided callback with a given delay.
 * @param {Function} callback The callback that needs to be debounced.
 * @param {Number} delay Time in ms that the timer should wait before the callback is executed.
 * @returns {Function} Returns the new debounced function.
 */
function debounce(callback, delay) {
    let timer;
    return (...args) => {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => callback.apply(this, args), delay);
    }
}

const debouncedFetchSearchResults = debounce((query) => {
    fetchSearchResults(query)
        .then(displaySearchResults)
        .catch(clearSearchResults);
}, 300);

//-----------------------------------------------------------------------------
// Event Handlers
//-----------------------------------------------------------------------------

// listen for input changes
if(searchInput)
    searchInput.addEventListener('keyup', function (e) {
        const query = searchInput.value;

        if(query === searchQuery) return;

        if(query.length) searchClearBtn.removeAttribute('hidden');
        else searchClearBtn.setAttribute('hidden', '');

        if (query.length > 2) {

            debouncedFetchSearchResults(query);

            document.addEventListener('click', function(e) {